From e167fa5229d72146664adddeda653a85d324a7ad Mon Sep 17 00:00:00 2001 From: Zhicheng Wang Date: Sat, 24 Mar 2018 16:33:17 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=BF=BB=E8=AF=91=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/content/guide/ajs-quick-reference.md | 60 - aio/content/guide/animations.md | 3 - aio/content/guide/aot-compiler.md | 75 +- aio/content/guide/api-page-class.md | 31 +- aio/content/guide/architecture-modules.md | 2 + aio/content/guide/architecture.md | 4 +- aio/content/guide/attribute-directives.md | 10 +- aio/content/guide/bootstrapping.md | 11 +- aio/content/guide/browser-support.md | 11 - aio/content/guide/change-log.md | 1 - aio/content/guide/cheatsheet.md | 41 +- aio/content/guide/comparing-observables.md | 85 +- aio/content/guide/component-interaction.md | 1 - aio/content/guide/component-styles.md | 23 +- .../guide/dependency-injection-pattern.md | 5 - aio/content/guide/dependency-injection.md | 42 +- aio/content/guide/deployment.md | 27 - aio/content/guide/displaying-data.md | 4 - aio/content/guide/docs-style-guide.md | 29 - aio/content/guide/dynamic-form.md | 1 - aio/content/guide/entry-components.md | 14 +- aio/content/guide/feature-modules.md | 17 +- aio/content/guide/form-validation.md | 7 - aio/content/guide/forms.md | 2 +- aio/content/guide/frequent-ngmodules.md | 4 +- aio/content/guide/glossary.md | 11 - aio/content/guide/http.md | 62 +- aio/content/guide/i18n.md | 50 +- aio/content/guide/language-service.md | 1 - aio/content/guide/lazy-loading-ngmodules.md | 6 +- aio/content/guide/lifecycle-hooks.md | 19 - aio/content/guide/module-types.md | 7 +- aio/content/guide/ngmodule-api.md | 6 +- aio/content/guide/ngmodule-faq.md | 2 - aio/content/guide/ngmodule-vs-jsmodule.md | 2 +- aio/content/guide/ngmodules.md | 7 +- aio/content/guide/npm-packages.md | 1 - aio/content/guide/observables.md | 12 +- aio/content/guide/pipes.md | 6 +- aio/content/guide/providers.md | 10 +- aio/content/guide/quickstart.md | 34 +- aio/content/guide/reactive-forms.md | 3 +- aio/content/guide/router.md | 27 +- aio/content/guide/security.md | 3 +- .../guide/service-worker-communications.md | 6 +- aio/content/guide/service-worker-config.md | 5 +- aio/content/guide/service-worker-devops.md | 10 +- .../guide/service-worker-getting-started.md | 6 +- aio/content/guide/service-worker-intro.md | 4 +- aio/content/guide/set-document-title.md | 5 - aio/content/guide/setup-systemjs-anatomy.md | 2 - aio/content/guide/setup.md | 4 - aio/content/guide/sharing-ngmodules.md | 8 +- aio/content/guide/singleton-services.md | 7 +- aio/content/guide/structural-directives.md | 1 - aio/content/guide/styleguide.md | 37 - aio/content/guide/template-syntax.md | 138 +- aio/content/guide/testing.md | 129 - aio/content/guide/typescript-configuration.md | 2 - aio/content/guide/universal.md | 25 +- aio/content/guide/upgrade.md | 133 - aio/content/guide/user-input.md | 4 - aio/content/guide/visual-studio-2015.md | 6 +- aio/content/guide/webpack.md | 22 +- aio/content/navigation.json | 2 +- aio/content/tutorial/toh-pt0.md | 14 +- aio/content/tutorial/toh-pt1.md | 18 +- aio/content/tutorial/toh-pt2.md | 17 +- aio/content/tutorial/toh-pt3.md | 14 +- aio/content/tutorial/toh-pt4.md | 31 +- aio/content/tutorial/toh-pt5.md | 43 +- aio/content/tutorial/toh-pt6.md | 30 - aio/tools/translator/bin/translate-one.ts | 2 +- aio/tools/translator/dict-entry.ts | 1 + aio/tools/translator/dict-latest.json | 10928 +++++++++++++--- aio/tools/translator/extractor.ts | 17 +- aio/tools/translator/translate.spec.ts | 10 +- aio/tools/translator/translate.ts | 38 +- aio/tools/translator/utils.spec.ts | 217 +- aio/tools/translator/utils.ts | 121 +- 80 files changed, 9875 insertions(+), 2961 deletions(-) diff --git a/aio/content/guide/ajs-quick-reference.md b/aio/content/guide/ajs-quick-reference.md index 2a928141b4..ba038fbd11 100644 --- a/aio/content/guide/ajs-quick-reference.md +++ b/aio/content/guide/ajs-quick-reference.md @@ -62,9 +62,7 @@ The following table lists some of the key AngularJS template features with their ### 绑定/插值表达式 - Your favorite hero is: {{vm.favoriteHero}} - In AngularJS, an expression in curly braces denotes one-way binding. @@ -118,9 +116,7 @@ The following table lists some of the key AngularJS template features with their ### 过滤器 - <td>{{movie.title | uppercase}}</td> - To filter output in AngularJS templates, use the pipe character (|) and one or more filters. @@ -165,11 +161,9 @@ The following table lists some of the key AngularJS template features with their ### 局部变量 - <tr ng-repeat="movie in vm.movies"> <td>{{movie.title}}</td> </tr> - Here, `movie` is a user-defined local variable. @@ -246,9 +240,7 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-app - <body ng-app="movieHunter"> - The application startup process is called **bootstrapping**. @@ -295,11 +287,9 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-class - <div ng-class="{active: isActive}"> <div ng-class="{active: isActive, shazam: isImportant}"> - In AngularJS, the `ng-class` directive includes/excludes CSS classes @@ -361,10 +351,8 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-click - <button ng-click="vm.toggleImage()"> <button ng-click="vm.toggleImage($event)"> - In AngularJS, the `ng-click` directive allows you to specify custom behavior when an element is clicked. @@ -433,9 +421,7 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-controller - <div ng-controller="MovieListCtrl as vm"> - In AngularJS, the `ng-controller` directive attaches a controller to the view. @@ -506,9 +492,7 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-href - <a ng-href="{{ angularDocsUrl }}">Angular Docs</a> - The `ng-href` directive allows AngularJS to preprocess the `href` property so that it @@ -522,9 +506,7 @@ AngularJS 为模板提供了七十多个内置指令。 在 AngularJS 中,`ng-href` 通常用来作为导航的一部分,激活一个路由。 - <a ng-href="#{{ moviesHash }}">Movies</a> - Routing is handled differently in Angular. @@ -574,9 +556,7 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-if - <table ng-if="movies.length"> - In AngularJS, the `ng-if` directive removes or recreates a portion of the DOM, @@ -623,9 +603,7 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-model - <input ng-model="vm.favoriteHero"/> - In AngularJS, the `ng-model` directive binds a form control to a property in the controller associated with the template. @@ -665,9 +643,7 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-repeat - <tr ng-repeat="movie in vm.movies"> - In AngularJS, the `ng-repeat` directive repeats the associated DOM element @@ -719,11 +695,9 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-show - <h3 ng-show="vm.favoriteHero"> Your favorite hero is: {{vm.favoriteHero}} </h3> - In AngularJS, the `ng-show` directive shows or hides the associated DOM element, based on @@ -776,9 +750,7 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-src - <img ng-src="{{movie.imageurl}}"> - The `ng-src` directive allows AngularJS to preprocess the `src` property so that it @@ -819,9 +791,7 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-style - <div ng-style="{color: colorPreference}"> - In AngularJS, the `ng-style` directive sets a CSS style on an HTML element @@ -877,7 +847,6 @@ AngularJS 为模板提供了七十多个内置指令。 ### ng-switch - <div ng-switch="vm.favoriteHero && vm.checkMovieHero(vm.favoriteHero)"> <div ng-switch-when="true"> @@ -890,7 +859,6 @@ AngularJS 为模板提供了七十多个内置指令。 Please enter your favorite hero. </div> </div> - In AngularJS, the `ng-switch` directive swaps the contents of @@ -996,9 +964,7 @@ AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 ### currency - <td>{{movie.price | currency}}</td> - Formats a number as currency. @@ -1028,9 +994,7 @@ AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 ### date - <td>{{movie.releaseDate | date}}</td> - Formats a date to a string based on the requested format. @@ -1060,9 +1024,7 @@ AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 ### filter - <tr ng-repeat="movie in movieList | filter: {title:listFilter}"> - Selects a subset of items from the defined collection, based on the filter criteria. @@ -1094,9 +1056,7 @@ AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 ### json - <pre>{{movie | json}}</pre> - Converts a JavaScript object into a JSON string. This is useful for debugging. @@ -1126,9 +1086,7 @@ AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 ### limitTo - <tr ng-repeat="movie in movieList | limitTo:2:0"> - Selects up to the first parameter (2) number of items from the collection @@ -1164,9 +1122,7 @@ AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 ### lowercase - <div>{{movie.title | lowercase}}</div> - Converts the string to lowercase. @@ -1196,9 +1152,7 @@ AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 ### number - <td>{{movie.starRating | number}}</td> - Formats a number as text. @@ -1236,9 +1190,7 @@ AngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。 ### orderBy - <tr ng-repeat="movie in movieList | orderBy : 'title'"> - Displays the collection in the order specified by the expression. @@ -1322,11 +1274,9 @@ The Angular code is shown using TypeScript. ### IIFE - (function () { ... }()); - In AngularJS, an immediately invoked function expression (or IIFE) around controller code @@ -1365,9 +1315,7 @@ The Angular code is shown using TypeScript. ### Angular 模块 - angular.module("movieHunter", ["ngRoute"]); - In AngularJS, an Angular module keeps track of controllers, services, and other code. @@ -1412,13 +1360,11 @@ The Angular code is shown using TypeScript. ### 控制器注册 - angular .module("movieHunter") .controller("MovieListCtrl", ["movieService", MovieListCtrl]); - AngularJS has code in each controller that looks up an appropriate Angular module @@ -1470,10 +1416,8 @@ The Angular code is shown using TypeScript. ### 控制器函数 - function MovieListCtrl(movieService) { } - In AngularJS, you write the code for the model and methods in a controller function. @@ -1516,11 +1460,9 @@ The Angular code is shown using TypeScript. ### 依赖注入 - MovieListCtrl.$inject = ['MovieService']; function MovieListCtrl(movieService) { } - In AngularJS, you pass in any dependencies as controller function arguments. @@ -1616,9 +1558,7 @@ also encapsulate a style sheet within a specific component. ### Link 标签 - <link href="styles.css" rel="stylesheet" /> - AngularJS, uses a `link` tag in the head section of the `index.html` file diff --git a/aio/content/guide/animations.md b/aio/content/guide/animations.md index 2ab2abc18e..40f95462f9 100644 --- a/aio/content/guide/animations.md +++ b/aio/content/guide/animations.md @@ -291,10 +291,8 @@ These two common animations have their own aliases: 这两个常见的动画有自己的别名: - transition(':enter', [ ... ]); // void => * transition(':leave', [ ... ]); // * => void - @@ -562,5 +560,4 @@ The callbacks receive an `AnimationEvent` that contains useful properties such a Those callbacks will fire whether or not an animation is picked up. - 无论动画是否实际执行过,那些回调都会触发。 diff --git a/aio/content/guide/aot-compiler.md b/aio/content/guide/aot-compiler.md index 0471294df9..1da52a6fe4 100644 --- a/aio/content/guide/aot-compiler.md +++ b/aio/content/guide/aot-compiler.md @@ -48,10 +48,8 @@ JIT compilation is the default when you run the _build-only_ or the _build-and-s 当你运行 *`build`* 或 *`serve`* 这两个 CLI 命令时 JIT 编译是默认选项: - ng build ng serve - {@a compile} @@ -61,10 +59,8 @@ For AOT compilation, append the `--aot` flags to the _build-only_ or the _build- 要进行 AOT 编译只要给这两个 CLI 命令添加 `--aot` 标志就行了: - ng build --aot ng serve --aot -
@@ -170,7 +166,7 @@ The option is `false` by default. 这个选项告诉编译器不要生成 `.metadata.json` 文件,它默认是 `false`。 -`.metadata.json` files contain information needed by the template compiler from a `.ts` +`.metadata.json` files contain infomration needed by the template compiler from a `.ts` file that is not included in the `.d.ts` file produced by the TypeScript compiler. This information contains, for example, the content of annotations (such as a component's template) which TypeScript emits to the `.js` file but not to the `.d.ts` file. @@ -195,7 +191,6 @@ include a copy of the information that is in the `.metadata.json` file. This option tells the template compiler to report an error to the `.metadata.json` file if `"skipMetadataEmit"` is `false` . This option is `false` by default. This should only be used when `"skipMetadataEmit"` is `false` and `"skipTemplateCodeGen"` is `true`. - 这个选项告诉模板编译器如果 `"skipMetadataEmit"` 为 `false`,那就把错误信息汇报到 `.metadata.json` 中。 只有当 `"skipMetadataEmit"` 为 `false` 且 `"skipTemplateCodeGen"` 为 `true` 时才应该使用这个选项。 @@ -383,21 +378,21 @@ rules. 这是供 `bazel` 构建规则使用的选项,它用于简化 `bazel` 规则跟踪文件依赖的方式。 除了 `bazel` 规则之外不建议使用该选项。 -### *enableIvy* + ### *enableIvy* -Tells the compiler to generate definitions using the Render3 style code generation. This option defaults to `false`. + Tells the compiler to generate definitions using the Render3 style code generation. This option defaults to `false`. -告诉编译器使用 Render3 风格的代码生成器来来生成各种定义。 + 告诉编译器使用 Render3 风格的代码生成器来来生成各种定义。 该选项默认为 `false`。 -Not all features are supported with this option enabled. It is only supported -for experimentation and testing of Render3 style code generation. + Not all features are supported with this option enabled. It is only supported + for experimentation and testing of Render3 style code generation. -当开启该选项时,有些特性不受支持。它仅仅用来为试验和测试 Render3 风格的代码生成提供支持。 + 当开启该选项时,有些特性不受支持。它仅仅用来为试验和测试 Render3 风格的代码生成提供支持。 -*Note*: Is it not recommended to use this option as it is not yet feature complete with the Render2 code generation. + *Note*: Is it not recommended to use this option as it is not yet feature complete with the Render2 code generation. -*注意*:不建议使用该选项,因为它在使用 Render2 的代码生成器时还缺少一些特性。 + *注意*:不建议使用该选项,因为它在使用 Render2 的代码生成器时还缺少一些特性。 ## Angular Metadata and AOT @@ -828,7 +823,7 @@ The compiler only supports metadata for these Angular decorators. 编译器只支持下列 Angular 装饰器的元数据。 -Decorator装饰器 | Module所在模块 +Decorator装饰器 | Module所在模块 ------------------|-------------- `Attribute` | `@angular/core` `Component` | `@angular/core` @@ -982,18 +977,18 @@ The following are metadata errors you may encounter, with explanations and sugge 你可能遇到一些元数据错误,下面是对它们的解释和纠正建议。 -[Expression form not supported 【不支持此表达式格式】](#expression-form-not-supported)
-[Reference to a local (non-exported) symbol【引用了局部(未导出的)符号】](#reference-to-a-local-symbol)
-[Only initialized variables and constants【只允许初始化过的变量和常量】](#only-initialized-variables)
-[Reference to a non-exported class【引用了未导出的类】](#reference-to-a-non-exported-class)
-[Reference to a non-exported function【引用了未导出的函数】](#reference-to-a-non-exported-function)
-[Function calls are not supported【不支持函数调用】](#function-calls-not-supported)
-[Destructured variable or constant not supported【不支持解构变量或常量】](#destructured-variable-not-supported)
-[Could not resolve type【不能解析此类型】](#could-not-resolve-type)
-[Name expected【期待是名字】](#name-expected)
-[Unsupported enum member name【不支持的枚举成员名】](#unsupported-enum-member-name)
-[Tagged template expressions are not supported【不支持带标签函数的模板表达式】](#tagged-template-expressions-not-supported)
-[Symbol reference expected【期待是符号引用】](#symbol-reference-expected)
+[Expression form not supported【不支持此表达式格式】](#expression-form-not-supported)
+[Reference to a local (non-exported) symbol【引用了局部(未导出的)符号】](#reference-to-a-local-symbol)
+[Only initialized variables and constants【只允许初始化过的变量和常量】](#only-initialized-variables)
+[Reference to a non-exported class【引用了未导出的类】](#reference-to-a-non-exported-class)
+[Reference to a non-exported function【引用了未导出的函数】](#reference-to-a-non-exported-function)
+[Function calls are not supported【不支持函数调用】](#function-calls-not-supported)
+[Destructured variable or constant not supported【不支持解构变量或常量】](#destructured-variable-not-supported)
+[Could not resolve type【不能解析此类型】](#could-not-resolve-type)
+[Name expected【期待是名字】](#name-expected)
+[Unsupported enum member name【不支持的枚举成员名】](#unsupported-enum-member-name)
+[Tagged template expressions are not supported【不支持带标签函数的模板表达式】](#tagged-template-expressions-not-supported)
+[Symbol reference expected【期待是符号引用】](#symbol-reference-expected)

@@ -1383,7 +1378,6 @@ To correct this error, export a function from the module and refer to the functi 要改正这个问题,就要从模块中导出这个函数,并改成在服务提供商的 `useFactory` 中引用该函数。 - // CORRECTED import { calculateValue } from './utilities'; @@ -1399,7 +1393,6 @@ export function someValueFactory() { { provide: SomeValue, useFactory: someValueFactory } ] ... -
@@ -1425,7 +1418,6 @@ For example, you cannot write something like this: 比如,你不能这么写: - // ERROR import { configuration } from './configuration'; @@ -1437,7 +1429,6 @@ const {foo, bar} = configuration; {provide: Bar, useValue: bar}, ] ... - To correct this error, refer to non-destructured values. @@ -1445,7 +1436,6 @@ To correct this error, refer to non-destructured values. 要纠正这个错误,就要引用非解构方式的变量。 - // CORRECTED import { configuration } from './configuration'; ... @@ -1454,7 +1444,6 @@ import { configuration } from './configuration'; {provide: Bar, useValue: configuration.bar}, ] ... -
@@ -1528,7 +1517,6 @@ Here's an illustrative example. 下面的例子说明了这一点。 - // CORRECTED import { Inject } from '@angular/core'; @@ -1544,7 +1532,6 @@ export function _window() { return window; } export class MyComponent { constructor (@Inject(WINDOW) private win: Window) { ... } } - The `Window` type in the constructor is no longer a problem for the compiler because it @@ -1557,7 +1544,6 @@ Angular does something similar with the `DOCUMENT` token so you can inject the b Angular 也用 `DOCUMENT` 令牌做了类似的事情,所以你也可以注入浏览器的 `document` 对象(或它的一个抽象层,取决于该应用运行在哪个平台)。 - import { Inject } from '@angular/core'; import { DOCUMENT } from '@angular/platform-browser'; @@ -1565,7 +1551,6 @@ import { DOCUMENT } from '@angular/platform-browser'; export class MyComponent { constructor (@Inject(DOCUMENT) private doc: Document) { ... } } -
@@ -1613,7 +1598,6 @@ The compiler can understand simple enum values but not complex values such as th 编译器可以理解简单的枚举值,但不能理解复杂的,比如从那些计算属性中派生出来的。 - // ERROR enum Colors { Red = 1, @@ -1628,7 +1612,6 @@ enum Colors { { provide: StrongColor, useValue: Colors.Blue } // bad ] ... - Avoid referring to enums with complicated initializers or computed properties. @@ -1915,28 +1898,28 @@ Chuck: After reviewing your PR comment I'm still at a loss. See [comment there]( * What the AOT compiler does and why it is important. - 什么是 AOT 编译器,以及它为什么如此重要。 + 什么是 AOT 编译器,以及它为什么如此重要。 * Why metadata must be written in a subset of JavaScript. - 为何元数据必须使用 JavaScript 的一个子集来书写。 + 为何元数据必须使用 JavaScript 的一个子集来书写。 * What that subset is. - 这个子集是什么。 + 这个子集是什么。 * Other restrictions on metadata definition. - 定义元数据时的其它限制。 + 定义元数据时的其它限制。 * Macro-functions and macro-static methods. - 宏函数和静态宏函数。 + 宏函数和静态宏函数。 * Compiler errors related to metadata. - 与元数据有关的编译器错误。 + 与元数据有关的编译器错误。 * Validation of binding expressions - 验证绑定表达式。 + 验证绑定表达式。 diff --git a/aio/content/guide/api-page-class.md b/aio/content/guide/api-page-class.md index 58e8e16edd..6261f05257 100644 --- a/aio/content/guide/api-page-class.md +++ b/aio/content/guide/api-page-class.md @@ -4,9 +4,7 @@
-
-

Class Name

-
+

Class Name

@@ -84,13 +82,13 @@ +

Constructor

-
   
         constructor(element: any, keyframes: {
         [key: string]: string | number;
@@ -103,7 +101,6 @@
 
         
-
         
-
         
-
         
-
         
-
         
-
         
@@ -131,10 +128,8 @@
@@ -156,7 +151,6 @@
@@ -180,7 +174,6 @@
@@ -204,7 +197,6 @@
@@ -214,7 +206,6 @@ - - - -
@@ -224,10 +215,8 @@
@@ -241,12 +230,10 @@
- - - - -
@@ -256,10 +243,8 @@
@@ -271,11 +256,10 @@
Declaration
-
                     class AnimationBuilder {build(animation: AnimationMetadata | AnimationMetadata[]): AnimationFactory}
-
+
Parameters
@@ -296,13 +280,10 @@ - - - -
-
   
         constructor(element: any, keyframes: {
         [key: string]: string | number;
@@ -318,13 +299,11 @@
                 
-
   
         constructor(element: any, keyframes: {
         [key: string]: string | number;
@@ -340,7 +319,6 @@
                 
@@ -351,9 +329,7 @@

Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.

@@ -364,7 +340,6 @@

Intro description text about what the example is and how it can be used.

-
   
         constructor(element: any, keyframes: {
         [key: string]: string | number;
diff --git a/aio/content/guide/architecture-modules.md b/aio/content/guide/architecture-modules.md
index e99b16a06c..cff91123a6 100644
--- a/aio/content/guide/architecture-modules.md
+++ b/aio/content/guide/architecture-modules.md
@@ -10,6 +10,8 @@ While a small application might have only one NgModule, most apps have many more
 
 ## NgModule metadata
 
+## `@NgModule` 元数据
+
 An NgModule is defined as a class decorated with `@NgModule`. The `@NgModule` decorator is a function that takes a single metadata object, whose properties describe the module. The most important properties are as follows.
 
 * `declarations`—The [components](guide/architecture-components), _directives_, and _pipes_ that belong to this NgModule.
diff --git a/aio/content/guide/architecture.md b/aio/content/guide/architecture.md
index e843637e9d..7b2a1c6e61 100644
--- a/aio/content/guide/architecture.md
+++ b/aio/content/guide/architecture.md
@@ -1,4 +1,4 @@
-# Architecture Overview
+# Architecture overview
 
 # 架构概览
 
@@ -122,6 +122,8 @@ To define navigation rules, you associate *navigation paths* with your component
 
 ## What's next
 
+## 接下来呢?
+
 You've learned the basics about the main building blocks of an Angular application. The following diagram shows how these basic pieces are related.
 
 
diff --git a/aio/content/guide/attribute-directives.md b/aio/content/guide/attribute-directives.md index 3e4dc9a283..071c52b146 100644 --- a/aio/content/guide/attribute-directives.md +++ b/aio/content/guide/attribute-directives.md @@ -83,9 +83,7 @@ Create the directive class file in a terminal window with this CLI command. 在命令行窗口下用 CLI 命令创建指令类文件。 - ng generate directive highlight - The CLI creates `src/app/highlight.directive.ts`, a corresponding test file (`.../spec.ts`, and _declares_ the directive class in the root `AppModule`. @@ -197,9 +195,7 @@ Now run the application to see the `HighlightDirective` in action. 运行这个应用以查看 `HighlightDirective` 的实际效果。 - ng serve - To summarize, Angular found the `appHighlight` attribute on the **host** `

` element. @@ -531,14 +527,12 @@ The final source code follows: 最终的源码如下: - - You can also experience and download the . @@ -624,12 +618,12 @@ Now apply that reasoning to the following example: The template and its component trust each other. The `color` property doesn't require the `@Input` decorator. - `color` 属性位于右侧的绑定表达式中,它属于模板所在的组件。 + `color` 属性位于右侧的绑定表达式中,它属于模板所在的组件。 该模板和组件相互信任。因此 `color` 不需要 `@Input` 装饰器。 * The `appHighlight` property on the left refers to an _aliased_ property of the `HighlightDirective`, not a property of the template's component. There are trust issues. Therefore, the directive property must carry the `@Input` decorator. - `appHighlight` 属性位于左侧,它引用了 `HighlightDirective` 中一个*带别名的*属性,它不是模板所属组件的一部分,因此存在信任问题。 + `appHighlight` 属性位于左侧,它引用了 `HighlightDirective` 中一个*带别名的*属性,它不是模板所属组件的一部分,因此存在信任问题。 所以,该属性必须带 `@Input` 装饰器。 diff --git a/aio/content/guide/bootstrapping.md b/aio/content/guide/bootstrapping.md index 4e19a13227..662ebcbb63 100644 --- a/aio/content/guide/bootstrapping.md +++ b/aio/content/guide/bootstrapping.md @@ -12,7 +12,7 @@ A basic understanding of the following: * [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule). - [JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule). + [JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。


@@ -69,15 +69,15 @@ The `@NgModule` decorator identifies `AppModule` as an `NgModule` class. * **_declarations_**—this application's lone component. - **_declarations_** —— 该应用所拥有的组件。 + **_declarations_** —— 该应用所拥有的组件。 * **_imports_**—import `BrowserModule` to have browser specific services such as DOM rendering, sanitization, and location. - **_imports_** —— 导入 `BrowserModule` 以获取浏览器特有的服务,比如 DOM 渲染、无害化处理和位置(location)。 + **_imports_** —— 导入 `BrowserModule` 以获取浏览器特有的服务,比如 DOM 渲染、无害化处理和位置(location)。 * **_providers_**—the service providers. - **_providers_** —— 各种服务提供商。 + **_providers_** —— 各种服务提供商。 * **_bootstrap_**—the _root_ component that Angular creates and inserts into the `index.html` host web page. @@ -176,7 +176,6 @@ The following example, named `ItemDirective` is the default directive structure 下面的例子中,`item.directive.ts` 中的 `ItemDirective` 是 CLI 自动生成的默认指令结构。 - The key point here is that you have to export it so you can import it elsewhere. Next, import it @@ -185,7 +184,6 @@ into the NgModule, in this example `app.module.ts`, with a JavaScript import sta 重点在于你要先在这里导出它才能在别处导入它。接下来,使用 JavaScript 的 `import` 语句把它导入到 NgModule 中(这里是 `app.module.ts`)。 - And in the same file, add it to the `@NgModule` `declarations` array: @@ -193,7 +191,6 @@ And in the same file, add it to the `@NgModule` `declarations` array: 同样在这个文件中,把它添加到 `@NgModule` 的 `declarations` 数组中: - Now you could use your `ItemDirective` in a component. This example uses `AppModule`, but you'd do it the same way for a feature module. For more about directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives). You'd also use the same technique for [pipes](guide/pipes) and components. diff --git a/aio/content/guide/browser-support.md b/aio/content/guide/browser-support.md index 553264a4f0..094b080ef5 100644 --- a/aio/content/guide/browser-support.md +++ b/aio/content/guide/browser-support.md @@ -81,7 +81,6 @@ Angular 支持大多数常用浏览器,包括下列版本: - @@ -97,9 +96,7 @@ Angular 支持大多数常用浏览器,包括下列版本: - - @@ -115,7 +112,6 @@ Angular 支持大多数常用浏览器,包括下列版本: - @@ -133,7 +129,6 @@ Angular 支持大多数常用浏览器,包括下列版本: - @@ -151,7 +146,6 @@ Angular 支持大多数常用浏览器,包括下列版本: - @@ -239,7 +233,6 @@ For example, [if you need the web animations polyfill](http://caniuse.com/#feat= # it isn't a strict requirement of Angular anymore (more below) npm install --save web-animations-js - Then open the `polyfills.ts` file and un-comment the corresponding `import` statement as in the following example: @@ -247,7 +240,6 @@ Then open the `polyfills.ts` file and un-comment the corresponding `import` stat 然后打开 `polyfills.ts` 文件,并反注释对应的 `import` 语句,就像这样: - /** * Required to support Web Animations `@angular/platform-browser/animations`. @@ -255,7 +247,6 @@ Then open the `polyfills.ts` file and un-comment the corresponding `import` stat * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation **/ import 'web-animations-js'; // Run `npm install --save web-animations-js`. - If you can't find the polyfill you want in `polyfills.ts`, @@ -799,7 +790,6 @@ If you are not using the CLI, you should add your polyfill scripts directly to t 如果你不使用 CLI,就要直接把腻子脚本添加到宿主页(`index.html`)中,就像这样: - <!-- pre-zone polyfills --> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/web-animations-js/web-animations.min.js"></script> @@ -828,5 +818,4 @@ If you are not using the CLI, you should add your polyfill scripts directly to t <script src="node_modules/zone.js/dist/zone.js"></script> <!-- application polyfills --> - diff --git a/aio/content/guide/change-log.md b/aio/content/guide/change-log.md index dc82bc2dad..1561b81d12 100644 --- a/aio/content/guide/change-log.md +++ b/aio/content/guide/change-log.md @@ -431,5 +431,4 @@ modules with SystemJS as the samples currently do. The [Lifecycle Hooks](guide/lifecycle-hooks) guide is shorter, simpler, and draws more attention to the order in which Angular calls the hooks. - [生命周期钩子](guide/lifecycle-hooks)章现在更加简短,并且对强调了 Angular 是以什么顺序来调用钩子方法的。 diff --git a/aio/content/guide/cheatsheet.md b/aio/content/guide/cheatsheet.md index 237026f6a1..ddc00029ad 100644 --- a/aio/content/guide/cheatsheet.md +++ b/aio/content/guide/cheatsheet.md @@ -18,13 +18,11 @@

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -

- @@ -42,7 +40,6 @@ - @@ -57,13 +54,11 @@ - -

import { NgModule } from '@angular/core'; -

@@ -162,7 +157,6 @@ is available to declarations of this module.

@@ -181,7 +175,6 @@ is available to declarations of this module.

- -
@@ -410,7 +403,6 @@ is available to declarations of this module.

@@ -427,13 +419,11 @@ is available to declarations of this module.

- - -

import { CommonModule } from '@angular/common'; -

@@ -499,7 +489,6 @@ is available to declarations of this module.

@@ -517,7 +506,6 @@ is available to declarations of this module.

@@ -534,13 +522,11 @@ is available to declarations of this module.

- -

import { FormsModule } from '@angular/forms'; -

@@ -558,7 +544,6 @@ is available to declarations of this module.

@@ -575,13 +560,11 @@ is available to declarations of this module.

- -

import { Directive, ... } from '@angular/core'; -

@@ -641,16 +624,13 @@ is available to declarations of this module.

Declares that a class has dependencies that should be injected into the constructor when the dependency injector is creating an instance of this class. -

-

声明某个类具有一些依赖。当依赖注入器要创建这个类的实例时,应该把这些依赖注入到它的构造函数中。

@@ -667,13 +647,11 @@ is available to declarations of this module.

- -

@Directive({ property1: value1, ... }) -

@@ -712,7 +690,6 @@ is available to declarations of this module.

@@ -728,7 +705,8 @@ is available to declarations of this module.

- -
-

@Component extends @Directive, +

+@Component extends @Directive, so the @Directive configuration applies to components as well

@Component 继承自 @Directive, @@ -737,7 +715,6 @@ so the @Directive configuration applies to components as well

@@ -803,7 +780,6 @@ so the @Directive configuration applies to components as well

@@ -820,13 +796,11 @@ so the @Directive configuration applies to components as well

- -

import { Input, ... } from '@angular/core'; -

@@ -957,7 +931,6 @@ so the @Directive configuration applies to components as well

@@ -974,15 +947,13 @@ so the @Directive configuration applies to components as well

- -

(implemented as class methods) -

-

由类的方法实现。

+

由类的方法实现。

@@ -1128,7 +1099,6 @@ so the @Directive configuration applies to components as well

@@ -1147,7 +1117,6 @@ so the @Directive configuration applies to components as well

- -
@@ -1197,7 +1166,6 @@ so the @Directive configuration applies to components as well

@@ -1214,13 +1182,11 @@ so the @Directive configuration applies to components as well

- -

import { Routes, RouterModule, ... } from '@angular/router'; -

@@ -1366,7 +1332,6 @@ so the @Directive configuration applies to components as well

diff --git a/aio/content/guide/comparing-observables.md b/aio/content/guide/comparing-observables.md index 8759e56f9e..d0bffb73ae 100644 --- a/aio/content/guide/comparing-observables.md +++ b/aio/content/guide/comparing-observables.md @@ -21,52 +21,48 @@ Observables are often compared to promises. Here are some key differences: * Observables are declarative; computation does not start until subscription. Promises execute immediately on creation. This makes observables useful for defining recipes that can be run whenever you need the result. - 可观察对象是声明式的,在被订阅之前,它不会开始执行。承诺是在创建时就立即执行的。这让可观察对象可用于定义那些应该按需执行的菜谱。 + 可观察对象是声明式的,在被订阅之前,它不会开始执行。承诺是在创建时就立即执行的。这让可观察对象可用于定义那些应该按需执行的菜谱。 * Observables provide many values. Promises provide one. This makes observables useful for getting multiple values over time. - 可观察对象能提供多个值。承诺只提供一个。这让可观察对象可用于随着时间的推移获取多个值。 + 可观察对象能提供多个值。承诺只提供一个。这让可观察对象可用于随着时间的推移获取多个值。 * Observables differentiate between chaining and subscription. Promises only have `.then()` clauses. This makes observables useful for creating complex transformation recipes to be used by other part of the system, without causing the work to be executed. - 可观察对象会区分串联处理和订阅语句。承诺只有 `.then()` 语句。这让可观察对象可用于创建供系统的其它部分使用而不希望立即执行的复杂菜谱。 + 可观察对象会区分串联处理和订阅语句。承诺只有 `.then()` 语句。这让可观察对象可用于创建供系统的其它部分使用而不希望立即执行的复杂菜谱。 * Observables `subscribe()` is responsible for handling errors. Promises push errors to the child promises. This makes observables useful for centralized and predictable error handling. - 可观察对象的 `subscribe()` 会负责处理错误。承诺会把错误推送给它的子承诺。这让可观察对象可用于进行集中式、可预测的错误处理。 + 可观察对象的 `subscribe()` 会负责处理错误。承诺会把错误推送给它的子承诺。这让可观察对象可用于进行集中式、可预测的错误处理。 ### Creation and subscription ### 创建与订阅 -* Observables are not executed until a consumer subscribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values. +* Observables are not executed until a consumer subcribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values. - 在有消费者订阅之前,可观察对象不会执行。`subscribe()` 会执行一次定义好的行为,并且可以再次调用它。每次订阅都是单独计算的。重新订阅会导致重新计算这些值。 + 在有消费者订阅之前,可观察对象不会执行。`subscribe()` 会执行一次定义好的行为,并且可以再次调用它。每次订阅都是单独计算的。重新订阅会导致重新计算这些值。 - // declare a publishing operation new Observable((observer) => { subscriber_fn }); // initiate execution observable.subscribe(() => { // observer handles notifications }); - * Promises execute immediately, and just once. The computation of the result is initiated when the promise is created. There is no way to restart work. All `then` clauses (subscriptions) share the same computation. - 承诺会立即执行,并且只执行一次。当承诺创建时,会立即计算出结果。没有办法重新做一次。所有的 `then` 语句(订阅)都会共享同一次计算。 + 承诺会立即执行,并且只执行一次。当承诺创建时,会立即计算出结果。没有办法重新做一次。所有的 `then` 语句(订阅)都会共享同一次计算。 - // initiate execution new Promise((resolve, reject) => { executer_fn }); // handle return value promise.then((value) => { // handle result here }); - ### Chaining @@ -75,13 +71,13 @@ promise.then((value) => { * Observables differentiate between transformation function such as a map and subscription. Only subscription activates the subscriber function to start computing the values. - 可观察对象会区分各种转换函数,比如映射和订阅。只有订阅才会激活订阅者函数,以开始计算那些值。 + 可观察对象会区分各种转换函数,比如映射和订阅。只有订阅才会激活订阅者函数,以开始计算那些值。 observable.map((v) => 2*v); * Promises do not differentiate between the last `.then` clauses (equivalent to subscription) and intermediate `.then` clauses (equivalent to map). - 承诺并不区分最后的 `.then()` 语句(等价于订阅)和中间的 `.then()` 语句(等价于映射)。 + 承诺并不区分最后的 `.then()` 语句(等价于订阅)和中间的 `.then()` 语句(等价于映射)。 promise.then((v) => 2*v); @@ -91,18 +87,16 @@ promise.then((value) => { * Observable subscriptions are cancellable. Unsubscribing removes the listener from receiving further values, and notifies the subscriber function to cancel work. - 可观察对象的订阅是可取消的。取消订阅会移除监听器,使其不再接受将来的值,并通知订阅者函数取消正在进行的工作。 + 可观察对象的订阅是可取消的。取消订阅会移除监听器,使其不再接受将来的值,并通知订阅者函数取消正在进行的工作。 - const sub = obs.subscribe(...); sub.unsubscribe(); - * Promises are not cancellable. - 承诺是不可取消的。 + 承诺是不可取消的。 ### Error handling @@ -110,26 +104,22 @@ sub.unsubscribe(); * Observable execution errors are delivered to the subscriber's error handler, and the subscriber automatically unsubscribes from the observable. - 可观察对象的错误处理是交给订阅者的错误处理器的,并且该订阅者会自动取消对这个可观察对象的订阅。 + 可观察对象的错误处理是交给订阅者的错误处理器的,并且该订阅者会自动取消对这个可观察对象的订阅。 - obs.subscribe(() => { throw Error('my error'); }); - * Promises push errors to the child promises. - 承诺会把错误推给其子承诺。 + 承诺会把错误推给其子承诺。 - promise.then(() => { throw Error('my error'); }); - ### Cheat sheet @@ -141,7 +131,6 @@ The following code snippets illustrate how the same kind of operation is defined 下列代码片段揭示了同样的操作要如何分别使用可观察对象和承诺进行实现。 - - - - - -
@@ -169,7 +158,6 @@ The following code snippets illustrate how the same kind of operation is defined
@@ -197,7 +185,6 @@ The following code snippets illustrate how the same kind of operation is defined
@@ -221,7 +208,6 @@ The following code snippets illustrate how the same kind of operation is defined
@@ -249,7 +235,6 @@ The following code snippets illustrate how the same kind of operation is defined
@@ -275,7 +260,6 @@ The following code snippets illustrate how the same kind of operation is defined
## Observables compared to events API @@ -295,9 +279,12 @@ Here are some code samples that illustrate how the same kind of operation is def 下列代码片段揭示了同样的操作要如何分别使用可观察对象和事件 API 进行实现。 - + + - - - -
+ + Observable @@ -315,7 +302,6 @@ Here are some code samples that illustrate how the same kind of operation is def
@@ -353,7 +339,6 @@ button.removeEventListener(‘click’, handler);
@@ -381,7 +366,6 @@ button.removeEventListener(‘click’, handler);
@@ -395,9 +379,9 @@ button.removeEventListener(‘click’, handler); Listen for keystrokes, but provide a stream representing the value in the input. - + 监听按键,提供一个流来表示这些输入的值。 - +
fromEvent(inputEl, 'keydown').pipe(
   map(e => e.target.value)
 );
@@ -407,7 +391,7 @@ button.removeEventListener(‘click’, handler);
Does not support configuration. - + 不支持配置。
element.addEventListener(eventName, (event) => {
@@ -418,7 +402,6 @@ button.removeEventListener(‘click’, handler);
     
## Observables compared to arrays @@ -431,9 +414,12 @@ An observable produces values over time. An array is created as a static set of 在下列例子中,➞ 符号表示异步传递值。 - + + - @@ -472,12 +458,12 @@ An observable produces values over time. An array is created as a static set of - @@ -496,12 +483,12 @@ An observable produces values over time. An array is created as a static set of - @@ -520,12 +508,12 @@ An observable produces values over time. An array is created as a static set of - @@ -544,12 +533,12 @@ An observable produces values over time. An array is created as a static set of - @@ -568,12 +558,12 @@ An observable produces values over time. An array is created as a static set of - - @@ -628,12 +618,12 @@ An observable produces values over time. An array is created as a static set of - @@ -652,10 +643,10 @@ An observable produces values over time. An array is created as a static set of -
+ + Observable @@ -451,7 +437,6 @@ An observable produces values over time. An array is created as a static set of
@@ -465,6 +450,7 @@ An observable produces values over time. An array is created as a static set of
obs: ➞1➞2➞3➞5➞7
+
obsB: ➞'a'➞'b'➞'c'
arr: [1, 2, 3, 5, 7]
+
arrB: ['a', 'b', 'c']
@@ -489,6 +475,7 @@ An observable produces values over time. An array is created as a static set of
obs.concat(obsB)
+
➞1➞2➞3➞5➞7➞'a'➞'b'➞'c'
arr.concat(arrB)
+
[1,2,3,5,7,'a','b','c']
@@ -513,6 +500,7 @@ An observable produces values over time. An array is created as a static set of
obs.filter((v) => v>3)
+
➞5➞7
arr.filter((v) => v>3)
+
[5, 7]
@@ -537,6 +525,7 @@ An observable produces values over time. An array is created as a static set of
obs.find((v) => v>3)
+
➞5
arr.find((v) => v>10)
+
5
@@ -561,6 +550,7 @@ An observable produces values over time. An array is created as a static set of
obs.findIndex((v) => v>3)
+
➞3
arr.findIndex((v) => v>3)
+
3
@@ -609,7 +599,6 @@ An observable produces values over time. An array is created as a static set of
@@ -621,6 +610,7 @@ An observable produces values over time. An array is created as a static set of
obs.map((v) => -v)
+
➞-1➞-2➞-3➞-5➞-7
arr.map((v) => -v)
+
[-1, -2, -3, -5, -7]
@@ -645,6 +635,7 @@ An observable produces values over time. An array is created as a static set of
obs.scan((s,v)=> s+v, 0)
+
➞1➞3➞6➞11➞18
arr.reduce((s,v) => s+v, 0)
+
18
diff --git a/aio/content/guide/component-interaction.md b/aio/content/guide/component-interaction.md index b6c43cfa68..343d078b2c 100644 --- a/aio/content/guide/component-interaction.md +++ b/aio/content/guide/component-interaction.md @@ -525,5 +525,4 @@ and verify that the history meets expectations: [Back to top](guide/component-interaction#top) - [回到顶部](guide/component-interaction#top) diff --git a/aio/content/guide/component-styles.md b/aio/content/guide/component-styles.md index 113e6fb696..9c28c78889 100644 --- a/aio/content/guide/component-styles.md +++ b/aio/content/guide/component-styles.md @@ -20,7 +20,7 @@ This page describes how to load and apply these component styles. You can run the in Stackblitz and download the code from there. -你可以运行来在 Stackblitz 中试用并下载本页的代码。 +你可以运行,在 Stackblitz 中试用并下载本页的代码。 ## Using component styles @@ -42,7 +42,6 @@ Usually you give it one string, as in the following example: 通常你只给它一个字符串就行了,如同下例: - ## Style scope @@ -116,7 +115,6 @@ targeting elements *inside* the component's template). 使用 `:host` 伪类选择器,用来选择组件*宿主*元素中的元素(相对于组件模板*内部*的元素)。 - The `:host` selector is the only way to target the host element. You can't reach @@ -136,7 +134,6 @@ The next example targets the host element again, but only when it also has the ` 下一个例子再次把宿主元素作为目标,但是只有当它同时带有 `active` CSS 类的时候才会生效。 - ### :host-context @@ -163,7 +160,6 @@ if some ancestor element has the CSS class `theme-light`. 在下面的例子中,只有当某个祖先元素有 CSS 类 `theme-light` 时,才会把 `background-color` 样式应用到组件*内部*的所有 `

` 元素中。 - ### (deprecated) `/deep/`, `>>>`, and `::ng-deep` @@ -257,7 +253,6 @@ Each string in the array defines some CSS for this component. 这个数组中的每一个字符串(通常也只有一个)定义一份 CSS。 -
@@ -275,9 +270,7 @@ The CLI defines an empty `styles` array when you create the component with the ` 当使用 `--inline-styles` 标识创建组件时,CLI 就会定义一个空的 `styles` 数组 - ng generate component hero-app --inline-style - ### Style files in component metadata @@ -290,10 +283,8 @@ to a component's `@Component` decorator: 你可以通过把外部 CSS 文件添加到 `@Component` 的 `styleUrls` 属性中来加载外部样式。 - -
@@ -319,9 +310,7 @@ The CLI creates an empty styles file for you by default and references that file CLI 会默认为你创建一个空白的样式表文件,并且在所生成组件的 `styleUrls` 中引用该文件。 - ng generate component hero-app - ### Template inline styles @@ -334,7 +323,6 @@ inside ` - - - - -
@@ -1266,7 +1246,6 @@ Use HTML tables to present tabular data.
@@ -1290,7 +1269,6 @@ Use HTML tables to present tabular data.
@@ -1316,7 +1294,6 @@ Use HTML tables to present tabular data.
@@ -1340,7 +1317,6 @@ Use HTML tables to present tabular data.
Here is the markup for this table. @@ -1352,7 +1328,6 @@ Here is the markup for this table. - - - - -
@@ -1374,7 +1349,6 @@ Here is the markup for this table.
@@ -1398,7 +1372,6 @@ Here is the markup for this table.
@@ -1424,7 +1397,6 @@ Here is the markup for this table.
@@ -1448,7 +1420,6 @@ Here is the markup for this table.
``` diff --git a/aio/content/guide/dynamic-form.md b/aio/content/guide/dynamic-form.md index 1ffe1469a1..87e86b8e26 100644 --- a/aio/content/guide/dynamic-form.md +++ b/aio/content/guide/dynamic-form.md @@ -266,5 +266,4 @@ The final form looks like this: [Back to top](guide/dynamic-form#top) - [回到顶部](guide/dynamic-form#top) diff --git a/aio/content/guide/entry-components.md b/aio/content/guide/entry-components.md index d4663c846a..85817c3a7d 100644 --- a/aio/content/guide/entry-components.md +++ b/aio/content/guide/entry-components.md @@ -12,7 +12,7 @@ A basic understanding of the following concepts: * [Bootstrapping](guide/bootstrapping). - [引导](guide/bootstrapping)。 + [引导启动](guide/bootstrapping)。
@@ -35,11 +35,11 @@ There are two main kinds of entry components: * The bootstrapped root component. - 引导用的根组件。 + 引导用的根组件。 * A component you specify in a route definition. - 在路由定义中指定的组件。 + 在路由定义中指定的组件。 ## A bootstrapped entry component @@ -172,16 +172,16 @@ You may also be interested in the following: * [Types of NgModules](guide/module-types) - [Angular 模块的分类](guide/module-types) + [NgModule 的分类](guide/module-types). * [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules). - [使用 Angular 路由器实现惰性加载模块](guide/lazy-loading-ngmodules). + [使用 Angular 路由器惰性加载模块](guide/lazy-loading-ngmodules)。 * [Providers](guide/providers). - [服务提供商](guide/providers). + [服务提供商](guide/providers)。 * [NgModules FAQ](guide/ngmodule-faq). - [NgModule 常见问题](guide/ngmodule-faq). + [NgModule 常见问题](guide/ngmodule-faq). diff --git a/aio/content/guide/feature-modules.md b/aio/content/guide/feature-modules.md index a6c7e7ab21..1ed01ff964 100644 --- a/aio/content/guide/feature-modules.md +++ b/aio/content/guide/feature-modules.md @@ -16,15 +16,15 @@ A basic understanding of the following: * [Bootstrapping](guide/bootstrapping). - [引导](guide/bootstrapping)。 + [引导启动](guide/bootstrapping)。 * [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule). - [JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。 + [JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。 * [Frequently Used Modules](guide/frequent-ngmodules). - [常用模块](guide/frequent-ngmodules). + [常用模块](guide/frequent-ngmodules)。 For the final sample app with a feature module that this page describes, see the . @@ -118,7 +118,6 @@ This generates a folder for the new component within the customer-dashboard fold 这会在 `customer-dashboard` 中为新组件生成一个目录,并使用 `CustomerDashboardComponent` 的信息修改这个特性模块: - The `CustomerDashboardComponent` is now in the JavaScript import list at the top and added to the `declarations` array, which lets Angular know to associate this new component with this feature module. @@ -134,7 +133,6 @@ To incorporate the feature module into your app, you have to let the root module 要想把这个特性模块包含进应用中,你还得让根模块 `app.module.ts` 知道它。注意,在 `customer-dashboard.module.ts` 的底部导出了 `CustomerDashboardModule`。这样就把它暴露出来,以便其它模块可以拿到它。要想把它导入到 `AppModule` 中,就把它加入 `app.module.ts` 的导入表中,并将其加入 `imports` 数组: - Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules don’t expose their components. @@ -150,7 +148,6 @@ When the CLI generated the `CustomerDashboardComponent` for the feature module, 当 CLI 为这个特性模块生成 `CustomerDashboardComponent` 时,还包含一个模板 `customer-dashboard.component.html`,它带有如下页面脚本: - To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardModule`: @@ -159,7 +156,6 @@ To see this HTML in the `AppComponent`, you first have to export the `CustomerDa 在 `customer-dashboard.module.ts` 中,`declarations` 数组的紧下方,加入一个包含 `CustomerDashboardModule` 的 `exports` 数组: - Next, in the `AppComponent`, `app.component.html`, add the tag ``: @@ -167,7 +163,6 @@ Next, in the `AppComponent`, `app.component.html`, add the tag ``: - Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too: @@ -190,12 +185,12 @@ You may also be interested in the following: * [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules). - [使用 Angular 路由器实现惰性加载模块](guide/lazy-loading-ngmodules). + [使用 Angular 路由器惰性加载模块](guide/lazy-loading-ngmodules)。 * [Providers](guide/providers). - [服务提供商](guide/providers). + [服务提供商](guide/providers)。 * [Types of Feature Modules](guide/module-types). - [Angular 模块的分类](guide/module-types) + [特性模块的分类](guide/module-types)。 diff --git a/aio/content/guide/form-validation.md b/aio/content/guide/form-validation.md index 3a376aa849..f30714ba88 100644 --- a/aio/content/guide/form-validation.md +++ b/aio/content/guide/form-validation.md @@ -140,7 +140,6 @@ built-in validators—this time, in function form. See below: {@a reactive-component-class} - Note that: @@ -169,7 +168,6 @@ If you look at the template for the name input again, it is fairly similar to th 如果你到模板中找到 name 输入框,就会发现它和模板驱动的例子很相似。 - Key takeaways: @@ -201,7 +199,6 @@ this guide. Here's what the definition of that function looks like: 考虑前面的[例子](guide/form-validation#reactive-component-class)中的 `forbiddenNameValidator` 函数。该函数的定义看起来是这样的: - The function is actually a factory that takes a regular expression to detect a _specific_ forbidden name and returns a validator function. @@ -241,7 +238,6 @@ to the `FormControl`. 在响应式表单组件中,添加自定义验证器相当简单。你所要做的一切就是直接把这个函数传给 `FormControl` 。 - ### Adding to template-driven forms @@ -263,7 +259,6 @@ with the `NG_VALIDATORS` provider, a provider with an extensible collection of v Angular 在验证流程中的识别出指令的作用,是因为指令把自己注册到了 `NG_VALIDATORS` 提供商中,该提供商拥有一组可扩展的验证器。 - The directive class then implements the `Validator` interface, so that it can easily integrate @@ -273,7 +268,6 @@ comes together: 然后该指令类实现了 `Validator` 接口,以便它能简单的与 Angular 表单集成在一起。这个指令的其余部分有助于你理解它们是如何协作的: - Once the `ForbiddenValidatorDirective` is ready, you can simply add its selector, `appForbiddenName`, to any input element to activate it. For example: @@ -330,5 +324,4 @@ set the color of each form control's border. **You can run the to see the complete reactive and template-driven example code.** - **你可以运行来查看完整的响应式和模板驱动表单的代码。** diff --git a/aio/content/guide/forms.md b/aio/content/guide/forms.md index 1964fdaa12..8fcb03fdfb 100644 --- a/aio/content/guide/forms.md +++ b/aio/content/guide/forms.md @@ -49,7 +49,7 @@ This page shows you how to build a simple form from scratch. Along the way you'l You can run the in Stackblitz and download the code from there. -运行来试用本页的代码。 +你可以运行,在 Stackblitz 中试用并下载本页的代码。 {@a template-driven} diff --git a/aio/content/guide/frequent-ngmodules.md b/aio/content/guide/frequent-ngmodules.md index c5f724a42c..2b58c60a23 100644 --- a/aio/content/guide/frequent-ngmodules.md +++ b/aio/content/guide/frequent-ngmodules.md @@ -8,7 +8,7 @@ A basic understanding of [Bootstrapping](guide/bootstrapping). -对[引导](guide/bootstrapping)有基本的理解。 +对[引导](guide/bootstrapping)有基本的了解。
@@ -287,4 +287,4 @@ You may also be interested in the following: * [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule). - [JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule). + [JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。 diff --git a/aio/content/guide/glossary.md b/aio/content/guide/glossary.md index 871ab68572..ab4b2a1cfb 100644 --- a/aio/content/guide/glossary.md +++ b/aio/content/guide/glossary.md @@ -83,7 +83,6 @@ For example, imagine three ES2015 modules in a `heroes` folder: 例如,设想在 `heroes` 目录下有三个 ES2015 模块: - // heroes/hero.component.ts export class HeroComponent {} @@ -92,7 +91,6 @@ For example, imagine three ES2015 modules in a `heroes` folder: // heroes/hero.service.ts export class HeroService {} - Without a barrel, a consumer needs three import statements: @@ -100,11 +98,9 @@ Without a barrel, a consumer needs three import statements: 如果没有封装桶,消费者需要三条导入语句: - import { HeroComponent } from '../heroes/hero.component.ts'; import { Hero } from '../heroes/hero.model.ts'; import { HeroService } from '../heroes/hero.service.ts'; - You can add a barrel to the `heroes` folder (called `index`, by convention) that exports all of these items: @@ -112,11 +108,9 @@ You can add a barrel to the `heroes` folder (called `index`, by convention) that 在 `heroes` 目录下添加一个封装桶(按约定叫做 `index`),它导出所有这三项: - export * from './hero.model.ts'; // re-export all of its exports export * from './hero.service.ts'; // re-export all of its exports export { HeroComponent } from './hero.component.ts'; // re-export the named thing - Now a consumer can import what it needs from the barrel. @@ -124,9 +118,7 @@ Now a consumer can import what it needs from the barrel. 现在,消费者就就可以从这个封装桶中导入它需要的东西了。 - import { Hero, HeroService } from '../heroes'; // index is implied - The Angular [scoped packages](guide/glossary#scoped-package) each have a barrel named `index`. @@ -615,7 +607,6 @@ or displayed between element tags, as in this example. 在被赋值给元素属性或者显示在元素标签中之前,这些文本可能会先与周边的文本合并,参见下面的例子。 - @@ -870,7 +861,6 @@ Angular 管道是一个函数,用于把输入值转换成输出值以供[视 下面这个例子中,用内置的 `currency` 管道把数字值显示为本地货币格式。 - {{product.price | currency}} @@ -1251,5 +1241,4 @@ Angular 会在一个 Zone 区域中运行应用程序,在这个区域中,它 Learn more about zones in this [Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U). - 更多信息,见 [Brian Ford 的视频](https://www.youtube.com/watch?v=3IqtmUscE_U)。 diff --git a/aio/content/guide/http.md b/aio/content/guide/http.md index 6dc047d0ee..3faac973f9 100644 --- a/aio/content/guide/http.md +++ b/aio/content/guide/http.md @@ -45,7 +45,6 @@ Most apps do so in the root `AppModule`. path="http/src/app/app.module.ts" region="sketch" title="app/app.module.ts (excerpt)" linenums="false"> - Having imported `HttpClientModule` into the `AppModule`, you can inject the `HttpClient` @@ -57,7 +56,6 @@ into an application class as shown in the following `ConfigService` example. path="http/src/app/config/config.service.ts" region="proto" title="app/config/config.service.ts (excerpt)" linenums="false"> - ## Getting JSON data @@ -74,7 +72,6 @@ that specifies resource URLs. - The `ConfigService` fetches this file with a `get()` method on `HttpClient`. @@ -85,7 +82,6 @@ The `ConfigService` fetches this file with a `get()` method on `HttpClient`. path="http/src/app/config/config.service.ts" region="getConfig_1" title="app/config/config.service.ts (getConfig v.1)" linenums="false"> - A component, such as `ConfigComponent`, injects the `ConfigService` and calls @@ -97,7 +93,6 @@ the `getConfig` service method. path="http/src/app/config/config.component.ts" region="v1" title="app/config/config.component.ts (showConfig v.1)" linenums="false"> - Because the service method returns an `Observable` of configuration data, @@ -148,7 +143,6 @@ The subscribe callback above requires bracket notation to extract the data value - You can't write `data.heroesUrl` because TypeScript correctly complains that the `data` object from the service does not have a `heroesUrl` property. @@ -170,7 +164,6 @@ First, define an interface with the correct shape: - Then, specify that interface as the `HttpClient.get()` call's type parameter in the service: @@ -181,7 +174,6 @@ Then, specify that interface as the `HttpClient.get()` call's type parameter in path="http/src/app/config/config.service.ts" region="getConfig_2" title="app/config/config.service.ts (getConfig v.2)" linenums="false"> - The callback in the updated component method receives a typed data object, which is @@ -193,7 +185,6 @@ easier and safer to consume: path="http/src/app/config/config.component.ts" region="v2" title="app/config/config.component.ts (showConfig v.2)" linenums="false"> - ### Reading the full response @@ -211,7 +202,6 @@ Tell `HttpClient` that you want the full response with the `observe` option: - Now `HttpClient.get()` returns an `Observable` of typed `HttpResponse` rather than just the JSON data. @@ -227,7 +217,6 @@ The component's `showConfigResponse()` method displays the response headers as w region="showConfigResponse" title="app/config/config.component.ts (showConfigResponse)" linenums="false"> - As you can see, the response object has a `body` property of the correct type. @@ -251,7 +240,6 @@ You _could_ handle in the component by adding a second callback to the `.subscri region="v3" title="app/config/config.component.ts (showConfig v.3 with error handling)" linenums="false"> - It's certainly a good idea to give the user some kind of feedback when data access fails. @@ -296,7 +284,6 @@ You might first devise an error handler like this one: path="http/src/app/config/config.service.ts" region="handleError" title="app/config/config.service.ts (handleError)" linenums="false"> - Notice that this handler returns an RxJS [`ErrorObservable`](#rxjs) with a user-friendly error message. @@ -315,7 +302,6 @@ and _pipe them through_ to the error handler. path="http/src/app/config/config.service.ts" region="getConfig_3" title="app/config/config.service.ts (getConfig v.3 with error handler)" linenums="false"> - ### `retry()` @@ -341,7 +327,6 @@ _Pipe_ it onto the `HttpClient` method result just before the error handler. path="http/src/app/config/config.service.ts" region="getConfig" title="app/config/config.service.ts (getConfig with retry)" linenums="false"> - {@a rxjs} @@ -377,7 +362,6 @@ If you're following along with these code snippets, note that you must import th path="http/src/app/config/config.service.ts" region="rxjs-imports" title="app/config/config.service.ts (RxJS imports)" linenums="false"> - ## Requesting non-JSON data @@ -396,7 +380,6 @@ as an `Observable`. path="http/src/app/downloader/downloader.service.ts" region="getTextFile" title="app/downloader/downloader.service.ts (getTextFile)" linenums="false"> - `HttpClient.get()` returns a string rather than the default JSON because of the `responseType` option. @@ -415,7 +398,6 @@ A `download()` method in the `DownloaderComponent` initiates the request by subs path="http/src/app/downloader/downloader.component.ts" region="download" title="app/downloader/downloader.component.ts (download)" linenums="false"> - ## Sending data to the server @@ -457,7 +439,6 @@ to every `HttpClient` save method. path="http/src/app/heroes/heroes.service.ts" region="http-options" title="app/heroes/heroes.service.ts (httpOptions)" linenums="false"> - ### Making a POST request @@ -474,7 +455,6 @@ In the following example, the `HeroService` posts when adding a hero to the data path="http/src/app/heroes/heroes.service.ts" region="addHero" title="app/heroes/heroes.service.ts (addHero)" linenums="false"> - The `HttpClient.post()` method is similar to `get()` in that it has a type parameter @@ -510,7 +490,6 @@ the `Observable` returned by this service method. path="http/src/app/heroes/heroes.component.ts" region="add-hero-subscribe" title="app/heroes/heroes.component.ts (addHero)" linenums="false"> - When the server responds successfully with the newly added hero, the component adds @@ -531,7 +510,6 @@ in the request URL. path="http/src/app/heroes/heroes.service.ts" region="deleteHero" title="app/heroes/heroes.service.ts (deleteHero)" linenums="false"> - The `HeroesComponent` initiates the actual DELETE operation by subscribing to @@ -543,7 +521,6 @@ the `Observable` returned by this service method. path="http/src/app/heroes/heroes.component.ts" region="delete-hero-subscribe" title="app/heroes/heroes.component.ts (deleteHero)" linenums="false"> -
@@ -570,7 +547,6 @@ Merely calling `HeroService.deleteHero()` **does not initiate the DELETE request - {@a always-subscribe} @@ -643,7 +619,6 @@ The following `HeroService` example is just like the POST example. path="http/src/app/heroes/heroes.service.ts" region="updateHero" title="app/heroes/heroes.service.ts (updateHero)" linenums="false"> - For the reasons [explained above](#always-subscribe), the caller (`HeroesComponent.update()` in this case) must `subscribe()` to the observable returned from the `HttpClient.put()` @@ -698,7 +673,6 @@ before making the next request. - #### URL Parameters @@ -714,14 +688,13 @@ Here is a `searchHeroes` method that queries for heroes whose names contain the - If there is a search term, the code constructs an options object with an HTML URL encoded search parameter. If the term were "foo", the GET request URL would be `api/heroes/?name=foo`. 如果有搜索词,这段代码就会构造一个包含进行过 URL 编码的搜索词的选项对象。如果这个搜索词是“foo”,这个 GET 请求的 URL 就会是 `api/heroes/?name=foo`。 -The `HttpParams` are immutable so you'll have to use the `set()` method to update the options. +The `HttpParms` are immutable so you'll have to use the `set()` method to update the options. `HttpParams` 是不可变的,所以你也要使用 `set()` 方法来修改这些选项。 @@ -746,7 +719,6 @@ Here's a pertinent excerpt from the template: path="http/src/app/package-search/package-search.component.html" region="search" title="app/package-search/package-search.component.html (search)"> - The `(keyup)` event binding sends every keystroke to the component's `search()` method. @@ -765,7 +737,6 @@ That's easy to implement with RxJS operators, as shown in this excerpt. path="http/src/app/package-search/package-search.component.ts" region="debounce" title="app/package-search/package-search.component.ts (excerpt))"> - The `searchText$` is the sequence of search-box values coming from the user. @@ -875,15 +846,14 @@ To implement an interceptor, declare a class that implements the `intercept()` m 要实现拦截器,就要实现一个实现了 `HttpInterceptor` 接口中的 `intercept()` 方法的类。 -Here is a do-nothing _noop_ interceptor that simply passes the request through without touching it: - -这里是一个什么也不做的*空白*拦截器,它只会不做任何修改的传递这个请求。 - + Here is a do-nothing _noop_ interceptor that simply passes the request through without touching it: + + 这里是一个什么也不做的*空白*拦截器,它只会不做任何修改的传递这个请求。 + - The `intercept` method transforms a request into an `Observable` that eventually returns the HTTP response. @@ -963,7 +933,6 @@ write the `NoopInterceptor` provider like this: - Note the `multi: true` option. @@ -990,7 +959,6 @@ Consider creating a "barrel" file that gathers all the interceptor providers int path="http/src/app/http-interceptors/index.ts" region="interceptor-providers" title="app/http-interceptors/index.ts" linenums="false"> - Then import and add it to the `AppModule` _providers array_ like this: @@ -1001,7 +969,6 @@ Then import and add it to the `AppModule` _providers array_ like this: path="http/src/app/app.module.ts" region="interceptor-providers" title="app/app.module.ts (interceptor providers)" linenums="false"> - As you create new interceptors, add them to the `httpInterceptorProviders` array and @@ -1100,7 +1067,6 @@ You can clone and modify the request in a single step as in this example. path="http/src/app/http-interceptors/ensure-https-interceptor.ts" region="excerpt" title="app/http-interceptors/ensure-https-interceptor.ts (excerpt)" linenums="false"> - The `clone()` method's hash argument allows you to mutate specific properties of the request while copying the others. @@ -1131,7 +1097,6 @@ If you must mutate the request body, copy it first, change the copy, path="http/src/app/http-interceptors/trim-name-interceptor.ts" region="excerpt" title="app/http-interceptors/trim-name-interceptor.ts (excerpt)" linenums="false"> - ##### Clearing the request body @@ -1174,7 +1139,6 @@ adds an authorization header with that token to every outgoing request: - The practice of cloning a request to set new headers is so common that @@ -1185,7 +1149,6 @@ there's a `setHeaders` shortcut for it: - An interceptor that alters headers can be used for a number of different operations, including: @@ -1223,7 +1186,6 @@ with the injected `MessageService`. path="http/src/app/http-interceptors/logging-interceptor.ts" region="excerpt" title="app/http-interceptors/logging-interceptor.ts)"> - The RxJS `tap` operator captures whether the request succeed or failed. @@ -1259,7 +1221,6 @@ The `CachingInterceptor` demonstrates this approach. path="http/src/app/http-interceptors/caching-interceptor.ts" region="v1" title="app/http-interceptors/caching-interceptor.ts)" linenums="false"> - The `isCachable()` function determines if the request is cachable. @@ -1287,7 +1248,6 @@ If a cachable request is not in cache, the code calls `sendRequest`. - The `sendRequest` function creates a [request clone](#immutability) without headers @@ -1343,7 +1303,6 @@ and emits again later with the updated search results. - The _cache-then-refresh_ option is triggered by the presence of a **custom `x-refresh` header**. @@ -1407,7 +1366,6 @@ with the `reportProgress` option set true to enable tracking of progress events. path="http/src/app/uploader/uploader.service.ts" region="upload-request" title="app/uploader/uploader.service.ts (upload request)"> -
@@ -1427,7 +1385,6 @@ returns an `Observable` of `HttpEvents`, the same events processed by intercepto path="http/src/app/uploader/uploader.service.ts" region="upload-body" title="app/uploader/uploader.service.ts (upload body)" linenums="false"> - The `getEventMessage` method interprets each type of `HttpEvent` in the event stream. @@ -1438,7 +1395,6 @@ The `getEventMessage` method interprets each type of `HttpEvent` in the event st path="http/src/app/uploader/uploader.service.ts" region="getEventMessage" title="app/uploader/uploader.service.ts (getEventMessage)" linenums="false"> -
@@ -1501,7 +1457,6 @@ use `HttpClientXsrfModule.withOptions()` to override the defaults. path="http/src/app/app.module.ts" region="xsrf" linenums="false"> - ## Testing HTTP requests @@ -1565,7 +1520,6 @@ along with the other symbols your tests require. path="http/src/testing/http-client.spec.ts" region="imports" title="app/testing/http-client.spec.ts (imports)" linenums="false"> - Then add the `HttpClientTestingModule` to the `TestBed` and continue with @@ -1577,7 +1531,6 @@ the setup of the _service-under-test_. path="http/src/testing/http-client.spec.ts" region="setup" title="app/testing/http-client.spec.ts(setup)" linenums="false"> - Now requests made in the course of your tests will hit the testing backend instead of the normal backend. @@ -1601,7 +1554,6 @@ Now you can write a test that expects a GET Request to occur and provides a mock path="http/src/testing/http-client.spec.ts" region="get-test" title="app/testing/http-client.spec.ts(httpClient.get)" linenums="false"> - The last step, verifying that no requests remain outstanding, is common enough for you to move it into an `afterEach()` step: @@ -1612,7 +1564,6 @@ The last step, verifying that no requests remain outstanding, is common enough f path="http/src/testing/http-client.spec.ts" region="afterEach" linenums="false"> - #### Custom request expectations @@ -1629,7 +1580,6 @@ For example, you could look for an outgoing request that has an authorization he path="http/src/testing/http-client.spec.ts" region="predicate" linenums="false"> - As with the previous `expectOne()`, @@ -1652,7 +1602,6 @@ you are responsible for flushing and verifying them. path="http/src/testing/http-client.spec.ts" region="multi-request" linenums="false"> - ### Testing for errors @@ -1671,5 +1620,4 @@ Call `request.error()` with an `ErrorEvent` instead of `request.flush()`, as in path="http/src/testing/http-client.spec.ts" region="404" linenums="false"> - diff --git a/aio/content/guide/i18n.md b/aio/content/guide/i18n.md index a9a365dbda..9ce2cab2b6 100644 --- a/aio/content/guide/i18n.md +++ b/aio/content/guide/i18n.md @@ -85,9 +85,7 @@ of the locale id that you want to use: 要把你的应用的地区改为其它值,可以使用 CLI 参数 `--locale` 来传入你要使用的地区标识: - ng serve --aot --locale fr - If you use JIT, you also need to define the `LOCALE_ID` provider in your main module: @@ -95,7 +93,6 @@ If you use JIT, you also need to define the `LOCALE_ID` provider in your main mo 如果要使用 JIT,你就得在你的主模块中定义 `LOCALE_ID` 这个服务提供商: - For more information about Unicode locale identifiers, see the @@ -150,7 +147,6 @@ If you want to import locale data for other languages, you can do it manually: 如果还要为其它语言导入本地化数据,你可以手工完成它: - The first parameter is an object containing the locale data imported from `@angular/common/locales`. @@ -174,7 +170,6 @@ import from `@angular/common/locales/extra`. An error message informs you when t 不过有些高级的格式选项只存在于从 `@angular/common/locales/extra` 中导入的扩展数据集中。遇到这种情况,你就会收到一条错误信息。 -
@@ -243,7 +238,6 @@ In the example below, an `

` tag displays a simple English language greeting, 在下面的例子中,`

`标签显示了一句简单的英文问候语,“Hello i18n!” - To mark the greeting for translation, add the `i18n` attribute to the `

` tag. @@ -251,7 +245,6 @@ To mark the greeting for translation, add the `i18n` attribute to the `

` tag 要想把它标记为需要翻译的文本,就给 `

` 标签添加上 `i18n` 属性。 -
@@ -280,7 +273,6 @@ example below: 你可以用 `i18n` 属性的值来添加这些文本信息的描述,例子如下: - The translator may also need to know the meaning or intent of the text message within this particular @@ -294,7 +286,6 @@ separating it from the _description_ with the `|` character: `||<描述>`)。 - All occurrences of a text message that have the same meaning will have the same translation. @@ -323,7 +314,6 @@ attribute in a template. By default, it assigns each translation unit a unique i Angular 的 `i18n` 提取工具会为模板中每个带有 `i18n` 属性的元素生成一个*翻译单元(translation unit)*条目,并保存到一个文件中。默认情况下,它为每个翻译单元指定一个唯一的 `id`,就像这样: - When you change the translatable text, the extractor tool generates a new id for that translation unit. @@ -339,7 +329,6 @@ The example below defines the custom id `introductionHeader`: 下面这个例子就定义了一个自定义 id `introductionHeader`: - When you specify a custom id, the extractor tool and compiler generate a translation unit with that @@ -348,7 +337,6 @@ custom id. 一旦你指定了自定义 id,提取工具和编译器就会用*你的自定义 id` 生成一个翻译单元,而不会再改变它。 - The custom id is persistent. The extractor tool does not change it when the translatable text changes. @@ -369,7 +357,6 @@ by the custom `id`: 下面的例子中,`i18n` 的属性中中就包含了一条跟在自定义 `id` 后面的描述信息: - You also can add a meaning, as shown in this example: @@ -377,7 +364,6 @@ You also can add a meaning, as shown in this example: 你还可以添加含义,例子如下: - #### Define unique custom ids @@ -446,7 +432,6 @@ The `` is transformed into an html comment: 但如果由于某些原因(比如 CSS 结构方面的考虑),你可能不希望仅仅为了翻译而创建一个新的 DOM 元素,那么也可以把这段文本包裹进一个 `` 元素中。`` 将被转换成一个 HTML 注释: - {@a translate-attributes} @@ -462,7 +447,6 @@ For example, assume that your template has an image with a `title` attribute: 比如,假设你的模板中有一个带 `title` 属性的图片: - This `title` attribute needs to be translated. @@ -477,7 +461,6 @@ where `x` is the name of the attribute to translate. The following example shows 下面的例子中演示了如何通过给 `img` 标签添加 `i18n-title` 属性来把 `title` 属性标记为待翻译的。 - This technique works for any attribute of any element. @@ -514,7 +497,6 @@ based on when the update occurred: 下面这个例子示范了如何使用 ICU 表达式 `plural` 来根据这次修改发生的时间显示这三个选项之一: - * The first parameter is the key. It is bound to the component property (`minutes`), which determines @@ -620,7 +602,6 @@ The message maps those values to the appropriate translations: 这个消息会把那些值映射到适当的翻译文本: - {@a nesting-ICUS} @@ -634,7 +615,6 @@ You can also nest different ICU expressions together, as shown in this example: 你也可以把不同的 ICU 表达式嵌套在一起,比如: - {@a ng-xi18n} @@ -653,9 +633,7 @@ Open a terminal window at the root of the app project and enter the `ng xi18n` c 在应用的项目根目录打开一个终端窗口,并输入 `ng xi18n` 命令: - ng xi18n - By default, the tool generates a translation file named `messages.xlf` in the @@ -711,11 +689,9 @@ these example commands: 你可以使用 `--i18nFormat` 来明确指定想用的格式,范例如下: - ng xi18n --i18nFormat=xlf ng xi18n --i18nFormat=xlf2 ng xi18n --i18nFormat=xmb - The sample in this guide uses the default XLIFF 1.2 format. @@ -870,7 +846,8 @@ This sample file is easy to translate without a special editor or knowledge of F 打开 `messages.fr.xlf` 并找到第一个 `` 区: -> +> + > This XML element represents the translation of the `

` greeting tag that you marked with the `i18n` attribute earlier in this guide. @@ -891,13 +868,15 @@ This sample file is easy to translate without a special editor or knowledge of F 复制 `` 标记,把它改名为 `target`,并把它的内容改为法语版的 “greeting”。 如果你要做的是更复杂的翻译,可能会使用由源文本、描述信息和含义等提供的信息和上下文来给出更恰当的法语翻译。 -> +> + 3. Translate the other text nodes the same way: 用同样的方式翻译其它文本节点: -> +> +
@@ -942,7 +921,6 @@ To translate a `plural`, translate its ICU format match values: 要翻译一个复数,就要翻译它的 ICU 格式中匹配的值: - You can add or remove plural cases, with each language having its own cardinality. (See @@ -961,7 +939,6 @@ Below is the content of our example `select` ICU expression in the component tem 下面是组件模板中的 ICU 表达式 `select` 的例子: - The extraction tool broke that into two translation units because ICU expressions are extracted @@ -980,7 +957,6 @@ the placeholder, the ICU expression will not be present in your translated app. 如果删除了占位符,ICU 表达式就不会出现在翻译后的应用中。 - The second translation unit, immediately below the first one, contains the `select` message. @@ -989,7 +965,6 @@ Translate that as well. 第一个翻译单元的紧下方就是第二个翻译单元,包含 `select` 中的消息。照样翻译它。 - Here they are together, after translation: @@ -997,7 +972,6 @@ Here they are together, after translation: 在翻译之后,它们会放在一起: - {@a translate-nested} @@ -1013,7 +987,6 @@ two translation units. The first one contains the text outside of the nested exp 第一个包含嵌套表达式之外的文本: - The second unit contains the complete nested expression: @@ -1021,7 +994,6 @@ The second unit contains the complete nested expression: 第二个包含完整的嵌套表达式: - And both together: @@ -1029,7 +1001,6 @@ And both together: 放在一起时: - The entire template translation is complete. The next section describes how to load that translation @@ -1048,7 +1019,6 @@ The sample app and its translation file are now as follows: 下面是例子应用及其翻译文件: - @@ -1059,7 +1029,6 @@ The sample app and its translation file are now as follows: - {@a merge} @@ -1144,9 +1113,7 @@ guide: 下面的例子演示了如何使用前面部分创建的法语文件来启动开发服务器: - ng serve --aot --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr - {@a merge-jit} @@ -1196,7 +1163,6 @@ behavior of the compiler. You can use it to provide the translation providers: 在下面的 `src/app/i18n-providers.ts` 文件的 `getTranslationProviders()` 函数中,根据用户的**语言环境**和对应的翻译文件构建这些提供商: - Then provide the `LOCALE_ID` in the main module: @@ -1204,7 +1170,6 @@ Then provide the `LOCALE_ID` in the main module: 然后在主文件包中提供 `LOCALE_ID`: - {@a missing-translation} @@ -1238,9 +1203,7 @@ If you use the AOT compiler, specify the warning level by using the CLI paramete 如果你使用 AOT 编译器,可以使用 CLI 参数 `--missingTranslation` 来指定警告级别。下面的例子示范了如何把警告级别设置为 `error`: - ng serve --aot --missingTranslation=error - If you use the JIT compiler, specify the warning level in the compiler config at bootstrap by adding @@ -1250,5 +1213,4 @@ error: 如果你要使用 JIT 编译器,就在启动时往编译器的配置中添加一个 `MissingTranslationStrategy` 属性来指定警告级别。下面的例子示范了如何把警告级别设置为 `error`: - diff --git a/aio/content/guide/language-service.md b/aio/content/guide/language-service.md index 5981c53f09..4406f1298e 100644 --- a/aio/content/guide/language-service.md +++ b/aio/content/guide/language-service.md @@ -257,5 +257,4 @@ For more in-depth information, see the For more information, see [Chuck Jazdzewski's presentation](https://www.youtube.com/watch?v=ez3R0Gi4z5A&t=368s) on the Angular Language Service from [ng-conf](https://www.ng-conf.org/) 2017. - 要了解更多信息,参见 [ng-conf](https://www.ng-conf.org/) 2017 中 [Chuck Jazdzewski 的演讲](https://www.youtube.com/watch?v=ez3R0Gi4z5A&t=368s) 中讲解的 Angular 语言服务。 diff --git a/aio/content/guide/lazy-loading-ngmodules.md b/aio/content/guide/lazy-loading-ngmodules.md index 247674a6ac..1af45855e5 100644 --- a/aio/content/guide/lazy-loading-ngmodules.md +++ b/aio/content/guide/lazy-loading-ngmodules.md @@ -355,7 +355,7 @@ CLI 还会把 `RouterModule.forChild(routes)` 添加到各个特性模块中。 You may also be interested in the following: -你可能还会对下列内容感兴趣: +你可能还对下列内容感兴趣: * [Routing and Navigation](guide/router). @@ -363,8 +363,8 @@ You may also be interested in the following: * [Providers](guide/providers). - [提供商](guide/providers)。 + [服务提供商](guide/providers)。 * [Types of Feature Modules](guide/module-types). - [特性模块的分类](guide/module-types)。 + [特性模块的分类](guide/module-types)。 diff --git a/aio/content/guide/lifecycle-hooks.md b/aio/content/guide/lifecycle-hooks.md index 389d9ba8b0..ff17bce57b 100644 --- a/aio/content/guide/lifecycle-hooks.md +++ b/aio/content/guide/lifecycle-hooks.md @@ -62,7 +62,6 @@ calls the lifecycle hook methods in the following sequence at specific moments: - - - - - - - - - -
@@ -82,7 +81,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
@@ -106,7 +104,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
@@ -129,7 +126,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
@@ -151,7 +147,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
@@ -173,7 +168,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
@@ -195,7 +189,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
@@ -217,7 +210,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
@@ -239,7 +231,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
@@ -263,7 +254,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
{@a interface-optional} @@ -335,7 +325,6 @@ Here's a brief description of each exercise: - - - - - - - - -
@@ -355,7 +344,6 @@ Here's a brief description of each exercise:
@@ -374,7 +362,6 @@ Here's a brief description of each exercise:
@@ -399,7 +386,6 @@ Here's a brief description of each exercise:
@@ -420,7 +406,6 @@ Here's a brief description of each exercise:
@@ -440,7 +425,6 @@ Here's a brief description of each exercise:
@@ -460,7 +444,6 @@ Here's a brief description of each exercise:
@@ -481,7 +464,6 @@ Here's a brief description of each exercise:
@@ -510,7 +492,6 @@ Here's a brief description of each exercise:
The remainder of this page discusses selected exercises in further detail. diff --git a/aio/content/guide/module-types.md b/aio/content/guide/module-types.md index 1eda0edb22..6c0ecfaf68 100644 --- a/aio/content/guide/module-types.md +++ b/aio/content/guide/module-types.md @@ -115,7 +115,6 @@ typical characteristics, in real world apps, you may see hybrids. - @@ -299,7 +298,6 @@ The following table summarizes the key characteristics of each feature module gr 下表中汇总了各种特性模块类型的关键特征。 - -
@@ -559,7 +557,6 @@ The following table summarizes the key characteristics of each feature module gr

@@ -570,7 +567,7 @@ The following table summarizes the key characteristics of each feature module gr You may also be interested in the following: -你可能还会对下列内容感兴趣: +你可能还对下列内容感兴趣: * [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules). @@ -578,4 +575,4 @@ You may also be interested in the following: * [Providers](guide/providers). - [服务提供商](guide/providers)。 + [服务提供商](guide/providers)。 diff --git a/aio/content/guide/ngmodule-api.md b/aio/content/guide/ngmodule-api.md index 7107a5e1c4..d0f71fa10a 100644 --- a/aio/content/guide/ngmodule-api.md +++ b/aio/content/guide/ngmodule-api.md @@ -139,7 +139,9 @@ The following table summarizes the `@NgModule` metadata properties. + + Components, directives, and pipes must belong to _exactly_ one module. @@ -402,8 +404,8 @@ You may also be interested in the following: * [Providers](guide/providers). - [提供商](guide/providers)。 + [服务提供商](guide/providers)。 * [Types of Feature Modules](guide/module-types). - [特性模块的分类](guide/module-types)。 + [特性模块的分类](guide/module-types)。 diff --git a/aio/content/guide/ngmodule-faq.md b/aio/content/guide/ngmodule-faq.md index a55b36bd5d..b9c7244961 100644 --- a/aio/content/guide/ngmodule-faq.md +++ b/aio/content/guide/ngmodule-faq.md @@ -803,7 +803,6 @@ Here is a custom constructor for an NgModule called `CoreModule`. 某些 Angular 模块(例如 `BrowserModule`)就实现了一个像 Angular 模块那一章的 `CoreModule` 构造函数那样的守卫。 -
@@ -1133,5 +1132,4 @@ the Angular compiler incorporates them into compiled component code too. `@NgModule` metadata tells the Angular compiler what components to compile for this module and how to link this module with other modules. - `@NgModule` 元数据告诉*Angular 编译器*要为当前模块编译哪些组件,以及如何把当前模块和其它模块链接起来。 diff --git a/aio/content/guide/ngmodule-vs-jsmodule.md b/aio/content/guide/ngmodule-vs-jsmodule.md index 29fbb9e4b7..ab2b107d47 100644 --- a/aio/content/guide/ngmodule-vs-jsmodule.md +++ b/aio/content/guide/ngmodule-vs-jsmodule.md @@ -126,4 +126,4 @@ For more information on NgModules, see: * [Providers](guide/providers). - [服务提供商](guide/providers). + [服务提供商](guide/providers)。 diff --git a/aio/content/guide/ngmodules.md b/aio/content/guide/ngmodules.md index c33fc25759..3ac115a7cf 100644 --- a/aio/content/guide/ngmodules.md +++ b/aio/content/guide/ngmodules.md @@ -121,7 +121,6 @@ The CLI generates the following basic app module when creating a new app. CLI 在创建新应用时会生成下列基本的应用模块。 - At the top are the import statements. The next section is where you configure the `@NgModule` by stating what components and directives belong to it (`declarations`) as well as which other modules it uses (`imports`). This page builds on [Bootstrapping](guide/bootstrapping), which covers the structure of an NgModule in detail. If you need more information on the structure of an `@NgModule`, be sure to read [Bootstrapping](guide/bootstrapping). @@ -137,7 +136,7 @@ At the top are the import statements. The next section is where you configure th You may also be interested in the following: -你可能还会对下列内容感兴趣: +你可能还对下列内容感兴趣: * [Feature Modules](guide/feature-modules). @@ -149,8 +148,8 @@ You may also be interested in the following: * [Providers](guide/providers). - [提供商](guide/providers)。 + [服务提供商](guide/providers)。 * [Types of NgModules](guide/module-types). - [NgModule 的分类](guide/module-types). + [NgModule 的分类](guide/module-types). diff --git a/aio/content/guide/npm-packages.md b/aio/content/guide/npm-packages.md index 7239c01ce3..88e6e1d285 100644 --- a/aio/content/guide/npm-packages.md +++ b/aio/content/guide/npm-packages.md @@ -280,5 +280,4 @@ The browser downloads this bundle, not the original package files. See the [Deployment](guide/deployment) to learn more. - 参见[部署](guide/deployment)一章了解详情。 diff --git a/aio/content/guide/observables.md b/aio/content/guide/observables.md index ce04c3e7fa..bdcbae5d55 100644 --- a/aio/content/guide/observables.md +++ b/aio/content/guide/observables.md @@ -52,11 +52,11 @@ A handler for receiving observable notifications implements the `Observer` inter 用于接收可观察对象通知的处理器要实现 `Observer` 接口。这个对象定义了一些回调函数来处理可观察对象可能会发来的三种通知: -|

Notification type

通知类型

|

Description

说明

| +| Notification type通知类型 | Description说明 | |:---------|:-------------------------------------------| -| `next` |

Required. A handler for each delivered value. Called zero or more times after execution starts.

必要。用来处理每个送达值。在开始执行后可能执行零次或多次。

| -| `error` |

Optional. A handler for an error notification. An error halts execution of the observable instance.

可选。用来处理错误通知。错误会中断这个可观察对象实例的执行过程。

| -| `complete` |

Optional. A handler for the execution-complete notification. Delayed values can continue to be delivered to the next handler after execution is complete.

可选。用来处理执行完毕(complete)通知。当执行完毕后,这些值就会继续传给下一个处理器。

| +| `next` | Required. A handler for each delivered value. Called zero or more times after execution starts.必要。用来处理每个送达值。在开始执行后可能执行零次或多次。| +| `error` | Optional. A handler for an error notification. An error halts execution of the observable instance. 可选。用来处理错误通知。错误会中断这个可观察对象实例的执行过程。 | +| `complete` | Optional. A handler for the execution-complete notification. Delayed values can continue to be delivered to the next handler after execution is complete. 可选。用来处理执行完毕(complete)通知。当执行完毕后,这些值就会继续传给下一个处理器。 | An observer object can define any combination of these handlers. If you don't supply a handler for a notification type, the observer ignores notifications of that type. @@ -107,7 +107,7 @@ In either case, a `next` handler is required. The `error` and `complete` handler 无论哪种情况,`next` 处理器都是必要的,而 `error` 和 `complete` 处理器是可选的。 -Note that a `next()` function could receive, for instance, message strings, or event objects, numeric values, or structures, depending on context. As a general term, we refer to data published by an observable as a *stream*. Any type of value can be represented with an observable, and the values are published as a stream. +Note that a `next()` function could receive, for instance, message strings, or event objects, numeric values, or stuctures, depending on context. As a general term, we refer to data published by an observable as a *stream*. Any type of value can be represented with an observable, and the values are published as a stream. 注意,`next()` 函数可以接受消息字符串、事件对象、数字值或各种结构,具体类型取决于上下文。 为了更通用一点,我们把由可观察对象发布出来的数据统称为*流*。任何类型的值都可以表示为可观察对象,而这些值会被发布为一个流。 @@ -196,12 +196,10 @@ Because observables produce values asynchronously, try/catch will not effectivel 由于可观察对象会异步生成值,所以用 `try/catch` 是无法捕获错误的。你应该在观察者中指定一个 `error` 回调来处理错误。发生错误时还会导致可观察对象清理现有的订阅,并且停止生成值。可观察对象可以生成值(调用 `next` 回调),也可以调用 `complete` 或 `error` 回调来主动结束。 - myObservable.subscribe({ next(num) { console.log('Next num: ' + num)}, error(err) { console.log('Received an errror: ' + err)} }); - Error handling (and specifically recovering from an error) is covered in more detail in a later section. diff --git a/aio/content/guide/pipes.md b/aio/content/guide/pipes.md index 7385c1fbd5..1223032457 100644 --- a/aio/content/guide/pipes.md +++ b/aio/content/guide/pipes.md @@ -32,7 +32,7 @@ Introducing Angular pipes, a way to write display-value transformations that you You can run the in Stackblitz and download the code from there. -运行来试用本页的代码。 +你可以运行,在 Stackblitz 中试用并下载本页的代码。 ## Using pipes @@ -249,7 +249,6 @@ Now you need a component to demonstrate the pipe. 现在,你需要一个组件来演示这个管道。 -
@@ -780,10 +779,8 @@ The list might be sorted by hero `name` and `planet` of origin properties in the 虽然不是很明显,但代码最小化方面也存在风险。想象一个用于英雄列表的排序管道。该列表可能根据英雄原始属性中的 `name` 和 `planet` 进行排序,就像这样: - <!-- NOT REAL CODE! --> <div *ngFor="let hero of heroes | orderBy:'name,planet'"></div> - You identify the sort fields by text strings, expecting the pipe to reference a property value by indexing @@ -817,5 +814,4 @@ Angular 开发组和一些有经验的 Angular 开发者强烈建议你:把你 If these performance and minification considerations don't apply to you, you can always create your own such pipes (similar to the [FlyingHeroesPipe](guide/pipes#impure-flying-heroes)) or find them in the community. - 如果你不需要顾虑这些性能和最小化问题,也可以创建自己的管道来实现这些功能(参考[FlyingHeroesPipe](guide/pipes#impure-flying-heroes)中的写法)或到社区中去找找。 diff --git a/aio/content/guide/providers.md b/aio/content/guide/providers.md index 087b7574ab..cfce752754 100644 --- a/aio/content/guide/providers.md +++ b/aio/content/guide/providers.md @@ -12,7 +12,7 @@ * Familiarity with [Frequently Used Modules](guide/frequent-ngmodules). - 熟悉[常用模块](guide/frequent-ngmodules). + 熟悉[常用模块](guide/frequent-ngmodules)。 For the final sample app using the provider that this page describes, see the . @@ -45,7 +45,6 @@ of the file and adding it to the `providers` array: 这将会创建一个名叫 `UserService` 的服务。你现在要让该服务在你的应用注入器中可用,就要修改 `app.module.ts` 文件。先在文件的顶部导入它,然后把它加入 `providers` 数组中: - ## Provider scope @@ -101,7 +100,6 @@ the same module can’t access it.) 在组件中提供服务,会限定该服务只能在该组件中有效(同一模块中的其它组件不能访问它)。 - ## Providing services in modules vs. components @@ -132,7 +130,7 @@ Register a provider with a component when you must limit a service instance to a You may also be interested in: -你可能还对下列内容感兴趣: +你还可能对下列内容感兴趣: * [Singleton Services](guide/singleton-services), which elaborates on the concepts covered on this page. @@ -140,8 +138,8 @@ You may also be interested in: * [Lazy Loading Modules](guide/lazy-loading-ngmodules). - [惰性加载模块](guide/lazy-loading-ngmodules). + [惰性加载模块](guide/lazy-loading-ngmodules)。 * [NgModule FAQ](guide/ngmodule-faq). - [NgModule 常见问题](guide/ngmodule-faq)。 + [NgModule 常见问题](guide/ngmodule-faq)。 diff --git a/aio/content/guide/quickstart.md b/aio/content/guide/quickstart.md index 583e83f6bc..7875c10ad9 100644 --- a/aio/content/guide/quickstart.md +++ b/aio/content/guide/quickstart.md @@ -59,7 +59,6 @@ Then **install the [Angular CLI](https://github.com/angular/angular-cli)** globa 然后全局安装 **[Angular CLI](https://github.com/angular/angular-cli)** 。 - npm install -g @angular/cli @@ -77,7 +76,6 @@ Generate a new project and skeleton application by running the following command 运行下列命令来生成一个新项目以及应用的骨架代码: - ng new my-app @@ -101,10 +99,8 @@ Go to the project directory and launch the server. 进入项目目录,并启动服务器。 - cd my-app ng serve --open - The `ng serve` command launches the server, watches your files, @@ -282,7 +278,6 @@ Any files outside of this folder are meant to support building your app. - @@ -302,7 +297,6 @@ Any files outside of this folder are meant to support building your app. - @@ -323,7 +317,6 @@ Any files outside of this folder are meant to support building your app. - @@ -345,7 +338,6 @@ Any files outside of this folder are meant to support building your app. - @@ -364,7 +356,6 @@ Any files outside of this folder are meant to support building your app. - @@ -385,14 +376,13 @@ Any files outside of this folder are meant to support building your app. 这个文件夹中包括为各个目标环境准备的文件,它们导出了一些应用中要用到的配置变量。 这些文件会在构建应用时被替换。 - 比如你可能在产品环境中使用不同的 API 端点地址,或使用不同的统计 Token 参数。 + 比如你可能在生产环境中使用不同的 API 端点地址,或使用不同的统计 Token 参数。 甚至使用一些模拟服务。 所有这些,CLI 都替你考虑到了。 - @@ -412,7 +402,6 @@ Any files outside of this folder are meant to support building your app. - @@ -435,7 +424,6 @@ Any files outside of this folder are meant to support building your app. - @@ -459,7 +447,6 @@ Any files outside of this folder are meant to support building your app. - @@ -482,7 +469,6 @@ Any files outside of this folder are meant to support building your app. - @@ -503,7 +489,6 @@ Any files outside of this folder are meant to support building your app. - @@ -524,7 +509,6 @@ Any files outside of this folder are meant to support building your app. - @@ -543,7 +527,6 @@ Any files outside of this folder are meant to support building your app. - ### The root folder @@ -610,7 +593,6 @@ These files go in the root folder next to `src/`. - @@ -625,12 +607,11 @@ These files go in the root folder next to `src/`. Purpose - 目的 + 用途 - @@ -653,7 +634,6 @@ These files go in the root folder next to `src/`. - @@ -672,7 +652,6 @@ These files go in the root folder next to `src/`. - @@ -695,7 +674,6 @@ These files go in the root folder next to `src/`. - @@ -717,7 +695,6 @@ These files go in the root folder next to `src/`. - @@ -735,7 +712,6 @@ These files go in the root folder next to `src/`. - @@ -754,7 +730,6 @@ These files go in the root folder next to `src/`. - @@ -774,7 +749,6 @@ These files go in the root folder next to `src/`. - @@ -793,7 +767,6 @@ These files go in the root folder next to `src/`. - @@ -814,7 +787,6 @@ These files go in the root folder next to `src/`. - @@ -832,7 +804,6 @@ These files go in the root folder next to `src/`. - @@ -853,7 +824,6 @@ These files go in the root folder next to `src/`. -
diff --git a/aio/content/guide/reactive-forms.md b/aio/content/guide/reactive-forms.md index a9f94b2f34..9c08299bf4 100644 --- a/aio/content/guide/reactive-forms.md +++ b/aio/content/guide/reactive-forms.md @@ -427,7 +427,7 @@ This guide uses four fundamental classes to build a reactive form: `FormControl`, `FormGroup`, and `FormArray`. It provides their common behaviors and properties. - [`AbstractControl`](api/forms/AbstractControl "API Reference: FormControl")是这三个具体表单类的抽象基类。 + [`AbstractControl`](api/forms/AbstractControl "API Reference: FormControl")是这三个具体表单类的抽象基类。 并为它们提供了一些共同的行为和属性。 @@ -1156,7 +1156,6 @@ which is covered in the section on [`FormArray`](guide/reactive-forms#form-array `Hero` 有一个住址数组。这个表单模型只表示了一个住址,稍后的 [`FormArray`] (guide/reactive-forms#form-array "Form arrays")则可以表示多个。 - Keeping the two models close in shape facilitates copying the data model properties to the form model with the `patchValue()` and `setValue()` methods in the next section. diff --git a/aio/content/guide/router.md b/aio/content/guide/router.md index 97df7dce7d..c9f3631a14 100644 --- a/aio/content/guide/router.md +++ b/aio/content/guide/router.md @@ -214,7 +214,6 @@ _after_ a `RouterOutlet` that you've placed in the host view's HTML. 有了这份配置,当本应用在浏览器中的 URL 变为 `/heroes` 时,路由器就会匹配到 `path` 为 `heroes` 的 `Route`,并在宿主视图中的*`RouterOutlet`*之后显示 `HeroListComponent` 组件。 - <router-outlet></router-outlet> <!-- Routed views go here --> @@ -294,7 +293,6 @@ It has a great deal of useful information including: 它有一大堆有用的信息,包括: - -
@@ -496,7 +494,6 @@ It has a great deal of useful information including:
@@ -525,7 +522,6 @@ During each navigation, the `Router` emits navigation events through the `Router 在每次导航中,`Router` 都会通过 `Router.events` 属性发布一些导航事件。这些事件的范围涵盖了从开始导航到结束导航之间的很多时间点。下表中列出了全部导航事件: - -
@@ -674,7 +670,6 @@ During each navigation, the `Router` emits navigation events through the `Router
These events are logged to the console when the `enableTracing` option is enabled also. Since the events are provided as an `Observable`, you can `filter()` for events of interest and `subscribe()` to them to make decisions based on the sequence of events in the navigation process. @@ -748,8 +743,6 @@ Here are the key `Router` terms and their meanings: RouterModule - RouterModule(路由器模块) - @@ -1218,7 +1211,6 @@ That's why the example code replaces the `` with a script that wri 这就是为什么范例代码中要用一个脚本动态写入 `` 标签,而不是直接写 ``。 - <script>document.write('<base href="' + document.location + '" />');</script> @@ -1344,7 +1336,7 @@ The corresponding component template looks like this: ### *RouterOutlet* -### *RouterOutlet* 指令 +### 路由出口 The `RouterOutlet` is a directive from the router library that marks the spot in the template where the router should display the views for that outlet. @@ -1525,9 +1517,7 @@ When the application launches, the initial URL in the browser bar is something l 应用启动时,浏览器地址栏中的初始 URL 是这样的: - localhost:3000 - That doesn't match any of the concrete configured routes which means @@ -1560,7 +1550,6 @@ It's just above the wildcard route in the following excerpt showing the complete 在下方的代码片段中,它出现在通配符路由的紧上方,展示了这个里程碑的完整 `appRoutes`。 - A redirect route requires a `pathMatch` property to tell the router how to match a URL to the path of a route. @@ -2361,7 +2350,6 @@ you expect a hero id to appear in the browser URL like this: 如果要告诉路由器导航到详情组件,并让它显示“Magneta”,你会期望这个英雄的 `id` 像这样显示在浏览器的 URL 中: - localhost:3000/hero/15 @@ -2505,7 +2493,6 @@ to handle parameter access for both route parameters (`paramMap`) and query para `ParamMap` API 是参照[URLSearchParams 接口](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)来设计的。它提供了一些方法来处理对路由参数(`paramMap`)和查询参数(`queryParamMap`)中的参数访问。 - -
@@ -2597,7 +2584,6 @@ to handle parameter access for both route parameters (`paramMap`) and query para
{@a reuse} @@ -2745,7 +2731,6 @@ as you do when navigating to the `HeroDetailComponent` in order to view the hero 如果想导航到 `HeroDetailComponent` 以对 id 为 15 的英雄进行查看并编辑,就要在路由的 URL 中使用[*路由参数*](guide/router#route-parameters)来指定*必要*参数值。 - localhost:3000/hero/15 @@ -2866,7 +2851,6 @@ It should look something like this, depending on where you run it: 它应该是这样的,不过也取决于你在哪里运行它: - localhost:3000/heroes;id=15;foo=foo @@ -3413,7 +3397,6 @@ Add the following `crisis-center.component.ts` to the `crisis-center` folder: 往 `crisis-center` 目录下添加下列 `crisis-center.component.ts` 文件: - The `CrisisCenterComponent` has the following in common with the `AppComponent`: @@ -3455,7 +3438,6 @@ As a host page for the "Crisis Center" feature, add the following `crisis-center 把下面这个 `crisis-center-home.component.ts` 添加到 `crisis-center` 目录下,作为 "危机中心" 特性区的宿主页面。 - Create a `crisis-center-routing.module.ts` file as you did the `heroes-routing.module.ts` file. @@ -3465,7 +3447,6 @@ This time, you define **child routes** *within* the parent `crisis-center` route 但这次,你要把**子路由**定义在父路由 `crisis-center` 中。 - Notice that the parent `crisis-center` route has a `children` property @@ -3529,7 +3510,6 @@ The absolute URL for the latter example, including the `localhost` origin, is 本例子中包含站点部分的绝对 URL,就是: - localhost:3000/crisis-center/2 @@ -3882,7 +3862,6 @@ you should see something like the following URL in the browser address bar. 导航到*危机中心*并点击“Contact”,你将会在浏览器的地址栏看到如下 URL: - http://.../crisis-center(popup:compose) @@ -3908,9 +3887,7 @@ Click the _Heroes_ link and look at the URL again. 点击 *Heroes* 链接,并再次查看 URL: - http://.../heroes(popup:compose) - The primary navigation part has changed; the secondary route is the same. @@ -5723,7 +5700,6 @@ Here's the *Crisis Center* URL in this "HTML5 pushState" style: 下面是*危机中心*的 URL 在“HTML 5 pushState”风格下的样子: - localhost:3002/crisis-center/ @@ -5736,7 +5712,6 @@ URLs with hashes. Here's a "hash URL" that routes to the *Crisis Center*. 老旧的浏览器在当前地址的 URL 变化时总会往服务器发送页面请求……唯一的例外规则是:当这些变化位于“#”(被称为“hash”)后面时不会发送。通过把应用内的路由 URL 拼接在 `#` 之后,路由器可以获得这条“例外规则”带来的优点。下面是到*危机中心*路由的“hash URL”: - localhost:3002/src/#/crisis-center/ diff --git a/aio/content/guide/security.md b/aio/content/guide/security.md index 2e8e7ed00e..7f0f2a351c 100644 --- a/aio/content/guide/security.md +++ b/aio/content/guide/security.md @@ -15,7 +15,7 @@ For more information about the attacks and mitigations described below, see [OWA You can run the in Stackblitz and download the code from there. -运行来试用本页的代码。 +你可以运行,在 Stackblitz 中试用并下载本页的代码。

Reporting vulnerabilities

@@ -426,6 +426,5 @@ must be audited as such. Angular-specific APIs that should be audited in a secur such as the [_bypassSecurityTrust_](guide/security#bypass-security-apis) methods, are marked in the documentation as security sensitive. - Angular 应用应该遵循和常规 Web 应用一样的安全原则并按照这些原则进行审计。Angular 中某些应该在安全评审中被审计的 API( 比如[_bypassSecurityTrust_](guide/security#bypass-security-apis) API)都在文档中被明确标记为安全性敏感的。 diff --git a/aio/content/guide/service-worker-communications.md b/aio/content/guide/service-worker-communications.md index d6e2938003..67970434df 100644 --- a/aio/content/guide/service-worker-communications.md +++ b/aio/content/guide/service-worker-communications.md @@ -16,7 +16,7 @@ A basic understanding of the following: * [Getting Started with Service Workers](guide/service-worker-getting-started). - [Service Worker 快速起步](guide/service-worker-getting-started). + [Service Worker 快速起步](guide/service-worker-getting-started)。
@@ -101,8 +101,8 @@ Doing this could break lazy-loading into currently running apps, especially if t You may also be interested in the following: -你可能对下列内容感兴趣: +你可能还对下列内容感兴趣: * [Service Worker in Production](guide/service-worker-devops). - [产品环境下的 Service Worker](guide/service-worker-devops). + [生产环境下的 Service Worker](guide/service-worker-devops)。 diff --git a/aio/content/guide/service-worker-config.md b/aio/content/guide/service-worker-config.md index 4c1317c652..5837add98f 100644 --- a/aio/content/guide/service-worker-config.md +++ b/aio/content/guide/service-worker-config.md @@ -14,7 +14,7 @@ A basic understanding of the following: * [Service Worker in Production](guide/service-worker-devops). - [产品环境下的 Service Worker](guide/service-worker-devops). + [生产环境下的 Service Worker](guide/service-worker-devops)。
@@ -313,5 +313,4 @@ Angular Service Worker 可以使用两种缓存策略之一来获取数据资源 * `freshness` optimizes for currency of data, preferentially fetching requested data from the network. Only if the network times out, according to `timeout`, does the request fall back to the cache. This is useful for resources that change frequently; for example, account balances. - `freshness` 为数据的即时性而优化,优先从网络获取请求的数据。只有当网络超时时,请求才会根据 `timeout` 的设置回退到缓存中。这对于那些频繁变化的资源很有用,例如账户余额。 - \ No newline at end of file + `freshness` 为数据的即时性而优化,优先从网络获取请求的数据。只有当网络超时时,请求才会根据 `timeout` 的设置回退到缓存中。这对于那些频繁变化的资源很有用,例如账户余额。 diff --git a/aio/content/guide/service-worker-devops.md b/aio/content/guide/service-worker-devops.md index 2ea8ab8650..db42bcd6e7 100644 --- a/aio/content/guide/service-worker-devops.md +++ b/aio/content/guide/service-worker-devops.md @@ -1,11 +1,11 @@ # Service worker in production -# 产品环境下的 Service Worker +# 生产环境下的 Service Worker This page is a reference for deploying and supporting production apps that use the Angular service worker. It explains how the Angular service worker fits into the larger production environment, the service worker's behavior under various conditions, and available recourses and fail-safes. -本页讲的是如何使用 Angular Service Worker 发布和支持产品环境下的应用。 -它解释了 Angular Service Worker 如何满足大规模产品环境的需求、Service Worker 在多种条件下有哪些行为以及有哪些可用的资源和故障保护机制。 +本页讲的是如何使用 Angular Service Worker 发布和支持生产环境下的应用。 +它解释了 Angular Service Worker 如何满足大规模生产环境的需求、Service Worker 在多种条件下有哪些行为以及有哪些可用的资源和故障保护机制。 #### Prerequisites @@ -557,8 +557,8 @@ the past on your site. You may also be interested in the following: -你可能对下列内容感兴趣: +你可能还对下列内容感兴趣: * [Service Worker Configuration](guide/service-worker-config). - [Service Worker 配置](guide/service-worker-config). + [Service Worker 配置](guide/service-worker-config)。 diff --git a/aio/content/guide/service-worker-getting-started.md b/aio/content/guide/service-worker-getting-started.md index 3d0a92c075..e27c8f93cd 100644 --- a/aio/content/guide/service-worker-getting-started.md +++ b/aio/content/guide/service-worker-getting-started.md @@ -120,7 +120,7 @@ At the top of the root module, `src/app/app.module.ts`, import `ServiceWorkerMod 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。 +把 `ServiceWorkerModule` 添加到 `@NgModule` 的 `imports` 数组中。使用 `register()` 来帮助管理 Service Worker 的注册并在非生产环境下运行时禁用 Service Worker。 @@ -367,8 +367,8 @@ Service Worker *在后台*安装好了这个更新后的版本,下次加载或 You may also be interested in the following: -你可能对下列内容感兴趣: +你可能还对下列内容感兴趣: * [Communicating with service workers](guide/service-worker-communications). - [与 Service Worker 通讯](guide/service-worker-communications). + [与 Service Worker 通讯](guide/service-worker-communications)。 diff --git a/aio/content/guide/service-worker-intro.md b/aio/content/guide/service-worker-intro.md index e0540816e5..6d78ff26dc 100644 --- a/aio/content/guide/service-worker-intro.md +++ b/aio/content/guide/service-worker-intro.md @@ -122,8 +122,8 @@ The remainder of this Angular documentation specifically addresses the Angular i You may also be interested in the following: -你可能还会对下列内容感兴趣: +你可能还对下列内容感兴趣: * [Getting Started with service workers](guide/service-worker-getting-started). - [Service Worker 快速起步](guide/service-worker-getting-started). + [Service Worker 快速起步](guide/service-worker-getting-started)。 diff --git a/aio/content/guide/set-document-title.md b/aio/content/guide/set-document-title.md index eadb6b71c3..4edd614068 100644 --- a/aio/content/guide/set-document-title.md +++ b/aio/content/guide/set-document-title.md @@ -22,9 +22,7 @@ The obvious approach is to bind a property of the component to the HTML ` 显而易见的方法是把组件的属性绑定到 HTML 的 `<title>` 标签上,像这样: <code-example format=''> - <title>{{This_Does_Not_Work}}</title> - </code-example> Sorry but that won't work. @@ -89,11 +87,9 @@ Here's the complete solution: 这里是完整的方案(代码)。 <code-tabs> - <code-pane title="src/main.ts" path="set-document-title/src/main.ts"></code-pane> <code-pane title="src/app/app.module.ts" path="set-document-title/src/app/app.module.ts"></code-pane> <code-pane title="src/app/app.component.ts" path="set-document-title/src/app/app.component.ts"></code-pane> - </code-tabs> ## Why provide the `Title` service in `bootstrap` @@ -116,5 +112,4 @@ you'll have to provide a different `Title` service that understands the concept of a "document title" for that specific platform. Ideally, the application itself neither knows nor cares about the runtime environment. - 你的做法正是如此。这里的 `Title` 服务是 Angular*浏览器平台*的一部分。如果在其它平台上引导应用程序,就得提供另一个专为那个平台准备的 `Title` 服务。 diff --git a/aio/content/guide/setup-systemjs-anatomy.md b/aio/content/guide/setup-systemjs-anatomy.md index 1790e52cbb..456ff25612 100644 --- a/aio/content/guide/setup-systemjs-anatomy.md +++ b/aio/content/guide/setup-systemjs-anatomy.md @@ -394,9 +394,7 @@ If you do, this page can help you understand their purpose. 为 **SystemJS** 模块加载器指定去哪儿查找在 JavaScript 的 `import` 语句中引用的模块。例如: <code-example language="ts"> - import { Component } from '@angular/core; - </code-example> Don't touch this file unless you are fully versed in SystemJS configuration. diff --git a/aio/content/guide/setup.md b/aio/content/guide/setup.md index 29f5cfbd75..beddeef79e 100644 --- a/aio/content/guide/setup.md +++ b/aio/content/guide/setup.md @@ -32,7 +32,6 @@ Perform the _clone-to-launch_ steps with these terminal commands. 运行下列命令来执行*克隆并启动*步骤。 <code-example language="sh" class="code-shell"> - git clone https://github.com/angular/quickstart.git quickstart cd quickstart npm install @@ -61,7 +60,6 @@ and unzip it into your project folder. Then perform the remaining steps with the 并解压到你的项目目录中。然后执行下面的命令完成剩余步骤。 <code-example language="sh" class="code-shell"> - cd quickstart npm install npm start @@ -103,7 +101,6 @@ Open a terminal window in the project folder and enter the following commands fo ### OS/X (bash) <code-example language="sh" class="code-shell"> - xargs rm -rf < non-essential-files.osx.txt rm src/app/*.spec*.ts rm non-essential-files.osx.txt @@ -113,7 +110,6 @@ Open a terminal window in the project folder and enter the following commands fo ### Windows <code-example language="sh" class="code-shell"> - for /f %i in (non-essential-files.txt) do del %i /F /S /Q rd .git /s /q rd e2e /s /q diff --git a/aio/content/guide/sharing-ngmodules.md b/aio/content/guide/sharing-ngmodules.md index 7ed56370d1..18b4f3cc39 100644 --- a/aio/content/guide/sharing-ngmodules.md +++ b/aio/content/guide/sharing-ngmodules.md @@ -28,7 +28,7 @@ A basic understanding of the following: * [Lazy loading modules](guide/lazy-loading-ngmodules). - [惰性加载模块](guide/lazy-loading-ngmodules). + [惰性加载模块](guide/lazy-loading-ngmodules)。 <!--* Components (#TBD) We don’t have a page just on the concept of components, but I think one would be helpful for beginners.--> @@ -123,12 +123,12 @@ To read about sharing services, see [Providers](guide/providers). You may also be interested in the following: -你可能还会对下列内容感兴趣: +你可能还对下列内容感兴趣: * [Providers](guide/providers). - [提供商](guide/providers)。 + [服务提供商](guide/providers)。 * [Types of Feature Modules](guide/module-types). - [特性模块的分类](guide/module-types). + [特性模块的分类](guide/module-types)。 diff --git a/aio/content/guide/singleton-services.md b/aio/content/guide/singleton-services.md index 36c9e0de5f..e06158b362 100644 --- a/aio/content/guide/singleton-services.md +++ b/aio/content/guide/singleton-services.md @@ -44,7 +44,6 @@ a way of providing services from a designated NgModule. 下面的范例模块习惯上叫做 `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> Here, `CoreModule` provides the `UserService`, and because `AppModule` @@ -269,7 +268,6 @@ Here are the two files in their entirety for reference: 以下这两个文件仅供参考: <code-tabs linenums="false"> - <code-pane title="app.module.ts" path="ngmodules/src/app/app.module.ts"> @@ -279,7 +277,6 @@ Here are the two files in their entirety for reference: region="whole-core-module" path="ngmodules/src/app/core/core.module.ts"> </code-pane> - </code-tabs> <hr> @@ -298,8 +295,8 @@ You may also be interested in: * [Lazy Loading Modules](guide/lazy-loading-ngmodules). - [惰性加载模块](guide/lazy-loading-ngmodules). + [惰性加载模块](guide/lazy-loading-ngmodules)。 * [NgModule FAQ](guide/ngmodule-faq). - [NgModule 常见问题](guide/ngmodule-faq)。 + [NgModule 常见问题](guide/ngmodule-faq)。 diff --git a/aio/content/guide/structural-directives.md b/aio/content/guide/structural-directives.md index ca5d118b00..4a128c7966 100644 --- a/aio/content/guide/structural-directives.md +++ b/aio/content/guide/structural-directives.md @@ -723,7 +723,6 @@ It's more like the curly braces in a JavaScript `if`-block: 它不是一个指令、组件、类或接口,更像是 JavaScript 中 `if` 块中的花括号。 <code-example language="javascript"> - if (someCondition) { statement1; statement2; diff --git a/aio/content/guide/styleguide.md b/aio/content/guide/styleguide.md index e748f1d639..b9bb9353fb 100644 --- a/aio/content/guide/styleguide.md +++ b/aio/content/guide/styleguide.md @@ -509,10 +509,8 @@ and reference assets of different types. <td> <code-example hideCopy class="no-box"> - @Component({ ... }) export class AppComponent { } - </code-example> </td> @@ -530,10 +528,8 @@ and reference assets of different types. <td> <code-example hideCopy class="no-box"> - @Component({ ... }) export class HeroesComponent { } - </code-example> </td> @@ -551,10 +547,8 @@ and reference assets of different types. <td> <code-example hideCopy class="no-box"> - @Component({ ... }) export class HeroListComponent { } - </code-example> </td> @@ -572,10 +566,8 @@ and reference assets of different types. <td> <code-example hideCopy class="no-box"> - @Component({ ... }) export class HeroDetailComponent { } - </code-example> </td> @@ -593,10 +585,8 @@ and reference assets of different types. <td> <code-example hideCopy class="no-box"> - @Directive({ ... }) export class ValidationDirective { } - </code-example> </td> @@ -614,10 +604,8 @@ and reference assets of different types. <td> <code-example hideCopy class="no-box"> - @NgModule({ ... }) export class AppModule - </code-example> </td> @@ -635,10 +623,8 @@ and reference assets of different types. <td> <code-example hideCopy class="no-box"> - @Pipe({ name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { } - </code-example> </td> @@ -656,10 +642,8 @@ and reference assets of different types. <td> <code-example hideCopy class="no-box"> - @Injectable() export class UserProfileService { } - </code-example> </td> @@ -775,10 +759,8 @@ As always, strive for consistency. <td> <code-example hideCopy class="no-box"> - @Injectable() export class HeroDataService { } - </code-example> </td> @@ -796,10 +778,8 @@ As always, strive for consistency. <td> <code-example hideCopy class="no-box"> - @Injectable() export class CreditService { } - </code-example> </td> @@ -817,10 +797,8 @@ As always, strive for consistency. <td> <code-example hideCopy class="no-box"> - @Injectable() export class Logger { } - </code-example> </td> @@ -1126,10 +1104,8 @@ For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the <td> <code-example hideCopy class="no-box"> - @Pipe({ name: 'ellipsis' }) export class EllipsisPipe implements PipeTransform { } - </code-example> </td> @@ -1147,10 +1123,8 @@ For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the <td> <code-example hideCopy class="no-box"> - @Pipe({ name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { } - </code-example> </td> @@ -1520,10 +1494,8 @@ A consistent class and file name convention make these modules easy to spot and <td> <code-example hideCopy class="no-box"> - @NgModule({ ... }) export class AppModule { } - </code-example> </td> @@ -1541,10 +1513,8 @@ A consistent class and file name convention make these modules easy to spot and <td> <code-example hideCopy class="no-box"> - @NgModule({ ... }) export class HeroesModule { } - </code-example> </td> @@ -1562,10 +1532,8 @@ A consistent class and file name convention make these modules easy to spot and <td> <code-example hideCopy class="no-box"> - @NgModule({ ... }) export class VillainsModule { } - </code-example> </td> @@ -1583,10 +1551,8 @@ A consistent class and file name convention make these modules easy to spot and <td> <code-example hideCopy class="no-box"> - @NgModule({ ... }) export class AppRoutingModule { } - </code-example> </td> @@ -1604,10 +1570,8 @@ A consistent class and file name convention make these modules easy to spot and <td> <code-example hideCopy class="no-box"> - @NgModule({ ... }) export class HeroesRoutingModule { } - </code-example> </td> @@ -4667,5 +4631,4 @@ Useful tools and tips for Angular. <a href="#toc">Back to top</a> - <a href="#toc">回到顶部</a> diff --git a/aio/content/guide/template-syntax.md b/aio/content/guide/template-syntax.md index 4af7c0a80c..741b84cded 100644 --- a/aio/content/guide/template-syntax.md +++ b/aio/content/guide/template-syntax.md @@ -75,7 +75,6 @@ You met the double-curly braces of interpolation, `{{` and `}}`, early in your A 在以前的 Angular 教程中,你遇到过由双花括号括起来的插值表达式,`{{` 和 `}}`。 <code-example path="template-syntax/src/app/app.component.html" region="first-interpolation" title="src/app/app.component.html" linenums="false"> - </code-example> You use interpolation to weave calculated strings into the text between HTML element tags and within attribute assignments. @@ -83,7 +82,6 @@ You use interpolation to weave calculated strings into the text between HTML ele 插值表达式可以把计算后的字符串插入到 HTML 元素标签内的文本或对标签的属性进行赋值。 <code-example path="template-syntax/src/app/app.component.html" region="title+image" title="src/app/app.component.html" linenums="false"> - </code-example> The text between the braces is often the name of a component property. Angular replaces that name with the @@ -101,7 +99,6 @@ and then **converts to a string**. The following interpolation illustrates the p 下列插值表达式通过把括号中的两个数字相加说明了这一点: <code-example path="template-syntax/src/app/app.component.html" region="sum-1" title="src/app/app.component.html" linenums="false"> - </code-example> The expression can invoke methods of the host component such as `getVal()`, seen here: @@ -109,7 +106,6 @@ The expression can invoke methods of the host component such as `getVal()`, seen 这个表达式可以调用宿主组件的方法,就像下面用的 `getVal()`: <code-example path="template-syntax/src/app/app.component.html" region="sum-2" title="src/app/app.component.html" linenums="false"> - </code-example> Angular evaluates all expressions in double curly braces, @@ -178,7 +174,7 @@ JavaScript 中那些具有或可能引发副作用的表达式是被禁止的, * increment and decrement operators (`++` and `--`) - 自增或自减操作符 (`++` 和 `--`) + 自增和自减运算符:`++` 和 `--` Other notable differences from JavaScript syntax include: @@ -206,7 +202,6 @@ In the following snippets, the `title` within double-curly braces and the 在下面的代码片段中,双花括号中的 `title` 和引号中的 `isUnchanged` 所引用的都是 `AppComponent` 中的属性。 <code-example path="template-syntax/src/app/app.component.html" region="context-component-expression" title="src/app/app.component.html" linenums="false"> - </code-example> An expression may also refer to properties of the _template's_ context @@ -217,7 +212,6 @@ or a [template reference variable](guide/template-syntax#ref-vars) (`#heroInput` 比如[模板输入变量](guide/template-syntax#template-input-variable) (`let hero`)和[模板引用变量](guide/template-syntax#ref-vars)(`#heroInput`)就是备选的上下文对象之一。 <code-example path="template-syntax/src/app/app.component.html" region="context-var" title="src/app/app.component.html" linenums="false"> - </code-example> The context for terms in an expression is a blend of the _template variables_, @@ -368,7 +362,6 @@ appearing in quotes to the right of the `=` symbol as in `(event)="statemen 模板语句将在[事件绑定](guide/template-syntax#event-binding)一节看到,它出现在 `=` 号右侧的引号中,就像这样:`(event)="statement"`。 <code-example path="template-syntax/src/app/app.component.html" region="context-component-statement" title="src/app/app.component.html" linenums="false"> - </code-example> A template statement *has a side effect*. @@ -432,7 +425,6 @@ The *deleteHero* in `(click)="deleteHero()"` is a method of the data-bound compo `(click)="deleteHero()"` 中的 *deleteHero* 就是这个数据绑定组件上的一个方法。 <code-example path="template-syntax/src/app/app.component.html" region="context-component-statement" title="src/app/app.component.html" linenums="false"> - </code-example> The statement context may also refer to properties of the template's own context. @@ -445,7 +437,6 @@ are passed to an event handling method of the component. 在下面的例子中,就把模板的 `$event` 对象、[模板输入变量](guide/template-syntax#template-input-variable) (`let hero`)和[模板引用变量](guide/template-syntax#ref-vars) (`#heroForm`)传给了组件中的一个事件处理器方法。 <code-example path="template-syntax/src/app/app.component.html" region="context-var-statement" title="src/app/app.component.html" linenums="false"> - </code-example> Template context names take precedence over component context names. @@ -518,7 +509,6 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _ </col> <col width="20%"> </col> - <tr> <th> @@ -546,7 +536,6 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _ </th> </tr> - <tr> <td> @@ -560,11 +549,9 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _ <td> <code-example> - {{expression}} [target]="expression" bind-target="expression" - </code-example> </td> @@ -598,10 +585,8 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _ <td> <code-example> - (target)="statement" on-target="statement" - </code-example> </td> @@ -615,7 +600,6 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _ </td> </tr> - <tr> <td> @@ -629,10 +613,8 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _ <td> <code-example> - [(target)]="expression" bindon-target="expression" - </code-example> </td> @@ -646,9 +628,7 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _ </td> </tr> - </tr> - </table> @@ -704,7 +684,6 @@ you modify those elements by setting element attributes with string constants. 通过把字符串常量设置到元素的 attribute 来修改那些元素。 <code-example path="template-syntax/src/app/app.component.html" region="img+button" title="src/app/app.component.html" linenums="false"> - </code-example> You still create a structure and initialize attribute values this way in Angular templates. @@ -717,7 +696,6 @@ and drop them into templates as if they were native HTML elements. 然后,用封装了 HTML 的组件创建新元素,并把它们当作原生 HTML 元素在模板中使用。 <code-example path="template-syntax/src/app/app.component.html" region="hero-detail-1" title="src/app/app.component.html" linenums="false"> - </code-example> That's HTML Plus. @@ -729,7 +707,6 @@ Then you learn about data binding. The first binding you meet might look like th 现在开始学习数据绑定。你碰到的第一种数据绑定是这样的: <code-example path="template-syntax/src/app/app.component.html" region="disabled-button-1" title="src/app/app.component.html" linenums="false"> - </code-example> You'll get to that peculiar bracket notation in a moment. Looking beyond it, @@ -880,7 +857,6 @@ The following table summarizes: </col> <col width="75%"> </col> - <tr> <th> @@ -908,7 +884,6 @@ The following table summarizes: </th> </tr> - <tr> <td> @@ -934,13 +909,11 @@ The following table summarizes: <td> <code-example path="template-syntax/src/app/app.component.html" region="property-binding-syntax-1" title="src/app/app.component.html" linenums="false"> - </code-example> </td> </tr> - <tr> <td> @@ -966,13 +939,11 @@ The following table summarizes: <td> <code-example path="template-syntax/src/app/app.component.html" region="event-binding-syntax-1" title="src/app/app.component.html" linenums="false"> - </code-example> </td> </tr> - <tr> <td> @@ -994,13 +965,11 @@ The following table summarizes: <td> <code-example path="template-syntax/src/app/app.component.html" region="2-way-binding-syntax-1" title="src/app/app.component.html" linenums="false"> - </code-example> </td> </tr> - <tr> <td> @@ -1021,13 +990,11 @@ The following table summarizes: <td> <code-example path="template-syntax/src/app/app.component.html" region="attribute-binding-syntax-1" title="src/app/app.component.html" linenums="false"> - </code-example> </td> </tr> - <tr> <td> @@ -1047,13 +1014,11 @@ The following table summarizes: <td> <code-example path="template-syntax/src/app/app.component.html" region="class-binding-syntax-1" title="src/app/app.component.html" linenums="false"> - </code-example> </td> </tr> - <tr> <td> @@ -1073,13 +1038,11 @@ The following table summarizes: <td> <code-example path="template-syntax/src/app/app.component.html" region="style-binding-syntax-1" title="src/app/app.component.html" linenums="false"> - </code-example> </td> </tr> - </table> With this broad view in mind, you're ready to look at binding types in detail. @@ -1106,7 +1069,6 @@ binding the `src` property of an image element to a component's `heroImageUrl` p 下面这个例子中,image 元素的 `src` 属性会被绑定到组件的 `heroImageUrl` 属性上: <code-example path="template-syntax/src/app/app.component.html" region="property-binding-1" title="src/app/app.component.html" linenums="false"> - </code-example> Another example is disabling a button when the component says that it `isUnchanged`: @@ -1114,7 +1076,6 @@ Another example is disabling a button when the component says that it `isUnchang 另一个例子是当组件说它 `isUnchanged`(未改变)时禁用按钮: <code-example path="template-syntax/src/app/app.component.html" region="property-binding-2" title="src/app/app.component.html" linenums="false"> - </code-example> Another is setting a property of a directive: @@ -1122,7 +1083,6 @@ Another is setting a property of a directive: 另一个例子是设置指令的属性: <code-example path="template-syntax/src/app/app.component.html" region="property-binding-3" title="src/app/app.component.html" linenums="false"> - </code-example> Yet another is setting the model property of a custom component (a great way @@ -1131,7 +1091,6 @@ for parent and child components to communicate): 还有另一个例子是设置自定义组件的模型属性(这是父子组件之间通讯的重要途径): <code-example path="template-syntax/src/app/app.component.html" region="property-binding-4" title="src/app/app.component.html" linenums="false"> - </code-example> ### One-way *in* @@ -1181,7 +1140,6 @@ The target property in the following code is the image element's `src` property. 包裹在方括号中的元素属性名标记着目标属性。下列代码中的目标属性是 image 元素的 `src` 属性。 <code-example path="template-syntax/src/app/app.component.html" region="property-binding-1" title="src/app/app.component.html" linenums="false"> - </code-example> Some people prefer the `bind-` prefix alternative, known as the *canonical form*: @@ -1189,7 +1147,6 @@ Some people prefer the `bind-` prefix alternative, known as the *canonical form* 有些人喜欢用 `bind-` 前缀的可选形式,并称之为*规范形式*: <code-example path="template-syntax/src/app/app.component.html" region="property-binding-5" title="src/app/app.component.html" linenums="false"> - </code-example> The target name is always the name of a property, even when it appears to be the name of something else. @@ -1205,7 +1162,6 @@ as it is in the following example: 元素属性可能是最常见的绑定目标,但 Angular 会先去看这个名字是否是某个已知指令的属性名,就像下面的例子中一样: <code-example path="template-syntax/src/app/app.component.html" region="property-binding-3" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -1269,7 +1225,6 @@ The `hero` property of the `HeroDetail` component expects a `Hero` object, which `HeroDetail` 组件的 `hero` 属性想要一个 `Hero` 对象,那就在属性绑定中精确地给它一个 `Hero` 对象: <code-example path="template-syntax/src/app/app.component.html" region="property-binding-4" title="src/app/app.component.html" linenums="false"> - </code-example> ### Remember the brackets @@ -1290,7 +1245,6 @@ Don't make the following mistake: 不要出现这样的失误: <code-example path="template-syntax/src/app/app.component.html" region="property-binding-6" title="src/app/app.component.html" linenums="false"> - </code-example> {@a one-time-initialization} @@ -1324,7 +1278,6 @@ not a template expression. Angular sets it and forgets about it. 下面这个例子把 `HeroDetailComponent` 的 `prefix` 属性初始化为固定的字符串,而不是模板表达式。Angular 设置它,然后忘记它。 <code-example path="template-syntax/src/app/app.component.html" region="property-binding-7" title="src/app/app.component.html" linenums="false"> - </code-example> The `[hero]` binding, on the other hand, remains a live binding to the component's `currentHero` property. @@ -1344,7 +1297,6 @@ The following binding pairs do the same thing: 下列这几对绑定做的事情完全相同: <code-example path="template-syntax/src/app/app.component.html" region="property-binding-vs-interpolation" title="src/app/app.component.html" linenums="false"> - </code-example> _Interpolation_ is a convenient alternative to _property binding_ in many cases. @@ -1375,7 +1327,6 @@ Imagine the following *malicious content*. 假设下面的*恶意内容* <code-example path="template-syntax/src/app/app.component.ts" region="evil-title" title="src/app/app.component.ts" linenums="false"> - </code-example> Fortunately, Angular data binding is on alert for dangerous HTML. @@ -1388,7 +1339,6 @@ nor property binding. 不管是插值表达式还是属性绑定,都**不会**允许带有 script 标签的 HTML 泄漏到浏览器中。 <code-example path="template-syntax/src/app/app.component.html" region="property-binding-vs-interpolation-sanitization" title="src/app/app.component.html" linenums="false"> - </code-example> Interpolation handles the script tags differently than property binding but both approaches render the @@ -1453,9 +1403,7 @@ This fact becomes painfully obvious when you write something like this. 如果想写出类似下面这样的东西,就会暴露出痛点了: <code-example language="html"> - <tr><td colspan="{{1 + 1}}">Three-Four</td></tr> - </code-example> And you get this error: @@ -1463,10 +1411,8 @@ And you get this error: 会得到这个错误: <code-example format="nocode"> - Template parse errors: Can't bind to 'colspan' since it isn't a known native property - </code-example> As the message says, the `<td>` element does not have a `colspan` property. @@ -1494,7 +1440,6 @@ Bind `[attr.colspan]` to a calculated value: 这里把 `[attr.colspan]` 绑定到一个计算值: <code-example path="template-syntax/src/app/app.component.html" region="attrib-binding-colspan" title="src/app/app.component.html" linenums="false"> - </code-example> Here's how the table renders: @@ -1517,16 +1462,10 @@ Here's how the table renders: <td> - Five + Five</td><td>Six </td> -<td> - - Six - -</td> - </tr> </table> @@ -1538,7 +1477,6 @@ attribute 绑定的主要用例之一是设置 ARIA attribute(译注:ARIA 就像这个例子中一样: <code-example path="template-syntax/src/app/app.component.html" region="attrib-binding-aria" title="src/app/app.component.html" linenums="false"> - </code-example> <hr/> @@ -1566,7 +1504,6 @@ with class bindings. Here's how to set the attribute without binding: 下列例子示范了如何通过 CSS 类绑定来添加和移除应用的 "special" 类。不用绑定直接设置 attribute 时是这样的: <code-example path="template-syntax/src/app/app.component.html" region="class-binding-1" title="src/app/app.component.html" linenums="false"> - </code-example> You can replace that with a binding to a string of the desired class names; this is an all-or-nothing, replacement binding. @@ -1575,7 +1512,6 @@ You can replace that with a binding to a string of the desired class names; this (译注:即当 badCurly 有值时 class 这个 attribute 设置的内容会被完全覆盖) <code-example path="template-syntax/src/app/app.component.html" region="class-binding-2" title="src/app/app.component.html" linenums="false"> - </code-example> Finally, you can bind to a specific class name. @@ -1586,7 +1522,6 @@ It removes the class when the expression is falsy. 当模板表达式的求值结果是真值时,Angular 会添加这个类,反之则移除它。 <code-example path="template-syntax/src/app/app.component.html" region="class-binding-3" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -1617,7 +1552,6 @@ followed by a dot (`.`) and the name of a CSS style property: `[style.style-prop 形如:`[style.style-property]`。 <code-example path="template-syntax/src/app/app.component.html" region="style-binding-1" title="src/app/app.component.html" linenums="false"> - </code-example> Some style binding styles have a unit extension. @@ -1626,7 +1560,6 @@ The following example conditionally sets the font size in “em” and “%” 有些样式绑定中的样式带有单位。在这里,以根据条件用 “em” 和 “%” 来设置字体大小的单位。 <code-example path="template-syntax/src/app/app.component.html" region="style-binding-2" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -1685,7 +1618,6 @@ the component's `onSave()` method whenever a click occurs: 下面事件绑定监听按钮的点击事件。每当点击发生时,都会调用组件的 `onSave()` 方法。 <code-example path="template-syntax/src/app/app.component.html" region="event-binding-1" title="src/app/app.component.html" linenums="false"> - </code-example> ### Target event @@ -1698,7 +1630,6 @@ identifies the target event. In the following example, the target is the button' **圆括号中的名称** —— 比如 `(click)` —— 标记出目标事件。在下面例子中,目标是按钮的 click 事件。 <code-example path="template-syntax/src/app/app.component.html" region="event-binding-1" title="src/app/app.component.html" linenums="false"> - </code-example> Some people prefer the `on-` prefix alternative, known as the **canonical form**: @@ -1706,7 +1637,6 @@ Some people prefer the `on-` prefix alternative, known as the **canonical form** 有些人更喜欢带 `on-` 前缀的备选形式,称之为**规范形式**: <code-example path="template-syntax/src/app/app.component.html" region="event-binding-2" title="src/app/app.component.html" linenums="false"> - </code-example> Element events may be the more common targets, but Angular looks first to see if the name matches an event property @@ -1715,7 +1645,6 @@ of a known directive, as it does in the following example: 元素事件可能是更常见的目标,但 Angular 会先看这个名字是否能匹配上已知指令的事件属性,就像下面这个例子: <code-example path="template-syntax/src/app/app.component.html" region="event-binding-3" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -1766,7 +1695,6 @@ Consider this example: 考虑这个范例: <code-example path="template-syntax/src/app/app.component.html" region="without-NgModel" title="src/app/app.component.html" linenums="false"> - </code-example> This code sets the input box `value` property by binding to the `name` property. @@ -1818,11 +1746,9 @@ Here are the pertinent excerpts from that `HeroDetailComponent`: 下面的代码节选自 `HeroDetailComponent`: <code-example path="template-syntax/src/app/hero-detail.component.ts" linenums="false" title="src/app/hero-detail.component.ts (template)" region="template-1"> - </code-example> <code-example path="template-syntax/src/app/hero-detail.component.ts" linenums="false" title="src/app/hero-detail.component.ts (deleteRequest)" region="deleteRequest"> - </code-example> The component defines a `deleteRequest` property that returns an `EventEmitter`. @@ -1837,7 +1763,6 @@ Now imagine a hosting parent component that binds to the `HeroDetailComponent`'s 现在,假设有个宿主的父组件,它绑定了 `HeroDetailComponent` 的 `deleteRequest` 事件。 <code-example path="template-syntax/src/app/app.component.html" linenums="false" title="src/app/app.component.html (event-binding-to-component)" region="event-binding-to-component"> - </code-example> When the `deleteRequest` event fires, Angular calls the parent component's `deleteHero` method, @@ -1908,7 +1833,6 @@ It has a `size` value property and a companion `sizeChange` event: 下面的 `SizerComponent` 符合这个模式。它有 `size` 属性和伴随的 `sizeChange` 事件: <code-example path="template-syntax/src/app/sizer.component.ts" title="src/app/sizer.component.ts"> - </code-example> The initial `size` is an input value from a property binding. @@ -1924,7 +1848,6 @@ Here's an example in which the `AppComponent.fontSizePx` is two-way bound to the 下面的例子中,`AppComponent.fontSize` 被双向绑定到 `SizerComponent`: <code-example path="template-syntax/src/app/app.component.html" linenums="false" title="src/app/app.component.html (two-way-1)" region="two-way-1"> - </code-example> The `AppComponent.fontSizePx` establishes the initial `SizerComponent.size` value. @@ -1943,7 +1866,6 @@ Angular _desugars_ the `SizerComponent` binding into this: Angular 将 `SizerComponent` 的绑定分解成这样: <code-example path="template-syntax/src/app/app.component.html" linenums="false" title="src/app/app.component.html (two-way-2)" region="two-way-2"> - </code-example> The `$event` variable contains the payload of the `SizerComponent.sizeChange` event. @@ -1990,7 +1912,6 @@ Why create a directive to handle a click when you can write a simple binding suc 如果能用简单的绑定达到目的,为什么还要创建指令来处理点击事件呢? <code-example path="template-syntax/src/app/app.component.html" region="event-binding-1" title="src/app/app.component.html" linenums="false"> - </code-example> You still benefit from directives that simplify complex tasks. @@ -2060,7 +1981,6 @@ A [class binding](guide/template-syntax#class-binding) is a good way to add or r [CSS 类绑定](guide/template-syntax#class-binding) 是添加或删除*单个*类的最佳途径。 <code-example path="template-syntax/src/app/app.component.html" region="class-binding-3a" title="src/app/app.component.html" linenums="false"> - </code-example> To add or remove *many* CSS classes at the same time, the `NgClass` directive may be the better choice. @@ -2080,7 +2000,6 @@ Consider a `setCurrentClasses` component method that sets a component property, 组件方法 `setCurrentClasses` 可以把组件的属性 `currentClasses` 设置为一个对象,它将会根据三个其它组件的状态为 `true` 或 `false` 而添加或移除三个类。 <code-example path="template-syntax/src/app/app.component.ts" region="setClasses" title="src/app/app.component.ts" linenums="false"> - </code-example> Adding an `ngClass` property binding to `currentClasses` sets the element's classes accordingly: @@ -2088,7 +2007,6 @@ Adding an `ngClass` property binding to `currentClasses` sets the element's clas 把 `NgClass` 属性绑定到 `currentClasses`,根据它来设置此元素的 CSS 类: <code-example path="template-syntax/src/app/app.component.html" region="NgClass-1" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -2116,7 +2034,6 @@ A [style binding](guide/template-syntax#style-binding) is an easy way to set a * [样式绑定](guide/template-syntax#style-binding)是设置*单一*样式值的简单方式。 <code-example path="template-syntax/src/app/app.component.html" region="NgStyle-1" title="src/app/app.component.html" linenums="false"> - </code-example> To set *many* inline styles at the same time, the `NgStyle` directive may be the better choice. @@ -2135,7 +2052,6 @@ with an object that defines three styles, based on the state of three other comp 来看看组件的 `setCurrentStyles` 方法,它会根据另外三个属性的状态把组件的 `currentStyles` 属性设置为一个定义了三个样式的对象: <code-example path="template-syntax/src/app/app.component.ts" region="setStyles" title="src/app/app.component.ts" linenums="false"> - </code-example> Adding an `ngStyle` property binding to `currentStyles` sets the element's styles accordingly: @@ -2143,7 +2059,6 @@ Adding an `ngStyle` property binding to `currentStyles` sets the element's style 把 `NgStyle` 属性绑定到 `currentStyles`,以据此设置此元素的样式: <code-example path="template-syntax/src/app/app.component.html" region="NgStyle-2" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -2172,7 +2087,6 @@ Two-way data binding with the `NgModel` directive makes that easy. Here's an exa 使用 `NgModel` 指令进行双向数据绑定可以简化这种工作。例子如下: <code-example path="template-syntax/src/app/app.component.html" linenums="false" title="src/app/app.component.html (NgModel-1)" region="NgModel-1"> - </code-example> #### _FormsModule_ is required to use _ngModel_ @@ -2192,7 +2106,6 @@ Here's how to import the `FormsModule` to make `[(ngModel)]` available. 导入 `FormsModule` 并让 `[(ngModel)]` 可用的代码如下: <code-example path="template-syntax/src/app/app.module.1.ts" linenums="false" title="src/app/app.module.ts (FormsModule import)"> - </code-example> #### Inside <span class="syntax">[(ngModel)]</span> @@ -2206,7 +2119,6 @@ the `<input>` element's `value` property and `input` event. 回头看看 `name` 绑定,注意,你可以通过分别绑定到 `<input>` 元素的 `value` 属性和 `input` 事件来达到同样的效果。 <code-example path="template-syntax/src/app/app.component.html" region="without-NgModel" title="src/app/app.component.html" linenums="false"> - </code-example> That's cumbersome. Who can remember which element property to set and which element event emits user changes? @@ -2221,7 +2133,6 @@ That `ngModel` directive hides these onerous details behind its own `ngModel` i `ngModel` 指令通过自己的输入属性 `ngModel` 和输出属性 `ngModelChange` 隐藏了那些细节。 <code-example path="template-syntax/src/app/app.component.html" region="NgModel-3" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -2270,7 +2181,6 @@ with a single declaration, which it can with the `[(ngModel)]` syntax: 你不用被迫两次引用这个数据属性,Angular 可以捕获该元素的数据属性,并且通过一个简单的声明来设置它,这样它就可以使用 `[(ngModel)]` 语法了。 <code-example path="template-syntax/src/app/app.component.html" region="NgModel-1" title="src/app/app.component.html" linenums="false"> - </code-example> Is `[(ngModel)]` all you need? Is there ever a reason to fall back to its expanded form? @@ -2288,7 +2198,6 @@ The following contrived example forces the input value to uppercase: 下面这个生造的例子强制输入框的内容变成大写: <code-example path="template-syntax/src/app/app.component.html" region="NgModel-4" title="src/app/app.component.html" linenums="false"> - </code-example> Here are all variations in action, including the uppercase version: @@ -2368,7 +2277,6 @@ Bind the directive to a condition expression like `isActive` in this example. 在下面的例子中,该指令绑定到了类似于 `isActive` 这样的条件表达式。 <code-example path="template-syntax/src/app/app.component.html" region="NgIf-1" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="alert is-critical"> @@ -2395,7 +2303,6 @@ You can control the visibility of an element with a 你也可以通过[类绑定](guide/template-syntax#class-binding)或[样式绑定](guide/template-syntax#style-binding)来显示或隐藏一个元素。 <code-example path="template-syntax/src/app/app.component.html" region="NgIf-3" title="src/app/app.component.html" linenums="false"> - </code-example> Hiding an element is quite different from removing an element with `NgIf`. @@ -2445,7 +2352,6 @@ The `nullHero` will never be displayed. 而 `nullHero` 永远不会显示。 <code-example path="template-syntax/src/app/app.component.html" region="NgIf-2" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -2477,7 +2383,6 @@ Here is an example of `NgForOf` applied to a simple `<div>`: 下例中,`NgFor` 应用在一个简单的 `<div>` 上: <code-example path="template-syntax/src/app/app.component.html" region="NgFor-1" title="src/app/app.component.html" linenums="false"> - </code-example> You can also apply an `NgForOf` to a component element, as in this example: @@ -2485,7 +2390,6 @@ You can also apply an `NgForOf` to a component element, as in this example: 也可以把 `NgFor` 应用在一个组件元素上,就下例这样: <code-example path="template-syntax/src/app/app.component.html" region="NgFor-2" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="alert is-critical"> @@ -2552,7 +2456,6 @@ and then passed in a binding to the `hero` property of the `<hero-detail>` compo 这里它首先在一个插值表达式中被引用到,然后通过一个绑定把它传给了 `<hero-detail>` 组件的 `hero` 属性。 <code-example path="template-syntax/src/app/app.component.html" region="NgFor-1-2" title="src/app/app.component.html" linenums="false"> - </code-example> Learn more about _template input variables_ in the @@ -2575,7 +2478,6 @@ The next example captures the `index` in a variable named `i` and displays it wi 下面这个例子把 `index` 捕获到了 `i` 变量中,并且把它显示在英雄名字的前面。 <code-example path="template-syntax/src/app/app.component.html" region="NgFor-3" title="src/app/app.component.html" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -2621,7 +2523,6 @@ In this case, that value is the hero's `id`. 在这里,这个值就是英雄的 `id`。 <code-example path="template-syntax/src/app/app.component.ts" region="trackByHeroes" title="src/app/app.component.ts" linenums="false"> - </code-example> In the microsyntax expression, set `trackBy` to this method. @@ -2629,7 +2530,6 @@ In the microsyntax expression, set `trackBy` to this method. 在微语法中,把 `trackBy` 设置为该方法。 <code-example path="template-syntax/src/app/app.component.html" region="trackBy" title="src/app/app.component.html" linenums="false"> - </code-example> Here is an illustration of the _trackBy_ effect. @@ -2674,7 +2574,6 @@ Angular 只会把*选中的*元素放进 DOM 中。 `NgSwitch` 实际上包括三个相互协作的指令:`NgSwitch`、`NgSwitchCase` 和 `NgSwitchDefault`,例子如下: <code-example path="template-syntax/src/app/app.component.html" region="NgSwitch" title="src/app/app.component.html" linenums="false"> - </code-example> <figure> @@ -2726,7 +2625,6 @@ For example, you could replace the `<confused-hero>` switch case with the follow 比如,你可以把 `<confused-hero>` 分支改成这样: <code-example path="template-syntax/src/app/app.component.html" region="NgSwitch-div" title="src/app/app.component.html" linenums="false"> - </code-example> <hr/> @@ -2754,7 +2652,6 @@ The `#phone` declares a `phone` variable on an `<input>` element. `#phone` 的意思就是声明一个名叫 `phone` 的变量来引用 `<input>` 元素。 <code-example path="template-syntax/src/app/app.component.html" region="ref-var" title="src/app/app.component.html" linenums="false"> - </code-example> You can refer to a template reference variable _anywhere_ in the template. @@ -2765,7 +2662,6 @@ consumed in a `<button>` on the other side of the template 比如声明在 `<input>` 上的 `phone` 变量就是在模板另一侧的 `<button>` 上使用的。 <code-example path="template-syntax/src/app/app.component.html" region="ref-phone" title="src/app/app.component.html" linenums="false"> - </code-example> <h3 class="no-toc">How a reference variable gets its value</h3> @@ -2789,7 +2685,6 @@ The following is a *simplified* version of the form example in the [Forms](guide 下面是[表单](guide/forms)一章中表单范例的*简化版*。 <code-example path="template-syntax/src/app/hero-form.component.html" title="src/app/hero-form.component.html" linenums="false"> - </code-example> A template reference variable, `heroForm`, appears three times in this example, separated @@ -2841,7 +2736,6 @@ This example declares the `fax` variable as `ref-fax` instead of `#fax`. 下面的例子中就用把 `fax` 变量声明成了 `ref-fax` 而不是 `#fax`。 <code-example path="template-syntax/src/app/app.component.html" region="ref-fax" title="src/app/app.component.html" linenums="false"> - </code-example> <hr/> @@ -2892,7 +2786,6 @@ In such binding expressions, the component's property or method is to the _right 在下面的例子中,`iconUrl` 和 `onSave` 是组件的成员,它们在 `=` 右侧引号语法中被引用了。 <code-example path="template-syntax/src/app/app.component.html" region="io-1" title="src/app/app.component.html" linenums="false"> - </code-example> The `iconUrl` and `onSave` are members of the `AppComponent` class. @@ -2930,7 +2823,6 @@ In the following example, the `AppComponent` template binds `AppComponent` class 下面的例子中,`AppComponent` 的模板把 `AppComponent` 类的成员绑定到了 `HeroDetailComponent`(选择器为 `'app-hero-detail'`) 的属性上。 <code-example path="template-syntax/src/app/app.component.html" region="io-2" title="src/app/app.component.html" linenums="false"> - </code-example> The Angular compiler _may_ reject these bindings with errors like this one: @@ -2938,10 +2830,8 @@ The Angular compiler _may_ reject these bindings with errors like this one: Angular 的编译器*可能*会对这些绑定报错,就像这样: <code-example language="sh" class="code-shell"> - Uncaught Error: Template parse errors: Can't bind to 'hero' since it isn't a known property of 'app-hero-detail' - </code-example> You know that `HeroDetailComponent` has `hero` and `deleteRequest` properties. @@ -3013,7 +2903,6 @@ because the data bound properties are annotated with `@Input()` and `@Output()` 在本章的例子中,绑定到 `HeroDetailComponent` 不会失败,这是因为这些要进行数据绑定的属性都带有 `@Input()` 和 `@Output()` 装饰器。 <code-example path="template-syntax/src/app/hero-detail.component.ts" region="input-output-1" title="src/app/hero-detail.component.ts" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -3024,7 +2913,6 @@ of the directive metadata, as in this example: 另外,还可以在指令元数据的 `inputs` 或 `outputs` 数组中标记出这些成员。比如这个例子: <code-example path="template-syntax/src/app/hero-detail.component.ts" region="input-output-2" title="src/app/hero-detail.component.ts" linenums="false"> - </code-example> </div> @@ -3077,7 +2965,6 @@ you expect to bind to an event property that is also called `myClick`. 希望绑定的事件属性也叫 `myClick`。 <code-example path="template-syntax/src/app/app.component.html" region="myClick" title="src/app/app.component.html" linenums="false"> - </code-example> However, the directive name is often a poor choice for the name of a property within the directive class. @@ -3101,7 +2988,6 @@ You can specify the alias for the property name by passing it into the input/out 把别名传进@Input/@Output 装饰器,就可以为属性指定别名,就像这样: <code-example path="template-syntax/src/app/click.directive.ts" region="output-myClick" title="src/app/click.directive.ts" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -3114,7 +3000,6 @@ the directive property name on the *left* and the public alias on the *right*: 可以写一个冒号 (`:`) 分隔的字符串,*左侧*是指令中的属性名,*右侧*则是公共别名。 <code-example path="template-syntax/src/app/click.directive.ts" region="output-myClick2" title="src/app/click.directive.ts" linenums="false"> - </code-example> </div> @@ -3153,7 +3038,6 @@ Angular [管道](guide/pipes)对像这样的小型转换来说是个明智的选 它们很容易用于模板表达式中,只要使用**管道操作符 (`|`) **就行了。 <code-example path="template-syntax/src/app/app.component.html" region="pipes-1" title="src/app/app.component.html" linenums="false"> - </code-example> The pipe operator passes the result of an expression on the left to a pipe function on the right. @@ -3165,7 +3049,6 @@ You can chain expressions through multiple pipes: 还可以通过多个管道串联表达式: <code-example path="template-syntax/src/app/app.component.html" region="pipes-2" title="src/app/app.component.html" linenums="false"> - </code-example> And you can also [apply parameters](guide/pipes#parameterizing-a-pipe) to a pipe: @@ -3173,7 +3056,6 @@ And you can also [apply parameters](guide/pipes#parameterizing-a-pipe) to a pipe 还能对它们使用参数: <code-example path="template-syntax/src/app/app.component.html" region="pipes-3" title="src/app/app.component.html" linenums="false"> - </code-example> The `json` pipe is particularly helpful for debugging bindings: @@ -3181,7 +3063,6 @@ The `json` pipe is particularly helpful for debugging bindings: `json` 管道对调试绑定特别有用: <code-example path="template-syntax/src/app/app.component.html" linenums="false" title="src/app/app.component.html (pipes-json)" region="pipes-json"> - </code-example> The generated output would look something like this @@ -3189,12 +3070,10 @@ The generated output would look something like this 它生成的输出是这样的: <code-example language="json"> - { "id": 0, "name": "Hercules", "emotion": "happy", "birthdate": "1970-02-25T08:00:00.000Z", "url": "http://www.imdb.com/title/tt0065832/", "rate": 325 } - </code-example> <hr/> @@ -3213,7 +3092,6 @@ Angular 的**安全导航操作符 (`?.`) **是一种流畅而便利的方式, 下例中,当 `currentHero` 为空时,保护视图渲染器,让它免于失败。 <code-example path="template-syntax/src/app/app.component.html" region="safe-2" title="src/app/app.component.html" linenums="false"> - </code-example> What happens when the following data bound `title` property is null? @@ -3221,7 +3099,6 @@ What happens when the following data bound `title` property is null? 如果下列数据绑定中 `title` 属性为空,会发生什么? <code-example path="template-syntax/src/app/app.component.html" region="safe-1" title="src/app/app.component.html" linenums="false"> - </code-example> The view still renders but the displayed value is blank; you see only "The title is" with nothing after it. @@ -3236,9 +3113,7 @@ that displays the `name` of a null hero. 假设模板表达式涉及属性路径,在下例中,显示一个空 (null) 英雄的 `firstName`。 <code-example language="html"> - The null hero's name is {{nullHero.name}} - </code-example> JavaScript throws a null reference error, and so does Angular: @@ -3246,9 +3121,7 @@ JavaScript throws a null reference error, and so does Angular: JavaScript 抛出了空引用错误,Angular 也是如此: <code-example format="nocode"> - TypeError: Cannot read property 'name' of null in [null]. - </code-example> Worse, the *entire view disappears*. @@ -3283,7 +3156,6 @@ You could code around that problem with [*ngIf](guide/template-syntax#ngIf). 可以通过用[NgIf](guide/template-syntax#ngIf)代码环绕它来解决这个问题。 <code-example path="template-syntax/src/app/app.component.html" region="safe-4" title="src/app/app.component.html" linenums="false"> - </code-example> You could try to chain parts of the property path with `&&`, knowing that the expression bails out @@ -3292,7 +3164,6 @@ when it encounters the first null. 或者可以尝试通过 `&&` 来把属性路径的各部分串起来,让它在遇到第一个空值的时候,就返回空。 <code-example path="template-syntax/src/app/app.component.html" region="safe-5" title="src/app/app.component.html" linenums="false"> - </code-example> These approaches have merit but can be cumbersome, especially if the property path is long. @@ -3310,7 +3181,6 @@ Angular 安全导航操作符 (`?.`) 是在属性路径中保护空值的更加 显示是空的,但应用正常工作,而没有发生错误。 <code-example path="template-syntax/src/app/app.component.html" region="safe-6" title="src/app/app.component.html" linenums="false"> - </code-example> It works perfectly with long property paths such as `a?.b?.c?.d`. @@ -3352,7 +3222,6 @@ For example, after you use [*ngIf](guide/template-syntax#ngIf) to check that `he 例如,在用[*ngIf](guide/template-syntax#ngIf)来检查过 `hero` 是已定义的之后,就可以断言 `hero` 属性一定是已定义的。 <code-example path="template-syntax/src/app/app.component.html" region="non-null-assertion-1" title="src/app/app.component.html" linenums="false"> - </code-example> When the Angular compiler turns your template into TypeScript code, @@ -3390,7 +3259,6 @@ the expression to [the `any` type](http://www.typescriptlang.org/docs/handbook/b 有时候,绑定表达式可能会报类型错误,并且它不能或很难指定类型。要消除这种报错,你可以使用 `$any` 转换函数来把表达式转换成 [`any` 类型](http://www.typescriptlang.org/docs/handbook/basic-types.html#any)。 <code-example path="template-syntax/src/app/app.component.html" region="any-type-cast-function-1" title="src/app/app.component.html" linenums="false"> - </code-example> In this example, when the Angular compiler turns your template into TypeScript code, @@ -3405,7 +3273,6 @@ the component. `$any` 转换函数可以和 `this` 联合使用,以便访问组件中未声明过的成员。 <code-example path="template-syntax/src/app/app.component.html" region="any-type-cast-function-2" title="src/app/app.component.html" linenums="false"> - </code-example> The `$any` cast function can be used anywhere in a binding expression where a method call is valid. @@ -3419,5 +3286,4 @@ The `$any` cast function can be used anywhere in a binding expression where a me You've completed this survey of template syntax. Now it's time to put that knowledge to work on your own components and directives. - 你完成了模板语法的概述。现在,该把如何写组件和指令的知识投入到实际工作当中了。 diff --git a/aio/content/guide/testing.md b/aio/content/guide/testing.md index 75100299a6..9f58723c71 100644 --- a/aio/content/guide/testing.md +++ b/aio/content/guide/testing.md @@ -39,9 +39,7 @@ Just run this one CLI command: 运行下列 CLI 命令即可: <code-example language="sh" class="code-shell"> - ng test - </code-example> The `ng test` command builds the app in _watch mode_, @@ -54,14 +52,12 @@ The console output looks a bit like this: 它的控制台输出一般是这样的: <code-example language="sh" class="code-shell"> - 10% building modules 1/1 modules 0 active ...INFO [karma]: Karma v1.7.1 server started at http://0.0.0.0:9876/ ...INFO [launcher]: Launching browser Chrome ... ...INFO [launcher]: Starting browser Chrome ...INFO [Chrome ...]: Connected on socket ... Chrome ...: Executed 3 of 3 SUCCESS (0.135 secs / 0.205 secs) - </code-example> The last line of the log is the most important. @@ -286,7 +282,6 @@ array of the services that you'll test or mock. path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-before-each" title="app/demo/demo.testbed.spec.ts (provide ValueService in beforeEach"> - </code-example> Then inject it inside a test by calling `TestBed.get()` with the service class as the argument. @@ -296,7 +291,6 @@ Then inject it inside a test by calling `TestBed.get()` with the service class a <code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-inject-it"> - </code-example> Or inside the `beforeEach()` if you prefer to inject the service as part of your setup. @@ -306,7 +300,6 @@ Or inside the `beforeEach()` if you prefer to inject the service as part of your <code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-inject-before-each"> - </code-example> When testing a service with a dependency, provide the mock in the `providers` array. @@ -320,7 +313,6 @@ In the following example, the mock is a spy object. <code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="master-service-before-each" linenums="false"> - </code-example> The test consumes that spy in the same way it did earlier. @@ -330,7 +322,6 @@ The test consumes that spy in the same way it did earlier. <code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="master-service-it"> - </code-example> {@a no-before-each} @@ -361,7 +352,6 @@ Begin by putting re-usable, preparatory code in a _setup_ function instead of `b path="testing/src/app/demo/demo.spec.ts" region="no-before-each-setup" title="app/demo/demo.spec.ts (setup)" linenums="false"> - </code-example> The `setup()` function returns an object literal @@ -380,7 +370,6 @@ with steps that manipulate the test subject and assert expectations. <code-example path="testing/src/app/demo/demo.spec.ts" region="no-before-each-test" linenums="false"> - </code-example> Notice how the test uses @@ -393,7 +382,6 @@ to extract the setup variables that it needs. <code-example path="testing/src/app/demo/demo.spec.ts" region="no-before-each-setup-call"> - </code-example> Many developers feel this approach is cleaner and more explicit than the @@ -427,7 +415,6 @@ test any service with a dependency. path="testing/src/app/model/hero.service.spec.ts" region="test-with-spies" title="app/model/hero.service.spec.ts (tests with spies)"> - </code-example> <div class="alert is-important"> @@ -521,7 +508,6 @@ Consider this `LightswitchComponent` which toggles a light on and off path="testing/src/app/demo/demo.ts" region="LightswitchComp" title="app/demo/demo.ts (LightswitchComp)" linenums="false"> - </code-example> You might decide only to test that the `clicked()` method @@ -542,7 +528,6 @@ Do the same with the component class. path="testing/src/app/demo/demo.spec.ts" region="Lightswitch" title="app/demo/demo.spec.ts (Lightswitch tests)" linenums="false"> - </code-example> Here is the `DashboardHeroComponent` from the _Tour of Heroes_ tutorial. @@ -553,7 +538,6 @@ Here is the `DashboardHeroComponent` from the _Tour of Heroes_ tutorial. path="testing/src/app/dashboard/dashboard-hero.component.ts" region="class" title="app/dashboard/dashboard-hero.component.ts (component)" linenums="false"> - </code-example> It appears within the template of a parent component, @@ -571,7 +555,6 @@ or its parent component. path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="class-only" title="app/dashboard/dashboard-hero.component.spec.ts (class tests)" linenums="false"> - </code-example> When a component has dependencies, you may wish to use the `TestBed` to both @@ -587,7 +570,6 @@ The following `WelcomeComponent` depends on the `UserService` to know the name o path="testing/src/app/welcome/welcome.component.ts" region="class" title="app/welcome/welcome.component.ts" linenums="false"> - </code-example> You might start by creating a mock of the `UserService` that meets the minimum needs of this component. @@ -598,7 +580,6 @@ You might start by creating a mock of the `UserService` that meets the minimum n path="testing/src/app/welcome/welcome.component.spec.ts" region="mock-user-service" title="app/welcome/welcome.component.spec.ts (MockUserService)" linenums="false"> - </code-example> Then provide and inject _both the_ **component** _and the service_ in the `TestBed` configuration. @@ -609,7 +590,6 @@ Then provide and inject _both the_ **component** _and the service_ in the `TestB path="testing/src/app/welcome/welcome.component.spec.ts" region="class-only-before-each" title="app/welcome/welcome.component.spec.ts (class-only setup)" linenums="false"> - </code-example> Then exercise the component class, remembering to call the [lifecycle hook methods](guide/lifecycle-hooks) as Angular does when running the app. @@ -620,7 +600,6 @@ Then exercise the component class, remembering to call the [lifecycle hook metho path="testing/src/app/welcome/welcome.component.spec.ts" region="class-only-tests" title="app/welcome/welcome.component.spec.ts (class-only tests)" linenums="false"> - </code-example> ### Component DOM testing @@ -702,9 +681,7 @@ For example, the following CLI command generates a `BannerComponent` in the `app 比如,下列 CLI 命令会在 `app/banner` 文件夹中创建带有内联模板和内联样式的 `BannerComponent`: <code-example language="sh" class="code-shell"> - ng generate component banner --inline-template --inline-style --module app - </code-example> It also generates an initial test file for the component, `banner-external.component.spec.ts`, that looks like this: @@ -715,7 +692,6 @@ It also generates an initial test file for the component, `banner-external.compo path="testing/src/app/banner/banner-initial.component.spec.ts" region="v1" title="app/banner/banner-external.component.spec.ts (initial)" linenums="false"> - </code-example> #### Reduce the setup @@ -741,7 +717,6 @@ For now, you can radically reduce this test file to a more manageable size: path="testing/src/app/banner/banner-initial.component.spec.ts" region="v2" title="app/banner/banner-initial.component.spec.ts (minimal)" linenums="false"> - </code-example> In this example, the metadata object passed to `TestBed.configureTestingModule` @@ -752,7 +727,6 @@ simply declares `BannerComponent`, the component to test. <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="configureTestingModule"> - </code-example> <div class="l-sub-section"> @@ -784,7 +758,6 @@ After configuring `TestBed`, you call its `createComponent()` method. <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="createComponent"> - </code-example> `TestBed.createComponent()` creates an instance of the `BannerComponent`, @@ -829,7 +802,6 @@ Access the component instance through the fixture and confirm it exists with a J <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="componentInstance"> - </code-example> #### _beforeEach()_ @@ -845,7 +817,6 @@ you refactor to pull the setup into a Jasmine `beforeEach()` and some supporting path="testing/src/app/banner/banner-initial.component.spec.ts" region="v3" linenums="false"> - </code-example> Now add a test that gets the component's element from `fixture.nativeElement` and @@ -856,7 +827,6 @@ looks for the expected text. <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="v4-test-2"> - </code-example> {@a native-element} @@ -896,7 +866,6 @@ Here's another test that calls `HTMLElement.querySelector` to get the paragraph <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="v4-test-3"> - </code-example> {@a debug-element} @@ -910,7 +879,6 @@ Angular 的*夹具*可以通过 `fixture.nativeElement` 直接提供组件的元 <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="nativeElement"> - </code-example> This is actually a convenience method, implemented as `fixture.debugElement.nativeElement`. @@ -920,7 +888,6 @@ This is actually a convenience method, implemented as `fixture.debugElement.nati <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="debugElement-nativeElement"> - </code-example> There's a good reason for this circuitous path to the element. @@ -956,7 +923,6 @@ Here's the previous test, re-implemented with `fixture.debugElement.nativeElemen <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="v4-test-4"> - </code-example> The `DebugElement` has other methods and properties that @@ -971,7 +937,6 @@ You import the `DebugElement` symbol from the Angular core library. <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="import-debug-element"> - </code-example> {@a by-css} @@ -1003,7 +968,6 @@ library for the runtime platform. Here's the `By` import for the browser platfor <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="import-by"> - </code-example> The following example re-implements the previous test with @@ -1014,7 +978,6 @@ The following example re-implements the previous test with <code-example path="testing/src/app/banner/banner-initial.component.spec.ts" region="v4-test-5"> - </code-example> Some noteworthy observations: @@ -1073,7 +1036,6 @@ the component's `title` property like this. path="testing/src/app/banner/banner.component.ts" region="component" title="app/banner/banner.component.ts" linenums="false"> - </code-example> Simple as this is, you decide to add a test to confirm that component @@ -1099,7 +1061,6 @@ and assign it to the `h1` variable. path="testing/src/app/banner/banner.component.spec.ts" region="setup" title="app/banner/banner.component.spec.ts (setup)" linenums="false"> - </code-example> {@a detect-changes} @@ -1117,7 +1078,6 @@ Your instinct is to write a test that immediately inspects the `<h1>` like this: <code-example path="testing/src/app/banner/banner.component.spec.ts" region="expect-h1-default-v1"> - </code-example> _That test fails_ with the message: @@ -1148,7 +1108,6 @@ a fact confirmed in the revised test: <code-example path="testing/src/app/banner/banner.component.spec.ts" region="test-w-o-detect-changes" linenums="false"> - </code-example> #### _detectChanges()_ @@ -1162,7 +1121,6 @@ Only then does the `<h1>` have the expected title. <code-example path="testing/src/app/banner/banner.component.spec.ts" region="expect-h1-default"> - </code-example> Delayed change detection is intentional and useful. @@ -1179,7 +1137,6 @@ Here's another test that changes the component's `title` property _before_ calli <code-example path="testing/src/app/banner/banner.component.spec.ts" region="after-change"> - </code-example> {@a auto-detect-changes} @@ -1293,7 +1250,6 @@ as the following variant of `BannerComponent` does. path="testing/src/app/banner/banner-external.component.ts" region="metadata" title="app/banner/banner-external.component.ts (metadata)" linenums="false"> - </code-example> This syntax tells the Angular compiler to read the external files during component compilation. @@ -1313,11 +1269,9 @@ For example, if you run the `BannerComponent` tests in a web coding environment 比如,如果你在像 [plunker](http://plnkr.co/) 这样的 Web 编程环境下运行 `BannerComponent` 的测试,就会看到如下信息: <code-example language="sh" class="code-shell" hideCopy> - Error: This test module uses the component BannerComponent which is using a "templateUrl" or "styleUrls", but they were never compiled. Please call "TestBed.compileComponents" before your test. - </code-example> You get this test failure message when the runtime environment @@ -1392,7 +1346,6 @@ and its tests: path="testing/src/app/welcome/welcome.component.spec.ts" region="user-service-stub" title="app/welcome/welcome.component.spec.ts" linenums="false"> - </code-example> {@a get-injected-service} @@ -1423,7 +1376,6 @@ The component injector is a property of the fixture's `DebugElement`. path="testing/src/app/welcome/welcome.component.spec.ts" region="injected-service" title="WelcomeComponent's injector"> - </code-example> {@a testbed-get} @@ -1447,7 +1399,6 @@ so it is safe to call `TestBed.get()` as follows: path="testing/src/app/welcome/welcome.component.spec.ts" region="inject-from-testbed" title="TestBed injector"> - </code-example> <div class="l-sub-section"> @@ -1537,7 +1488,6 @@ The `TwainComponent` displays Mark Twain quotes. path="testing/src/app/twain/twain.component.ts" region="template" title="app/twain/twain.component.ts (template)" linenums="false"> - </code-example> Note that value of the component's `quote` property passes through an `AsyncPipe`. @@ -1555,7 +1505,6 @@ the `quote` property returns an `Observable`. path="testing/src/app/twain/twain.component.ts" region="get-quote" title="app/twain/twain.component.ts (getQuote)" linenums="false"> - </code-example> The `TwainComponent` gets quotes from an injected `TwainService`. @@ -1593,7 +1542,6 @@ They should emulate such calls. The setup in this `app/twain/twain.component.spe path="testing/src/app/twain/twain.component.spec.ts" region="setup" title="app/twain/twain.component.spec.ts (setup)" linenums="false"> - </code-example> {@a service-spy} @@ -1605,7 +1553,6 @@ Focus on the spy. <code-example path="testing/src/app/twain/twain.component.spec.ts" region="spy"> - </code-example> The spy is designed such that any call to `getQuote` receives an Observable with a test quote. @@ -1633,7 +1580,6 @@ you can often turn asynchronous processes into synchronous tests. <code-example path="testing/src/app/twain/twain.component.spec.ts" region="sync-test"> - </code-example> Because the spy result returns synchronously, the `getQuote()` method updates @@ -1665,7 +1611,6 @@ The following test confirms the expected behavior when the service returns an `E <code-example path="testing/src/app/twain/twain.component.spec.ts" region="error-test"> - </code-example> Note that the `it()` function receives an argument of the following form. @@ -1733,7 +1678,6 @@ from the `getQuote()` spy like this. <code-example path="testing/src/app/twain/twain.component.spec.ts" region="async-setup"> - </code-example> #### Async observable helpers @@ -1751,7 +1695,6 @@ Or you can copy this one from the sample code. path="testing/src/testing/async-observable-helpers.ts" region="async-data" title="testing/async-observable-helpers.ts"> - </code-example> This helper's observable emits the `data` value in the next turn of the JavaScript engine. @@ -1781,7 +1724,6 @@ There's a similar helper for producing an async error. <code-example path="testing/src/testing/async-observable-helpers.ts" region="async-error"> - </code-example> #### More async tests @@ -1801,7 +1743,6 @@ in the real world. <code-example path="testing/src/app/twain/twain.component.spec.ts" region="fake-async-test"> - </code-example> Notice that the quote element displays the placeholder value (`'...'`) after `ngOnInit()`. @@ -1855,7 +1796,6 @@ Here's the previous `fakeAsync()` test, re-written with the `async()` utility. <code-example path="testing/src/app/twain/twain.component.spec.ts" region="async-test"> - </code-example> The `async()` utility hides some asynchronous boilerplate by arranging for the tester's code @@ -1928,7 +1868,6 @@ The first one subscribes to the `Observable` exposed to the template by the comp <code-example path="testing/src/app/twain/twain.component.spec.ts" region="quote-done-test" linenums="false"> - </code-example> The RxJS `last()` operator emits the observable's last value before completing, which will be the test quote. @@ -1951,7 +1890,6 @@ can give you that information and make assertions about the state of the view. <code-example path="testing/src/app/twain/twain.component.spec.ts" region="spy-done-test" linenums="false"> - </code-example> <hr> @@ -2003,7 +1941,6 @@ Then import the symbols you need. path="testing/src/app/twain/twain.component.marbles.spec.ts" region="import-marbles" title="app/twain/twain.component.marbles.spec.ts (import marbles)" linenums="false"> - </code-example> Here's the complete test for getting a quote: @@ -2013,7 +1950,6 @@ Here's the complete test for getting a quote: <code-example path="testing/src/app/twain/twain.component.marbles.spec.ts" region="get-quote-test" linenums="false"> - </code-example> Notice that the Jasmine test is synchronous. There's no `fakeAsync()`. @@ -2036,7 +1972,6 @@ In the second argument you map the value marker (`x`) to the emitted value (`tes <code-example path="testing/src/app/twain/twain.component.marbles.spec.ts" region="test-quote-marbles" linenums="false"> - </code-example> The marble library constructs the corresponding observable, which the @@ -2052,7 +1987,6 @@ you tell the `TestScheduler` to _flush_ its queue of prepared tasks like this. <code-example path="testing/src/app/twain/twain.component.marbles.spec.ts" region="test-scheduler-flush" linenums="false"> - </code-example> This step serves a purpose analogous to `tick()` and `whenStable()` in the @@ -2073,7 +2007,6 @@ Here's the marble testing version of the `getQuote()` error test. <code-example path="testing/src/app/twain/twain.component.marbles.spec.ts" region="error-test" linenums="false"> - </code-example> It's still an async test, calling `fakeAsync()` and `tick()`, because the component itself @@ -2088,7 +2021,6 @@ Look at the marble observable definition. <code-example path="testing/src/app/twain/twain.component.marbles.spec.ts" region="error-marbles" linenums="false"> - </code-example> This is a _cold_ observable that waits three frames and then emits an error, @@ -2172,7 +2104,6 @@ The `DashboardHeroComponent` is embedded in the `DashboardComponent` template li path="testing/src/app/dashboard/dashboard.component.html" region="dashboard-hero" title="app/dashboard/dashboard.component.html (excerpt)" linenums="false"> - </code-example> The `DashboardHeroComponent` appears in an `*ngFor` repeater, which sets each component's `hero` input property @@ -2190,7 +2121,6 @@ Here's the component's full definition: path="testing/src/app/dashboard/dashboard-hero.component.ts" region="component" title="app/dashboard/dashboard-hero.component.ts (component)" linenums="false"> - </code-example> While testing a component this simple has little intrinsic value, it's worth knowing how. @@ -2219,7 +2149,6 @@ A quick look at the `DashboardComponent` constructor discourages the first appro path="testing/src/app/dashboard/dashboard.component.ts" region="ctor" title="app/dashboard/dashboard.component.ts (constructor)" linenums="false"> - </code-example> The `DashboardComponent` depends on the Angular router and the `HeroService`. @@ -2258,7 +2187,6 @@ Here's the meat of the spec file setup. path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="setup" title="app/dashboard/dashboard-hero.component.spec.ts (setup)" linenums="false"> - </code-example> Note how the setup code assigns a test hero (`expectedHero`) to the component's `hero` property, @@ -2274,7 +2202,6 @@ The following test verifies that the hero name is propagated to the template via <code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="name-test"> - </code-example> Because the [template](#dashboard-hero-component) passes the hero name through the Angular `UpperCasePipe`, @@ -2306,7 +2233,6 @@ the host component (`DashboardComponent` presumably) can hear: <code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="click-test"> - </code-example> The component's `selected` property returns an `EventEmitter`, @@ -2353,7 +2279,6 @@ The test triggered a "click" event with a `null` event object. <code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="trigger-event-handler"> - </code-example> The test assumes (correctly in this case) that the runtime @@ -2386,7 +2311,6 @@ which is perfectly fine for _this component_. <code-example path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="click-test-2"> - </code-example> {@a click-helper} @@ -2408,7 +2332,6 @@ in a helper such as the `click()` function below: path="testing/src/testing/index.ts" region="click-event" title="testing/index.ts (click helper)" linenums="false"> - </code-example> The first parameter is the _element-to-click_. If you wish, you can pass a @@ -2441,7 +2364,6 @@ Here's the previous test, rewritten using the click helper. path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="click-test-3" title="app/dashboard/dashboard-hero.component.spec.ts (test with click helper)"> - </code-example> <hr> @@ -2479,7 +2401,6 @@ that can be made satisfactorily with a _test host_ like this one: region="test-host" title="app/dashboard/dashboard-hero.component.spec.ts (test host)" linenums="false"> - </code-example> This test host binds to `DashboardHeroComponent` as the `DashboardComponent` would @@ -2542,7 +2463,6 @@ The tests themselves are almost identical to the stand-alone version: path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="test-host-tests" title="app/dashboard/dashboard-hero.component.spec.ts (test-host)" linenums="false"> - </code-example> Only the selected event test differs. It confirms that the selected `DashboardHeroComponent` hero @@ -2576,7 +2496,6 @@ which it injects together with the `HeroService`. path="testing/src/app/dashboard/dashboard.component.ts" region="ctor" title="app/dashboard/dashboard.component.ts (constructor)" linenums="false"> - </code-example> Mocking the `HeroService` with a spy is a [familiar story](#component-with-async-service). @@ -2593,7 +2512,6 @@ Fortunately, not in this case because the `DashboardComponent` isn't doing much path="testing/src/app/dashboard/dashboard.component.ts" region="goto-detail" title="app/dashboard/dashboard.component.ts (goToDetail)"> - </code-example> This is often the case with _routing components_. @@ -2612,7 +2530,6 @@ as providing a `HeroService` spy. path="testing/src/app/dashboard/dashboard.component.spec.ts" region="router-spy" title="app/dashboard/dashboard.component.spec.ts (spies)" linenums="false"> - </code-example> The following test clicks the displayed hero and confirms that @@ -2624,7 +2541,6 @@ The following test clicks the displayed hero and confirms that path="testing/src/app/dashboard/dashboard.component.spec.ts" region="navigate-test" title="app/dashboard/dashboard.component.spec.ts (navigate test)" linenums="false"> - </code-example> {@a routed-component-w-param} @@ -2728,7 +2644,6 @@ The following `ActivatedRouteStub` class serves as a test double for `ActivatedR path="testing/src/testing/activated-route-stub.ts" region="activated-route-stub" title="testing/activated-route-stub.ts (ActivatedRouteStub)" linenums="false"> - </code-example> Consider placing such helpers in a `testing` folder sibling to the `app` folder. @@ -2798,7 +2713,6 @@ New heroes have `id=0` and a blank `name`. This test confirms that the component path="testing/src/app/hero/hero-detail.component.spec.ts" region="route-no-id" title="app/hero/hero-detail.component.spec.ts (no id)" linenums="false"> - </code-example> <hr> @@ -2824,7 +2738,6 @@ The `AppComponent`, for example, displays a navigation bar with anchors and thei <code-example path="testing/src/app/app.component.html" title="app/app.component.html" linenums="false"> - </code-example> While the `AppComponent` _class_ is empty, @@ -2885,7 +2798,6 @@ and directive that play little or no role in the tests. path="testing/src/app/app.component.spec.ts" region="component-stubs" title="app/app.component.spec.ts (stub declaration)" linenums="false"> - </code-example> The stub selectors match the selectors for the corresponding real components. @@ -2902,7 +2814,6 @@ components, directives, and pipes that need to be real. path="testing/src/app/app.component.spec.ts" region="testbed-stubs" title="app/app.component.spec.ts (TestBed stubs)" linenums="false"> - </code-example> The `AppComponent` is the test subject, so of course you declare the real version. @@ -2930,7 +2841,6 @@ In the second approach, add `NO_ERRORS_SCHEMA` to the `TestBed.schemas` metadata path="testing/src/app/app.component.spec.ts" region="no-errors-schema" title="app/app.component.spec.ts (NO_ERRORS_SCHEMA)" linenums="false"> - </code-example> The `NO_ERRORS_SCHEMA` tells the Angular compiler to ignore unrecognized elements and attributes. @@ -2992,7 +2902,6 @@ as seen in this example. path="testing/src/app/app.component.spec.ts" region="mixed-setup" title="app/app.component.spec.ts (mixed setup)" linenums="false"> - </code-example> The Angular compiler creates the `BannerComponentStub` for the `<app-banner>` element @@ -3026,7 +2935,6 @@ seen in the `AppComponent` template. path="testing/src/testing/router-link-directive-stub.ts" region="router-link" title="testing/router-link-directive-stub.ts (RouterLinkDirectiveStub)" linenums="false"> - </code-example> The URL bound to the `[routerLink]` attribute flows in to the directive's `linkParams` property. @@ -3071,7 +2979,6 @@ A little more setup triggers the initial data binding and gets references to the path="testing/src/app/app.component.spec.ts" region="test-setup" title="app/app.component.spec.ts (test setup)" linenums="false"> - </code-example> Three points of special interest: @@ -3099,7 +3006,6 @@ The `AppComponent` links to validate are as follows: path="testing/src/app/app.component.html" region="links" title="app/app.component.html (navigation links)" linenums="false"> - </code-example> {@a app-component-tests} @@ -3194,7 +3100,6 @@ But there's plenty of template complexity even in this simple form. <code-example path="testing/src/app/hero/hero-detail.component.html" title="app/hero/hero-detail.component.html" linenums="false"> - </code-example> Tests that exercise the component need ... @@ -3238,7 +3143,6 @@ Here is such a `Page` class for the `hero-detail.component.spec.ts` path="testing/src/app/hero/hero-detail.component.spec.ts" region="page" title="app/hero/hero-detail.component.spec.ts (Page)" linenums="false"> - </code-example> Now the important hooks for component manipulation and inspection are neatly organized and accessible from an instance of `Page`. @@ -3253,7 +3157,6 @@ A `createComponent` method creates a `page` object and fills in the blanks once path="testing/src/app/hero/hero-detail.component.spec.ts" region="create-component" title="app/hero/hero-detail.component.spec.ts (createComponent)" linenums="false"> - </code-example> The [_HeroDetailComponent_ tests](#tests-w-test-double) in an earlier section demonstrate how `createComponent` and `page` @@ -3271,7 +3174,6 @@ Here are a few more `HeroDetailComponent` tests to reinforce the point. path="testing/src/app/hero/hero-detail.component.spec.ts" region="selected-tests" title="app/hero/hero-detail.component.spec.ts (selected tests)" linenums="false"> - </code-example> <hr> @@ -3296,11 +3198,9 @@ If you run tests in a **non-CLI environment**, the tests may fail with a message 如果你在**非 CLI 环境**中运行测试,这些测试可能会报错,错误信息如下: <code-example language="sh" class="code-shell" hideCopy> - Error: This test module uses the component BannerComponent which is using a "templateUrl" or "styleUrls", but they were never compiled. Please call "TestBed.compileComponents" before your test. - </code-example> The root of the problem is at least one of the components involved in the test @@ -3312,7 +3212,6 @@ the following version of the `BannerComponent` does. <code-example path="testing/src/app/banner/banner-external.component.ts" title="app/banner/banner-external.component.ts (external template & css)" linenums="false"> - </code-example> The test fails when the `TestBed` tries to create the component. @@ -3324,7 +3223,6 @@ The test fails when the `TestBed` tries to create the component. region="configure-and-create" title="app/banner/banner.component.spec.ts (setup that fails)" avoid linenums="false"> - </code-example> Recall that the app hasn't been compiled. @@ -3367,9 +3265,7 @@ you'll see this error message 如果你忘了把测试函数标为异步的(比如忘了像稍后的代码中那样使用 `async()`),就会看到下列错误。 <code-example language="sh" class="code-shell" hideCopy> - Error: ViewDestroyedError: Attempt to use a destroyed view - </code-example> </div> @@ -3393,7 +3289,6 @@ To follow this pattern, import the `async()` helper with the other testing symbo <code-example path="testing/src/app/banner/banner-external.component.spec.ts" region="import-async"> - </code-example> #### The async _beforeEach_ @@ -3408,7 +3303,6 @@ Write the first async `beforeEach` like this. path="testing/src/app/banner/banner-external.component.spec.ts" region="async-before-each" title="app/banner/banner-external.component.spec.ts (async beforeEach)" linenums="false"> - </code-example> The `async()` helper function takes a parameterless function with the body of the setup. @@ -3467,7 +3361,6 @@ which include creating the component and querying for elements to inspect. path="testing/src/app/banner/banner-external.component.spec.ts" region="sync-before-each" title="app/banner/banner-external.component.spec.ts (synchronous beforeEach)" linenums="false"> - </code-example> You can count on the test runner to wait for the first asynchronous `beforeEach` to finish before calling the second. @@ -3493,7 +3386,6 @@ into a `then(...)` callback. path="testing/src/app/banner/banner-external.component.spec.ts" region="one-before-each" title="app/banner/banner-external.component.spec.ts (one beforeEach)" linenums="false"> - </code-example> #### _compileComponents()_ is harmless @@ -3529,7 +3421,6 @@ Earlier component tests configured the testing module with a few `declarations` path="testing/src/app/dashboard/dashboard-hero.component.spec.ts" region="config-testbed" title="app/dashboard/dashboard-hero.component.spec.ts (configure TestBed)"> - </code-example> The `DashboardComponent` is simple. It needs no help. @@ -3576,7 +3467,6 @@ One approach is to configure the testing module from the individual pieces as in path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-forms-module" title="app/hero/hero-detail.component.spec.ts (FormsModule setup)" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -3611,7 +3501,6 @@ The test configuration can use the `SharedModule` too as seen in this alternativ path="testing/src/app/hero/hero-detail.component.spec.ts" region="setup-shared-module" title="app/hero/hero-detail.component.spec.ts (SharedModule setup)" linenums="false"> - </code-example> It's a bit tighter and smaller, with fewer import statements (not shown). @@ -3743,13 +3632,11 @@ The [overide metadata object](#metadata-override-object) is a generic defined as 它接受两个参数:要改写的组件类(`HeroDetailComponent`),以及用于改写的元数据对象: <code-example format="." language="javascript"> - type MetadataOverride<T> = { add?: T; remove?: T; set?: T; }; - </code-example> A metadata override object can either add-and-remove elements in metadata properties or completely reset those properties. @@ -3763,13 +3650,11 @@ The type parameter, `T`, is the kind of metadata you'd pass to the `@Component` 这个类型参数,`T`,是你会传递给 `@Component` 装饰器的元数据的类型。 <code-example format="." language="javascript"> - selector?: string; template?: string; templateUrl?: string; providers?: any[]; ... - </code-example> {@a spy-stub} @@ -4057,7 +3942,6 @@ Here's a summary of the stand-alone functions, in order of likely utility: 下面是一些独立函数的总结,以使用频率排序: <table> - <tr> <th> @@ -4272,7 +4156,6 @@ Here's a summary of the stand-alone functions, in order of likely utility: </td> </tr> - </table> <hr> @@ -4297,14 +4180,12 @@ is a subset of the `@NgModule` metadata properties. 传递给 `configureTestingModule` 的模块定义是 `@NgModule` 元数据属性的子集。 <code-example format="." language="javascript"> - type TestModuleMetadata = { providers?: any[]; declarations?: any[]; imports?: any[]; schemas?: Array<SchemaMetadata | any[]>; }; - </code-example> {@a metadata-override-object} @@ -4316,13 +4197,11 @@ appropriate to the method, that is, the parameter of an `@NgModule`, 每一个重载方法接受一个 `MetadataOverride<T>`,这里 `T` 是适合这个方法的元数据类型,也就是 `@NgModule`、`@Component`、`@Directive` 或者 `@Pipe` 的参数。 <code-example format="." language="javascript"> - type MetadataOverride<T> = { add?: T; remove?: T; set?: T; }; - </code-example> {@a testbed-methods} @@ -4347,7 +4226,6 @@ Here are the most important static methods, in order of likely utility. 这里列出了最重要的静态方法,以使用频率排序: <table> - <tr> <th> @@ -4614,7 +4492,6 @@ Here are the most important static methods, in order of likely utility. </td> </tr> - </table> A few of the `TestBed` instance methods are not covered by static `TestBed` _class_ methods. @@ -4650,7 +4527,6 @@ Here are the most important properties for testers, in order of likely utility. 下面是对测试最重要的属性,以使用频率排序: <table> - <tr> <th> @@ -4754,7 +4630,6 @@ Here are the most important properties for testers, in order of likely utility. </td> </tr> - </table> {@a component-fixture-methods} @@ -4774,7 +4649,6 @@ Here are the most useful methods for testers. 下面是对测试最有用的方法。 <table> - <tr> <th> @@ -4939,7 +4813,6 @@ Here are the most useful methods for testers. </td> </tr> - </table> {@a debug-element-details} @@ -4960,7 +4833,6 @@ Here are the most useful `DebugElement` members for testers, in approximate orde 下面是 `DebugElement` 最有用的成员,以使用频率排序。 <table> - <tr> <th> @@ -5267,7 +5139,6 @@ Here are the most useful `DebugElement` members for testers, in approximate orde </td> </tr> - </table> {@a query-predicate} diff --git a/aio/content/guide/typescript-configuration.md b/aio/content/guide/typescript-configuration.md index f65a2689fe..7b46f4aeca 100644 --- a/aio/content/guide/typescript-configuration.md +++ b/aio/content/guide/typescript-configuration.md @@ -102,7 +102,6 @@ You can suppress them with the following additional flag: 你可以使用另一个标志来禁止它们。 <code-example format="."> - "suppressImplicitAnyIndexErrors":true </code-example> @@ -166,7 +165,6 @@ list of declaration files to be included: 因为《快速上手》的目标为 `es5`,所以你可以重写声明文件列表来包含: <code-example format="."> - "lib": ["es2015", "dom"] </code-example> diff --git a/aio/content/guide/universal.md b/aio/content/guide/universal.md index fa1b6711a2..89090416c2 100644 --- a/aio/content/guide/universal.md +++ b/aio/content/guide/universal.md @@ -261,7 +261,6 @@ When you're done, the folder structure will look like this: 当做完这些后,文件夹的结构是这样的: <code-example format="." language="none" linenums="false"> - src/ index.html <t><i>app web page</i></t><t>应用的宿主页</t> main.ts <t><i>bootstrapper for client app</i></t><t>客户端应用的引导程序</t> @@ -276,7 +275,6 @@ server.ts <t><i>* express web server</i></t><t>* Express 的 tsconfig.json <t><i>TypeScript client configuration</i></t><t>TypeScript 的客户端配置</t> package.json <t><i>npm configuration</i></t><t>npm 配置</t> webpack.server.config.js <t><i>* Webpack server configuration</i></t><t>* Webpack 的服务端配置</t> - </code-example> The files marked with `*` are new and not in the original tutorial sample. @@ -326,9 +324,7 @@ Install them with the following commands: 使用下列命令安装它们: <code-example format="." language="bash"> - npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader @nguniversal/express-engine - </code-example> {@a transition} @@ -364,7 +360,6 @@ Replace that import with this one: 把该导入改成这样: <code-example path="universal/src/app/app.module.ts" region="browsermodule" title="src/app/app.module.ts (withServerTransition)"> - </code-example> Angular adds the `appId` value (which can be _any_ string) to the style-names of the server-rendered pages, @@ -377,7 +372,6 @@ You can get runtime information about the current platform and the `appId` by in 你可以通过依赖注入取得关于当前平台和 `appId` 的运行时信息。 <code-example path="universal/src/app/app.module.ts" region="platform-detection" title="src/app/app.module.ts (platform detection)"> - </code-example> {@a http-urls} @@ -413,7 +407,6 @@ Start by changing the `HeroService` constructor to take a second `origin` parame 先为 `HeroService` 的构造函数添加第二个 `origin` 参数,它是可选的,并通过 `APP_BASE_HREF` 令牌进行注入。 <code-example path="universal/src/app/hero.service.ts" region="ctor" title="src/app/hero.service.ts (constructor with optional origin)"> - </code-example> Note how the constructor prepends the origin (if it exists) to the `heroesUrl`. @@ -460,7 +453,6 @@ Create an `app.server.module.ts` file in the `src/app/` directory with the follo 在 `src/app/` 目录下创建 `app.server.module.ts` 文件,代码如下: <code-example path="universal/src/app/app.server.module.ts" title="src/app/app.server.module.ts"> - </code-example> Notice that it imports first the client app's `AppModule`, the Angular Universal's `ServerModule` and the `ModuleMapLoaderModule`. @@ -512,7 +504,6 @@ Create a `server.ts` file in the root directory and add the following code: 在根目录下创建 `server.ts` 文件,并添加下列代码: <code-example path="universal/server.ts" title="server.ts"> - </code-example> <div class="alert is-critical"> @@ -537,7 +528,6 @@ The important bit in this file is the `ngExpressEngine` function: 这个文件中最重要的部分是 `ngExpressEngine` 函数: <code-example path="universal/server.ts" title="server.ts" region="ngExpressEngine"> - </code-example> The `ngExpressEngine` is a wrapper around the universal's `renderModuleFactory` function that turns a client's requests into server-rendered HTML pages. @@ -641,7 +631,6 @@ You configure the Express server pipeline with calls to `app.get()` like this on 你通过通过调用 `app.get()` 来配置 Express 服务器的管道,就像下面这个数据请求一样: <code-example path="universal/server.ts" title="server.ts (data URL)" region="data-request" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -688,7 +677,6 @@ The following code filters for request URLs with no extensions and treats them a 下列代码会过滤出不带扩展名的 URL,并把它们当做导航请求进行处理。 <code-example path="universal/server.ts" title="server.ts (navigation)" region="navigation-request" linenums="false"> - </code-example> #### Serve static files safely @@ -710,7 +698,6 @@ The following express code routes all remaining requests to `/dist`; it returns 下列 Express 代码会把剩下的所有请求都路由到 `/dist` 目录下,如果文件未找到,就会返回 `404 - NOT FOUND`。 <code-example path="universal/server.ts" title="server.ts (static files)" region="static" linenums="false"> - </code-example> {@a universal-configuration} @@ -734,7 +721,6 @@ Create a `tsconfig.server.json` file in the project root directory to configure 在项目的根目录下创建一个 `tsconfig.server.json` 文件来配置 TypeScript 和这个 Universal 应用的 AOT 编译选项。 <code-example path="universal/src/tsconfig.server.json" title="src/tsconfig.server.json"> - </code-example> This config extends from the root's `tsconfig.json` file. Certain settings are noteworthy for their differences. @@ -743,7 +729,7 @@ This config extends from the root's `tsconfig.json` file. Certain settings are n * The `module` property must be **commonjs** which can be required into our server application. - `module` 属性必须是 **commonjs**,这样它才能被 `require()` 进你的服务端应用。 + `module` 属性必须是 **commonjs**,这样它才能被 `require()` 进你的服务端应用。 * The `angularCompilerOptions` section guides the AOT compiler: @@ -767,7 +753,6 @@ Create a `webpack.server.config.js` file in the project root directory with the 在项目的根目录下创建一个 `webpack.server.config.js` 文件,代码如下: <code-example path="universal/webpack.server.config.js" title="webpack.server.config.js"> - </code-example> **Webpack configuration** is a rich topic beyond the scope of this guide. @@ -787,7 +772,6 @@ First add the _build_ and _serve_ commands to the `scripts` section of the `pack 首先把 `build` 和 `serve` 命令添加到 `package.json` 的 `scripts` 区: <code-example format="." language="ts"> - "scripts": { ... "build:universal": "npm run build:client-and-server-bundles && npm run webpack:server", @@ -796,7 +780,6 @@ First add the _build_ and _serve_ commands to the `scripts` section of the `pack "webpack:server": "webpack --config webpack.server.config.js --progress --colors" ... } - </code-example> {@a build} @@ -810,9 +793,7 @@ From the command prompt, type 在命令行提示中输入 <code-example format="." language="bash"> - npm run build:universal - </code-example> The Angular CLI compiles and bundles the universal app into two different folders, `browser` and `server`. @@ -832,9 +813,7 @@ After building the application, start the server. 构建完应用之后,启动服务器。 <code-example format="." language="bash"> - npm run serve:universal - </code-example> The console window should say @@ -842,9 +821,7 @@ The console window should say 在控制台窗口中应该看到 <code-example format="." language="bash"> - Node server listening on http://localhost:4000 - </code-example> ## Universal in action diff --git a/aio/content/guide/upgrade.md b/aio/content/guide/upgrade.md index 076f9bc6fe..50d0598498 100644 --- a/aio/content/guide/upgrade.md +++ b/aio/content/guide/upgrade.md @@ -282,7 +282,6 @@ architecture may look something like this: AngularJS 中一个完全向 Angular 架构对齐过的组件型指令是这样的: <code-example path="upgrade-module/src/app/hero-detail.directive.ts" title="hero-detail.directive.ts"> - </code-example> AngularJS 1.5 introduces the [component API](https://docs.angularjs.org/api/ng/type/angular.Module#component) @@ -310,7 +309,6 @@ using the component API: 如果使用这个组件 API 进行快捷定义,那么上面看到的组件型指令就变成了这样: <code-example path="upgrade-module/src/app/upgrade-io/hero-detail.component.ts" region="hero-detail-io" title="hero-detail.component.ts"> - </code-example> Controller lifecycle hook methods `$onInit()`, `$onDestroy()`, and `$onChanges()` @@ -373,7 +371,6 @@ frameworks in how it actually works. 无论是在 AngularJS 中还是在 Angular 中,依赖注入都位于前沿和中心的位置,但在两个框架的工作原理上,却存在着一些关键的不同之处。 <table> - <tr> <th> @@ -389,7 +386,6 @@ frameworks in how it actually works. </th> </tr> - <tr> <td> @@ -411,7 +407,6 @@ frameworks in how it actually works. </td> </tr> - <tr> <td> @@ -433,7 +428,6 @@ frameworks in how it actually works. </td> </tr> - </table> Even accounting for these differences you can still have dependency injection @@ -529,9 +523,7 @@ where you use an Angular component from AngularJS like this: 考虑一个场景,你从 AngularJS 中使用一个 Angular 组件,就像这样: <code-example language="html" escape="html"> - <a-component></a-component> - </code-example> The DOM element `<a-component>` will remain to be an AngularJS managed @@ -671,7 +663,6 @@ be used to bootstrap the AngularJS application. 在 AngularJS 应用中有一个 AngularJS 的根模块,它用于引导 AngularJS 应用。 <code-example path="upgrade-module/src/app/ajs-bootstrap/app.module.ts" region="ng1module" title="app.module.ts"> - </code-example> Pure AngularJS applications can be automatically bootstrapped by using an `ng-app` @@ -687,7 +678,6 @@ Say you have an `ng-app` driven bootstrap such as this one: 比如你现在有这样一个通过 `ng-app` 进行引导的应用: <code-example path="upgrade-module/src/index-ng-app.html"> - </code-example> You can remove the `ng-app` and `ng-strict-di` directives from the HTML @@ -697,7 +687,6 @@ will result in the same thing: 你可以从 HTML 中移除 `ng-app` 和 `ng-strict-di` 指令,改为从 JavaScript 中调用 `angular.bootstrap`,它能达到同样效果: <code-example path="upgrade-module/src/app/ajs-bootstrap/app.module.ts" region="bootstrap" title="app.module.ts"> - </code-example> To begin converting your AngularJS application to a hybrid, you need to load the Angular framework. @@ -713,7 +702,6 @@ and add a mapping for the `@angular/upgrade/static` package: 也可以通过 `npm install @angular/upgrade --save` 命令来安装 `@angular/upgrade` 包,并给它添加一个到 `@angular/upgrade/static` 包的映射。 <code-example path="upgrade-module/src/systemjs.config.1.js" region="upgrade-static-umd" title="systemjs.config.js (map)"> - </code-example> Next, create an `app.module.ts` file and add the following `NgModule` class: @@ -721,7 +709,6 @@ Next, create an `app.module.ts` file and add the following `NgModule` class: 接下来,创建一个 `app.module.ts` 文件,并添加下列 `NgModule` 类: <code-example path="upgrade-module/src/app/ajs-a-hybrid-bootstrap/app.module.ts" region="ngmodule" title="app.module.ts"> - </code-example> This bare minimum `NgModule` imports `BrowserModule`, the module every Angular browser-based app must have. @@ -752,7 +739,6 @@ Now you can bootstrap `AppModule` using the `platformBrowserDynamic.bootstrapMod 现在,你就可以使用 `platformBrowserDynamic.bootstrapModule` 方法来启动 `AppModule` 了。 <code-example path="upgrade-module/src/app/ajs-a-hybrid-bootstrap/app.module.ts" region="bootstrap" title="app.module.ts'"> - </code-example> Congratulations! You're running a hybrid application! The @@ -779,7 +765,6 @@ Say you have a simple Angular component that shows information about a hero: 假设你有一个简单的用来显示英雄信息的 Angular 组件: <code-example path="upgrade-module/src/app/downgrade-static/hero-detail.component.ts" title="hero-detail.component.ts"> - </code-example> If you want to use this component from AngularJS, you need to *downgrade* it @@ -790,7 +775,6 @@ using the `downgradeComponent()` method. The result is an AngularJS 其结果是一个 AngularJS 的*指令*,你可以把它注册到 AngularJS 的模块中: <code-example path="upgrade-module/src/app/downgrade-static/app.module.ts" region="downgradecomponent" title="app.module.ts"> - </code-example> Because `HeroDetailComponent` is an Angular component, you must also add it to the @@ -806,7 +790,6 @@ NgModule. 将它加入到 Angular 模块的 `entryComponents` 列表中。 <code-example path="upgrade-module/src/app/downgrade-static/app.module.ts" region="ngmodule" title="app.module.ts"> - </code-example> <div class="l-sub-section"> @@ -823,7 +806,6 @@ use like any other directive in AngularJS templates. 最终的结果是一个叫做 `heroDetail` 的 AngularJS 指令,你可以像用其它指令一样把它用在 AngularJS 模板中。 <code-example path="upgrade-module/src/index-downgrade-static.html" region="usecomponent"> - </code-example> <div class="alert is-helpful"> @@ -847,7 +829,6 @@ like this: Angular 的英雄详情组件带有像这样的输入属性与输出属性: <code-example path="upgrade-module/src/app/downgrade-io/hero-detail.component.ts" title="hero-detail.component.ts"> - </code-example> These inputs and outputs can be supplied from the AngularJS template, and the @@ -856,7 +837,6 @@ These inputs and outputs can be supplied from the AngularJS template, and the 这些输入属性和输出属性的值来自于 AngularJS 的模板,而 `downgradeComponent()` 方法负责桥接它们: <code-example path="upgrade-module/src/index-downgrade-io.html" region="usecomponent"> - </code-example> Note that even though you are in an AngularJS template, **you're using Angular @@ -880,9 +860,7 @@ of multiple words. In Angular, you would bind these attributes using camelCase: 它适用于由多个单词组成的输入或输出属性。在 Angular 中,你要使用小驼峰命名法绑定这些属性: <code-example format=""> - [myHero]="hero" - </code-example> But when using them from AngularJS templates, you must use kebab-case: @@ -890,9 +868,7 @@ But when using them from AngularJS templates, you must use kebab-case: 但是从 AngularJS 的模板中使用它们时,你得使用中线命名法: <code-example format=""> - [my-hero]="hero" - </code-example> </div> @@ -911,7 +887,6 @@ For example, you can easily make multiple copies of the component using `ng-repe 例如,你可以用 `ng-repeat` 简单的制作该组件的多份拷贝: <code-example path="upgrade-module/src/index-downgrade-io.html" region="userepeatedcomponent"> - </code-example> ### Using AngularJS Component Directives from Angular Code @@ -949,7 +924,6 @@ and a controller: 可升级组件的简单例子是只有一个模板和一个控制器的指令: <code-example path="upgrade-module/src/app/upgrade-static/hero-detail.component.ts" region="hero-detail" title="hero-detail.component.ts"> - </code-example> You can *upgrade* this component to Angular using the `UpgradeComponent` class. @@ -963,11 +937,9 @@ All that is left is to add it to `AppModule`'s `declarations` array. 剩下是工作就是把它加入到 `AppModule` 的 `declarations` 数组。 <code-example path="upgrade-module/src/app/upgrade-static/hero-detail.component.ts" region="hero-detail-upgrade" title="hero-detail.component.ts"> - </code-example> <code-example path="upgrade-module/src/app/upgrade-static/app.module.ts" region="hero-detail-upgrade" title="app.module.ts"> - </code-example> <div class="alert is-helpful"> @@ -992,7 +964,6 @@ observing the following rules: 当你从 Angular 模板中使用该组件时,就要使用**Angular 模板语法**来提供这些输入属性和输出属性,但要遵循下列规则: <table> - <tr> <th> @@ -1016,7 +987,6 @@ observing the following rules: </th> </tr> - <tr> <th> @@ -1040,7 +1010,6 @@ observing the following rules: </td> </tr> - <tr> <th> @@ -1064,7 +1033,6 @@ observing the following rules: </td> </tr> - <tr> <th> @@ -1088,7 +1056,6 @@ observing the following rules: </td> </tr> - <tr> <th> @@ -1117,7 +1084,6 @@ observing the following rules: </td> </tr> - </table> For example, imagine a hero detail AngularJS component directive @@ -1126,7 +1092,6 @@ with one input and one output: 举个例子,假设 AngularJS 中有一个表示“英雄详情”的组件型指令,它带有一个输入属性和一个输出属性: <code-example path="upgrade-module/src/app/upgrade-io/hero-detail.component.ts" region="hero-detail-io" title="hero-detail.component.ts"> - </code-example> You can upgrade this component to Angular, annotate inputs and outputs in the upgrade directive, @@ -1135,11 +1100,9 @@ and then provide the input and output using Angular template syntax: 你可以把这个组件升级到 Angular,然后使用 Angular 的模板语法提供这个输入属性和输出属性: <code-example path="upgrade-module/src/app/upgrade-io/hero-detail.component.ts" region="hero-detail-io-upgrade" title="hero-detail.component.ts"> - </code-example> <code-example path="upgrade-module/src/app/upgrade-io/container.component.ts" title="container.component.ts"> - </code-example> ### Projecting AngularJS Content into Angular Components @@ -1164,7 +1127,6 @@ tag within them. Here's an example of such a component: Angular 的组件通过使用 `<ng-content>` 标签来支持内容投影。下面是这类组件的一个例子: <code-example path="upgrade-module/src/app/ajs-to-a-projection/hero-detail.component.ts" title="hero-detail.component.ts"> - </code-example> When using the component from AngularJS, you can supply contents for it. Just @@ -1175,7 +1137,6 @@ of the `<ng-content>` tag in Angular: 它们也在 Angular 中被投影到了 `<ng-content>` 标签所在的位置: <code-example path="upgrade-module/src/index-ajs-to-a-projection.html" region="usecomponent"> - </code-example> <div class="alert is-helpful"> @@ -1207,7 +1168,6 @@ point: 如果一个 AngularJS 组件型指令支持透传,它就会在自己的模板中使用 `ng-transclude` 指令标记出透传到的位置: <code-example path="upgrade-module/src/app/a-to-ajs-transclusion/hero-detail.component.ts" title="hero-detail.component.ts"> - </code-example> If you upgrade this component and use it from Angular, you can populate @@ -1216,7 +1176,6 @@ the component tag with contents that will then get transcluded: 如果你升级这个组件,并把它用在 Angular 中,你就能把准备透传的内容放进这个组件的标签中。 <code-example path="upgrade-module/src/app/a-to-ajs-transclusion/container.component.ts" title="container.component.ts"> - </code-example> ### Making AngularJS Dependencies Injectable to Angular @@ -1239,7 +1198,6 @@ code. For example, you might have a service called `HeroesService` in AngularJS: 比如,你可能在 AngularJS 中有一个名叫 `HeroesService` 的服务: <code-example path="upgrade-module/src/app/ajs-to-a-providers/heroes.service.ts" title="heroes.service.ts"> - </code-example> You can upgrade the service using a Angular [factory provider](guide/dependency-injection#factory-providers) @@ -1260,11 +1218,9 @@ compilation can pick it up. 同时,建议导出 `heroesServiceFactory` 函数,以便 AOT 编译器可以拿到它们。 <code-example path="upgrade-module/src/app/ajs-to-a-providers/ajs-upgraded-providers.ts" title="ajs-upgraded-providers.ts"> - </code-example> <code-example path="upgrade-module/src/app/ajs-to-a-providers/app.module.ts" region="register" title="app.module.ts"> - </code-example> You can then inject it in Angular using its class as a type annotation: @@ -1306,7 +1262,6 @@ For example, you might have an Angular service called `Heroes`: 例如,你可能有一个 Angular 的 `Heroes` 服务: <code-example path="upgrade-module/src/app/a-to-ajs-providers/heroes.ts" title="heroes.ts"> - </code-example> Again, as with Angular components, register the provider with the `NgModule` by adding it to the module's `providers` list. @@ -1314,7 +1269,6 @@ Again, as with Angular components, register the provider with the `NgModule` by 仿照 Angular 组件,把该提供商加入 `NgModule` 的 `providers` 列表中,以注册它。 <code-example path="upgrade-module/src/app/a-to-ajs-providers/app.module.ts" region="ngmodule" title="app.module.ts"> - </code-example> Now wrap the Angular `Heroes` in an *AngularJS factory function* using `downgradeInjectable()` @@ -1325,7 +1279,6 @@ The name of the AngularJS dependency is up to you: 依赖在 AngularJS 中的名字你可以自己定: <code-example path="upgrade-module/src/app/a-to-ajs-providers/app.module.ts" region="register" title="app.module.ts"> - </code-example> After this, the service is injectable anywhere in AngularJS code: @@ -1333,7 +1286,6 @@ After this, the service is injectable anywhere in AngularJS code: 此后,该服务就能被注入到 AngularJS 代码中的任何地方了: <code-example path="upgrade-module/src/app/a-to-ajs-providers/hero-detail.component.ts" title="hero-detail.component.ts"> - </code-example> ## Using Ahead-of-time compilation with hybrid apps @@ -1362,7 +1314,6 @@ bootstrap the hybrid app: 你还要使用所生成的 `AppModuleFactory` 而不是原来的 `AppModule` 来引导一个混合式应用: <code-example path="upgrade-phonecat-2-hybrid/app/main-aot.ts" title="app/main-aot.ts"> - </code-example> And that's all you need do to get the full benefit of AOT for Angular apps! @@ -1712,9 +1663,7 @@ Begin by installing TypeScript to the project. 先把 TypeScript 包安装到项目中。 <code-example format=""> - npm i typescript --save-dev - </code-example> Install type definitions for the existing libraries that @@ -1724,9 +1673,7 @@ Jasmine unit test framework. 还要为那些没有自带类型信息的库(比如 AngularJS 和 Jasmine)安装类型定义文件。 <code-example format=""> - npm install @types/jasmine @types/angular @types/angular-animate @types/angular-cookies @types/angular-mocks @types/angular-resource @types/angular-route @types/angular-sanitize --save-dev - </code-example> You should also configure the TypeScript compiler with a `tsconfig.json` in the project directory @@ -1744,12 +1691,10 @@ JavaScript (based on the `tsconfig.json` configuration file): 最后,你应该把下列 npm 脚本添加到 `package.json` 中,用于把 TypeScript 文件编译成 JavaScript (根据 `tsconfig.json` 的配置): <code-example format=""> - "script": { "tsc": "tsc", "tsc:w": "tsc -w", ... - </code-example> Now launch the TypeScript compiler from the command line in watch mode: @@ -1757,9 +1702,7 @@ Now launch the TypeScript compiler from the command line in watch mode: 现在,从命令行中用监视模式启动 TypeScript 编译器: <code-example format=""> - npm run tsc:w - </code-example> Keep this process running in the background, watching and recompiling as you make changes. @@ -1813,7 +1756,6 @@ what the filter is supposed to do. 这可以更清楚的表明此过滤器打算做什么 <code-example path="upgrade-phonecat-1-typescript/app/core/checkmark/checkmark.filter.ts" title="app/core/checkmark/checkmark.filter.ts"> - </code-example> In the `Phone` service, you can explicitly annotate the `$resource` service dependency @@ -1822,7 +1764,6 @@ as an `angular.resource.IResourceService` - a type defined by the AngularJS typi 在 `Phone` 服务中,你可以明确的把 `$resource` 服务声明为 `angular.resource.IResourceService`,一个 AngularJS 类型定义提供的类型。 <code-example path="upgrade-phonecat-1-typescript/app/core/phone/phone.service.ts" title="app/core/phone/phone.service.ts"> - </code-example> You can apply the same trick to the application's route configuration file in `app.config.ts`, @@ -1833,7 +1774,6 @@ can verify you're calling their APIs with the correct kinds of arguments. 一旦为它们提供了类型信息,TypeScript 就能检查你是否在用类型的正确参数来调用它们了。 <code-example path="upgrade-phonecat-1-typescript/app/app.config.ts" title="app/app.config.ts"> - </code-example> <div class="l-sub-section"> @@ -1878,7 +1818,6 @@ Here's what the new class for the phone list component controller looks like: 新的“电话列表(phone list)”组件控制器类是这样的: <code-example path="upgrade-phonecat-1-typescript/app/phone-list/phone-list.component.ts" title="app/phone-list/phone-list.component.ts"> - </code-example> What was previously done in the controller function is now done in the class @@ -1906,7 +1845,6 @@ that the user is looking at and another for the URL of the currently displayed i 在电话详情控制器中,你有两个成员:一个是用户正在查看的电话,另一个是正在显示的图像: <code-example path="upgrade-phonecat-1-typescript/app/phone-detail/phone-detail.component.ts" title="app/phone-detail/phone-detail.component.ts"> - </code-example> This makes the controller code look a lot more like Angular already. You're @@ -1969,9 +1907,7 @@ Once these are done, run: 这些完成之后,就运行: <code-example format=""> - npm install - </code-example> Soon you can load Angular dependencies into the application via `index.html`, @@ -1989,9 +1925,7 @@ instead of `app`: 把 `app/index.html` 移入项目的根目录,然后把 `package.json` 中的开发服务器根目录也指向项目的根目录,而不再是 `app` 目录: <code-example format=""> - "start": "http-server ./ -a localhost -p 8000 -c-1", - </code-example> Now you're able to serve everything from the project root to the web browser. But you do *not* @@ -2002,7 +1936,6 @@ cause relative URLs to be resolved back to the `/app` directory: 现在,你就能把项目根目录下的每一样东西发给浏览器了。但你*不想*为了适应开发环境中的设置,被迫修改应用代码中用到的所有图片和数据的路径。因此,你要往 `index.html` 中添加一个 `<base>` 标签,它将导致各种相对路径被解析回 `/app` 目录: <code-example path="upgrade-phonecat-2-hybrid/index.html" region="base" title="index.html"> - </code-example> Now you can load Angular via SystemJS. You'll add the Angular polyfills and the @@ -2013,7 +1946,6 @@ to load the actual application: 和 SystemJS 的配置加到 `<head>` 区的末尾,然后,你能就用 `System.import` 来加载实际的应用了: <code-example path="upgrade-phonecat-2-hybrid/index.html" region="angular" title="index.html"> - </code-example> You also need to make a couple of adjustments @@ -2032,7 +1964,6 @@ and add a mapping for the `@angular/upgrade/static` package. 再通过 `npm install @angular/upgrade --save` 安装 `upgrade` 包,并为 `@angular/upgrade/static` 包添加一个映射。 <code-example path="upgrade-phonecat-2-hybrid/systemjs.config.1.js" region="paths" title="systemjs.config.js"> - </code-example> ### Creating the _AppModule_ @@ -2050,7 +1981,6 @@ The file contents remain: 文件的内容保留: <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ajs.ts" title="app.module.ajs.ts"> - </code-example> Now create a new `app.module.ts` with the minimum `NgModule` class: @@ -2058,7 +1988,6 @@ Now create a new `app.module.ts` with the minimum `NgModule` class: 然后创建一个新的 `app.module.ts` 文件,其中是一个最小化的 `NgModule` 类: <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="bare" title="app.module.ts"> - </code-example> ### Bootstrapping a hybrid PhoneCat @@ -2086,7 +2015,6 @@ Then import `UpgradeModule` in the `AppModule`, and override its `ngDoBootstrap` 首先,从 `index.html` 中移除 `ng-app`。然后在 `AppModule` 中导入 `UpgradeModule`,并改写它的 `ngDoBootstrap` 方法: <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="upgrademodule" title="app/app.module.ts"> - </code-example> Note that you are bootstrapping the AngularJS module from inside `ngDoBootstrap`. @@ -2104,7 +2032,6 @@ so it is already being loaded by the browser. 最后,在 `src/main.ts` 中引导这个 `AppModule`。该文件在 `systemjs.config.js` 中被配置为了应用的入口,所以它已经被加载进了浏览器中。 <code-example path="upgrade-phonecat-2-hybrid/app/main.ts" region="bootstrap" title="app/main.ts"> - </code-example> Now you're running both AngularJS and Angular at the same time. That's pretty @@ -2183,7 +2110,6 @@ Re-open the `app.module.ts` file, import and add `HttpModule` to the `imports` a 再次打开 `app.module.ts` 文件,导入并把 `HttpModule` 添加到 `AppModule` 的 `imports` 数组中: <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="httpmodule" title="app.module.ts"> - </code-example> Now you're ready to upgrade the Phone service itself. Replace the ngResource-based @@ -2192,7 +2118,6 @@ service in `phone.service.ts` with a TypeScript class decorated as `@Injectable` 现在,你已经准备好了升级 `Phones` 服务本身。你将为 `phone.service.ts` 文件中基于 ngResource 的服务加上 `@Injectable` 装饰器: <code-example path="upgrade-phonecat-2-hybrid/app/core/phone/phone.service.ts" region="classdef" title="app/core/phone/phone.service.ts (skeleton)" linenums="false"> - </code-example> The `@Injectable` decorator will attach some dependency injection metadata @@ -2214,7 +2139,6 @@ and the other loads the details of a specified phone: 然后该服务在两个实例方法中被使用到,一个加载所有电话的列表,另一个加载一台指定电话的详情: <code-example path="upgrade-phonecat-2-hybrid/app/core/phone/phone.service.ts" region="fullclass" title="app/core/phone/phone.service.ts"> - </code-example> The methods now return Observables of type `PhoneData` and `PhoneData[]`. This is @@ -2224,7 +2148,6 @@ a type you don't have yet. Add a simple interface for it: 这是一个你从未用过的类型,因此你得为它新增一个简单的接口: <code-example path="upgrade-phonecat-2-hybrid/app/core/phone/phone.service.ts" region="phonedata-interface" title="app/core/phone/phone.service.ts (interface)" linenums="false"> - </code-example> `@angular/upgrade/static` has a `downgradeInjectable` method for the purpose of making @@ -2234,7 +2157,6 @@ Angular services available to AngularJS code. Use it to plug in the `Phone` serv 使用它来插入 `Phone` 服务: <code-example path="upgrade-phonecat-2-hybrid/app/core/phone/phone.service.ts" region="downgrade-injectable" title="app/core/phone/phone.service.ts (downgrade)" linenums="false"> - </code-example> Here's the full, final code for the service: @@ -2242,7 +2164,6 @@ Here's the full, final code for the service: 最终,该类的全部代码如下: <code-example path="upgrade-phonecat-2-hybrid/app/core/phone/phone.service.ts" title="app/core/phone/phone.service.ts"> - </code-example> Notice that you're importing the `map` operator of the RxJS `Observable` separately. @@ -2258,7 +2179,6 @@ Because it's an Angular service, you register it with the `NgModule` providers: 因为它是 Angular 服务,你通过 `NgModule` 的 `providers` 数组来注册它: <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="phone" title="app.module.ts"> - </code-example> Now that you are loading `phone.service.ts` through an import that is resolved @@ -2277,11 +2197,9 @@ it's really an instance of the `Phone` class and you annotate its type according 但它实际上是一个 `Phones` 类的实例,并且你可以据此注解它的类型: <code-example path="upgrade-phonecat-2-hybrid/app/phone-list/phone-list.component.ajs.ts" title="app/phone-list/phone-list.component.ts"> - </code-example> <code-example path="upgrade-phonecat-2-hybrid/app/phone-detail/phone-detail.component.ajs.ts" title="app/phone-detail/phone-detail.component.ts"> - </code-example> Now there are two AngularJS components using an Angular service! @@ -2325,7 +2243,6 @@ You can then also remove the static `$inject` property from the class: 的组件了。然后,你还要从类中移除静态 `$inject` 属性。 <code-example path="upgrade-phonecat-2-hybrid/app/phone-list/phone-list.component.ts" region="initialclass" title="app/phone-list/phone-list.component.ts"> - </code-example> The `selector` attribute is a CSS selector that defines where on the page the component @@ -2343,7 +2260,6 @@ with Angular's two-way `[(ngModel)]` binding syntax: 现在,将组件的模版也转换为 Angular 语法。在搜索控件中,把 AngularJS 的 `$ctrl` 表达式替换成 Angular 的双向绑定语法 `[(ngModel)]`: <code-example path="upgrade-phonecat-2-hybrid/app/phone-list/phone-list.template.html" region="controls" title="app/phone-list/phone-list.template.html (search controls)" linenums="false"> - </code-example> Replace the list's `ng-repeat` with an `*ngFor` as @@ -2355,7 +2271,6 @@ Replace the image tag's `ng-src` with a binding to the native `src` property. 再把 `img` 标签的 `ng-src` 替换为一个标准的 `src` 属性(property)绑定。 <code-example path="upgrade-phonecat-2-hybrid/app/phone-list/phone-list.template.html" region="list" title="app/phone-list/phone-list.template.html (phones)" linenums="false"> - </code-example> #### No Angular _filter_ or _orderBy_ filters @@ -2374,7 +2289,6 @@ which implements the filtering and ordering logic inside the component itself. 你把 `filter` 和 `orderBy` 过滤器改成绑定到控制器中的 `getPhones()` 方法,通过该方法,组件本身实现了过滤和排序逻辑。 <code-example path="upgrade-phonecat-2-hybrid/app/phone-list/phone-list.component.ts" region="getphones" title="app/phone-list/phone-list.component.ts"> - </code-example> Now you need to downgrade the Angular component so you can use it in AngularJS. @@ -2391,7 +2305,6 @@ that the return value of the `downgradeComponent` method is a directive factory. 的返回值是一个指令工厂。 <code-example path="upgrade-phonecat-2-hybrid/app/phone-list/phone-list.component.ts" region="downgrade-component" title="app/phone-list/phone-list.component.ts"> - </code-example> The new `PhoneListComponent` uses the Angular `ngModel` directive, located in the `FormsModule`. @@ -2403,7 +2316,6 @@ finally add it to `entryComponents` since you downgraded it: 最后,把降级的结果添加到 `entryComponents`中: <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="phonelist" title="app.module.ts"> - </code-example> Remove the <script> tag for the phone list component from `index.html`. @@ -2415,7 +2327,6 @@ Now set the remaining `phone-detail.component.ts` as follows: 现在,剩下的 `phone-detail.component.ts` 文件变成了这样: <code-example path="upgrade-phonecat-2-hybrid/app/phone-detail/phone-detail.component.ts" title="app/phone-detail/phone-detail.component.ts"> - </code-example> This is similar to the phone list component. @@ -2443,11 +2354,9 @@ Do that in a new file called `ajs-upgraded-providers.ts` and import it in `app.m 新建一个名叫 `ajs-upgraded-providers.ts` 的文件,并且在 `app.module.ts` 中导入它: <code-example path="upgrade-phonecat-2-hybrid/app/ajs-upgraded-providers.ts" title="app/ajs-upgraded-providers.ts"> - </code-example> <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="routeparams" title="app/app.module.ts ($routeParams)" linenums="false"> - </code-example> Convert the phone detail component template into Angular syntax as follows: @@ -2455,7 +2364,6 @@ Convert the phone detail component template into Angular syntax as follows: 把该组件的模板转变成 Angular 的语法,代码如下: <code-example path="upgrade-phonecat-2-hybrid/app/phone-detail/phone-detail.template.html" title="app/phone-detail/phone-detail.template.html"> - </code-example> There are several notable changes here: @@ -2507,7 +2415,6 @@ Add `PhoneDetailComponent` component to the `NgModule` _declarations_ and _entry 把 `PhoneDetailComponent` 组件添加到 `NgModule` 的 *declarations* 和 *entryComponents* 中: <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="phonedetail" title="app.module.ts"> - </code-example> You should now also remove the phone detail component <script> tag from `index.html`. @@ -2536,7 +2443,6 @@ Rename the file to `checkmark.pipe.ts` to conform with Angular conventions: 把该文件改名成 `checkmark.pipe.ts`,以符合 Angular 中的命名约定: <code-example path="upgrade-phonecat-2-hybrid/app/core/checkmark/checkmark.pipe.ts" title="app/core/checkmark/checkmark.pipe.ts" linenums="false"> - </code-example> Now import and declare the newly created pipe and @@ -2545,7 +2451,6 @@ remove the filter <script> tag from `index.html`: 现在,导入并声明这个新创建的管道,同时从 `index.html` 文件中移除该过滤器的`<script>` 标签: <code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="checkmarkpipe" title="app.module.ts"> - </code-example> ### AOT compile the hybrid app @@ -2563,7 +2468,6 @@ by the AOT compiler: 然后修改 `main-aot.ts` 的引导代码,通过所生成的 `AppComponentFactory` 来引导 AngularJS 应用: <code-example path="upgrade-phonecat-2-hybrid/app/main-aot.ts" title="app/main-aot.ts"> - </code-example> You need to load all the AngularJS files you already use in `index.html` in `aot/index.html` @@ -2572,7 +2476,6 @@ as well: 你还要把在 `index.html` 中已经用到的所有 AngularJS 文件加载到 `aot/index.html` 中: <code-example path="upgrade-phonecat-2-hybrid/aot/index.html" title="aot/index.html"> - </code-example> These files need to be copied together with the polyfills. The files the application @@ -2586,7 +2489,6 @@ Install `fs-extra` via `npm install fs-extra --save-dev` for better file copying 通过 `npm install fs-extra --save-dev` 安装 `fs-extra` 可以更好的复制文件,并且把 `copy-dist-files.js` 文件改成这样: <code-example path="upgrade-phonecat-2-hybrid/copy-dist-files.js" title="copy-dist-files.js"> - </code-example> And that's all you need to use AOT while upgrading your app! @@ -2624,7 +2526,6 @@ Create a new `app.component.ts` file with the following `AppComponent` class: 创建新的 `app.component.ts` 文件,放入像这样的 `AppComponent` 类: <code-example path="upgrade-phonecat-3-final/app/app.component.ts" title="app/app.component.ts"> - </code-example> It has a simple template that only includes the `<router-outlet>. @@ -2645,7 +2546,6 @@ It replaces the old AngularJS `ng-view` directive: 用它来代替 AngularJS 中的 `ng-view` 指令: <code-example path="upgrade-phonecat-3-final/index.html" region="appcomponent" title="index.html (body)" linenums="false"> - </code-example> #### Create the _Routing Module_ @@ -2664,7 +2564,6 @@ Angular 路由器配置的详情最好去查阅下[路由与导航](guide/router 它建议你创建一个专们用于路由器配置的 `NgModule`(名叫*路由模块*)。 <code-example path="upgrade-phonecat-3-final/app/app-routing.module.ts" title="app/app-routing.module.ts"> - </code-example> This module defines a `routes` object with two routes to the two phone components @@ -2693,7 +2592,6 @@ and the `UpgradeModule` import. 你还要从 `app.module.ts` 中移除调用 `ngDoBootstrap()` 来引导 AngularJS 模块的代码,以及对 `UpgradeModule` 的导入代码。 <code-example path="upgrade-phonecat-3-final/app/app.module.ts" title="app/app.module.ts"> - </code-example> And since you are routing to `PhoneListComponent` and `PhoneDetailComponent` directly rather than @@ -2714,7 +2612,6 @@ and let that directive construct the appropriate URL to the `PhoneDetailComponen 你可以通过把每个电话的 `id` 绑定到 `routerLink` 指令来生成它们了,该指令的构造函数会为 `PhoneDetailComponent` 生成正确的 URL: <code-example path="upgrade-phonecat-3-final/app/phone-list/phone-list.template.html" region="list" title="app/phone-list/phone-list.template.html (list with links)" linenums="false"> - </code-example> <div class="l-sub-section"> @@ -2738,7 +2635,6 @@ Angular 路由器会传入不同的路由参数。 从 `ActivatedRoute.snapshot.params` 中提取出 `phoneId`,并像以前一样获取手机的数据: <code-example path="upgrade-phonecat-3-final/app/phone-detail/phone-detail.component.ts" title="app/phone-detail/phone-detail.component.ts"> - </code-example> You are now running a pure Angular application! @@ -2766,7 +2662,6 @@ Switch the bootstrap method of the application from the `UpgradeModule` to the A 把应用的引导(`bootstrap`)方法从 `UpgradeAdapter` 的改为 Angular 的。 <code-example path="upgrade-phonecat-3-final/app/main.ts" title="main.ts"> - </code-example> If you haven't already, remove all references to the `UpgradeModule` from `app.module.ts`, @@ -2785,7 +2680,6 @@ in `entryComponents`. 因为你不再需要降级任何组件了,也不再需要把它们列在 `entryComponents` 中。 <code-example path="upgrade-phonecat-3-final/app/app.module.ts" title="app.module.ts"> - </code-example> You may also completely remove the following files. They are AngularJS @@ -2813,10 +2707,8 @@ The `@angular/upgrade` package and its mapping in `systemjs.config.js` can also `systemjs.config.js` 中的 `@angular/upgrade` 包及其映射也可以移除了。 <code-example format=""> - npm uninstall @angular/upgrade --save npm uninstall @types/angular @types/angular-animate @types/angular-cookies @types/angular-mocks @types/angular-resource @types/angular-route @types/angular-sanitize --save-dev - </code-example> Finally, from `index.html`, remove all references to AngularJS scripts and jQuery. @@ -2826,7 +2718,6 @@ When you're done, this is what it should look like: 当这些全部做完时,`index.html` 应该是这样的: <code-example path="upgrade-phonecat-3-final/index.html" region="full" title="index.html"> - </code-example> That is the last you'll see of AngularJS! It has served us well but now @@ -2875,9 +2766,7 @@ Update the `protractor-conf.js` to sync with hybrid apps: 再对 `protractor-conf.js` 做下列修改,与混合应用同步: <code-example format=""> - ng12Hybrid: true - </code-example> When you start to upgrade components and their templates to Angular, you'll make more changes @@ -2888,7 +2777,6 @@ For PhoneCat you need to make the following changes in order to make things work 这是因为 E2E 测试有一些匹配器是 AngularJS 中特有的。对于 PhoneCat 来说,为了让它能在 Angular 下工作,你得做下列修改: <table> - <tr> <th> @@ -2916,7 +2804,6 @@ For PhoneCat you need to make the following changes in order to make things work </th> </tr> - <tr> <td> @@ -2940,7 +2827,6 @@ For PhoneCat you need to make the following changes in order to make things work </td> </tr> - <tr> <td> @@ -2964,7 +2850,6 @@ For PhoneCat you need to make the following changes in order to make things work </td> </tr> - <tr> <td> @@ -2988,7 +2873,6 @@ For PhoneCat you need to make the following changes in order to make things work </td> </tr> - <tr> <td> @@ -3012,7 +2896,6 @@ For PhoneCat you need to make the following changes in order to make things work </td> </tr> - <tr> <td> @@ -3036,7 +2919,6 @@ For PhoneCat you need to make the following changes in order to make things work </td> </tr> - </table> When the bootstrap method is switched from that of `UpgradeModule` to @@ -3054,9 +2936,7 @@ Replace the `ng12Hybrid` previously added with the following in `protractor-conf 替换之前在 `protractor-conf.js` 中加入 `ng12Hybrid`,象这样: <code-example format=""> - useAllAngular2AppRoots: true, - </code-example> Also, there are a couple of Protractor API calls in the PhoneCat test code that @@ -3069,7 +2949,6 @@ the redirection spec: 你就得把这些调用用一个 WebDriver 的通用 URL API 代替。第一个 API 是“重定向(redirect)”规约: <code-example path="upgrade-phonecat-3-final/e2e-spec.ts" region="redirect" title="e2e-tests/scenarios.ts"> - </code-example> And the second is the phone links spec: @@ -3077,7 +2956,6 @@ And the second is the phone links spec: 然后是“电话链接(phone links)”规约: <code-example path="upgrade-phonecat-3-final/e2e-spec.ts" region="links" title="e2e-tests/scenarios.ts"> - </code-example> ### Unit Tests @@ -3103,7 +2981,6 @@ definitions of the AngularJS services you're consuming: AngularJS 服务提供了类型定义。 <code-example path="upgrade-phonecat-1-typescript/app/phone-detail/phone-detail.component.spec.ts" title="app/phone-detail/phone-detail.component.spec.ts"> - </code-example> Once you start the upgrade process and bring in SystemJS, configuration changes @@ -3114,7 +2991,6 @@ which can be done with the following kind of shim file: 你需要让 SystemJS 加载所有的 Angular 新代码, <code-example path="upgrade-phonecat-2-hybrid/karma-test-shim.1.js" title="karma-test-shim.js"> - </code-example> The shim first loads the SystemJS configuration, then Angular's test support libraries, @@ -3128,7 +3004,6 @@ as the base directory, instead of `app`. 然后需要修改 Karma 配置,来让它使用本应用的根目录作为基础目录(base directory),而不是 `app`。 <code-example path="upgrade-phonecat-2-hybrid/karma.conf.ajs.js" region="basepath" title="karma.conf.js"> - </code-example> Once done, you can load SystemJS and other dependencies, and also switch the configuration @@ -3139,7 +3014,6 @@ the shim and SystemJS load them. 你要让这个 shim 文件和 SystemJS 去加载它们。 <code-example path="upgrade-phonecat-2-hybrid/karma.conf.ajs.js" region="files" title="karma.conf.js"> - </code-example> Since the HTML templates of Angular components will be loaded as well, you must help @@ -3148,7 +3022,6 @@ Karma out a bit so that it can route them to the right paths: 由于 Angular 组件中的 HTML 模板也同样要被加载,所以你得帮 Karma 一把,帮它在正确的路径下找到这些模板: <code-example path="upgrade-phonecat-2-hybrid/karma.conf.ajs.js" region="html" title="karma.conf.js"> - </code-example> The unit test files themselves also need to be switched to Angular when their production @@ -3158,7 +3031,6 @@ as the pipe has no dependencies: 如果产品代码被切换到了 Angular,单元测试文件本身也需要切换过来。对勾(checkmark)管道的规约可能是最简单的,因为它没有任何依赖: <code-example path="upgrade-phonecat-2-hybrid/app/core/checkmark/checkmark.pipe.spec.ts" title="app/core/checkmark/checkmark.pipe.spec.ts"> - </code-example> The unit test for the phone service is a bit more involved. You need to switch from the mocked-out @@ -3167,7 +3039,6 @@ AngularJS `$httpBackend` to a mocked-out Angular Http backend. `Phone` 服务的测试会牵扯到一点别的。你需要把模拟版的 AngularJS `$httpBackend` 服务切换到模拟板的 Angular Http 后端。 <code-example path="upgrade-phonecat-2-hybrid/app/core/phone/phone.service.spec.ts" title="app/core/phone/phone.service.spec.ts"> - </code-example> For the component specs, you can mock out the `Phone` service itself, and have it provide @@ -3176,11 +3047,9 @@ canned phone data. You use Angular's component unit testing APIs for both compon 对于组件的规约,你可以模拟出 `Phone` 服务本身,并且让它提供电话的数据。你可以对这些组件使用 Angular 的组件单元测试 API。 <code-example path="upgrade-phonecat-2-hybrid/app/phone-detail/phone-detail.component.spec.ts" title="app/phone-detail/phone-detail.component.spec.ts"> - </code-example> <code-example path="upgrade-phonecat-2-hybrid/app/phone-list/phone-list.component.spec.ts" title="app/phone-list/phone-list.component.spec.ts"> - </code-example> Finally, revisit both of the component tests when you switch to the Angular @@ -3191,7 +3060,6 @@ instead of using the AngularJS `$routeParams`. `RouteParams` 的 mock 对象,而不再用 AngularJS 中的 `$routeParams`。 <code-example path="upgrade-phonecat-3-final/app/phone-detail/phone-detail.component.spec.ts" region="activatedroute" title="app/phone-detail/phone-detail.component.spec.ts"> - </code-example> And for the phone list component, a few adjustments to the router make @@ -3200,5 +3068,4 @@ the `RouteLink` directives work. 对于电话列表组件,还要再做少量的调整,以便路由器能让 `RouteLink` 指令正常工作。 <code-example path="upgrade-phonecat-3-final/app/phone-list/phone-list.component.spec.ts" region="routestuff" title="app/phone-list/phone-list.component.spec.ts"> - </code-example> diff --git a/aio/content/guide/user-input.md b/aio/content/guide/user-input.md index 802e9b3416..399e8728ec 100644 --- a/aio/content/guide/user-input.md +++ b/aio/content/guide/user-input.md @@ -125,9 +125,7 @@ Here's what the UI displays: 用户界面将显示: <code-example> - a | ab | abc | ab | a | | - </code-example> <figure> @@ -142,7 +140,6 @@ for `event.target.value` in which case the same user input would produce: 或者,你可以用 `event.key` 替代 `event.target.value`,积累各个按键本身,这样同样的用户输入可以产生: <code-example> - a | b | c | backspace | backspace | backspace | </code-example> @@ -428,7 +425,6 @@ values between data entry fields and model properties. The next page, `Forms`, explains how to write two-way bindings with `NgModel`. - 这些技术对小规模演示很实用,但是在处理大量用户输入时,很容易变得累赘和笨拙。 要在数据录入字段和模型属性之间传递数据,双向数据绑定是更加优雅和简洁的方式。 下一章 ` 表单 ` 解释了如何用 `NgModel` 来进行双向绑定。 diff --git a/aio/content/guide/visual-studio-2015.md b/aio/content/guide/visual-studio-2015.md index 6d9c069e83..12aa6866a1 100644 --- a/aio/content/guide/visual-studio-2015.md +++ b/aio/content/guide/visual-studio-2015.md @@ -222,7 +222,7 @@ Include the files in the Visual Studio project as follows: <h2 id='restore'>Step 4: Restore the required packages</h2> -<h2 id='restore'> 第四步: 恢复需要的包 </h2> +<h2 id='restore'>第四步: 恢复需要的包 </h2> Restore the packages required for an Angular application as follows: @@ -348,7 +348,6 @@ rewrite rules near the bottom of the `web.config`: 通过把下列重写规则添加到 `web.config` 的底部,就可以告诉 Visual Studio 如何处理到应用页面的请求。 <code-example format='.'> - <system.webServer> <rewrite> <rules> @@ -397,7 +396,6 @@ The default browser opens and displays the QuickStart sample application. 默认浏览器打开并显示《快速上手》例子应用。 Try editing any of the project files. Save and refresh the browser to -see the changes. - +see the changes. 尝试编辑任何项目文件,*保存*并刷新浏览器来查看效果。 diff --git a/aio/content/guide/webpack.md b/aio/content/guide/webpack.md index 38cea3d274..3ac695f01c 100644 --- a/aio/content/guide/webpack.md +++ b/aio/content/guide/webpack.md @@ -175,7 +175,6 @@ Then it **outputs** these files to the `app.js` _bundle file_ designated in conf 然后它把这些文件**输出**到当前配置所指定的*包文件*`app.js` 中: <code-example name="webpack.config.js (single output)" language="javascript"> - output: { filename: 'app.js' } @@ -204,7 +203,6 @@ Change the configuration so that it has two entry points, `main.ts` and `vendor. 所以要修改配置,以获得两个入口点:`main.ts` 和 `vendor.ts`: <code-example language="javascript"> - entry: { app: 'src/app.ts', vendor: 'src/vendor.ts' @@ -257,7 +255,6 @@ Webpack 可以打包任何类型的文件:JavaScript、TypeScript、CSS、SASS 再为 TypeScript 和 CSS 文件配置如下加载器。 <code-example language="javascript"> - rules: [ { test: /\.ts$/, @@ -277,7 +274,6 @@ it applies the `test` RegEx patterns. 当 Webpack 遇到如下所示的 `import` 语句时,它就会调用正则表达式的 `test` 方法。 <code-example language="typescript"> - import { AppComponent } from './app.component.ts'; import 'uiframework/dist/uiframework.css'; @@ -316,7 +312,6 @@ Webpack 有一条构建流水线,它被划分成多个经过精心定义的阶 可以把插件(比如 `uglify` 代码最小化插件)挂到流水线上: <code-example language="javascript"> - plugins: [ new webpack.optimize.UglifyJsPlugin() ] @@ -342,7 +337,6 @@ Create a new project folder. 创建一个新的项目文件夹。 <code-example language="sh" class="code-shell"> - mkdir angular-webpack cd angular-webpack @@ -396,7 +390,6 @@ Open a terminal window and install the npm packages. 打开命令行窗口并安装这些 *npm* 包 <code-example language="sh" class="code-shell"> - npm install </code-example> @@ -530,7 +523,6 @@ You could write `import` statements with explicit extensions like this example: 如果你的应用程序只须 `import` 几十个 JavaScript 或 TypeScript 文件,而不是几百个,你可以在 `import` 语句里完整写上扩展名,如: <code-example language="typescript"> - import { AppComponent } from './app.component.ts'; </code-example> @@ -737,7 +729,6 @@ Grab the app code at the end of this guide and try: 抓取本指南底部的应用代码,并试一试: <code-example language="sh" class="code-shell"> - npm start </code-example> @@ -746,11 +737,11 @@ Grab the app code at the end of this guide and try: ### Production configuration -### 产品环境配置 +### 生产环境配置 Configuration of a *production* build resembles *development* configuration with a few key changes. -*产品环境*下的配置和*开发环境*下的配置很相似……除了一些关键的改动。 +*生产环境*下的配置和*开发环境*下的配置很相似……除了一些关键的改动。 <code-example path="webpack/config/webpack.prod.js" title="config/webpack.prod.js" linenums="false"> @@ -764,7 +755,7 @@ You won't deploy the artifacts needed only in development. Put the production output bundle files in the `dist` folder. -把产品环境的输出包放在 `dist` 目录下。 +把生产环境的输出包放在 `dist` 目录下。 Webpack generates file names with cache-busting hash. Thanks to the `HtmlWebpackPlugin`, you don't have to update the `index.html` file when the hash changes. @@ -809,7 +800,6 @@ Grab the app code at the end of this guide and try: 抓取本指南底部的应用代码,并试一试: <code-example language="sh" class="code-shell"> - npm run build </code-example> @@ -826,7 +816,7 @@ You probably don't need to load and process the application-wide styles files fo you'll use the `null` loader for those CSS files. 你并不需要使用很多配置项来运行单元测试。 -也不需要在开发环境和产品环境下引入的那些加载器和插件。 +也不需要在开发环境和生产环境下引入的那些加载器和插件。 如果有可能拖慢执行速度,甚至都不需要在单元测试中加载和处理应用全局样式文件,所以你用一个 `null` 加载器来处理所有 CSS。 You could merge the test configuration into the `webpack.common` configuration and override the parts you don't want or need. @@ -877,7 +867,6 @@ Grab the app code at the end of this guide and try: 抓取本指南底部的应用代码,并试一试: <code-example language="sh" class="code-shell"> - npm test </code-example> @@ -1002,7 +991,7 @@ if the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `a You've learned just enough Webpack to configurate development, test and production builds for a small Angular application. -你学到了刚好够用来在开发、测试、产品环境下构建一个小型 Angular 应用的 Webpack 配置知识。 +你学到了刚好够用来在开发、测试、生产环境下构建一个小型 Angular 应用的 Webpack 配置知识。 _You could always do more_. Search the web for expert advice and expand your Webpack knowledge. @@ -1010,5 +999,4 @@ _You could always do more_. Search the web for expert advice and expand your Web [Back to top](guide/webpack#top) - [回到顶部](guide/webpack#top) diff --git a/aio/content/navigation.json b/aio/content/navigation.json index ecdb71243b..a1e58beafb 100644 --- a/aio/content/navigation.json +++ b/aio/content/navigation.json @@ -421,7 +421,7 @@ }, { "url": "guide/service-worker-devops", - "title": "产品环境下的 Service Worker", + "title": "生产环境下的 Service Worker", "tooltip": "使用 Service Worker 运行应用、管理应用更新、调试以及杀掉正在运行的应用。" }, { diff --git a/aio/content/tutorial/toh-pt0.md b/aio/content/tutorial/toh-pt0.md index 4d26244372..3a944ccab7 100644 --- a/aio/content/tutorial/toh-pt0.md +++ b/aio/content/tutorial/toh-pt0.md @@ -11,9 +11,7 @@ 如果还没有安装 [Angular CLI](https://github.com/angular/angular-cli),请执行: <code-example language="sh" class="code-shell"> - npm install -g @angular/cli - </code-example> ## Create a new application @@ -25,9 +23,7 @@ Create a new project named `angular-tour-of-heroes` with this CLI command. 使用 CLI 命令创建一个名叫 `angular-tour-of-heroes` 的新项目。 <code-example language="sh" class="code-shell"> - ng new angular-tour-of-heroes - </code-example> The Angular CLI generated a new project with a default application and supporting files. @@ -43,10 +39,8 @@ Go to the project directory and launch the application. 进入项目目录,并启动这个应用。 <code-example language="sh" class="code-shell"> - cd angular-tour-of-heroes ng serve --open - </code-example> <div class="l-sub-section"> @@ -111,7 +105,6 @@ Open the component class file (`app.component.ts`) and change the value of the ` 打开组件的类文件 (`app.component.ts`),并把 `title` 属性的值修改为 'Tour of Heroes' (英雄指南)。 <code-example path="toh-pt0/src/app/app.component.ts" region="set-title" title="app.component.ts (class title property)" linenums="false"> - </code-example> Open the component template file (`app.component.html`) and @@ -122,7 +115,6 @@ Replace it with the following line of HTML. <code-example path="toh-pt0/src/app/app.component.html" title="app.component.html (template)" linenums="false"> - </code-example> The double curly braces are Angular's *interpolation binding* syntax. @@ -155,7 +147,6 @@ Here's an excerpt from the `styles.css` for the _Tour of Heroes_ sample app. 下面是这个*英雄指南*范例应用中 `styles.css` 文件的片段。 <code-example path="toh-pt0/src/styles.1.css" title="src/styles.css (excerpt)"> - </code-example> ## Final code review @@ -183,7 +174,6 @@ Here are the code files discussed on this page. title="src/styles.css (excerpt)" path="toh-pt0/src/styles.1.css"> </code-pane> - </code-tabs> ## Summary @@ -198,6 +188,6 @@ Here are the code files discussed on this page. 你学会了使用 Angular 组件来显示数据。 -* You used the double curly braces of interpolation to display the app title. +* You used the double curly braces of interpolation to display the app title. - 你使用双花括号插值表达式显示了应用标题。 + 你使用双花括号插值表达式显示了应用标题。 diff --git a/aio/content/tutorial/toh-pt1.md b/aio/content/tutorial/toh-pt1.md index 79f645f295..f11c6311ff 100644 --- a/aio/content/tutorial/toh-pt1.md +++ b/aio/content/tutorial/toh-pt1.md @@ -18,9 +18,7 @@ Using the Angular CLI, generate a new component named `heroes`. 使用 Angular CLI 创建一个名为 `heroes` 的新组件。 <code-example language="sh" class="code-shell"> - ng generate component heroes - </code-example> The CLI creates a new folder, `src/app/heroes/` and generates @@ -35,7 +33,6 @@ The `HeroesComponent` class file is as follows: <code-example path="toh-pt1/src/app/heroes/heroes.component.ts" region="v1" title="app/heroes/heroes.component.ts (initial version)" linenums="false"> - </code-example> You always import the `Component` symbol from the Angular core library @@ -89,7 +86,6 @@ Add a `hero` property to the `HeroesComponent` for a hero named "Windstorm." 往 `HeroesComponent` 中添加一个 `hero` 属性,用来表示一个名叫 “Windstorm” 的英雄。 <code-example path="toh-pt1/src/app/heroes/heroes.component.ts" region="add-hero" title="heroes.component.ts (hero property)" linenums="false"> - </code-example> ### Show the hero @@ -103,7 +99,6 @@ replace it with a data binding to the new `hero` property. 打开模板文件 `heroes.component.html`。删除 Angular CLI 自动生成的默认内容,改为到 `hero` 属性的数据绑定。 <code-example path="toh-pt1/src/app/heroes/heroes.component.1.html" title="heroes.component.html" region="show-hero-1" linenums="false"> - </code-example> ## Show the _HeroesComponent_ view @@ -121,7 +116,6 @@ So add an `<app-heroes>` element to the `AppComponent` template file, just below 所以,只要把 `<app-heroes>` 元素添加到 `AppComponent` 的模板文件中就可以了,就放在标题下方。 <code-example path="toh-pt1/src/app/app.component.html" title="src/app/app.component.html" linenums="false"> - </code-example> Assuming that the CLI `ng serve` command is still running, @@ -143,7 +137,6 @@ Give it `id` and `name` properties. 在 `src/app` 文件夹中为 `Hero` 类创建一个文件,并添加 `id` 和 `name` 属性。 <code-example path="toh-pt1/src/app/hero.ts" title="src/app/hero.ts" linenums="false"> - </code-example> Return to the `HeroesComponent` class and import the `Hero` class. @@ -162,7 +155,6 @@ The revised `HeroesComponent` class file should look like this: <code-example path="toh-pt1/src/app/heroes/heroes.component.ts" linenums="false" title= "src/app/heroes/heroes.component.ts"> - </code-example> The page no longer displays properly because you changed the hero from a string to an object. @@ -182,7 +174,6 @@ and show both `id` and `name` in a details layout like this: path="toh-pt1/src/app/heroes/heroes.component.1.html" region="show-hero-2" title="heroes.component.html (HeroesComponent's template)" linenums="false"> - </code-example> The browser refreshes and display's the hero's information. @@ -200,7 +191,6 @@ Modify the `hero.name` binding like this. <code-example path="toh-pt1/src/app/heroes/heroes.component.html" region="pipe"> - </code-example> The browser refreshes and now the hero's name is displayed in capital letters. @@ -273,10 +263,8 @@ for a message like 打开浏览器的开发工具,就会在控制台中看到如下信息: <code-example language="sh" class="code-shell"> - Template parse errors: Can't bind to 'ngModel' since it isn't a known property of 'input'. - </code-example> Although `ngModel` is a valid Angular directive, it isn't available by default. @@ -322,7 +310,6 @@ Open `AppModule` (`app.module.ts`) and import the `FormsModule` symbol from the <code-example path="toh-pt1/src/app/app.module.ts" title="app.module.ts (FormsModule symbol import)" region="formsmodule-js-import"> - </code-example> Then add `FormsModule` to the `@NgModule` metadata's `imports` array, which contains a list of external modules that the app needs. @@ -331,7 +318,6 @@ Then add `FormsModule` to the `@NgModule` metadata's `imports` array, which cont <code-example path="toh-pt1/src/app/app.module.ts" title="app.module.ts ( @NgModule imports)" region="ng-imports"> - </code-example> When the browser refreshes, the app should work again. You can edit the hero's name and see the changes reflected immediately in the `<h2>` above the textbox. @@ -360,7 +346,6 @@ Open `src/app/app.module.ts` and find `HeroesComponent` imported near the top. 打开 `src/app/app.module.ts` 你就会发现 `HeroesComponent` 已经在顶部导入过了。 <code-example path="toh-pt1/src/app/app.module.ts" region="heroes-import" > - </code-example> The `HeroesComponent` is declared in the `@NgModule.declarations` array. @@ -368,7 +353,6 @@ The `HeroesComponent` is declared in the `@NgModule.declarations` array. `HeroesComponent` 也已经声明在了 `@NgModule.declarations` 数组中。 <code-example path="toh-pt1/src/app/app.module.ts" region="declarations"> - </code-example> Note that `AppModule` declares both application components, `AppComponent` and `HeroesComponent`. @@ -438,4 +422,4 @@ Your app should look like this <live-example></live-example>. Here are the code * You learned the importance of declaring components in the `AppModule` and appreciated that the CLI declared it for you. - 你知道了把组件声明到 `AppModule` 是很重要的,并认识到 CLI 会自动帮你声明它。 + 你知道了把组件声明到 `AppModule` 是很重要的,并认识到 CLI 会自动帮你声明它。 diff --git a/aio/content/tutorial/toh-pt2.md b/aio/content/tutorial/toh-pt2.md index 936eb134a0..137ffa96ad 100644 --- a/aio/content/tutorial/toh-pt2.md +++ b/aio/content/tutorial/toh-pt2.md @@ -32,7 +32,6 @@ The file should look like this. <code-example path="toh-pt2/src/app/mock-heroes.ts" linenums="false" title="src/app/mock-heroes.ts"> - </code-example> ## Displaying heroes @@ -48,7 +47,6 @@ Open the `HeroesComponent` class file and import the mock `HEROES`. 打开 `HeroesComponent` 类文件,并导入模拟的 `HEROES`。 <code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="import-heroes" title="src/app/heroes/heroes.component.ts (import HEROES)"> - </code-example> Add a `heroes` property to the class that exposes these heroes for binding. @@ -56,7 +54,6 @@ Add a `heroes` property to the class that exposes these heroes for binding. 往类中添加一个 `heroes` 属性,这样可以暴露出这些英雄,以供绑定。 <code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="heroes"> - </code-example> ### List heroes with _*ngFor_ @@ -88,7 +85,6 @@ Make it look like this: 做完之后应该是这样的: <code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="list" title="heroes.component.html (heroes template)" linenums="false"> - </code-example> Now change the `<li>` to this: @@ -96,7 +92,6 @@ Now change the `<li>` to this: 现在,把 `<li>` 修改成这样: <code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="li"> - </code-example> The [`*ngFor`](guide/template-syntax#ngFor) is Angular's _repeater_ directive. @@ -176,7 +171,6 @@ and pointed to it in `@Component.styleUrls` like this. <code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="metadata" title="src/app/heroes/heroes.component.ts (@Component)"> - </code-example> Open the `heroes.component.css` file and paste in the private CSS styles for the `HeroesComponent`. @@ -218,7 +212,6 @@ Add a click event binding to the `<li>` like this: 再往 `<li>` 元素上插入一句点击事件的绑定代码: <code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="selectedHero-click" title="heroes.component.html (template excerpt)" linenums="false"> - </code-example> This is an example of Angular's [event binding](guide/template-syntax#event-binding) syntax. @@ -254,7 +247,6 @@ to the component's `selectedHero`. 添加如下 `onSelect()` 方法,它会把模板中被点击的英雄赋值给组件的 `selectedHero` 属性。 <code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="on-select" title="src/app/heroes/heroes.component.ts (onSelect)" linenums="false"> - </code-example> ### Update the details template @@ -268,7 +260,6 @@ Rename `hero` to `selectedHero`. 把 `hero` 改名为 `selectedHero`。 <code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="selectedHero-details" title="heroes.component.html (selected hero details)" linenums="false"> - </code-example> ### Hide empty details with _*ngIf_ @@ -284,9 +275,7 @@ Open the browser developer tools and look in the console for an error message li 打开浏览器的开发者工具,它的控制台中显示出如下错误信息: <code-example language="sh" class="code-shell"> - HeroesComponent.html:3 ERROR TypeError: Cannot read property 'name' of undefined - </code-example> Now click one of the list items. @@ -332,7 +321,6 @@ Don't forget the asterisk (*) in front of `ngIf`. It's a critical part of the sy </div> <code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="ng-if" title="src/app/heroes/heroes.component.html (*ngIf)" linenums="false"> - </code-example> After the browser refreshes, the list of names reappears. @@ -391,7 +379,6 @@ Add the following `[class.selected]` binding to the `<li>` in the `HeroesCompon 在 `HeroesComponent` 模板中的 `<li>` 元素上添加 `[class.selected]` 绑定,代码如下: <code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="class-selected" title="heroes.component.html (toggle the 'selected' CSS class)" linenums="false"> - </code-example> When the current row hero is the same as the `selectedHero`, Angular adds the `selected` CSS class. When the two heroes are different, Angular removes the class. @@ -421,7 +408,6 @@ Here are the code files discussed on this page, including the `HeroesComponent` 下面是本页面中所提及的代码文件,包括 `HeroesComponent` 的样式。 <code-tabs> - <code-pane title="src/app/heroes/heroes.component.ts" path="toh-pt2/src/app/heroes/heroes.component.ts"> </code-pane> @@ -430,7 +416,6 @@ Here are the code files discussed on this page, including the `HeroesComponent` <code-pane title="src/app/heroes/heroes.component.css" path="toh-pt2/src/app/heroes/heroes.component.css"> </code-pane> - </code-tabs> ## Summary @@ -455,4 +440,4 @@ Here are the code files discussed on this page, including the `HeroesComponent` * You can toggle a CSS style class with a `class` binding. - 你可以用 `class` 绑定来切换 CSS 的样式类。 \ No newline at end of file + 你可以用 `class` 绑定来切换 CSS 的样式类。 diff --git a/aio/content/tutorial/toh-pt3.md b/aio/content/tutorial/toh-pt3.md index af4674baa6..a57a424ad5 100644 --- a/aio/content/tutorial/toh-pt3.md +++ b/aio/content/tutorial/toh-pt3.md @@ -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 `HeroDetailComponent`. +In this page, you'll take the first step in that direction by moving the hero details into a separate, reusable `HeroDetailsComponent`. 本页面中,你将迈出第一步 —— 把英雄详情移入一个独立的、可复用的 `HeroDetailComponent`。 The `HeroesComponent` will only present the list of heroes. -The `HeroDetailComponent` will present details of a selected hero. +The `HeroDetailsComponent` will present details of a selected hero. `HeroesComponent` 将仅仅用来表示英雄列表。 `HeroDetailComponent` 将用来表示所选英雄的详情。 @@ -31,9 +31,7 @@ Use the Angular CLI to generate a new component named `hero-detail`. 使用 Angular CLI 生成一个名叫 `hero-detail` 的新组件。 <code-example language="sh" class="code-shell"> - ng generate component hero-detail - </code-example> The command scaffolds the `HeroDetailComponent` files and declares the component in `AppModule`. @@ -78,7 +76,6 @@ Open the `HeroDetailComponent` class file and import the `Hero` symbol. <code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts" region="import-hero" title="src/app/hero-detail/hero-detail.component.ts (import Hero)"> - </code-example> The `hero` property @@ -89,7 +86,6 @@ because the _external_ `HeroesComponent` [will bind to it](#heroes-component-tem `hero` 属性[必须是一个带有 `@Input()` 装饰器的输入属性](guide/template-syntax#inputs-outputs "Input and Output properties"),因为*外部的* `HeroesComponent` 组件[将会绑定到它](#heroes-component-template)。就像这样: <code-example path="toh-pt3/src/app/heroes/heroes.component.html" region="hero-detail-binding"> - </code-example> Amend the `@angular/core` import statement to include the `Input` symbol. @@ -97,7 +93,6 @@ Amend the `@angular/core` import statement to include the `Input` symbol. 修改 `@angular/core` 的导入语句,导入 `Input` 符号。 <code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts" region="import-input" title="src/app/hero-detail/hero-detail.component.ts (import Input)" linenums="false"> - </code-example> Add a `hero` property, preceded by the `@Input()` decorator. @@ -105,7 +100,6 @@ Add a `hero` property, preceded by the `@Input()` decorator. 添加一个带有 `@Input()` 装饰器的 `hero` 属性。 <code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts" region="input-hero" linenums="false"> - </code-example> That's the only change you should make to the `HeroDetailComponent` class. @@ -181,7 +175,6 @@ The revised `HeroesComponent` template should look like this: <code-example path="toh-pt3/src/app/heroes/heroes.component.html" title="heroes.component.html" linenums="false"> - </code-example> The browser refreshes and the app starts working again as it did before. @@ -257,5 +250,4 @@ Here are the code files discussed on this page and your app should look like thi to make the `hero` property available for binding by the external `HeroesComponent`. - 你用 [`@Input` 装饰器](guide/template-syntax#inputs-outputs)来让 `hero` 属性可以在外部的 `HeroesComponent` 中绑定。 - \ No newline at end of file + 你用 [`@Input` 装饰器](guide/template-syntax#inputs-outputs)来让 `hero` 属性可以在外部的 `HeroesComponent` 中绑定。 diff --git a/aio/content/tutorial/toh-pt4.md b/aio/content/tutorial/toh-pt4.md index dba8fe64ee..4b6586682a 100644 --- a/aio/content/tutorial/toh-pt4.md +++ b/aio/content/tutorial/toh-pt4.md @@ -52,9 +52,7 @@ Using the Angular CLI, create a service called `hero`. 使用 Angular CLI 创建一个名叫 `hero` 的服务。 <code-example language="sh" class="code-shell"> - ng generate service hero - </code-example> The command generates skeleton `HeroService` class in `src/app/hero.service.ts` @@ -65,7 +63,6 @@ The `HeroService` class should look like the below. <code-example path="toh-pt4/src/app/hero.service.1.ts" region="new" title="src/app/hero.service.ts (new service)" linenums="false"> - </code-example> ### _@Injectable()_ services @@ -118,7 +115,6 @@ Import the `Hero` and `HEROES`. 导入 `Hero` 和 `HEROES`。 <code-example path="toh-pt4/src/app/hero.service.ts" region="import-heroes"> - </code-example> Add a `getHeroes` method to return the _mock heroes_. @@ -126,7 +122,6 @@ Add a `getHeroes` method to return the _mock heroes_. 添加一个 `getHeroes` 方法,让它返回*模拟的英雄列表*。 <code-example path="toh-pt4/src/app/hero.service.1.ts" region="getHeroes"> - </code-example> {@a provide} @@ -158,9 +153,7 @@ by appending `--module=app`. 这是一个常用的选择,因此你可以通过 `--module=app` 选项让 CLI 自动把它提供给 `AppModule`。 <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. @@ -172,7 +165,6 @@ Open the `AppModule` class, import the `HeroService`, and add it to the `@NgModu 打开 `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` @@ -215,7 +207,6 @@ Import the `HeroService` instead. 转而导入 `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"> - </code-example> Replace the definition of the `heroes` property with a simple declaration. @@ -223,7 +214,6 @@ Replace the definition of the `heroes` property with a simple declaration. 把 `heroes` 属性的定义改为一句简单的声明。 <code-example path="toh-pt4/src/app/heroes/heroes.component.ts" region="heroes"> - </code-example> {@a inject} @@ -237,7 +227,6 @@ Add a private `heroService` parameter of type `HeroService` to the constructor. 往构造函数中添加一个私有的 `heroService`,其类型为 `HeroService`。 <code-example path="toh-pt4/src/app/heroes/heroes.component.ts" region="ctor"> - </code-example> The parameter simultaneously defines a private `heroService` property and identifies it as a `HeroService` injection site. @@ -258,7 +247,6 @@ Create a function to retrieve the heroes from the service. 创建一个函数,以从服务中获取这些英雄数据。 <code-example path="toh-pt4/src/app/heroes/heroes.component.1.ts" region="getHeroes"> - </code-example> {@a oninit} @@ -285,7 +273,6 @@ let Angular call `ngOnInit` at an appropriate time _after_ constructing a `Heroe 你应该改为在 [*ngOnInit 生命周期钩子*](guide/lifecycle-hooks)中调用 `getHeroes()`,并且等 Angular 构造出 `HeroesComponent` 的实例之后,找个恰当的时机调用 `ngOnInit`。 <code-example path="toh-pt4/src/app/heroes/heroes.component.ts" region="ng-on-init"> - </code-example> ### See it run @@ -311,7 +298,6 @@ as if heroes could be fetched synchronously. 而 `HeroesComponent` 也同样假设能同步取到 `getHeroes()` 的结果。 <code-example path="toh-pt4/src/app/heroes/heroes.component.1.ts" region="get-heroes"> - </code-example> This will not work in a real app. @@ -365,7 +351,6 @@ Open the `HeroService` file and import the `Observable` and `of` symbols from Rx <code-example path="toh-pt4/src/app/hero.service.ts" title="src/app/hero.service.ts (Observable imports)" region="import-observable"> - </code-example> Replace the `getHeroes` method with this one. @@ -478,9 +463,7 @@ Use the CLI to create the `MessagesComponent`. 使用 CLI 创建 `MessagesComponent`。 <code-example language="sh" class="code-shell"> - ng generate component messages - </code-example> The CLI creates the component files in the `src/app/messages` folder and declare `MessagesComponent` in `AppModule`. @@ -494,7 +477,6 @@ Modify the `AppComponent` template to display the generated `MessagesComponent` <code-example title = "/src/app/app.component.html" path="toh-pt4/src/app/app.component.html"> - </code-example> You should see the default paragraph from `MessagesComponent` at the bottom of the page. @@ -512,9 +494,7 @@ The `--module=app` option tells the CLI to [_provide_ this service](#provide) i `--module=app` 选项告诉 CLI 在 `AppModule` 中[提供这个服务](#provide)。 <code-example language="sh" class="code-shell"> - ng generate service message --module=app - </code-example> Open `MessageService` and replace its contents with the following. @@ -524,7 +504,6 @@ Open `MessageService` and replace its contents with the following. <code-example title = "/src/app/message.service.ts" path="toh-pt4/src/app/message.service.ts"> - </code-example> The service exposes its cache of `messages` and two methods: one to `add()` a message to the cache and another to `clear()` the cache. @@ -544,7 +523,6 @@ Re-open the `HeroService` and import the `MessageService`. <code-example title = "/src/app/hero.service.ts (import MessageService)" path="toh-pt4/src/app/hero.service.ts" region="import-message-service"> - </code-example> Modify the constructor with a parameter that declares a private `messageService` property. @@ -556,7 +534,6 @@ Angular 将会在创建 `HeroService` 时把 `MessageService` 的单例注入到 <code-example path="toh-pt4/src/app/hero.service.ts" region="ctor"> - </code-example> <div class="l-sub-section"> @@ -578,7 +555,6 @@ Modify the `getHeroes` method to send a message when the heroes are fetched. 修改 `getHeroes` 方法,在获取到英雄数组时发送一条消息。 <code-example path="toh-pt4/src/app/hero.service.ts" region="getHeroes"> - </code-example> ### Display the message from `HeroService` @@ -598,19 +574,17 @@ Open `MessagesComponent` and import the `MessageService`. <code-example title = "/src/app/messages/messages.component.ts (import MessageService)" path="toh-pt4/src/app/messages/messages.component.ts" region="import-message-service"> - </code-example> 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 `MessagesComponent`. +when it creates the `HeroService`. 修改构造函数,添加一个 **public** 的 `messageService` 属性。 Angular 将会在创建 `MessagesComponent` 的实例时 把 `MessageService` 的实例注入到这个属性中。 <code-example path="toh-pt4/src/app/messages/messages.component.ts" region="ctor"> - </code-example> The `messageService` property **must be public** because you're about to bind to it in the template. @@ -636,7 +610,6 @@ Replace the CLI-generated `MessagesComponent` template with the following. <code-example title = "src/app/messages/messages.component.html" path="toh-pt4/src/app/messages/messages.component.html"> - </code-example> This template binds directly to the component's `messageService`. @@ -754,4 +727,4 @@ Here are the code files discussed on this page and your app should look like thi * The `HeroService` injected into a component is created with another injected service, `MessageService`. - `HeroService` 连同注入到它的服务 `MessageService` 一起,注入到了组件中。 + `HeroService` 连同注入到它的服务 `MessageService` 一起,注入到了组件中。 diff --git a/aio/content/tutorial/toh-pt5.md b/aio/content/tutorial/toh-pt5.md index 6c7ba94994..93a7adef57 100644 --- a/aio/content/tutorial/toh-pt5.md +++ b/aio/content/tutorial/toh-pt5.md @@ -50,9 +50,7 @@ Use the CLI to generate it. 使用 CLI 生成它。 <code-example language="sh" class="code-shell"> - ng generate module app-routing --flat --module=app - </code-example> <div class="l-sub-section"> @@ -71,7 +69,6 @@ The generated file looks like this: <code-example path="toh-pt5/src/app/app-routing.module.0.ts" title="src/app/app-routing.module.ts (generated)"> - </code-example> You generally don't declare components in a routing module so you can delete the @@ -98,7 +95,6 @@ in the `AppModule` components that will need them. <code-example path="toh-pt5/src/app/app-routing.module.ts" region="v1" title="src/app/app-routing.module.ts (v1)"> - </code-example> ### Add routes @@ -134,7 +130,6 @@ Then define an array of routes with a single `route` to that component. <code-example path="toh-pt5/src/app/app-routing.module.ts" region="heroes-route"> - </code-example> Once you've finished setting up, the router will match that URL to `path: 'heroes'` @@ -157,7 +152,6 @@ configure it with the `routes` in one step by calling <code-example path="toh-pt5/src/app/app-routing.module.ts" region="ngmodule-imports"> - </code-example> <div class="l-sub-section"> @@ -182,7 +176,6 @@ Open the `AppComponent` template replace the `<app-heroes>` element with a `<rou <code-example path="toh-pt5/src/app/app.component.html" region="outlet" title="src/app/app.component.html (router-outlet)"> - </code-example> You removed `<app-heroes>` because you will only display the `HeroesComponent` when the user navigates to it. @@ -211,9 +204,7 @@ You should still be running with this CLI command. 你的 CLI 命令应该仍在运行吧。 <code-example language="sh" class="code-shell"> - ng serve - </code-example> The browser should refresh and display the app title but not the list of heroes. @@ -255,7 +246,6 @@ The revised `AppComponent` template looks like this: path="toh-pt5/src/app/app.component.html" region="heroes" title="src/app/app.component.html (heroes RouterLink)"> - </code-example> A [`routerLink` attribute](#routerlink) is set to `"/heroes"`, @@ -301,9 +291,7 @@ Add a `DashboardComponent` using the CLI: 使用 CLI 添加一个 `DashboardComponent`: <code-example language="sh" class="code-shell"> - ng generate component dashboard - </code-example> The CLI generates the files for the `DashboardComponent` and declares it in `AppModule`. @@ -315,7 +303,6 @@ Replace the default file content in these three files as follows and then return 把这三个文件中的内容改成这样,并回来做一个随堂讨论: <code-tabs> - <code-pane title="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.1.html"> </code-pane> @@ -327,7 +314,6 @@ Replace the default file content in these three files as follows and then return <code-pane title="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css"> </code-pane> - </code-tabs> The _template_ presents a grid of hero name links. @@ -368,7 +354,6 @@ This `getHeroes` reduces the number of heroes displayed to four 这个 `getHeroes` 函数把要显示的英雄的数量缩减为四个(第二、第三、第四、第五)。 <code-example path="toh-pt5/src/app/dashboard/dashboard.component.ts" region="getHeroes"> - </code-example> ### Add the dashboard route @@ -387,7 +372,6 @@ Import the `DashboardComponent` in the `AppRoutingModule`. path="toh-pt5/src/app/app-routing.module.ts" region="import-dashboard" title="src/app/app-routing.module.ts (import DashboardComponent)"> - </code-example> Add a route to the `AppRoutingModule.routes` array that matches a path to the `DashboardComponent`. @@ -397,7 +381,6 @@ Add a route to the `AppRoutingModule.routes` array that matches a path to the `D <code-example path="toh-pt5/src/app/app-routing.module.ts" region="dashboard-route"> - </code-example> ### Add a default route @@ -418,7 +401,6 @@ route to the `AppRoutingModule.Routes` array. 要让应用自动导航到这个仪表盘,请把下列路由添加到 `AppRoutingModule.Routes` 数组中。 <code-example path="toh-pt5/src/app/app-routing.module.ts" region="redirect-route"> - </code-example> This route redirects a URL that fully matches the empty path to the route whose path is `'/dashboard'`. @@ -445,7 +427,6 @@ Add a dashboard navigation link to the `AppComponent` shell template, just above 把仪表盘的导航链接添加到壳组件 `AppComponent` 的模板中,就放在 *Heroes* 链接的前面。 <code-example path="toh-pt5/src/app/app.component.html" title="src/app/app.component.html"> - </code-example> After the browser refreshes you can navigate freely between the two views by clicking the links. @@ -523,7 +504,6 @@ Open `AppRoutingModule` and import `HeroDetailComponent`. path="toh-pt5/src/app/app-routing.module.ts" region="import-herodetail" title="src/app/app-routing.module.ts (import HeroDetailComponent)"> - </code-example> Then add a _parameterized_ route to the `AppRoutingModule.routes` array that matches the path pattern to the _hero detail_ view. @@ -533,7 +513,6 @@ Then add a _parameterized_ route to the `AppRoutingModule.routes` array that mat <code-example path="toh-pt5/src/app/app-routing.module.ts" region="detail-route"> - </code-example> The colon (:) in the `path` indicates that `:id` is a placeholder for a specific hero `id`. @@ -548,7 +527,6 @@ At this point, all application routes are in place. path="toh-pt5/src/app/app-routing.module.ts" region="routes" title="src/app/app-routing.module.ts (all routes)"> - </code-example> ### `DashboardComponent` hero links @@ -569,7 +547,6 @@ fix the dashboard hero links to navigate via the _parameterized_ dashboard route path="toh-pt5/src/app/dashboard/dashboard.component.html" region="click" title="src/app/dashboard/dashboard.component.html (hero links)"> - </code-example> You're using Angular [interpolation binding](guide/template-syntax#interpolation) within the `*ngFor` repeater @@ -593,7 +570,6 @@ are bound to the component's `onSelect()` method. path="toh-pt4/src/app/heroes/heroes.component.html" region="list" title="src/app/heroes/heroes.component.html (list with onSelect)"> - </code-example> Strip the `<li>` back to just its `*ngFor`, @@ -608,7 +584,6 @@ is the same as in the dashboard template path="toh-pt5/src/app/heroes/heroes.component.html" region="list" title="src/app/heroes/heroes.component.html (list with links)"> - </code-example> You'll have to fix the private stylesheet (`heroes.component.css`) to make @@ -637,7 +612,6 @@ Here's the class after pruning away the dead code. path="toh-pt5/src/app/heroes/heroes.component.ts" region="class" title="src/app/heroes/heroes.component.ts (cleaned up)" linenums="false"> - </code-example> ## Routable *HeroDetailComponent* @@ -679,7 +653,6 @@ Add the following imports: path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="added-imports" title="src/app/hero-detail/hero-detail.component.ts"> - </code-example> {@a hero-detail-ctor} @@ -691,7 +664,6 @@ into the constructor, saving their values in private fields: <code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="ctor"> - </code-example> The [`ActivatedRoute`](api/router/ActivatedRoute) holds information about the route to this instance of the `HeroDetailComponent`. @@ -725,7 +697,6 @@ call `getHero()` and define it as follows. <code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="ngOnInit"> - </code-example> The `route.snapshot` is a static image of the route information shortly after the component was created. @@ -764,7 +735,6 @@ Open `HeroService` and add this `getHero()` method path="toh-pt5/src/app/hero.service.ts" region="getHero" title="src/app/hero.service.ts (getHero)"> - </code-example> <div class="alert is-important"> @@ -829,7 +799,6 @@ to the component's `goBack()` method. path="toh-pt5/src/app/hero-detail/hero-detail.component.html" region="back-button" title="src/app/hero-detail/hero-detail.component.html (back button)"> - </code-example> Add a `goBack()` _method_ to the component class that navigates backward one step @@ -870,7 +839,6 @@ Here are the code files discussed on this page and your app should look like thi #### `AppRoutingModule`、`AppModule` 和 `HeroService` <code-tabs> - <code-pane title="src/app/app-routing.module.ts" path="toh-pt5/src/app/app-routing.module.ts"> @@ -883,7 +851,6 @@ Here are the code files discussed on this page and your app should look like thi title="src/app/hero.service.ts" path="toh-pt5/src/app/hero.service.ts"> </code-pane> - </code-tabs> {@a appcomponent} @@ -891,7 +858,6 @@ Here are the code files discussed on this page and your app should look like thi #### _AppComponent_ <code-tabs> - <code-pane title="src/app/app.component.html" path="toh-pt5/src/app/app.component.html"> @@ -901,7 +867,6 @@ Here are the code files discussed on this page and your app should look like thi title="src/app/app.component.css" path="toh-pt5/src/app/app.component.css"> </code-pane> - </code-tabs> {@a dashboardcomponent} @@ -909,7 +874,6 @@ Here are the code files discussed on this page and your app should look like thi #### _DashboardComponent_ <code-tabs> - <code-pane title="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.html"> </code-pane> @@ -921,7 +885,6 @@ Here are the code files discussed on this page and your app should look like thi <code-pane title="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css"> </code-pane> - </code-tabs> {@a heroescomponent} @@ -929,7 +892,6 @@ Here are the code files discussed on this page and your app should look like thi #### _HeroesComponent_ <code-tabs> - <code-pane title="src/app/heroes/heroes.component.html" path="toh-pt5/src/app/heroes/heroes.component.html"> </code-pane> @@ -943,7 +905,6 @@ Here are the code files discussed on this page and your app should look like thi title="src/app/heroes/heroes.component.css" path="toh-pt5/src/app/heroes/heroes.component.css"> </code-pane> - </code-tabs> {@a herodetailcomponent} @@ -951,7 +912,6 @@ Here are the code files discussed on this page and your app should look like thi #### _HeroDetailComponent_ <code-tabs> - <code-pane title="src/app/hero-detail/hero-detail.component.html" path="toh-pt5/src/app/hero-detail/hero-detail.component.html"> </code-pane> @@ -963,7 +923,6 @@ Here are the code files discussed on this page and your app should look like thi <code-pane title="src/app/hero-detail/hero-detail.component.css" path="toh-pt5/src/app/hero-detail/hero-detail.component.css"> </code-pane> - </code-tabs> ## Summary @@ -1000,4 +959,4 @@ Here are the code files discussed on this page and your app should look like thi * You shared the `HeroService` among multiple components. - 在多个组件之间共享了 `HeroService` 服务。 + 在多个组件之间共享了 `HeroService` 服务。 diff --git a/aio/content/tutorial/toh-pt6.md b/aio/content/tutorial/toh-pt6.md index 1db6be7706..9824a8e099 100644 --- a/aio/content/tutorial/toh-pt6.md +++ b/aio/content/tutorial/toh-pt6.md @@ -89,9 +89,7 @@ Install the *In-memory Web API* package from _npm_ 从 `npm` 中安装这个*内存 Web API* 包(译注:请使用 0.5+ 的版本,不要使用 0.4-) <code-example language="sh" class="code-shell"> - npm install angular-in-memory-web-api --save - </code-example> Import the `InMemoryWebApiModule` and the `InMemoryDataService` class, @@ -103,7 +101,6 @@ which you will create in a moment. path="toh-pt6/src/app/app.module.ts" region="import-in-mem-stuff" title="src/app/app.module.ts (In-memory Web API imports)"> - </code-example> Add the `InMemoryWebApiModule` to the `@NgModule.imports` array— @@ -116,7 +113,6 @@ _after importing the `HttpClient`_, <code-example path="toh-pt6/src/app/app.module.ts" region="in-mem-web-api-imports"> - </code-example> The `forRoot()` configuration method takes an `InMemoryDataService` class @@ -157,7 +153,6 @@ Import some HTTP symbols that you'll need: path="toh-pt6/src/app/hero.service.ts" region="import-httpclient" title="src/app/hero.service.ts (import HTTP symbols)"> - </code-example> Inject `HttpClient` into the constructor in a private property called `http`. @@ -167,7 +162,6 @@ Inject `HttpClient` into the constructor in a private property called `http`. <code-example path="toh-pt6/src/app/hero.service.ts" region="ctor" > - </code-example> Keep injecting the `MessageService`. You'll call it so frequently that @@ -178,7 +172,6 @@ you'll wrap it in private `log` method. <code-example path="toh-pt6/src/app/hero.service.ts" region="log" > - </code-example> Define the `heroesUrl` with the address of the heroes resource on the server. @@ -188,7 +181,6 @@ Define the `heroesUrl` with the address of the heroes resource on the server. <code-example path="toh-pt6/src/app/hero.service.ts" region="heroesUrl" > - </code-example> ### Get heroes with _HttpClient_ @@ -205,7 +197,6 @@ as an `Observable<Hero[]>`. path="toh-pt4/src/app/hero.service.ts" region="getHeroes-1" title="src/app/hero.service.ts (getHeroes with RxJs 'of()')"> - </code-example> Convert that method to use `HttpClient` @@ -215,7 +206,6 @@ Convert that method to use `HttpClient` <code-example path="toh-pt6/src/app/hero.service.ts" region="getHeroes-1"> - </code-example> Refresh the browser. The hero data should successfully load from the @@ -304,7 +294,6 @@ Import the `catchError` symbol from `rxjs/operators`, along with some other oper <code-example path="toh-pt6/src/app/hero.service.ts" region="import-rxjs-operators"> - </code-example> Now extend the observable result with the `.pipe()` method and @@ -315,7 +304,6 @@ give it a `catchError()` operator. <code-example path="toh-pt6/src/app/hero.service.ts" region="getHeroes-2" > - </code-example> The `catchError()` operator intercepts an **`Observable` that failed**. @@ -344,7 +332,6 @@ has configured with both the name of the operation that failed and a safe return <code-example path="toh-pt6/src/app/hero.service.ts" region="handleError"> - </code-example> After reporting the error to console, the handler constructs @@ -381,7 +368,6 @@ Here is the final version of `getHeroes` with the `tap` that logs the operation. <code-example path="toh-pt6/src/app/hero.service.ts" region="getHeroes" > - </code-example> ### Get hero by id @@ -459,7 +445,6 @@ on the server. path="toh-pt6/src/app/hero.service.ts" region="updateHero" title="src/app/hero.service.ts (update)"> - </code-example> The `HttpClient.put()` method takes three parameters @@ -491,7 +476,6 @@ That header is in the `httpOptions` constant defined in the `HeroService`. <code-example path="toh-pt6/src/app/hero.service.ts" region="http-options"> - </code-example> Refresh the browser, change a hero name, save your change, @@ -690,7 +674,6 @@ Start by adding a `searchHeroes` method to the `HeroService`. path="toh-pt6/src/app/hero.service.ts" region="searchHeroes" title="src/app/hero.service.ts"> - </code-example> The method returns immediately with an empty array if there is no search term. @@ -713,7 +696,6 @@ Add the hero search element, `<app-hero-search>`, to the bottom of the `Dashboar <code-example path="toh-pt6/src/app/dashboard/dashboard.component.html" title="src/app/dashboard/dashboard.component.html" linenums="false"> - </code-example> This template looks a lot like the `*ngFor` repeater in the `HeroesComponent` template. @@ -739,9 +721,7 @@ Create a `HeroSearchComponent` with the CLI. 使用 CLI 创建一个 `HeroSearchComponent`。 <code-example language="sh" class="code-shell"> - ng generate component hero-search - </code-example> The CLI generates the three `HeroSearchComponent` and adds the component to the `AppModule' declarations @@ -811,7 +791,6 @@ Notice the declaration of `heroes$` as an `Observable` <code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" region="heroes-stream"> - </code-example> You'll set it in [`ngOnInit()`](#search-pipe). @@ -876,7 +855,6 @@ Here's the code. <code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" region="search"> - </code-example> * `debounceTime(300)` waits until the flow of new string events pauses for 300 milliseconds @@ -960,7 +938,6 @@ Here are the code files discussed on this page (all in the `src/app/` folder). #### _HeroService_, _InMemoryDataService_, _AppModule_ <code-tabs> - <code-pane title="hero.service.ts" path="toh-pt6/src/app/hero.service.ts"> @@ -973,7 +950,6 @@ Here are the code files discussed on this page (all in the `src/app/` folder). title="app.module.ts" path="toh-pt6/src/app/app.module.ts"> </code-pane> - </code-tabs> {@a heroescomponent} @@ -981,7 +957,6 @@ Here are the code files discussed on this page (all in the `src/app/` folder). #### _HeroesComponent_ <code-tabs> - <code-pane title="heroes/heroes.component.html" path="toh-pt6/src/app/heroes/heroes.component.html"> @@ -994,7 +969,6 @@ Here are the code files discussed on this page (all in the `src/app/` folder). title="heroes/heroes.component.css" path="toh-pt6/src/app/heroes/heroes.component.css"> </code-pane> - </code-tabs> {@a herodetailcomponent} @@ -1002,7 +976,6 @@ Here are the code files discussed on this page (all in the `src/app/` folder). #### _HeroDetailComponent_ <code-tabs> - <code-pane title="hero-detail/hero-detail.component.html" path="toh-pt6/src/app/hero-detail/hero-detail.component.html"> @@ -1011,7 +984,6 @@ Here are the code files discussed on this page (all in the `src/app/` folder). title="hero-detail/hero-detail.component.ts" path="toh-pt6/src/app/hero-detail/hero-detail.component.ts"> </code-pane> - </code-tabs> {@a herosearchcomponent} @@ -1019,7 +991,6 @@ Here are the code files discussed on this page (all in the `src/app/` folder). #### _HeroSearchComponent_ <code-tabs> - <code-pane title="hero-search/hero-search.component.html" path="toh-pt6/src/app/hero-search/hero-search.component.html"> @@ -1032,7 +1003,6 @@ Here are the code files discussed on this page (all in the `src/app/` folder). title="hero-search/hero-search.component.css" path="toh-pt6/src/app/hero-search/hero-search.component.css"> </code-pane> - </code-tabs> ## Summary diff --git a/aio/tools/translator/bin/translate-one.ts b/aio/tools/translator/bin/translate-one.ts index c415acbfbd..0b79aecc04 100644 --- a/aio/tools/translator/bin/translate-one.ts +++ b/aio/tools/translator/bin/translate-one.ts @@ -3,5 +3,5 @@ import { dirs } from '../dirs'; import { translateFile } from '../translate'; -const filename = 'guide/testing.md'; +const filename = 'guide/aot-compiler.md'; translateFile(__dirname + '/../../../../../content-en/' + filename, dirs.content + filename); diff --git a/aio/tools/translator/dict-entry.ts b/aio/tools/translator/dict-entry.ts index b589995b4c..19a3466f57 100644 --- a/aio/tools/translator/dict-entry.ts +++ b/aio/tools/translator/dict-entry.ts @@ -2,4 +2,5 @@ export class DictEntry { original: string; translation: string; sourceFile?: string; + key: string; } diff --git a/aio/tools/translator/dict-latest.json b/aio/tools/translator/dict-latest.json index b039280077..54c1d76de8 100644 --- a/aio/tools/translator/dict-latest.json +++ b/aio/tools/translator/dict-latest.json @@ -1,43692 +1,51656 @@ [ { + "key": "##TRANSPILE", "original": "## Transpile", "translation": "## 转译(transpile)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/_fragments/glossary-t2.md" }, { + "key": "THEPROCESSOFTRANSFORMINGCODEWRITTENINONEFORMOFJAVASCRIPTSUCHASTYPESCRIPTINTOANOTHERFORMOFJAVASCRIPTSUCHASES5FRAGMENTSGLOSSARYT2#ES5", "original": "The process of transforming code written in one form of JavaScript\n(such as TypeScript) into another form of JavaScript (such as [ES5](_fragments/glossary-t2#es5)).", "translation": "把一种形式的 JavaScript(例如 TypeScript)转换成另一种形式的 JavaScript(例如 [ES5](_fragments/glossary-t2#es5))的过程。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/_fragments/glossary-t2.md" }, { + "key": "##TYPESCRIPT", "original": "## TypeScript", "translation": "## TypeScript 语言", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/_fragments/glossary-t2.md" }, { + "key": "AVERSIONOFJAVASCRIPTTHATSUPPORTSMOSTECMASCRIPT2015FRAGMENTSGLOSSARYT2#ES2015LANGUAGEFEATURESSUCHASDECORATORSFRAGMENTSGLOSSARYT2#DECORATOR", "original": "A version of JavaScript that supports most [ECMAScript 2015](_fragments/glossary-t2#es2015)\nlanguage features such as [decorators](_fragments/glossary-t2#decorator).", "translation": "JavaScript 的一个版本,支持了几乎所有 [ECMAScript 2015](_fragments/glossary-t2#ecmascript=2015) 语言特性,例如[装饰器 (decorator)](_fragments/glossary-t2#decorator))。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/_fragments/glossary-t2.md" }, { + "key": "TYPESCRIPTISALSONOTABLEFORITSOPTIONALTYPINGSYSTEMWHICHPROVIDESCOMPILETIMETYPECHECKINGANDSTRONGTOOLINGSUPPORTSUCHASINTELLISENSECODECOMPLETIONREFACTORINGANDINTELLIGENTSEARCHMANYCODEEDITORSANDIDESSUPPORTTYPESCRIPTEITHERNATIVELYORWITHPLUGINS", "original": "TypeScript is also notable for its optional typing system, which provides\ncompile-time type checking and strong tooling support (such as \"intellisense,\"\ncode completion, refactoring, and intelligent search). Many code editors\nand IDEs support TypeScript either natively or with plugins.", "translation": "TypeScript 还以它的可选类型系统而著称。\n该类型系统提供了编译时类型检查和强大的工具支持(例如 “Intellisense”,代码补齐,重构和智能搜索等)。\n许多代码编辑器和 IDE 都原生支持 TypeScript 或通过插件提供支持。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/_fragments/glossary-t2.md" }, { + "key": "TYPESCRIPTISTHEPREFERREDLANGUAGEFORANGULARDEVELOPMENTALTHOUGHYOUCANUSEOTHERJAVASCRIPTDIALECTSSUCHASES5FRAGMENTSGLOSSARYT2#ES5", "original": "TypeScript is the preferred language for Angular development, although\nyou can use other JavaScript dialects such as [ES5](_fragments/glossary-t2#es5).", "translation": "TypeScript 是 Angular 的首选语言,当然,你可以使用其它 JavaScript 方言,例如[ES5](_fragments/glossary-t2#es5)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/_fragments/glossary-t2.md" }, { + "key": "READMOREABOUTTYPESCRIPTATTYPESCRIPTLANGORGHTTP:WWWTYPESCRIPTLANGORG", "original": "Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).", "translation": "更多信息,见[typescript.org](http://www.typescriptlang.org/)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/_fragments/glossary-t2.md" }, { + "key": "#ANGULARJSTOANGULARQUICKREFERENCE", "original": "# AngularJS to Angular Quick Reference", "translation": "# 从 AngularJS 到 Angular 快速参考", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARISTHENAMEFORTHEANGULAROFTODAYANDTOMORROWANGULARJSISTHENAMEFORALLV1XVERSIONSOFANGULAR", "original": "_Angular_ is the name for the Angular of today and tomorrow.\n_AngularJS_ is the name for all v1.x versions of Angular.", "translation": "*Angular* 这个名字专指现在和未来的 Angular 版本,而 *AngularJS* 专指 Angular 的所有 v1.x 版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THISGUIDEHELPSYOUTRANSITIONFROMANGULARJSTOANGULARBYMAPPINGANGULARJSSYNTAXTOTHEEQUIVALENTANGULARSYNTAX", "original": "This guide helps you transition from AngularJS to Angular\nby mapping AngularJS syntax to the equivalent Angular syntax.", "translation": "本章提供了一个快速的参考指南,指出一些常用的 AngularJS 语法及其在 Angular 中的等价物。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "SEETHEANGULARSYNTAXINTHISLIVEEXAMPLENAMEAJSQUICKREFERENCELIVEEXAMPLE", "original": "**See the Angular syntax in this <live-example name=\"ajs-quick-reference\"></live-example>**.", "translation": "**参见 <live-example name=\"ajs-quick-reference\"></live-example> 以学习 Angular 语法**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "##TEMPLATEBASICS", "original": "## Template basics", "translation": "## 模板基础", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "TEMPLATESARETHEUSERFACINGPARTOFANANGULARAPPLICATIONANDAREWRITTENINHTMLTHEFOLLOWINGTABLELISTSSOMEOFTHEKEYANGULARJSTEMPLATEFEATURESWITHTHEIREQUIVALENTANGULARTEMPLATESYNTAX", "original": "Templates are the user-facing part of an Angular application and are written in HTML.\nThe following table lists some of the key AngularJS template features with their equivalent Angular template syntax.", "translation": "模板是 Angular 应用中的门面部分,它是用 HTML 写的。下表中是一些 AngularJS 中的关键模板特性及其在 Angular 中的等价语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###BINDINGSINTERPOLATION", "original": "### Bindings/interpolation", "translation": "### 绑定/插值表达式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSANEXPRESSIONINCURLYBRACESDENOTESONEWAYBINDINGTHISBINDSTHEVALUEOFTHEELEMENTTOAPROPERTYINTHECONTROLLERASSOCIATEDWITHTHISTEMPLATE", "original": "In AngularJS, an expression in curly braces denotes one-way binding.\n This binds the value of the element to a property in the controller\n associated with this template.", "translation": "在 AngularJS 中,花括号中的表达式代表单向绑定。\n 它把元素的值绑定到了与模板相关控制器的属性上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "WHENUSINGTHECONTROLLERASSYNTAXTHEBINDINGISPREFIXEDWITHTHECONTROLLERALIASVMORCTRLBECAUSEYOUHAVETOBESPECIFICABOUTTHESOURCEOFTHEBINDING", "original": "When using the `controller as` syntax,\n the binding is prefixed with the controller alias (`vm` or `$ctrl`) because you\n have to be specific about the source of the binding.", "translation": "当使用 `controller as` 语法时,该绑定需要用控制器的别名(`vm`)为前缀,这是因为你不得不通过它来指定绑定源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###BINDINGSINTERPOLATION", "original": "### Bindings/interpolation", "translation": "### 绑定/插值表达式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARATEMPLATEEXPRESSIONINCURLYBRACESSTILLDENOTESONEWAYBINDINGTHISBINDSTHEVALUEOFTHEELEMENTTOAPROPERTYOFTHECOMPONENTTHECONTEXTOFTHEBINDINGISIMPLIEDANDISALWAYSTHEASSOCIATEDCOMPONENTSOITNEEDSNOREFERENCEVARIABLE", "original": "In Angular, a template expression in curly braces still denotes one-way binding.\n This binds the value of the element to a property of the component.\n The context of the binding is implied and is always the\n associated component, so it needs no reference variable.", "translation": "在 Angular 中,花括号中的模板表达式同样代表单向绑定。\n 它把元素的值绑定到了组件的属性上。\n 它绑定的上下文变量是隐式的,并且总是关联到组件。\n 所以,它不需要一个引用变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHEINTERPOLATIONGUIDETEMPLATESYNTAX#INTERPOLATIONSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information, see the [Interpolation](guide/template-syntax#interpolation)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解更多,请参见[模板语法](guide/template-syntax)中的[插值表达式](guide/template-syntax#interpolation)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###FILTERS", "original": "### Filters", "translation": "### 过滤器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "TOFILTEROUTPUTINANGULARJSTEMPLATESUSETHEPIPECHARACTERANDONEORMOREFILTERS", "original": "To filter output in AngularJS templates, use the pipe character (|) and one or more filters.", "translation": "要在 AngularJS 中过滤输出,使用管道字符(|)以及一个或多个过滤器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THISEXAMPLEFILTERSTHETITLEPROPERTYTOUPPERCASE", "original": "This example filters the `title` property to uppercase.", "translation": "这个例子中把 `title` 属性过滤成了大写形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###PIPES", "original": "### Pipes", "translation": "### 管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARYOUUSESIMILARSYNTAXWITHTHEPIPECHARACTERTOFILTEROUTPUTBUTNOWYOUCALLTHEMPIPESMANYBUTNOTALLOFTHEBUILTINFILTERSFROMANGULARJSAREBUILTINPIPESINANGULAR", "original": "In Angular you use similar syntax with the pipe (|) character to filter output, but now you call them **pipes**.\n Many (but not all) of the built-in filters from AngularJS are\n built-in pipes in Angular.", "translation": "在 Angular 中,你使用类似的语法 —— 用管道字符(|)来过滤输出,但是现在直接把它叫做**管道**了。\n 很多(但不是所有)AngularJS 中的内置过滤器也成了 Angular 中的内置管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEEFILTERSPIPESGUIDEAJSQUICKREFERENCE#FILTERSPIPESBELOW", "original": "For more information, see [Filters/pipes](guide/ajs-quick-reference#filters-pipes) below.", "translation": "请参见下面[过滤器/管道](guide/ajs-quick-reference#filters-pipes)了解更多信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###LOCALVARIABLES", "original": "### Local variables", "translation": "### 局部变量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "HEREMOVIEISAUSERDEFINEDLOCALVARIABLE", "original": "Here, `movie` is a user-defined local variable.", "translation": "这里的 `movie` 是一个用户定义的局部变量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###INPUTVARIABLES", "original": "### Input variables", "translation": "### 输入变量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARHASTRUETEMPLATEINPUTVARIABLESTHATAREEXPLICITLYDEFINEDUSINGTHELETKEYWORD", "original": "Angular has true template input variables that are explicitly defined using the `let` keyword.", "translation": "Angular 有了真正的模板输入变量,它需要使用 `let` 关键字进行明确定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHENGFORMICROSYNTAXGUIDETEMPLATESYNTAX#MICROSYNTAXSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information, see the [ngFor micro-syntax](guide/template-syntax#microsyntax)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解更多信息,请参见[模板语法](guide/template-syntax)中的[ngFor 微语法](guide/template-syntax#microsyntax)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "##TEMPLATEDIRECTIVES", "original": "## Template directives", "translation": "## 模板指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARJSPROVIDESMORETHANSEVENTYBUILTINDIRECTIVESFORTEMPLATESMANYOFTHEMARENTNEEDEDINANGULARBECAUSEOFITSMORECAPABLEANDEXPRESSIVEBINDINGSYSTEMTHEFOLLOWINGARESOMEOFTHEKEYANGULARJSBUILTINDIRECTIVESANDTHEIREQUIVALENTSINANGULAR", "original": "AngularJS provides more than seventy built-in directives for templates.\nMany of them aren't needed in Angular because of its more capable and expressive binding system.\nThe following are some of the key AngularJS built-in directives and their equivalents in Angular.", "translation": "AngularJS 为模板提供了七十多个内置指令。\n在 Angular 中,它们很多都已经不需要了,因为 Angular 有了一个更加强大、快捷的绑定系统。\n下面是一些 AngularJS 中的关键指令及其在 Angular 中的等价物。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEAPPLICATIONSTARTUPPROCESSISCALLEDBOOTSTRAPPING", "original": "The application startup process is called **bootstrapping**.", "translation": "应用的启动过程被称为**引导**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ALTHOUGHYOUCANBOOTSTRAPANANGULARJSAPPINCODEMANYAPPLICATIONSBOOTSTRAPDECLARATIVELYWITHTHENGAPPDIRECTIVEGIVINGITTHENAMEOFTHEAPPLICATIONSMODULEMOVIEHUNTER", "original": "Although you can bootstrap an AngularJS app in code,\n many applications bootstrap declaratively with the `ng-app` directive,\n giving it the name of the application's module (`movieHunter`).", "translation": "虽然可以从代码中引导 Angular 应用,\n 但很多应用都是通过 `ng-app` 指令进行声明式引导的,只要给它一个应用模块的名字(`movieHunter`)就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###BOOTSTRAPPING", "original": "### Bootstrapping", "translation": "### 引导", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARDOESNTHAVEABOOTSTRAPDIRECTIVETOLAUNCHTHEAPPINCODEEXPLICITLYBOOTSTRAPTHEAPPLICATIONSROOTMODULEAPPMODULEINMAINTSANDTHEAPPLICATIONSROOTCOMPONENTAPPCOMPONENTINAPPMODULETS", "original": "Angular doesn't have a bootstrap directive.\n To launch the app in code, explicitly bootstrap the application's root module (`AppModule`)\n in `main.ts`\n and the application's root component (`AppComponent`) in `app.module.ts`.", "translation": "Angular 没有引导指令。\n 总是要通过显式调用一个 `bootstrap` 函数,并传入应用模块的名字(`AppComponent`)来启动应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGCLASSDIRECTIVEINCLUDESEXCLUDESCSSCLASSESBASEDONANEXPRESSIONTHATEXPRESSIONISOFTENAKEYVALUECONTROLOBJECTWITHEACHKEYOFTHEOBJECTDEFINEDASACSSCLASSNAMEANDEACHVALUEDEFINEDASATEMPLATEEXPRESSIONTHATEVALUATESTOABOOLEANVALUE", "original": "In AngularJS, the `ng-class` directive includes/excludes CSS classes\n based on an expression. That expression is often a key-value control object with each\n key of the object defined as a CSS class name, and each value defined as a template expression\n that evaluates to a Boolean value.", "translation": "在 AngularJS 中,`ng-class` 指令会基于一个表达式来包含/排除某些 CSS 类。该表达式通常是一个“键-值”型的控制对象,\n 对象中的每一个键代表一个 CSS 类名,每一个值定义为一个返回布尔值的模板表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHEFIRSTEXAMPLETHEACTIVECLASSISAPPLIEDTOTHEELEMENTIFISACTIVEISTRUE", "original": "In the first example, the `active` class is applied to the element if `isActive` is true.", "translation": "在第一个例子中,如果 `isActive` 为真,则 `active` 类被应用到那个元素上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "YOUCANSPECIFYMULTIPLECLASSESASSHOWNINTHESECONDEXAMPLE", "original": "You can specify multiple classes, as shown in the second example.", "translation": "就像第二个例子中所展示的那样,可以同时指定多个类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARTHENGCLASSDIRECTIVEWORKSSIMILARLYITINCLUDESEXCLUDESCSSCLASSESBASEDONANEXPRESSION", "original": "In Angular, the `ngClass` directive works similarly.\n It includes/excludes CSS classes based on an expression.", "translation": "在 Angular 中,`ngClass` 指令用类似的方式工作。\n 它根据一个表达式包含/排除某些 CSS 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHEFIRSTEXAMPLETHEACTIVECLASSISAPPLIEDTOTHEELEMENTIFISACTIVEISTRUE", "original": "In the first example, the `active` class is applied to the element if `isActive` is true.", "translation": "在第一个例子中,如果 `isActive` 为真,则 `active` 类被应用到那个元素上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "YOUCANSPECIFYMULTIPLECLASSESASSHOWNINTHESECONDEXAMPLE", "original": "You can specify multiple classes, as shown in the second example.", "translation": "就像第二个例子中所展示的那样,可以同时指定多个类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARALSOHASCLASSBINDINGWHICHISAGOODWAYTOADDORREMOVEASINGLECLASSASSHOWNINTHETHIRDEXAMPLE", "original": "Angular also has **class binding**, which is a good way to add or remove a single class,\n as shown in the third example.", "translation": "Angular 还有**类绑定**,它是单独添加或移除一个类的好办法 —— 就像第三个例子中展示的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHEATTRIBUTECLASSANDSTYLEBINDINGSGUIDETEMPLATESYNTAX#OTHERBINDINGSSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information see the [Attribute, class, and style bindings](guide/template-syntax#other-bindings)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解更多信息,参见[模板语法](guide/template-syntax)中的[属性、CSS 类和样式绑定](guide/template-syntax#other-bindings)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGCLICKDIRECTIVEALLOWSYOUTOSPECIFYCUSTOMBEHAVIORWHENANELEMENTISCLICKED", "original": "In AngularJS, the `ng-click` directive allows you to specify custom behavior when an element is clicked.", "translation": "在 AngularJS 中,`ng-click` 指令指定当元素被点击时的自定义行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHEFIRSTEXAMPLEWHENTHEUSERCLICKSTHEBUTTONTHETOGGLEIMAGEMETHODINTHECONTROLLERREFERENCEDBYTHEVMCONTROLLERASALIASISEXECUTED", "original": "In the first example, when the user clicks the button, the `toggleImage()` method in the controller referenced by the `vm` `controller as` alias is executed.", "translation": "在第一个例子中,如果用户点击了这个按钮,那么控制器的 `toggleImage()` 方法就会被执行,这个控制器是被 `controller as` 中指定的 `vm` 别名所引用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THESECONDEXAMPLEDEMONSTRATESPASSINGINTHEEVENTOBJECTWHICHPROVIDESDETAILSABOUTTHEEVENTTOTHECONTROLLER", "original": "The second example demonstrates passing in the `$event` object, which provides details about the event\n to the controller.", "translation": "第二个例子演示了传入 `$event` 对象,它提供了事件的详情,并被传到控制器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###BINDTOTHECLICKEVENT", "original": "### Bind to the `click` event", "translation": "### 绑定到 `click` 事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARJSEVENTBASEDDIRECTIVESDONOTEXISTINANGULARRATHERDEFINEONEWAYBINDINGFROMTHETEMPLATEVIEWTOTHECOMPONENTUSINGEVENTBINDING", "original": "AngularJS event-based directives do not exist in Angular.\n Rather, define one-way binding from the template view to the component using **event binding**.", "translation": "AngularJS 基于事件的指令在 Angular 中已经不存在了。\n 不过,可以使用**事件绑定**来定义从模板视图到组件的单向数据绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FOREVENTBINDINGDEFINETHENAMEOFTHETARGETEVENTWITHINPARENTHESISANDSPECIFYATEMPLATESTATEMENTINQUOTESTOTHERIGHTOFTHEEQUALSANGULARTHENSETSUPANEVENTHANDLERFORTHETARGETEVENTWHENTHEEVENTISRAISEDTHEHANDLEREXECUTESTHETEMPLATESTATEMENT", "original": "For event binding, define the name of the target event within parenthesis and\n specify a template statement, in quotes, to the right of the equals. Angular then\n sets up an event handler for the target event. When the event is raised, the handler\n executes the template statement.", "translation": "要使用事件绑定,把目标事件的名字放在圆括号中,并且使用等号右侧引号中的模板语句对它赋值。\n 然后 Angular 为这个目标时间设置事件处理器。当事件被触发时,这个处理器就会执行模板语句。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHEFIRSTEXAMPLEWHENAUSERCLICKSTHEBUTTONTHETOGGLEIMAGEMETHODINTHEASSOCIATEDCOMPONENTISEXECUTED", "original": "In the first example, when a user clicks the button, the `toggleImage()` method in the associated component is executed.", "translation": "在第一个例子中,当用户点击此按钮时,相关组件中的 `toggleImage()` 方法就被执行了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THESECONDEXAMPLEDEMONSTRATESPASSINGINTHEEVENTOBJECTWHICHPROVIDESDETAILSABOUTTHEEVENTTOTHECOMPONENT", "original": "The second example demonstrates passing in the `$event` object, which provides details about the event\n to the component.", "translation": "第二个例子演示了如何传入 `$event` 对象,它为组件提供了此事件的详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORALISTOFDOMEVENTSSEE:HTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBEVENTS", "original": "For a list of DOM events, see: https://developer.mozilla.org/en-US/docs/Web/Events.", "translation": "要查看 DOM 事件的列表,请参见[网络事件](https://developer.mozilla.org/en-US/docs/Web/Events)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHEEVENTBINDINGGUIDETEMPLATESYNTAX#EVENTBINDINGSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information, see the [Event binding](guide/template-syntax#event-binding)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解更多,请参见[模板语法](guide/template-syntax)中的[事件绑定](guide/template-syntax#event-binding)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGCONTROLLERDIRECTIVEATTACHESACONTROLLERTOTHEVIEWUSINGTHENGCONTROLLERORDEFININGTHECONTROLLERASPARTOFTHEROUTINGTIESTHEVIEWTOTHECONTROLLERCODEASSOCIATEDWITHTHATVIEW", "original": "In AngularJS, the `ng-controller` directive attaches a controller to the view.\n Using the `ng-controller` (or defining the controller as part of the routing) ties the\n view to the controller code associated with that view.", "translation": "在 AngularJS 中,`ng-controller` 指令把控制器附加到视图上。\n 使用 `ng-controller`(或把控制器定义为路由的一部分)把视图及其控制器的代码联系在一起。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###COMPONENTDECORATOR", "original": "### Component decorator", "translation": "### 组件装饰器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARTHETEMPLATENOLONGERSPECIFIESITSASSOCIATEDCONTROLLERRATHERTHECOMPONENTSPECIFIESITSASSOCIATEDTEMPLATEASPARTOFTHECOMPONENTCLASSDECORATOR", "original": "In Angular, the template no longer specifies its associated controller.\n Rather, the component specifies its associated template as part of the component class decorator.", "translation": "在 Angular 中,模板不用再指定它相关的控制器。\n 反过来,组件会在组件类的装饰器中指定与它相关的模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEEARCHITECTUREOVERVIEWGUIDEARCHITECTURE#COMPONENTS", "original": "For more information, see [Architecture Overview](guide/architecture#components).", "translation": "要了解更多,请参见[架构概览](guide/architecture#components)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGHIDEDIRECTIVESHOWSORHIDESTHEASSOCIATEDHTMLELEMENTBASEDONANEXPRESSIONFORMOREINFORMATIONSEENGSHOWGUIDEAJSQUICKREFERENCE#NGSHOW", "original": "In AngularJS, the `ng-hide` directive shows or hides the associated HTML element based on\n an expression. For more information, see [ng-show](guide/ajs-quick-reference#ng-show).", "translation": "在 AngularJS 中,`ng-hide` 指令会基于一个表达式显示或隐藏相关的 HTML 元素。\n 参见[ng-show](guide/ajs-quick-reference#ng-show)了解更多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###BINDTOTHEHIDDENPROPERTY", "original": "### Bind to the `hidden` property", "translation": "### 绑定到 `hidden` 属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARYOUUSEPROPERTYBINDINGTHEREISNOBUILTINHIDEDIRECTIVEFORMOREINFORMATIONSEENGSHOWGUIDEAJSQUICKREFERENCE#NGSHOW", "original": "In Angular, you use property binding; there is no built-in *hide* directive.\n For more information, see [ng-show](guide/ajs-quick-reference#ng-show).", "translation": "在 Angular 中,并没有一个内置的 *hide* 指令,可以改用属性绑定。\n 参见[ng-show](guide/ajs-quick-reference#ng-show)了解更多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THENGHREFDIRECTIVEALLOWSANGULARJSTOPREPROCESSTHEHREFPROPERTYSOTHATITCANREPLACETHEBINDINGEXPRESSIONWITHTHEAPPROPRIATEURLBEFORETHEBROWSERFETCHESFROMTHATURL", "original": "The `ng-href` directive allows AngularJS to preprocess the `href` property so that it\n can replace the binding expression with the appropriate URL before the browser\n fetches from that URL.", "translation": "`ng-href` 指令允许 AngularJS 对 `href` 属性进行预处理,以便它能在浏览器获取那个 URL 之前,使用一个返回适当 URL 的绑定表达式替换它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGHREFISOFTENUSEDTOACTIVATEAROUTEASPARTOFNAVIGATION", "original": "In AngularJS, the `ng-href` is often used to activate a route as part of navigation.", "translation": "在 AngularJS 中,`ng-href` 通常用来作为导航的一部分,激活一个路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ROUTINGISHANDLEDDIFFERENTLYINANGULAR", "original": "Routing is handled differently in Angular.", "translation": "路由在 Angular 中的处理方式不同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###BINDTOTHEHREFPROPERTY", "original": "### Bind to the `href` property", "translation": "### 绑定到 `href` 属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARUSESPROPERTYBINDINGTHEREISNOBUILTINHREFDIRECTIVEPLACETHEELEMENTSHREFPROPERTYINSQUAREBRACKETSANDSETITTOAQUOTEDTEMPLATEEXPRESSION", "original": "Angular uses property binding; there is no built-in *href* directive.\n Place the element's `href` property in square brackets and set it to a quoted template expression.", "translation": "在 Angular 中,并没有内置的 *href* 指令,改用属性绑定。\n 把元素的 `href` 属性放在方括号中,并把它设成一个引号中的模板表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHEPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDINGSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information see the [Property binding](guide/template-syntax#property-binding)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解[属性绑定](guide/template-syntax#property-binding)的更多知识,参见[模板语法](guide/template-syntax)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARHREFISNOLONGERUSEDFORROUTINGROUTINGUSESROUTERLINKASSHOWNINTHEFOLLOWINGEXAMPLE", "original": "In Angular, `href` is no longer used for routing. Routing uses `routerLink`, as shown in the following example.", "translation": "在 Angular 中,`href` 不再用作路由,而是改用第三个例子中所展示的 `routerLink` 指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONONROUTINGSEETHEROUTERLINKBINDINGGUIDEROUTER#ROUTERLINKSECTIONOFTHEROUTINGNAVIGATIONGUIDEROUTERPAGE", "original": "For more information on routing, see the [RouterLink binding](guide/router#router-link)\n section of the [Routing & Navigation](guide/router) page.", "translation": "要了解关于路由的更多信息,请参见[路由与导航](guide/router)的[RouterLink 绑定](guide/router#router-link)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGIFDIRECTIVEREMOVESORRECREATESAPORTIONOFTHEDOMBASEDONANEXPRESSIONIFTHEEXPRESSIONISFALSETHEELEMENTISREMOVEDFROMTHEDOM", "original": "In AngularJS, the `ng-if` directive removes or recreates a portion of the DOM,\n based on an expression. If the expression is false, the element is removed from the DOM.", "translation": "在 AngularJS 中,`ng-if` 指令会根据一个表达式来移除或重建 DOM 中的一部分。如果表达式为假,元素就会被从 DOM 中移除。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHISEXAMPLETHETABLEELEMENTISREMOVEDFROMTHEDOMUNLESSTHEMOVIESARRAYHASALENGTHGREATERTHANZERO", "original": "In this example, the `<table>` element is removed from the DOM unless the `movies` array has a length greater than zero.", "translation": "在这个例子中,除非 `movies` 数组的长度大于 0,否则 `<table>` 元素就会被从 DOM 中移除。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THENGIFDIRECTIVEINANGULARWORKSTHESAMEASTHENGIFDIRECTIVEINANGULARJSITREMOVESORRECREATESAPORTIONOFTHEDOMBASEDONANEXPRESSION", "original": "The `*ngIf` directive in Angular works the same as the `ng-if` directive in AngularJS. It removes\n or recreates a portion of the DOM based on an expression.", "translation": "Angular 中的 `*ngIf` 指令与 AngularJS 中的 `ng-if` 指令一样,\n 它根据表达式的值移除或重建 DOM 中的一部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHISEXAMPLETHETABLEELEMENTISREMOVEDFROMTHEDOMUNLESSTHEMOVIESARRAYHASALENGTH", "original": "In this example, the `<table>` element is removed from the DOM unless the `movies` array has a length.", "translation": "在这个例子中,除非 `movies` 数组的长度大于 0,否则 `<table>` 元素就会被从 DOM 中移除。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEBEFORENGIFISREQUIREDINTHISEXAMPLEFORMOREINFORMATIONSEESTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVES", "original": "The (*) before `ngIf` is required in this example.\n For more information, see [Structural Directives](guide/structural-directives).", "translation": "在这个例子中 `ngIf` 前的星号(*)是必须的。\n 要了解更多信息,参见[结构型指令](guide/structural-directives)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGMODELDIRECTIVEBINDSAFORMCONTROLTOAPROPERTYINTHECONTROLLERASSOCIATEDWITHTHETEMPLATETHISPROVIDESTWOWAYBINDINGWHEREBYANYCHANGEMADETOTHEVALUEINTHEVIEWISSYNCHRONIZEDWITHTHEMODELANDANYCHANGETOTHEMODELISSYNCHRONIZEDWITHTHEVALUEINTHEVIEW", "original": "In AngularJS, the `ng-model` directive binds a form control to a property in the controller associated with the template.\n This provides **two-way binding**, whereby any change made to the value in the view is synchronized with the model, and any change to the model is synchronized with the value in the view.", "translation": "在 Angular1 中,`ng-model` 指令把一个表单控件绑定到了模板相关控制器的一个属性上。\n 这提供了**双向绑定**功能,因此,任何对视图中值的改动,都会同步到模型中,对模型的改动,也会同步到视图中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARTWOWAYBINDINGISDENOTEDBYDESCRIPTIVELYREFERREDTOASABANANAINABOXTHISSYNTAXISASHORTCUTFORDEFININGBOTHPROPERTYBINDINGFROMTHECOMPONENTTOTHEVIEWANDEVENTBINDINGFROMTHEVIEWTOTHECOMPONENTTHEREBYPROVIDINGTWOWAYBINDING", "original": "In Angular, **two-way binding** is denoted by `[()]`, descriptively referred to as a \"banana in a box\". This syntax is a shortcut for defining both property binding (from the component to the view)\n and event binding (from the view to the component), thereby providing two-way binding.", "translation": "在 Angular 中,**双向绑定**使用[()]标记出来,它被形象的比作“盒子中的香蕉”。\n 这种语法是一个简写形式,用来同时定义一个属性绑定(从组件到视图)和一个事件绑定(从视图到组件),就成了双向绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONONTWOWAYBINDINGWITHNGMODELSEETHENGMODELMDASHTWOWAYBINDINGTOFORMELEMENTSWITHNGMODELGUIDETEMPLATESYNTAXHTML#NGMODELSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information on two-way binding with `ngModel`, see the [NgModel—Two-way binding to\n form elements with `[(ngModel)]`](../guide/template-syntax.html#ngModel)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解使用 ngModel 进行双向绑定的更多知识,参见[模板语法](guide/template-syntax)中的[NgModel—使用 `[(ngModel)]` 进行双向绑定](../guide/template-syntax.html#ngModel)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGREPEATDIRECTIVEREPEATSTHEASSOCIATEDDOMELEMENTFOREACHITEMINTHESPECIFIEDCOLLECTION", "original": "In AngularJS, the `ng-repeat` directive repeats the associated DOM element\n for each item in the specified collection.", "translation": "在 Angular1 中,`ng-repeat` 指令会为指定集合中的每一个条目重复渲染相关的 DOM 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHISEXAMPLETHETABLEROWTRELEMENTREPEATSFOREACHMOVIEOBJECTINTHECOLLECTIONOFMOVIES", "original": "In this example, the table row (`<tr>`) element repeats for each movie object in the collection of movies.", "translation": "在这个例子中,对 `movies` 集合中的每一个 `movie` 对象重复渲染了这个表格行元素(`<tr>`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THENGFORDIRECTIVEINANGULARISSIMILARTOTHENGREPEATDIRECTIVEINANGULARJSITREPEATSTHEASSOCIATEDDOMELEMENTFOREACHITEMINTHESPECIFIEDCOLLECTIONMOREACCURATELYITTURNSTHEDEFINEDELEMENTTRINTHISEXAMPLEANDITSCONTENTSINTOATEMPLATEANDUSESTHATTEMPLATETOINSTANTIATEAVIEWFOREACHITEMINTHELIST", "original": "The `*ngFor` directive in Angular is similar to the `ng-repeat` directive in AngularJS. It repeats\n the associated DOM element for each item in the specified collection.\n More accurately, it turns the defined element (`<tr>` in this example) and its contents into a template and\n uses that template to instantiate a view for each item in the list.", "translation": "Angular 中的 `*ngFor` 指令类似于 AngularJS 中的 `ng-repeat` 指令。\n 它为指定集合中的每一个条目重复渲染了相关的 DOM 元素。\n 更准确的说,它把被界定出来的元素(这个例子中是 `<tr>`)及其内容转成了一个模板,并使用那个模板来为列表中的每一个条目实例化一个视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "NOTICETHEOTHERSYNTAXDIFFERENCES:THEBEFORENGFORISREQUIREDTHELETKEYWORDIDENTIFIESMOVIEASANINPUTVARIABLETHELISTPREPOSITIONISOFNOTIN", "original": "Notice the other syntax differences:\n The (*) before `ngFor` is required;\n the `let` keyword identifies `movie` as an input variable;\n the list preposition is `of`, not `in`.", "translation": "请注意其它语法上的差异:\n 在 `ngFor` 前面的星号(*)是必须的;`let` 关键字把 `movie` 标记成一个输入变量;列表中使用的介词是 `of`,而不再是 `in`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEESTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVES", "original": "For more information, see [Structural Directives](guide/structural-directives).", "translation": "要了解更多信息,参见[结构性指令](guide/structural-directives)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGSHOWDIRECTIVESHOWSORHIDESTHEASSOCIATEDDOMELEMENTBASEDONANEXPRESSION", "original": "In AngularJS, the `ng-show` directive shows or hides the associated DOM element, based on\n an expression.", "translation": "在 AngularJS 中,`ng-show` 指令根据一个表达式来显示或隐藏相关的 DOM 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHISEXAMPLETHEDIVELEMENTISSHOWNIFTHEFAVORITEHEROVARIABLEISTRUTHY", "original": "In this example, the `<div>` element is shown if the `favoriteHero` variable is truthy.", "translation": "在这个例子中,如果 `favoriteHero` 变量为真,`<div>` 元素就会显示出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###BINDTOTHEHIDDENPROPERTY", "original": "### Bind to the `hidden` property", "translation": "### 绑定到 `hidden` 属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARUSESPROPERTYBINDINGTHEREISNOBUILTINSHOWDIRECTIVEFORHIDINGANDSHOWINGELEMENTSBINDTOTHEHTMLHIDDENPROPERTY", "original": "Angular uses property binding; there is no built-in *show* directive.\n For hiding and showing elements, bind to the HTML `hidden` property.", "translation": "在 Angular 中,并没有内置的 *show* 指令,可以改用属性绑定。\n 要隐藏或显示一个元素,绑定到它的 `hidden` 属性就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "TOCONDITIONALLYDISPLAYANELEMENTPLACETHEELEMENTSHIDDENPROPERTYINSQUAREBRACKETSANDSETITTOAQUOTEDTEMPLATEEXPRESSIONTHATEVALUATESTOTHEOPPOSITEOFSHOW", "original": "To conditionally display an element, place the element's `hidden` property in square brackets and\n set it to a quoted template expression that evaluates to the *opposite* of *show*.", "translation": "要想有条件的显示一个元素,就把该元素的 `hidden` 属性放到一个方括号里,并且把它设置为引号中的模板表达式,它的结果应该是与*显示*时*相反*的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHISEXAMPLETHEDIVELEMENTISHIDDENIFTHEFAVORITEHEROVARIABLEISNOTTRUTHY", "original": "In this example, the `<div>` element is hidden if the `favoriteHero` variable is not truthy.", "translation": "在这个例子中,如果 `favoriteHero` 变量不是真值,`<div>` 元素就会被隐藏。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONONPROPERTYBINDINGSEETHEPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDINGSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information on property binding, see the [Property binding](guide/template-syntax#property-binding)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解属性绑定的更多知识,参见[模板语法](guide/template-syntax)中的[属性绑定](guide/template-syntax#property-binding)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THENGSRCDIRECTIVEALLOWSANGULARJSTOPREPROCESSTHESRCPROPERTYSOTHATITCANREPLACETHEBINDINGEXPRESSIONWITHTHEAPPROPRIATEURLBEFORETHEBROWSERFETCHESFROMTHATURL", "original": "The `ng-src` directive allows AngularJS to preprocess the `src` property so that it\n can replace the binding expression with the appropriate URL before the browser\n fetches from that URL.", "translation": "`ng-src` 指令允许 AngularJS 对 `src` 属性进行预处理,以便它能够在浏览器获取此 URL 之前,用一个返回适当 URL 的绑定表达式替换它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###BINDTOTHESRCPROPERTY", "original": "### Bind to the `src` property", "translation": "### 绑定到 `src` 属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARUSESPROPERTYBINDINGTHEREISNOBUILTINSRCDIRECTIVEPLACETHESRCPROPERTYINSQUAREBRACKETSANDSETITTOAQUOTEDTEMPLATEEXPRESSION", "original": "Angular uses property binding; there is no built-in *src* directive.\n Place the `src` property in square brackets and set it to a quoted template expression.", "translation": "在 Angular 中,并没有一个内置的 *src* 指令,可以使用属性绑定。\n 把 `src` 属性放到方括号中,并且把它设为一个引号中的绑定表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONONPROPERTYBINDINGSEETHEPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDINGSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information on property binding, see the [Property binding](guide/template-syntax#property-binding)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解属性绑定的更多知识,参见[模板语法](guide/template-syntax)中的[属性绑定](guide/template-syntax#property-binding)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGSTYLEDIRECTIVESETSACSSSTYLEONANHTMLELEMENTBASEDONANEXPRESSIONTHATEXPRESSIONISOFTENAKEYVALUECONTROLOBJECTWITHEACHKEYOFTHEOBJECTDEFINEDASACSSPROPERTYANDEACHVALUEDEFINEDASANEXPRESSIONTHATEVALUATESTOAVALUEAPPROPRIATEFORTHESTYLE", "original": "In AngularJS, the `ng-style` directive sets a CSS style on an HTML element\n based on an expression. That expression is often a key-value control object with each\n key of the object defined as a CSS property, and each value defined as an expression\n that evaluates to a value appropriate for the style.", "translation": "在 AngularJS 中,`ng-style` 指令根据一个绑定表达式设置一个 HTML 元素的 CSS 样式。\n 该表达式通常是一个“键-值”形式的控制对象,对象的每个键都是一个 CSS 属性,每个值都是一个能计算为此样式的合适值的表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHEEXAMPLETHECOLORSTYLEISSETTOTHECURRENTVALUEOFTHECOLORPREFERENCEVARIABLE", "original": "In the example, the `color` style is set to the current value of the `colorPreference` variable.", "translation": "在这个例子中,`color` 样式被设置为 `colorPreference` 变量的当前值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARTHENGSTYLEDIRECTIVEWORKSSIMILARLYITSETSACSSSTYLEONANHTMLELEMENTBASEDONANEXPRESSION", "original": "In Angular, the `ngStyle` directive works similarly. It sets a CSS style on an HTML element based on an expression.", "translation": "在 Angular 中,`ngStyle` 指令的工作方式与此类似。它根据一个表达式设置 HTML 元素上的 CSS 样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHEFIRSTEXAMPLETHECOLORSTYLEISSETTOTHECURRENTVALUEOFTHECOLORPREFERENCEVARIABLE", "original": "In the first example, the `color` style is set to the current value of the `colorPreference` variable.", "translation": "在第一个例子中,`color` 样式被设置成了 `colorPreference` 变量的当前值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARALSOHASSTYLEBINDINGWHICHISGOODWAYTOSETASINGLESTYLETHISISSHOWNINTHESECONDEXAMPLE", "original": "Angular also has **style binding**, which is good way to set a single style. This is shown in the second example.", "translation": "Angular 还有**样式绑定**语法,它是单独设置一个样式的好方法。它展示在第二个例子中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONONSTYLEBINDINGSEETHESTYLEBINDINGGUIDETEMPLATESYNTAX#STYLEBINDINGSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information on style binding, see the [Style binding](guide/template-syntax#style-binding) section of the\n [Template Syntax](guide/template-syntax) page.", "translation": "要了解样式绑定的更多知识,参见[模板语法](guide/template-syntax)中的[样式绑定](guide/template-syntax#style-binding)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONONTHENGSTYLEDIRECTIVESEENGSTYLEGUIDETEMPLATESYNTAX#NGSTYLESECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information on the `ngStyle` directive, see [NgStyle](guide/template-syntax#ngStyle)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解关于 `ngStyle` 指令的更多知识,参见[模板语法](guide/template-syntax)中的[NgStyle](guide/template-syntax#ngStyle)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSTHENGSWITCHDIRECTIVESWAPSTHECONTENTSOFANELEMENTBYSELECTINGONEOFTHETEMPLATESBASEDONTHECURRENTVALUEOFANEXPRESSION", "original": "In AngularJS, the `ng-switch` directive swaps the contents of\n an element by selecting one of the templates based on the current value of an expression.", "translation": "在 Angular1 中,`ng-switch` 指令根据一个表达式的当前值把元素的内容替换成几个模板之一。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHISEXAMPLEIFFAVORITEHEROISNOTSETTHETEMPLATEDISPLAYSPLEASEENTERIFFAVORITEHEROISSETITCHECKSTHEMOVIEHEROBYCALLINGACONTROLLERMETHODIFTHATMETHODRETURNSTRUETHETEMPLATEDISPLAYSEXCELLENTCHOICEIFTHATMETHODSRETURNSFALSETHETEMPLATEDISPLAYSNOMOVIESORRY", "original": "In this example, if `favoriteHero` is not set, the template displays \"Please enter ...\".\n If `favoriteHero` is set, it checks the movie hero by calling a controller method.\n If that method returns `true`, the template displays \"Excellent choice!\".\n If that methods returns `false`, the template displays \"No movie, sorry!\".", "translation": "在这个例子中,如果 `favoriteHero` 没有设置,则模板显示“Please enter ...”。\n 如果 `favoriteHero` 设置过,它就会通过调用一个控制其方法来检查它是否电影里的英雄。\n 如果该方法返回 `true`,模板就会显示“Excellent choice!”。\n 如果该方法返回 `false`,该模板就会显示“No movie, sorry!”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARTHENGSWITCHDIRECTIVEWORKSSIMILARLYITDISPLAYSANELEMENTWHOSENGSWITCHCASEMATCHESTHECURRENTNGSWITCHEXPRESSIONVALUE", "original": "In Angular, the `ngSwitch` directive works similarly.\n It displays an element whose `*ngSwitchCase` matches the current `ngSwitch` expression value.", "translation": "在 Angular 中,`ngSwitch` 指令的工作方式与此类似。\n 它会显示那个与 `ngSwitch` 表达式的当前值匹配的那个 `*ngSwitchCase` 所在的元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INTHISEXAMPLEIFFAVORITEHEROISNOTSETTHENGSWITCHVALUEISNULLANDNGSWITCHDEFAULTDISPLAYSPLEASEENTERIFFAVORITEHEROISSETTHEAPPCHECKSTHEMOVIEHEROBYCALLINGACOMPONENTMETHODIFTHATMETHODRETURNSTRUETHEAPPSELECTSNGSWITCHCASETRUEANDDISPLAYS:EXCELLENTCHOICEIFTHATMETHODSRETURNSFALSETHEAPPSELECTSNGSWITCHCASEFALSEANDDISPLAYS:NOMOVIESORRY", "original": "In this example, if `favoriteHero` is not set, the `ngSwitch` value is `null`\n and `*ngSwitchDefault` displays, \"Please enter ...\".\n If `favoriteHero` is set, the app checks the movie hero by calling a component method.\n If that method returns `true`, the app selects `*ngSwitchCase=\"true\"` and displays: \"Excellent choice!\"\n If that methods returns `false`, the app selects `*ngSwitchCase=\"false\"` and displays: \"No movie, sorry!\"", "translation": "在这个例子中,如果 `favoriteHero` 没有设置,则 `ngSwitch` 的值是 `null`,\n `*ngSwitchDefault` 中会显示 “Please enter ...”。\n 如果设置了 `favoriteHero`,应用就会通过调用一个组件方法来检查电影英雄。\n 如果该方法返回 `true`,就会显示 “Excellent choice!”。\n 如果该方法返回 `false`,就会显示 “No movie, sorry!”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEBEFORENGSWITCHCASEANDNGSWITCHDEFAULTISREQUIREDINTHISEXAMPLE", "original": "The (*) before `ngSwitchCase` and `ngSwitchDefault` is required in this example.", "translation": "在这个例子中,`ngSwitchCase` 和 `ngSwitchDefault` 前面的星号(*)是必须的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHENGSWITCHDIRECTIVESGUIDETEMPLATESYNTAX#NGSWITCHSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "For more information, see [The NgSwitch directives](guide/template-syntax#ngSwitch)\n section of the [Template Syntax](guide/template-syntax) page.", "translation": "要了解更多信息,参见[模板语法](guide/template-syntax)中的[NgSwitch 指令](guide/template-syntax#ngSwitch)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "##FILTERSPIPES", "original": "## Filters/pipes", "translation": "## 过滤器/管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARPIPESPROVIDEFORMATTINGANDTRANSFORMATIONFORDATAINTHETEMPLATESIMILARTOANGULARJSFILTERSMANYOFTHEBUILTINFILTERSINANGULARJSHAVECORRESPONDINGPIPESINANGULARFORMOREINFORMATIONONPIPESSEEPIPESGUIDEPIPES", "original": "Angular **pipes** provide formatting and transformation for data in the template, similar to AngularJS **filters**.\nMany of the built-in filters in AngularJS have corresponding pipes in Angular.\nFor more information on pipes, see [Pipes](guide/pipes).", "translation": "Angular 中的**管道**为模板提供了格式化和数据转换功能,类似于 AngularJS 中的**过滤器**。\nAngularJS 中的很多内置过滤器在 Angular 中都有对应的管道。\n要了解管道的更多信息,参见[Pipes](guide/pipes)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMATSANUMBERASCURRENCY", "original": "Formats a number as currency.", "translation": "把一个数字格式化成货币。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEANGULARCURRENCYPIPEISSIMILARALTHOUGHSOMEOFTHEPARAMETERSHAVECHANGED", "original": "The Angular `currency` pipe is similar although some of the parameters have changed.", "translation": "Angular 的 `currency` 管道和 1 中很相似,只是有些参数变化了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMATSADATETOASTRINGBASEDONTHEREQUESTEDFORMAT", "original": "Formats a date to a string based on the requested format.", "translation": "基于要求的格式把日期格式化成字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEANGULARDATEPIPEISSIMILAR", "original": "The Angular `date` pipe is similar.", "translation": "Angular 的 `date` 管道和它很相似。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "SELECTSASUBSETOFITEMSFROMTHEDEFINEDCOLLECTIONBASEDONTHEFILTERCRITERIA", "original": "Selects a subset of items from the defined collection, based on the filter criteria.", "translation": "基于过滤条件从指定的集合中选取出一个子集。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###NONE", "original": "### none", "translation": "### 没了", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORPERFORMANCEREASONSNOCOMPARABLEPIPEEXISTSINANGULARDOALLYOURFILTERINGINTHECOMPONENTIFYOUNEEDTHESAMEFILTERINGCODEINSEVERALTEMPLATESCONSIDERBUILDINGACUSTOMPIPE", "original": "For performance reasons, no comparable pipe exists in Angular. Do all your filtering in the component. If you need the same filtering code in several templates, consider building a custom pipe.", "translation": "在 Angular 中,出于性能的考虑,并没有一个类似的管道。\n 过滤逻辑应该在组件中用代码实现。\n 如果它将被复用在几个模板中,可以考虑构建一个自定义管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "CONVERTSAJAVASCRIPTOBJECTINTOAJSONSTRINGTHISISUSEFULFORDEBUGGING", "original": "Converts a JavaScript object into a JSON string. This is useful for debugging.", "translation": "把一个 JavaScript 对象转换成一个 JSON 字符串。这对调试很有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEANGULARJSONPIPEDOESTHESAMETHING", "original": "The Angular `json` pipe does the same thing.", "translation": "Angular 的 `json` 管道做完全相同的事。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "SELECTSUPTOTHEFIRSTPARAMETER2NUMBEROFITEMSFROMTHECOLLECTIONSTARTINGOPTIONALLYATTHEBEGINNINGINDEX0", "original": "Selects up to the first parameter (2) number of items from the collection\n starting (optionally) at the beginning index (0).", "translation": "从集合中选择从(第二参数指定的)起始索引号(0)开始的最多(第一参数指定的)条目数(2)个条目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THESLICEPIPEDOESTHESAMETHINGBUTTHEORDEROFTHEPARAMETERSISREVERSEDINKEEPINGWITHTHEJAVASCRIPTSLICEMETHODTHEFIRSTPARAMETERISTHESTARTINGINDEXTHESECONDISTHELIMITASINANGULARJSCODINGTHISOPERATIONWITHINTHECOMPONENTINSTEADCOULDIMPROVEPERFORMANCE", "original": "The `SlicePipe` does the same thing but the *order of the parameters is reversed*, in keeping\n with the JavaScript `Slice` method.\n The first parameter is the starting index; the second is the limit.\n As in AngularJS, coding this operation within the component instead could improve performance.", "translation": "`SlicePipe` 做同样的事,但是*两个参数的顺序是相反的*,以便于 JavaScript 中的 `slice` 方法保持一致。\n 第一个参数是起始索引号,第二个参数是限制的数量。\n 和 AngularJS 中一样,如果们改用组件中的代码实现此操作,性能将会提升。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "CONVERTSTHESTRINGTOLOWERCASE", "original": "Converts the string to lowercase.", "translation": "把该字符串转成小写形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEANGULARLOWERCASEPIPEDOESTHESAMETHING", "original": "The Angular `lowercase` pipe does the same thing.", "translation": "Angular 的 `lowercase` 管道和 1 中的功能完全相同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMATSANUMBERASTEXT", "original": "Formats a number as text.", "translation": "把数字格式化为文本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEANGULARNUMBERPIPEISSIMILARITPROVIDESMOREFUNCTIONALITYWHENDEFININGTHEDECIMALPLACESASSHOWNINTHESECONDEXAMPLEABOVE", "original": "The Angular `number` pipe is similar.\n It provides more functionality when defining\n the decimal places, as shown in the second example above.", "translation": "Angular 的 `number` 管道很相似。\n 但在指定小数点位置时,它提供了更多的功能,如第二个范例所示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARALSOHASAPERCENTPIPEWHICHFORMATSANUMBERASALOCALPERCENTAGEASSHOWNINTHETHIRDEXAMPLE", "original": "Angular also has a `percent` pipe, which formats a number as a local percentage\n as shown in the third example.", "translation": "Angular 还有一个 `percent` 管道,它把一个数组格式化为本地化的(local)百分比格式,如第三个范例所示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "DISPLAYSTHECOLLECTIONINTHEORDERSPECIFIEDBYTHEEXPRESSIONINTHISEXAMPLETHEMOVIETITLEORDERSTHEMOVIELIST", "original": "Displays the collection in the order specified by the expression.\n In this example, the movie title orders the `movieList`.", "translation": "使用表达式中所指定的方式对集合进行排序。\n 在这个例子中,`movieList` 被根据 movie 的 title 排序了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###NONE", "original": "### none", "translation": "### 没了", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORPERFORMANCEREASONSNOCOMPARABLEPIPEEXISTSINANGULARINSTEADUSECOMPONENTCODETOORDERORSORTRESULTSIFYOUNEEDTHESAMEORDERINGORSORTINGCODEINSEVERALTEMPLATESCONSIDERBUILDINGACUSTOMPIPE", "original": "For performance reasons, no comparable pipe exists in Angular.\n Instead, use component code to order or sort results. If you need the same ordering or sorting code in several templates, consider building a custom pipe.", "translation": "在 Angular 中,出于性能的考虑,并没有一个类似的管道。\n 排序逻辑应该在组件中用代码实现。\n 如果它将被复用在几个模板中,可以考虑构建一个自定义管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "##MODULESCONTROLLERSCOMPONENTS", "original": "## Modules/controllers/components", "translation": "## 模块/控制器/组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INBOTHANGULARJSANDANGULARMODULESHELPYOUORGANIZEYOURAPPLICATIONINTOCOHESIVEBLOCKSOFFUNCTIONALITY", "original": "In both AngularJS and Angular, modules help you organize your application into cohesive blocks of functionality.", "translation": "无论在 AngularJS 还是 Angular 中,你都要借助“模块”来把应用拆分成一些紧密相关的功能块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSYOUWRITETHECODETHATPROVIDESTHEMODELANDTHEMETHODSFORTHEVIEWINACONTROLLERINANGULARYOUBUILDACOMPONENT", "original": "In AngularJS, you write the code that provides the model and the methods for the view in a **controller**.\nIn Angular, you build a **component**.", "translation": "在 AngularJS 中,你要在**控制器**中写代码,来为视图提供模型和方法。\n在 Angular 中,你要创建**组件**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "BECAUSEMUCHANGULARJSCODEISINJAVASCRIPTJAVASCRIPTCODEISSHOWNINTHEANGULARJSCOLUMNTHEANGULARCODEISSHOWNUSINGTYPESCRIPT", "original": "Because much AngularJS code is in JavaScript, JavaScript code is shown in the AngularJS column.\nThe Angular code is shown using TypeScript.", "translation": "因为很多 AngularJS 的代码是用 JavaScript 写的,所以在 AngularJS 列显示的是 JavaScript 代码,而 Angular 列显示的是 TypeScript 代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSANIMMEDIATELYINVOKEDFUNCTIONEXPRESSIONORIIFEAROUNDCONTROLLERCODEKEEPSITOUTOFTHEGLOBALNAMESPACE", "original": "In AngularJS, an immediately invoked function expression (or IIFE) around controller code\n keeps it out of the global namespace.", "translation": "在 AngularJS 中,用立即调用的函数表达式(IIFE)来包裹控制器代码可以让控制器代码不会污染全局命名空间。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###NONE", "original": "### none", "translation": "### 没了", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THISISANONISSUEINANGULARBECAUSEES2015MODULESHANDLETHENAMESPACINGFORYOU", "original": "This is a nonissue in Angular because ES 2015 modules\n handle the namespacing for you.", "translation": "在 Angular 中不用担心这个问题,因为使用 ES 2015 的模块,模块会替你处理命名空间问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONONMODULESSEETHEMODULESGUIDEARCHITECTURE#MODULESSECTIONOFTHEARCHITECTUREOVERVIEWGUIDEARCHITECTURE", "original": "For more information on modules, see the [Modules](guide/architecture#modules) section of the\n [Architecture Overview](guide/architecture).", "translation": "要了解关于模块的更多信息,参见[架构概览](guide/architecture)中的[模块](guide/architecture#modules)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###ANGULARMODULES", "original": "### Angular modules", "translation": "### Angular 模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSANANGULARMODULEKEEPSTRACKOFCONTROLLERSSERVICESANDOTHERCODETHESECONDARGUMENTDEFINESTHELISTOFOTHERMODULESTHATTHISMODULEDEPENDSUPON", "original": "In AngularJS, an Angular module keeps track of controllers, services, and other code.\n The second argument defines the list of other modules that this module depends upon.", "translation": "在 AngularJS 中,Angular 模块用来对控制器、服务和其它代码进行跟踪。第二个参数定义该模块依赖的其它模块列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "NGMODULESDEFINEDWITHTHENGMODULEDECORATORSERVETHESAMEPURPOSE:", "original": "NgModules, defined with the `NgModule` decorator, serve the same purpose:", "translation": "Angular 的模块用 `NgModule` 装饰器进行定义,有如下用途:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "IMPORTS:SPECIFIESTHELISTOFOTHERMODULESTHATTHISMODULEDEPENDSUPON", "original": "* `imports`: specifies the list of other modules that this module depends upon", "translation": "`imports`: 指定当前模块依赖的其它模块列表", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "DECLARATION:KEEPSTRACKOFYOURCOMPONENTSPIPESANDDIRECTIVES", "original": "* `declaration`: keeps track of your components, pipes, and directives.", "translation": "`declaration`: 用于记录组件、管道和指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONONMODULESSEENGMODULESGUIDENGMODULES", "original": "For more information on modules, see [NgModules](guide/ngmodules).", "translation": "要了解关于模块的更多知识,参见[NgModules](guide/ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###CONTROLLERREGISTRATION", "original": "### Controller registration", "translation": "### 控制器注册", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARJSHASCODEINEACHCONTROLLERTHATLOOKSUPANAPPROPRIATEANGULARMODULEANDREGISTERSTHECONTROLLERWITHTHATMODULE", "original": "AngularJS has code in each controller that looks up an appropriate Angular module\n and registers the controller with that module.", "translation": "在 AngularJS 中,在每个控制器中都有一些代码,用于找到合适的 Angular 模块并把该控制器注册进去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THEFIRSTARGUMENTISTHECONTROLLERNAMETHESECONDARGUMENTDEFINESTHESTRINGNAMESOFALLDEPENDENCIESINJECTEDINTOTHISCONTROLLERANDAREFERENCETOTHECONTROLLERFUNCTION", "original": "The first argument is the controller name. The second argument defines the string names of\n all dependencies injected into this controller, and a reference to the controller function.", "translation": "第一个参数是控制器的名称,第二个参数定义了所有将注入到该控制器的依赖的字符串名称,以及一个到控制器函数的引用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###COMPONENTDECORATOR", "original": "### Component decorator", "translation": "### 组件装饰器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARADDSADECORATORTOTHECOMPONENTCLASSTOPROVIDEANYREQUIREDMETADATATHECOMPONENTDECORATORDECLARESTHATTHECLASSISACOMPONENTANDPROVIDESMETADATAABOUTTHATCOMPONENTSUCHASITSSELECTORORTAGANDITSTEMPLATE", "original": "Angular adds a decorator to the component class to provide any required metadata.\n The `@Component` decorator declares that the class is a component and provides metadata about\n that component such as its selector (or tag) and its template.", "translation": "Angular 会往组件类上添加了一个装饰器,以提供所需的任何元数据。\n `@Component` 装饰器把该类声明为组件,并提供了关于该组件的元数据,比如它的选择器(或标签)和模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THISISHOWYOUASSOCIATEATEMPLATEWITHLOGICWHICHISDEFINEDINTHECOMPONENTCLASS", "original": "This is how you associate a template with logic, which is defined in the component class.", "translation": "这就是把模板关联到代码的方式,它定义在组件类中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHECOMPONENTSGUIDEARCHITECTURE#COMPONENTSSECTIONOFTHEARCHITECTUREOVERVIEWGUIDEARCHITECTUREPAGE", "original": "For more information, see the [Components](guide/architecture#components)\n section of the [Architecture Overview](guide/architecture) page.", "translation": "要了解关于组件的更多信息,参见[架构概览](guide/architecture)中的[组件](guide/architecture#components)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###CONTROLLERFUNCTION", "original": "### Controller function", "translation": "### 控制器函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSYOUWRITETHECODEFORTHEMODELANDMETHODSINACONTROLLERFUNCTION", "original": "In AngularJS, you write the code for the model and methods in a controller function.", "translation": "在 Angular1 中,你在控制器函数中编写模型和方法的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###COMPONENTCLASS", "original": "### Component class", "translation": "### 组件类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARYOUCREATEACOMPONENTCLASS", "original": "In Angular, you create a component class.", "translation": "在 Angular 中,你要创建组件类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "NOTE:IFYOUAREUSINGTYPESCRIPTWITHANGULARJSYOUMUSTUSETHEEXPORTKEYWORDTOEXPORTTHECOMPONENTCLASS", "original": "NOTE: If you are using TypeScript with AngularJS, you must use the `export` keyword to export the component class.", "translation": "注意:如果你正在用 TypeScript 写 AngularJS,那么必须用 `export` 关键字来导出组件类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHECOMPONENTSGUIDEARCHITECTURE#COMPONENTSSECTIONOFTHEARCHITECTUREOVERVIEWGUIDEARCHITECTUREPAGE", "original": "For more information, see the [Components](guide/architecture#components)\n section of the [Architecture Overview](guide/architecture) page.", "translation": "要了解关于组件的更多信息,参见[架构概览](guide/architecture)中的[组件](guide/architecture#components)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###DEPENDENCYINJECTION", "original": "### Dependency injection", "translation": "### 依赖注入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARJSYOUPASSINANYDEPENDENCIESASCONTROLLERFUNCTIONARGUMENTSTHISEXAMPLEINJECTSAMOVIESERVICE", "original": "In AngularJS, you pass in any dependencies as controller function arguments.\n This example injects a `MovieService`.", "translation": "在 AngularJS 中,你把所有依赖都作为控制器函数的参数。\n 这个例子注入了一个 `MovieService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "TOGUARDAGAINSTMINIFICATIONPROBLEMSTELLANGULAREXPLICITLYTHATITSHOULDINJECTANINSTANCEOFTHEMOVIESERVICEINTHEFIRSTPARAMETER", "original": "To guard against minification problems, tell Angular explicitly\n that it should inject an instance of the `MovieService` in the first parameter.", "translation": "为了防止在最小化时出现问题,第一个参数明确告诉 Angular 它应该注入一个 `MovieService` 的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###DEPENDENCYINJECTION", "original": "### Dependency injection", "translation": "### 依赖注入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARYOUPASSINDEPENDENCIESASARGUMENTSTOTHECOMPONENTCLASSCONSTRUCTORTHISEXAMPLEINJECTSAMOVIESERVICETHEFIRSTPARAMETERSTYPESCRIPTTYPETELLSANGULARWHATTOINJECTEVENAFTERMINIFICATION", "original": "In Angular, you pass in dependencies as arguments to the component class constructor.\n This example injects a `MovieService`.\n The first parameter's TypeScript type tells Angular what to inject, even after minification.", "translation": "在 Angular 中,你要把依赖作为组件构造函数的参数传入。\n 这个例子注入了一个 `MovieService`。\n 即使在最小化之后,第一个参数的 TypeScript 类型也会告诉 Angular 它该注入什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "FORMOREINFORMATIONSEETHEDEPENDENCYINJECTIONGUIDEARCHITECTURE#DEPENDENCYINJECTIONSECTIONOFTHEARCHITECTUREOVERVIEWGUIDEARCHITECTURE", "original": "For more information, see the [Dependency injection](guide/architecture#dependency-injection)\n section of the [Architecture Overview](guide/architecture).", "translation": "要了解关于依赖注入的更多信息,参见[架构概览](guide/architecture)中的[依赖注入](guide/architecture#dependency-injection)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "##STYLESHEETS", "original": "## Style sheets", "translation": "## 样式表", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "STYLESHEETSGIVEYOURAPPLICATIONANICELOOKINANGULARJSYOUSPECIFYTHESTYLESHEETSFORYOURENTIREAPPLICATIONASTHEAPPLICATIONGROWSOVERTIMETHESTYLESFORTHEMANYPARTSOFTHEAPPLICATIONMERGEWHICHCANCAUSEUNEXPECTEDRESULTSINANGULARYOUCANSTILLDEFINESTYLESHEETSFORYOURENTIREAPPLICATIONBUTNOWYOUCANALSOENCAPSULATEASTYLESHEETWITHINASPECIFICCOMPONENT", "original": "Style sheets give your application a nice look.\nIn AngularJS, you specify the style sheets for your entire application.\nAs the application grows over time, the styles for the many parts of the application\nmerge, which can cause unexpected results.\nIn Angular, you can still define style sheets for your entire application. But now you can\nalso encapsulate a style sheet within a specific component.", "translation": "样式表让你的应用程序看起来更漂亮。\n在 AngularJS 中,你要为整个应用程序指定样式表。\n随着应用程序的不断成长,为各个部分指定的样式会被合并,导致无法预计的后果。\n在 Angular 中,你仍然要为整个应用程序定义样式,不过现在也可以把样式表封装在特定的组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###LINKTAG", "original": "### Link tag", "translation": "### Link 标签", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "ANGULARJSUSESALINKTAGINTHEHEADSECTIONOFTHEINDEXHTMLFILETODEFINETHESTYLESFORTHEAPPLICATION", "original": "AngularJS, uses a `link` tag in the head section of the `index.html` file\n to define the styles for the application.", "translation": "AngularJS 在 `index.html` 的 `head` 区使用 `link` 标签来为应用程序定义样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "###STYLESCONFIGURATION", "original": "### Styles configuration", "translation": "### 样式配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "WITHTHEANGULARCLIYOUCANCONFIGUREYOURGLOBALSTYLESINTHEANGULARCLIJSONFILEYOUCANRENAMETHEEXTENSIONTOSCSSTOUSESASS", "original": "With the Angular CLI, you can configure your global styles in the `.angular-cli.json` file.\n You can rename the extension to `.scss` to use sass.", "translation": "使用 Angular CLI,你可以在 `.angular-cli.json` 文件中配置全局样式。\n 也可以把扩展名改为 `.scss` 来使用 sass。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "INANGULARYOUCANUSETHESTYLESORSTYLEURLSPROPERTYOFTHECOMPONENTMETADATATODEFINEASTYLESHEETFORAPARTICULARCOMPONENT", "original": "In Angular, you can use the `styles` or `styleUrls` property of the `@Component` metadata to define\n a style sheet for a particular component.", "translation": "在 Angular 中,你可以在 `@Component` 的元数据中使用 `styles` 或 `styleUrls` 属性来为一个特定的组件定义样式表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "THISALLOWSYOUTOSETAPPROPRIATESTYLESFORINDIVIDUALCOMPONENTSTHATWONTLEAKINTOOTHERPARTSOFTHEAPPLICATION", "original": "This allows you to set appropriate styles for individual components that won’t leak into\n other parts of the application.", "translation": "这让你可以为各个组件设置合适的样式,而不用担心它被泄漏到程序中的其它部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ajs-quick-reference.md" }, { + "key": "#ANIMATIONS", "original": "# Animations", "translation": "# 动画", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "MOTIONISANIMPORTANTASPECTINTHEDESIGNOFMODERNWEBAPPLICATIONSGOODUSERINTERFACESTRANSITIONSMOOTHLYBETWEENSTATESWITHENGAGINGANIMATIONSTHATCALLATTENTIONWHEREITSNEEDEDWELLDESIGNEDANIMATIONSCANMAKEAUINOTONLYMOREFUNBUTALSOEASIERTOUSE", "original": "Motion is an important aspect in the design of modern web applications. Good\nuser interfaces transition smoothly between states with engaging animations\nthat call attention where it's needed. Well-designed animations can make a UI not only\nmore fun but also easier to use.", "translation": "动画是现代 Web 应用设计中一个很重要的方面。好的用户界面要能在不同的状态之间更平滑的转场。如果需要,还可以用适当的动画来吸引注意力。\n设计良好的动画不但会让 UI 更有趣,还会让它更容易使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##OVERVIEW", "original": "## Overview", "translation": "## 概览", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ANGULARSANIMATIONSYSTEMLETSYOUBUILDANIMATIONSTHATRUNWITHTHESAMEKINDOFNATIVEPERFORMANCEFOUNDINPURECSSANIMATIONSYOUCANALSOTIGHTLYINTEGRATEYOURANIMATIONLOGICWITHTHERESTOFYOURAPPLICATIONCODEFOREASEOFCONTROL", "original": "Angular's animation system lets you build animations that run with the same kind of native\nperformance found in pure CSS animations. You can also tightly integrate your\nanimation logic with the rest of your application code, for ease of control.", "translation": "Angular 的动画系统赋予了制作各种动画效果的能力,以构建出与原生 CSS 动画性能相同的动画。\n你还获得了额外的让动画逻辑与其它应用代码紧紧集成在一起的能力,这让动画可以被更容易的触发与控制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ANGULARANIMATIONSAREBUILTONTOPOFTHESTANDARDWEBANIMATIONSAPIHTTPS:W3CGITHUBIOWEBANIMATIONSANDRUNNATIVELYONBROWSERSTHATSUPPORTITHTTP:CANIUSECOM#FEATWEBANIMATION", "original": "Angular animations are built on top of the standard [Web Animations API](https://w3c.github.io/web-animations/)\nand run natively on [browsers that support it](http://caniuse.com/#feat=web-animation).", "translation": "Angular 动画是基于标准的[Web 动画 API(Web Animations API)](https://w3c.github.io/web-animations/)构建的,它们在[支持此 API 的浏览器中](http://caniuse.com/#feat=web-animation)会用原生方式工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ASOFANGULAR6IFTHEWEBANIMATIONSAPIISNOTSUPPORTEDNATIVELYBYTHEBROWSERTHENANGULARWILLUSECSSKEYFRAMESASAFALLBACKINSTEADAUTOMATICALLYTHISMEANSTHATTHEPOLYFILLISNOLONGERREQUIREDUNLESSANYCODEUSESANIMATIONBUILDERAPIANIMATIONSANIMATIONBUILDERIFYOURCODEDOESUSEANIMATIONBUILDERTHENUNCOMMENTTHEWEBANIMATIONSJSPOLYFILLFROMTHEPOLYFILLSTSFILEGENERATEDBYANGULARCLI", "original": "As of Angular 6, If the Web Animations API is not supported natively by the browser, then Angular will use CSS\nkeyframes as a fallback instead (automatically). This means that the polyfill is no longer required unless any\ncode uses [AnimationBuilder](/api/animations/AnimationBuilder). If your code does use AnimationBuilder, then\nuncomment the `web-animations-js` polyfill from the `polyfills.ts` file generated by Angular CLI.", "translation": "对于 Angular 6,如果浏览器没有提供对 Web 动画 API 的原生支持,Angular 就会自动改用 CSS 的关键帧动画作为后备实现。这意味,除非要在代码中使用 [AnimationBuilder](/api/animations/AnimationBuilder) ,否则不必使用相关的腻子脚本。\n如果你要在代码中使用 AnimationBuilder ,就要从 Angular CLI 自动生成的 `polyfills.ts` 文件中反注释掉 `web-animations-js` 腻子脚本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEEXAMPLESINTHISPAGEAREAVAILABLEASALIVEEXAMPLELIVEEXAMPLE", "original": "The examples in this page are available as a <live-example></live-example>.", "translation": "本章中引用的这个例子可以到<live-example></live-example>去体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##SETUP", "original": "## Setup", "translation": "## 准备工作", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "BEFOREYOUCANADDANIMATIONSTOYOURAPPLICATIONYOUNEEDTOIMPORTAFEWANIMATIONSPECIFICMODULESANDFUNCTIONSTOTHEROOTAPPLICATIONMODULE", "original": "Before you can add animations to your application, you need\nto import a few animation-specific modules and functions to the root application module.", "translation": "在往应用中添加动画之前,你要首先在应用的根模块中引入一些与动画有关的模块和函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "####EXAMPLEBASICS", "original": "#### Example basics", "translation": "#### 基本例子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEANIMATIONSEXAMPLESINTHISGUIDEANIMATEALISTOFHEROES", "original": "The animations examples in this guide animate a list of heroes.", "translation": "这里的动画例子用来给英雄列表添加动画。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "AHEROCLASSHASANAMEPROPERTYASTATEPROPERTYTHATINDICATESIFTHEHEROISACTIVEORNOTANDATOGGLESTATEMETHODTOSWITCHBETWEENTHESTATES", "original": "A `Hero` class has a `name` property, a `state` property that indicates if the hero is active or not,\nand a `toggleState()` method to switch between the states.", "translation": "`Hero` 类有一个 `name` 属性、一个 `state` 属性(用于表明该英雄是否为激活状态)和一个 `toggleState()` 函数,用来在这两种状态之间切换。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ACROSSTHETOPOFTHESCREENAPPHEROTEAMBUILDERCOMPONENTTSAREASERIESOFBUTTONSTHATADDANDREMOVEHEROESFROMTHELISTVIATHEHEROSERVICETHEBUTTONSTRIGGERCHANGESTOTHELISTTHATALLOFTHEEXAMPLECOMPONENTSSEEATTHESAMETIME", "original": "Across the top of the screen (`app.hero-team-builder.component.ts`)\nare a series of buttons that add and remove heroes from the list (via the `HeroService`). \nThe buttons trigger changes to the list that all of the example components see at the same time.", "translation": "在屏幕的顶部(`app.hero-team-builder.component.ts`)是一系列按钮,用于从列表中添加和删除英雄(通过 `HeroService`)。\n这些按钮会引起列表的变化,同时可以看到列表中的所有范例组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##TRANSITIONINGBETWEENTWOSTATES", "original": "## Transitioning between two states", "translation": "## 快速起步范例:在两个状态间转场", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "YOUCANBUILDASIMPLEANIMATIONTHATTRANSITIONSANELEMENTBETWEENTWOSTATESDRIVENBYAMODELATTRIBUTE", "original": "You can build a simple animation that transitions an element between two states\ndriven by a model attribute.", "translation": "你可以构建一个简单的动画,它会让一个元素用模型驱动的方式在两个状态之间转场。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ANIMATIONSCANBEDEFINEDINSIDECOMPONENTMETADATA", "original": "Animations can be defined inside `@Component` metadata.", "translation": "动画会被定义在 `@Component` 元数据中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "WITHTHESEYOUCANDEFINEANANIMATIONTRIGGERCALLEDHEROSTATEINTHECOMPONENTMETADATAITUSESANIMATIONSTOTRANSITIONBETWEENTWOSTATES:ACTIVEANDINACTIVEWHENAHEROISACTIVETHEELEMENTAPPEARSINASLIGHTLYLARGERSIZEANDLIGHTERCOLOR", "original": "With these, you can define an *animation trigger* called `heroState` in the component\nmetadata. It uses animations to transition between two states: `active` and `inactive`. When a\nhero is active, the element appears in a slightly larger size and lighter color.", "translation": "通过这些,可以在组件元数据中定义一个名叫 `heroState` 的*动画触发器*。它在两个状态 `active` 和 `inactive` 之间进行转场。\n当英雄处于激活状态时,它会把该元素显示得稍微大一点、亮一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "INTHISEXAMPLEYOUAREDEFININGANIMATIONSTYLESCOLORANDTRANSFORMINLINEINTHEANIMATIONMETADATA", "original": "In this example, you are defining animation styles (color and transform) inline in the\nanimation metadata.", "translation": "在这个例子中,你在元数据中用内联的方式定义了动画样式(`color` 和 `transform`)。在即将到来的一个 Angular 版本中,还将支持从组件的 CSS 样式表中提取样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "NOWUSINGTHETRIGGERNAMESYNTAXATTACHTHEANIMATIONTHATYOUJUSTDEFINEDTOONEORMOREELEMENTSINTHECOMPONENTSTEMPLATE", "original": "Now, using the `[@triggerName]` syntax, attach the animation that you just defined to\none or more elements in the component's template.", "translation": "现在,使用 `[@triggerName]` 语法来把刚刚定义的动画附加到组件模板中一个或多个元素上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "HERETHEANIMATIONTRIGGERAPPLIESTOEVERYELEMENTREPEATEDBYANNGFOREACHOFTHEREPEATEDELEMENTSANIMATESINDEPENDENTLYTHEVALUEOFTHEATTRIBUTEISBOUNDTOTHEEXPRESSIONHEROSTATEANDISALWAYSEITHERACTIVEORINACTIVE", "original": "Here, the animation trigger applies to every element repeated by an `ngFor`. Each of\nthe repeated elements animates independently. The value of the\nattribute is bound to the expression `hero.state` and is always either `active` or `inactive`.", "translation": "这里,动画触发器被添加到了由 `ngFor` 重复出来的每一个元素上。每个重复出来的元素都有独立的动画效果。\n然后把 `@triggerName` 属性(Attribute)的值设置成表达式 `hero.state`。这个值应该是 `inactive` 或 `active` 之一。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "WITHTHISSETUPANANIMATEDTRANSITIONAPPEARSWHENEVERAHEROOBJECTCHANGESSTATEHERESTHEFULLCOMPONENTIMPLEMENTATION:", "original": "With this setup, an animated transition appears whenever a hero object changes state.\nHere's the full component implementation:", "translation": "通过这些设置,一旦英雄对象的状态发生了变化,就会触发一个转场动画。下面是完整的组件实现:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##STATESANDTRANSITIONS", "original": "## States and transitions", "translation": "## 状态与转场", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ANGULARANIMATIONSAREDEFINEDASLOGICALSTATESANDTRANSITIONSBETWEENSTATES", "original": "Angular animations are defined as logical **states** and **transitions**\nbetween states.", "translation": "Angular 动画是由**状态**和**状态之间的转场效果**所定义的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ANANIMATIONSTATEISASTRINGVALUETHATYOUDEFINEINYOURAPPLICATIONCODEINTHEEXAMPLEABOVETHESTATESACTIVEANDINACTIVEAREBASEDONTHELOGICALSTATEOFHEROOBJECTSTHESOURCEOFTHESTATECANBEASIMPLEOBJECTATTRIBUTEASITWASINTHISCASEORITCANBEAVALUECOMPUTEDINAMETHODTHEIMPORTANTTHINGISTHATYOUCANREADITINTOTHECOMPONENTSTEMPLATE", "original": "An animation state is a string value that you define in your application code. In the example\nabove, the states `'active'` and `'inactive'` are based on the logical state of\nhero objects. The source of the state can be a simple object attribute, as it was in this case,\nor it can be a value computed in a method. The important thing is that you can read it into the\ncomponent's template.", "translation": "动画状态是一个由程序代码中定义的字符串值。在上面的例子中,`'active'` 和 `'inactive'` 是基于英雄对象的逻辑状态的。\n状态的来源可以是像本例中这样简单的对象属性,也可以是由方法计算出来的值。重点是,你要能从组件模板中读取它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "YOUCANDEFINESTYLESFOREACHANIMATIONSTATE:", "original": "You can define *styles* for each animation state:", "translation": "你可以为每个动画状态定义了*一组样式*:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THESESTATEDEFINITIONSSPECIFYTHEENDSTYLESOFEACHSTATETHEYAREAPPLIEDTOTHEELEMENTONCEITHASTRANSITIONEDTOTHATSTATEANDSTAYASLONGASITREMAINSINTHATSTATEINEFFECTYOUREDEFININGWHATSTYLESTHEELEMENTHASINDIFFERENTSTATES", "original": "These `state` definitions specify the *end styles* of each state.\nThey are applied to the element once it has transitioned to that state, and stay\n*as long as it remains in that state*. In effect, you're defining what styles the element has in different states.", "translation": "这些 `state` 具体定义了每个状态的*最终样式*。一旦元素转场到那个状态,该样式就会被应用到此元素上,*当它留在此状态时*,这些样式也会一直保持着。\n从这个意义上讲,这里其实并不只是在定义动画,而是在定义该元素在不同状态时应该具有的样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "AFTERYOUDEFINESTATESYOUCANDEFINETRANSITIONSBETWEENTHESTATESEACHTRANSITIONCONTROLSTHETIMINGOFSWITCHINGBETWEENONESETOFSTYLESANDTHENEXT:", "original": "After you define states, you can define *transitions* between the states. Each transition\ncontrols the timing of switching between one set of styles and the next:", "translation": "定义完状态,就能定义在状态之间的各种*转场*了。每个转场都会控制一条在一组样式和下一组样式之间切换的时间线:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "IFSEVERALTRANSITIONSHAVETHESAMETIMINGCONFIGURATIONYOUCANCOMBINETHEMINTOTHESAMETRANSITIONDEFINITION:", "original": "If several transitions have the same timing configuration, you can combine\nthem into the same `transition` definition:", "translation": "如果多个转场都有同样的时间线配置,就可以把它们合并进同一个 `transition` 定义中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "WHENBOTHDIRECTIONSOFATRANSITIONHAVETHESAMETIMINGASINTHEPREVIOUSEXAMPLEYOUCANUSETHESHORTHANDSYNTAX:", "original": "When both directions of a transition have the same timing, as in the previous\nexample, you can use the shorthand syntax `<=>`:", "translation": "如果要对同一个转场的两个方向都使用相同的时间线(就像前面的例子中那样),就可以使用 `<=>` 这种简写语法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "YOUCANALSOAPPLYASTYLEDURINGANANIMATIONBUTNOTKEEPITAROUNDAFTERTHEANIMATIONFINISHESYOUCANDEFINESUCHSTYLESINLINEINTHETRANSITIONINTHISEXAMPLETHEELEMENTRECEIVESONESETOFSTYLESIMMEDIATELYANDISTHENANIMATEDTOTHENEXTWHENTHETRANSITIONFINISHESNONEOFTHESESTYLESAREKEPTBECAUSETHEYRENOTDEFINEDINASTATE", "original": "You can also apply a style during an animation but not keep it around\nafter the animation finishes. You can define such styles inline, in the `transition`. In this example,\nthe element receives one set of styles immediately and is then animated to the next.\nWhen the transition finishes, none of these styles are kept because they're not\ndefined in a `state`.", "translation": "有时希望一些样式只在动画期间生效,但在结束后并不保留它们。这时可以把这些样式内联在 `transition` 中进行定义。\n在这个例子中,该元素会立刻获得一组样式,然后动态转场到下一个状态。当转场结束时,这些样式并不会被保留,因为它们并没有被定义在 `state` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "###THEWILDCARDSTATE", "original": "### The wildcard state `*`", "translation": "### `*`(通配符)状态", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEWILDCARDSTATEMATCHESANYANIMATIONSTATETHISISUSEFULFORDEFININGSTYLESANDTRANSITIONSTHATAPPLYREGARDLESSOFWHICHSTATETHEANIMATIONISINFOREXAMPLE:", "original": "The `*` (\"wildcard\") state matches *any* animation state. This is useful for defining styles and\ntransitions that apply regardless of which state the animation is in. For example:", "translation": "`*`(通配符)状态匹配*任何*动画状态。当定义那些不需要管当前处于什么状态的样式及转场时,这很有用。比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEACTIVETRANSITIONAPPLIESWHENTHEELEMENTSSTATECHANGESFROMACTIVETOANYTHINGELSE", "original": "* The `active => *` transition applies when the element's state changes from `active` to anything else.", "translation": "当该元素的状态从 `active` 变成任何其它状态时,`active => *` 转场都会生效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THETRANSITIONAPPLIESWHENANYCHANGEBETWEENTWOSTATESTAKESPLACE", "original": "* The `* => *` transition applies when *any* change between two states takes place.", "translation": "当在*任意*两个状态之间切换时,`* => *` 转场都会生效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "###THEVOIDSTATE", "original": "### The `void` state", "translation": "### `void` 状态", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THESPECIALSTATECALLEDVOIDCANAPPLYTOANYANIMATIONITAPPLIESWHENTHEELEMENTISNOTATTACHEDTOAVIEWPERHAPSBECAUSEITHASNOTYETBEENADDEDORBECAUSEITHASBEENREMOVEDTHEVOIDSTATEISUSEFULFORDEFININGENTERANDLEAVEANIMATIONS", "original": "The special state called `void` can apply to any animation. It applies\nwhen the element is *not* attached to a view, perhaps because it has not yet been\nadded or because it has been removed. The `void` state is useful for defining enter and\nleave animations.", "translation": "有一种叫做 `void` 的特殊状态,它可以应用在任何动画中。它表示元素*没有*被附加到视图。这种情况可能是由于它尚未被添加进来或者已经被移除了。\n`void` 状态在定义“进场”和“离场”的动画时会非常有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "FOREXAMPLETHEVOIDTRANSITIONAPPLIESWHENTHEELEMENTLEAVESTHEVIEWREGARDLESSOFWHATSTATEITWASINBEFOREITLEFT", "original": "For example the `* => void` transition applies when the element leaves the view,\nregardless of what state it was in before it left.", "translation": "比如当一个元素离开视图时,`* => void` 转场就会生效,而不管它在离场以前是什么状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEWILDCARDSTATEALSOMATCHESVOID", "original": "The wildcard state `*` also matches `void`.", "translation": "`*` 通配符状态也能匹配 `void`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##EXAMPLE:ENTERINGANDLEAVING", "original": "## Example: Entering and leaving", "translation": "## 例子:进场与离场", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "USINGTHEVOIDANDSTATESYOUCANDEFINETRANSITIONSTHATANIMATETHEENTERINGANDLEAVINGOFELEMENTS:", "original": "Using the `void` and `*` states you can define transitions that animate the\nentering and leaving of elements:", "translation": "使用 `void` 和 `*` 状态,可以定义元素进场与离场时的转场动画:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ENTER:VOID", "original": "* Enter: `void => *`", "translation": "进场:`void => *`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "LEAVE:VOID", "original": "* Leave: `* => void`", "translation": "离场:`* => void`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "FOREXAMPLEINTHEANIMATIONSARRAYBELOWTHEREARETWOTRANSITIONSTHATUSETHEVOIDANDVOIDSYNTAXTOANIMATETHEELEMENTINANDOUTOFTHEVIEW", "original": "For example, in the `animations` array below there are two transitions that use\nthe `void => *` and `* => void` syntax to animate the element in and out of the view.", "translation": "例如,在下面的 `animations` 数组中,这两个转场语句使用 `void => *` 和 `* => void` 语法来让该元素以动画形式进入和离开当前视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "NOTETHATINTHISCASETHESTYLESAREAPPLIEDTOTHEVOIDSTATEDIRECTLYINTHETRANSITIONDEFINITIONSANDNOTINASEPARATESTATEVOIDDEFINITIONTHUSTHETRANSFORMSAREDIFFERENTONENTERANDLEAVE:THEELEMENTENTERSFROMTHELEFTANDLEAVESTOTHERIGHT", "original": "Note that in this case the styles are applied to the void state directly in the\ntransition definitions, and not in a separate `state(void)` definition. Thus, the transforms\nare different on enter and leave: the element enters from the left\nand leaves to the right.", "translation": "注意,在这个例子中,这些样式在转场定义中被直接应用到了 `void` 状态,但并没有一个单独的 `state(void)` 定义。\n这么做是因为希望在进场与离场时使用不一样的转换效果:元素从左侧进场,从右侧离开。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THESETWOCOMMONANIMATIONSHAVETHEIROWNALIASES:", "original": "These two common animations have their own aliases:", "translation": "这两个常见的动画有自己的别名:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##EXAMPLE:ENTERINGANDLEAVINGFROMDIFFERENTSTATES", "original": "## Example: Entering and leaving from different states", "translation": "## 范例:从不同的状态下进场和离场", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "YOUCANALSOCOMBINETHISANIMATIONWITHTHEEARLIERSTATETRANSITIONANIMATIONBYUSINGTHEHEROSTATEASTHEANIMATIONSTATETHISLETSYOUCONFIGUREDIFFERENTTRANSITIONSFORENTERINGANDLEAVINGBASEDONWHATTHESTATEOFTHEHEROIS:", "original": "You can also combine this animation with the earlier state transition animation by\nusing the hero state as the animation state. This lets you configure\ndifferent transitions for entering and leaving based on what the state of the hero\nis:", "translation": "通过把英雄的状态用作动画的状态,还能把该动画跟以前的转场动画组合成一个复合动画。这让你能根据该英雄的当前状态为其配置不同的进场与离场动画:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "INACTIVEHEROENTER:VOIDINACTIVE", "original": "* Inactive hero enter: `void => inactive`", "translation": "非激活英雄进场:`void => inactive`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ACTIVEHEROENTER:VOIDACTIVE", "original": "* Active hero enter: `void => active`", "translation": "激活英雄进场:`void => active`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "INACTIVEHEROLEAVE:INACTIVEVOID", "original": "* Inactive hero leave: `inactive => void`", "translation": "非激活英雄离场:`inactive => void`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ACTIVEHEROLEAVE:ACTIVEVOID", "original": "* Active hero leave: `active => void`", "translation": "激活英雄离场:`active => void`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THISGIVESYOUFINEGRAINEDCONTROLOVEREACHTRANSITION:", "original": "This gives you fine-grained control over each transition:", "translation": "现在就对每一种转场都有了细粒度的控制:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##ANIMATABLEPROPERTIESANDUNITS", "original": "## Animatable properties and units", "translation": "## 可动的(Animatable)属性与单位", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "SINCEANGULARSANIMATIONSUPPORTBUILDSONTOPOFWEBANIMATIONSYOUCANANIMATEANYPROPERTYTHATTHEBROWSERCONSIDERSANIMATABLETHISINCLUDESPOSITIONSSIZESTRANSFORMSCOLORSBORDERSANDMANYOTHERSTHEW3CMAINTAINSALISTOFANIMATABLEPROPERTIESHTTPS:WWWW3ORGTRCSS3TRANSITIONS#ANIMATABLEPROPERTIESONITSCSSTRANSITIONSPAGEHTTPS:WWWW3ORGTRCSS3TRANSITIONS", "original": "Since Angular's animation support builds on top of Web Animations, you can animate any property\nthat the browser considers *animatable*. This includes positions, sizes, transforms, colors,\nborders, and many others. The W3C maintains\n[a list of animatable properties](https://www.w3.org/TR/css3-transitions/#animatable-properties)\non its [CSS Transitions page](https://www.w3.org/TR/css3-transitions).", "translation": "由于 Angular 的动画支持是基于 Web Animations 标准的,所以也能支持浏览器认为可以*参与动画*的任何属性。这些属性包括位置(position)、大小(size)、变换(transform)、颜色(color)、边框(border)等很多属性。W3C 维护着\n[一个“可动”属性列表](https://www.w3.org/TR/css3-transitions/#animatable-properties)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "FORPOSITIONALPROPERTIESTHATHAVEANUMERICVALUEYOUCANDEFINEAUNITBYPROVIDINGTHEVALUEASASTRINGWITHTHEAPPROPRIATESUFFIX:", "original": "For positional properties that have a numeric value, you can define a unit by providing\nthe value as a string with the appropriate suffix:", "translation": "尺寸类属性(如位置、大小、边框等)包括一个数字值和一个用来定义长度单位的后缀:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "IFYOUDONTPROVIDEAUNITWHENSPECIFYINGDIMENSIONANGULARASSUMESTHEDEFAULTOFPX:", "original": "If you don't provide a unit when specifying dimension, Angular assumes the default of `px`:", "translation": "对大多数尺寸类属性而言,还能只定义一个数字,那就表示它使用的是像素(px)数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "50ISTHESAMEASSAYING50PX", "original": "* `50` is the same as saying `'50px'`", "translation": "`50` 相当于 `'50px'`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##AUTOMATICPROPERTYCALCULATION", "original": "## Automatic property calculation", "translation": "## 自动属性值计算", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "SOMETIMESYOUDONTKNOWTHEVALUEOFADIMENSIONALSTYLEPROPERTYUNTILRUNTIMEFOREXAMPLEELEMENTSOFTENHAVEWIDTHSANDHEIGHTSTHATDEPENDONTHEIRCONTENTANDTHESCREENSIZETHESEPROPERTIESAREOFTENTRICKYTOANIMATEWITHCSS", "original": "Sometimes you don't know the value of a dimensional style property until runtime.\nFor example, elements often have widths and heights that\ndepend on their content and the screen size. These properties are often tricky\nto animate with CSS.", "translation": "有时候,你在开始运行之前都无法知道某个样式属性的值。比如,元素的宽度和高度往往依赖于它们的内容和屏幕的尺寸。处理这些属性对 CSS 动画而言通常是相当棘手的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "INTHESECASESYOUCANUSEASPECIALPROPERTYVALUESOTHATTHEVALUEOFTHEPROPERTYISCOMPUTEDATRUNTIMEANDTHENPLUGGEDINTOTHEANIMATION", "original": "In these cases, you can use a special `*` property value so that the value of the\nproperty is computed at runtime and then plugged into the animation.", "translation": "如果用 Angular 动画,就可以用一个特殊的 `*` 属性值来处理这种情况。该属性的值将会在运行期被计算出来,然后插入到这个动画中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "INTHISEXAMPLETHELEAVEANIMATIONTAKESWHATEVERHEIGHTTHEELEMENTHASBEFOREITLEAVESANDANIMATESFROMTHATHEIGHTTOZERO:", "original": "In this example, the leave animation takes whatever height the element has before it\nleaves and animates from that height to zero:", "translation": "这个例子中的“离场”动画会取得该元素在离场前的高度,并且把它从这个高度用动画转场到 0 高度:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##ANIMATIONTIMING", "original": "## Animation timing", "translation": "## 动画时间线", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEREARETHREETIMINGPROPERTIESYOUCANTUNEFOREVERYANIMATEDTRANSITION:THEDURATIONTHEDELAYANDTHEEASINGFUNCTIONTHEYAREALLCOMBINEDINTOASINGLETRANSITIONTIMINGSTRING", "original": "There are three timing properties you can tune for every animated transition:\nthe duration, the delay, and the easing function. They are all combined into\na single transition *timing string*.", "translation": "对每一个动画转场效果,有三种时间线属性可以调整:持续时间(duration)、延迟(delay)和缓动(easing)函数。它们被合并到了一个单独的*转场时间线字符串*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "###DURATION", "original": "### Duration", "translation": "### 持续时间", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEDURATIONCONTROLSHOWLONGTHEANIMATIONTAKESTORUNFROMSTARTTOFINISHYOUCANDEFINEADURATIONINTHREEWAYS:", "original": "The duration controls how long the animation takes to run from start to finish.\nYou can define a duration in three ways:", "translation": "持续时间控制动画从开始到结束要花多长时间。可以用三种方式定义持续时间:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ASAPLAINNUMBERINMILLISECONDS:100", "original": "* As a plain number, in milliseconds: `100`", "translation": "作为一个普通数字,以毫秒为单位,如:`100`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "INASTRINGASMILLISECONDS:100MS", "original": "* In a string, as milliseconds: `'100ms'`", "translation": "作为一个字符串,以毫秒为单位,如:`'100ms'`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "INASTRINGASSECONDS:01S", "original": "* In a string, as seconds: `'0.1s'`", "translation": "作为一个字符串,以秒为单位,如:`'0.1s'`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "###DELAY", "original": "### Delay", "translation": "### 延迟", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEDELAYCONTROLSTHELENGTHOFTIMEBETWEENTHEANIMATIONTRIGGERANDTHEBEGINNINGOFTHETRANSITIONYOUCANDEFINEONEBYADDINGITTOTHESAMESTRINGFOLLOWINGTHEDURATIONITALSOHASTHESAMEFORMATOPTIONSASTHEDURATION:", "original": "The delay controls the length of time between the animation trigger and the beginning\nof the transition. You can define one by adding it to the same string\nfollowing the duration. It also has the same format options as the duration:", "translation": "延迟控制的是在动画已经触发但尚未真正开始转场之前要等待多久。可以把它添加到字符串中的持续时间后面,它的选项格式也跟持续时间是一样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "WAITFOR100MSANDTHENRUNFOR200MS:02S100MS", "original": "* Wait for 100ms and then run for 200ms: `'0.2s 100ms'`", "translation": "等待 100 毫秒,然后运行 200 毫秒:`'0.2s 100ms'`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "###EASING", "original": "### Easing", "translation": "### 缓动函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THEEASINGFUNCTIONHTTP:EASINGSNETCONTROLSHOWTHEANIMATIONACCELERATESANDDECELERATESDURINGITSRUNTIMEFOREXAMPLEANEASEINFUNCTIONCAUSESTHEANIMATIONTOBEGINRELATIVELYSLOWLYBUTPICKUPSPEEDASITPROGRESSESYOUCANCONTROLTHEEASINGBYADDINGITASATHIRDVALUEINTHESTRINGAFTERTHEDURATIONANDTHEDELAYORASTHESECONDVALUEWHENTHEREISNODELAY:", "original": "The [easing function](http://easings.net/) controls how the animation accelerates\nand decelerates during its runtime. For example, an `ease-in` function causes\nthe animation to begin relatively slowly but pick up speed as it progresses. You\ncan control the easing by adding it as a *third* value in the string after the duration\nand the delay (or as the *second* value when there is no delay):", "translation": "[缓动函数](http://easings.net/)用于控制动画在运行期间如何加速和减速。比如:使用 `ease-in` 函数意味着动画开始时相对缓慢,然后在进行中逐步加速。可以通过在这个字符串中的持续时间和延迟后面添加*第三个*值来控制使用哪个缓动函数(如果没有定义延迟就作为*第二个*值)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "WAITFOR100MSANDTHENRUNFOR200MSWITHEASING:02S100MSEASEOUT", "original": "* Wait for 100ms and then run for 200ms, with easing: `'0.2s 100ms ease-out'`", "translation": "等待 100 毫秒,然后运行 200 毫秒,并且带缓动:`'0.2s 100ms ease-out'`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "RUNFOR200MSWITHEASING:02SEASEINOUT", "original": "* Run for 200ms, with easing: `'0.2s ease-in-out'`", "translation": "运行 200 毫秒,并且带缓动:`'0.2s ease-in-out'`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "###EXAMPLE", "original": "### Example", "translation": "### 例子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "HEREAREACOUPLEOFCUSTOMTIMINGSINACTIONBOTHENTERANDLEAVELASTFOR200MILLISECONDSTHATIS02SBUTTHEYHAVEDIFFERENTEASINGSTHELEAVEBEGINSAFTERASLIGHTDELAYOF10MILLISECONDSASSPECIFIEDIN02S10EASEOUT:", "original": "Here are a couple of custom timings in action. Both enter and leave last for\n200 milliseconds, that is `0.2s`, but they have different easings. The leave begins after a\nslight delay of 10 milliseconds as specified in `'0.2s 10 ease-out'`:", "translation": "这里是两个自定义时间线的动态演示。“进场”和“离场”都持续 200 毫秒,也就是 `0.2s`,但它们有不同的缓动函数。“离场”动画会在 100 毫秒的延迟之后开始,也就是 `'0.2s 10 ease-out'`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##MULTISTEPANIMATIONSWITHKEYFRAMES", "original": "## Multi-step animations with keyframes", "translation": "## 基于关键帧(Keyframes)的多阶段动画", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ANIMATIONKEYFRAMESGOBEYONDASIMPLETRANSITIONTOAMOREINTRICATEANIMATIONTHATGOESTHROUGHONEORMOREINTERMEDIATESTYLESWHENTRANSITIONINGBETWEENTWOSETSOFSTYLES", "original": "Animation *keyframes* go beyond a simple transition to a more intricate animation\nthat goes through one or more intermediate styles when transitioning between two sets of styles.", "translation": "通过定义动画的*关键帧*,可以把两组样式之间的简单转场,升级成一种更复杂的动画,它会在转场期间经历一个或多个中间样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "FOREACHKEYFRAMEYOUSPECIFYANOFFSETTHATDEFINESATWHICHPOINTINTHEANIMATIONTHATKEYFRAMEAPPLIESTHEOFFSETISANUMBERBETWEENZEROWHICHMARKSTHEBEGINNINGOFTHEANIMATIONANDONEWHICHMARKSTHEEND", "original": "For each keyframe, you specify an *offset* that defines at which point\nin the animation that keyframe applies. The offset is a number between zero,\nwhich marks the beginning of the animation, and one, which marks the end.", "translation": "每个关键帧都可以被指定一个*偏移量*,用来定义该关键帧将被用在动画期间的哪个时间点。偏移量是一个介于 0(表示动画起点)和 1(表示动画终点)之间的数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THISEXAMPLEADDSSOMEBOUNCETOTHEENTERANDLEAVEANIMATIONSWITHKEYFRAMES:", "original": "This example adds some \"bounce\" to the enter and leave animations with\nkeyframes:", "translation": "这个例子使用关键帧来为进场和离场动画添加一些“反弹效果”:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "NOTETHATTHEOFFSETSARENOTDEFINEDINTERMSOFABSOLUTETIMETHEYARERELATIVEMEASURESFROMZEROTOONETHEFINALTIMELINEOFTHEANIMATIONISBASEDONTHECOMBINATIONOFKEYFRAMEOFFSETSDURATIONDELAYANDEASING", "original": "Note that the offsets are *not* defined in terms of absolute time. They are relative\nmeasures from zero to one. The final timeline of the animation is based on the combination\nof keyframe offsets, duration, delay, and easing.", "translation": "注意,这个偏移量并*不是*用绝对数字定义的时间段,而是在 0 到 1 之间的相对值(百分比)。动画的最终时间线会基于关键帧的偏移量、持续时间、延迟和缓动函数计算出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "DEFININGOFFSETSFORKEYFRAMESISOPTIONALIFYOUOMITTHEMOFFSETSWITHEVENSPACINGAREAUTOMATICALLYASSIGNEDFOREXAMPLETHREEKEYFRAMESWITHOUTPREDEFINEDOFFSETSRECEIVEOFFSETS005AND1", "original": "Defining offsets for keyframes is optional. If you omit them, offsets with even\nspacing are automatically assigned. For example, three keyframes without predefined\noffsets receive offsets `0`, `0.5`, and `1`.", "translation": "为关键帧定义偏移量是可选的。如果省略它们,偏移量会自动根据帧数平均分布出来。例如,三个未定义过偏移量的关键帧会分别获得偏移量:`0`、`0.5` 和 `1`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##PARALLELANIMATIONGROUPS", "original": "## Parallel animation groups", "translation": "## 并行动画组(Group)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "YOUVESEENHOWTOANIMATEMULTIPLESTYLEPROPERTIESATTHESAMETIME:JUSTPUTALLOFTHEMINTOTHESAMESTYLEDEFINITION", "original": "You've seen how to animate multiple style properties at the same time:\njust put all of them into the same `style()` definition.", "translation": "你已经知道该如何在同一时间段进行多个样式的动画了:只要把它们都放进同一个 `style()` 定义中就行了!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "BUTYOUMAYALSOWANTTOCONFIGUREDIFFERENTTIMINGSFORANIMATIONSTHATHAPPENINPARALLELFOREXAMPLEYOUMAYWANTTOANIMATETWOCSSPROPERTIESBUTUSEADIFFERENTEASINGFUNCTIONFOREACHONE", "original": "But you may also want to configure different *timings* for animations that happen\nin parallel. For example, you may want to animate two CSS properties but use a\ndifferent easing function for each one.", "translation": "但你也可能会希望为同时发生的几个动画配置不同的*时间线*。比如,同时对两个 CSS 属性做动画,但又得为它们定义不同的缓动函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "FORTHISYOUCANUSEANIMATIONGROUPSINTHISEXAMPLEUSINGGROUPSBOTHONENTERANDLEAVEALLOWSFORTWODIFFERENTTIMINGCONFIGURATIONSBOTHAREAPPLIEDTOTHESAMEELEMENTINPARALLELBUTRUNINDEPENDENTLYOFEACHOTHER:", "original": "For this you can use animation *groups*. In this example, using groups both on\nenter and leave allows for two different timing configurations. Both\nare applied to the same element in parallel, but run independently of each other:", "translation": "这种情况下就可以用动画*组*来解决了。在这个例子中,同时在进场和离场时使用了组,以便能让它们使用两种不同的时间线配置。\n它们被同时应用到同一个元素上,但又彼此独立运行:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ONEGROUPANIMATESTHEELEMENTTRANSFORMANDWIDTHTHEOTHERGROUPANIMATESTHEOPACITY", "original": "One group animates the element transform and width; the other group animates the opacity.", "translation": "其中一个动画组对元素的 `transform` 和 `width` 做动画,另一个组则对 `opacity` 做动画。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "##ANIMATIONCALLBACKS", "original": "## Animation callbacks", "translation": "## 动画回调", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "ACALLBACKISFIREDWHENANANIMATIONISSTARTEDANDALSOWHENITISDONE", "original": "A callback is fired when an animation is started and also when it is done.", "translation": "当动画开始和结束时,会触发一个回调。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "INTHEKEYFRAMESEXAMPLEYOUHAVEATRIGGERCALLEDFLYINOUTYOUCANHOOKTHOSECALLBACKSLIKETHIS:", "original": "In the keyframes example, you have a `trigger` called `@flyInOut`. You can hook\nthose callbacks like this:", "translation": "对于例子中的这个关键帧,你有一个叫做 `@flyInOut` 的 `trigger`。在那里你可以挂钩到那些回调,比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THECALLBACKSRECEIVEANANIMATIONEVENTTHATCONTAINSUSEFULPROPERTIESSUCHASFROMSTATETOSTATEANDTOTALTIME", "original": "The callbacks receive an `AnimationEvent` that contains useful properties such as\n`fromState`, `toState` and `totalTime`.", "translation": "这些回调接收一个 `AnimationTransitionEvent` 参数,它包含一些有用的属性,例如 `fromState`,`toState` 和 `totalTime`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "THOSECALLBACKSWILLFIREWHETHERORNOTANANIMATIONISPICKEDUP", "original": "Those callbacks will fire whether or not an animation is picked up.", "translation": "无论动画是否实际执行过,那些回调都会触发。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/animations.md" }, { + "key": "#THEAHEADOFTIMEAOTCOMPILER", "original": "# The Ahead-of-Time (AOT) Compiler", "translation": "# 预先(AOT)编译", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEANGULARAHEADOFTIMEAOTCOMPILERCONVERTSYOURANGULARHTMLANDTYPESCRIPTCODEINTOEFFICIENTJAVASCRIPTCODEDURINGTHEBUILDPHASEBEFORETHEBROWSERDOWNLOADSANDRUNSTHATCODE", "original": "The Angular Ahead-of-Time (AOT) compiler converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase _before_ the browser downloads and runs that code.", "translation": "Angular 的“预先(AOT)编译器”会在构建期间把 Angular 应用的 HTML 和 TypeScript 代码编译成高效的 JavaScript 代码,之后浏览器就可以下载并快速运行这些代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISGUIDEEXPLAINSHOWTOBUILDWITHTHEAOTCOMPILERUSINGDIFFERENTCOMPILEROPTIONSANDHOWTOWRITEANGULARMETADATATHATAOTCANCOMPILE", "original": "This guide explains how to build with the AOT compiler using different compiler options and how to write Angular metadata that AOT can compile.", "translation": "本章描述了如何使用 AOT 编译器,以及如何书写能被 AOT 编译的 Angular 元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "AHREFHTTPS:WWWYOUTUBECOMWATCHVKW9CJSVCSGOWATCHCOMPILERAUTHORTOBIASBOSCHEXPLAINTHEANGULARCOMPILERAATANGULARCONNECT2016", "original": "<a href=\"https://www.youtube.com/watch?v=kW9cJsvcsGo\">Watch compiler author Tobias Bosch explain the Angular Compiler</a> at AngularConnect 2016.", "translation": "观看编译器作者 Tobias Bosch 在 AngularConnect 2016 大会里,对<a href=\"http://v.youku.com/v_show/id_XMTc1NTE4NTkwOA==.html?from=y1.7-1.4\" target=\"_blank\">Angular 编译器</a>的演讲。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##ANGULARCOMPILATION", "original": "## Angular compilation", "translation": "## Angular 中的编译", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANANGULARAPPLICATIONCONSISTSLARGELYOFCOMPONENTSANDTHEIRHTMLTEMPLATESBEFORETHEBROWSERCANRENDERTHEAPPLICATIONTHECOMPONENTSANDTEMPLATESMUSTBECONVERTEDTOEXECUTABLEJAVASCRIPTBYANANGULARCOMPILER", "original": "An Angular application consists largely of components and their HTML templates.\nBefore the browser can render the application,\nthe components and templates must be converted to executable JavaScript by an _Angular compiler_.", "translation": "Angular 应用由大量组件及其 HTML 模板组成。\n在浏览器渲染应用之前,组件和模板必须由 *Angular 编译器*转换成可执行的 JavaScript 代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANGULAROFFERSTWOWAYSTOCOMPILEYOURAPPLICATION:", "original": "Angular offers two ways to compile your application:", "translation": "Angular 提供了两种方式来编译你的应用:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "1JUSTINTIMEJITWHICHCOMPILESYOURAPPINTHEBROWSERATRUNTIME", "original": "1. **_Just-in-Time_ (JIT)**, which compiles your app in the browser at runtime", "translation": "**即时(JIT)编译**,它会在浏览器中运行时编译你的应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "1AHEADOFTIMEAOTWHICHCOMPILESYOURAPPATBUILDTIME", "original": "1. **_Ahead-of-Time_ (AOT)**, which compiles your app at build time.", "translation": "**预先(AOT)编译**,它会在构建时编译你的应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "JITCOMPILATIONISTHEDEFAULTWHENYOURUNTHEBUILDONLYORTHEBUILDANDSERVELOCALLYCLICOMMANDS:", "original": "JIT compilation is the default when you run the _build-only_ or the _build-and-serve-locally_ CLI commands:", "translation": "当你运行 *`build`* 或 *`serve`* 这两个 CLI 命令时 JIT 编译是默认选项:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FORAOTCOMPILATIONAPPENDTHEAOTFLAGSTOTHEBUILDONLYORTHEBUILDANDSERVELOCALLYCLICOMMANDS:", "original": "For AOT compilation, append the `--aot` flags to the _build-only_ or the _build-and-serve-locally_ CLI commands:", "translation": "要进行 AOT 编译只要给这两个 CLI 命令添加 `--aot` 标志就行了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEPRODMETAFLAGCOMPILESWITHAOTBYDEFAULT", "original": "The `--prod` meta-flag compiles with AOT by default.", "translation": "`--prod` 标志也会默认使用 AOT 编译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "SEETHECLIDOCUMENTATIONHTTPS:GITHUBCOMANGULARANGULARCLIWIKIFORDETAILSESPECIALLYTHEBUILDTOPICHTTPS:GITHUBCOMANGULARANGULARCLIWIKIBUILD", "original": "See the [CLI documentation](https://github.com/angular/angular-cli/wiki) for details, especially the [`build` topic](https://github.com/angular/angular-cli/wiki/build).", "translation": "要了解更多,请参见[CLI 文档](https://github.com/angular/angular-cli/wiki),特别是[`build` 这个主题](https://github.com/angular/angular-cli/wiki/build)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##WHYCOMPILEWITHAOT", "original": "## Why compile with AOT?", "translation": "## 为什么需要 AOT 编译?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FASTERRENDERING", "original": "*Faster rendering*", "translation": "**渲染得更快**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "WITHAOTTHEBROWSERDOWNLOADSAPRECOMPILEDVERSIONOFTHEAPPLICATIONTHEBROWSERLOADSEXECUTABLECODESOITCANRENDERTHEAPPLICATIONIMMEDIATELYWITHOUTWAITINGTOCOMPILETHEAPPFIRST", "original": "With AOT, the browser downloads a pre-compiled version of the application.\nThe browser loads executable code so it can render the application immediately, without waiting to compile the app first.", "translation": "使用 AOT,浏览器下载预编译版本的应用程序。\n浏览器直接加载运行代码,所以它可以立即渲染该应用,而不用等应用完成首次编译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FEWERASYNCHRONOUSREQUESTS", "original": "*Fewer asynchronous requests*", "translation": "**需要的异步请求更少**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERINLINESEXTERNALHTMLTEMPLATESANDCSSSTYLESHEETSWITHINTHEAPPLICATIONJAVASCRIPTELIMINATINGSEPARATEAJAXREQUESTSFORTHOSESOURCEFILES", "original": "The compiler _inlines_ external HTML templates and CSS style sheets within the application JavaScript,\neliminating separate ajax requests for those source files.", "translation": "编译器把外部 HTML 模板和 CSS 样式表内联到了该应用的 JavaScript 中。\n消除了用来下载那些源文件的 Ajax 请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "SMALLERANGULARFRAMEWORKDOWNLOADSIZE", "original": "*Smaller Angular framework download size*", "translation": "**需要下载的 Angular 框架体积更小**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THERESNONEEDTODOWNLOADTHEANGULARCOMPILERIFTHEAPPISALREADYCOMPILEDTHECOMPILERISROUGHLYHALFOFANGULARITSELFSOOMITTINGITDRAMATICALLYREDUCESTHEAPPLICATIONPAYLOAD", "original": "There's no need to download the Angular compiler if the app is already compiled.\nThe compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.", "translation": "如果应用已经编译过了,自然不需要再下载 Angular 编译器了。\n该编译器差不多占了 Angular 自身体积的一半儿,所以,省略它可以显著减小应用的体积。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "DETECTTEMPLATEERRORSEARLIER", "original": "*Detect template errors earlier*", "translation": "**提早检测模板错误**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEAOTCOMPILERDETECTSANDREPORTSTEMPLATEBINDINGERRORSDURINGTHEBUILDSTEPBEFOREUSERSCANSEETHEM", "original": "The AOT compiler detects and reports template binding errors during the build step\nbefore users can see them.", "translation": "AOT 编译器在构建过程中检测和报告模板绑定错误,避免用户遇到这些错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "BETTERSECURITY", "original": "*Better security*", "translation": "**更安全**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "AOTCOMPILESHTMLTEMPLATESANDCOMPONENTSINTOJAVASCRIPTFILESLONGBEFORETHEYARESERVEDTOTHECLIENTWITHNOTEMPLATESTOREADANDNORISKYCLIENTSIDEHTMLORJAVASCRIPTEVALUATIONTHEREAREFEWEROPPORTUNITIESFORINJECTIONATTACKS", "original": "AOT compiles HTML templates and components into JavaScript files long before they are served to the client.\nWith no templates to read and no risky client-side HTML or JavaScript evaluation,\nthere are fewer opportunities for injection attacks.", "translation": "AOT 编译远在 HTML 模版和组件被服务到客户端之前,将它们编译到 JavaScript 文件。\n没有模版可以阅读,没有高风险客户端 HTML 或 JavaScript 可利用,所以注入攻击的机会较少。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##ANGULARCOMPILEROPTIONS", "original": "## Angular Compiler Options", "translation": "## Angular 编译器选项", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUCANCONTROLYOURAPPCOMPILATIONBYPROVIDINGTEMPLATECOMPILEROPTIONSINTHETSCONFIGJSONFILEALONGWITHTHEOPTIONSSUPPLIEDTOTHETYPESCRIPTCOMPILERTHETEMPLATECOMPILEROPTIONSARESPECIFIEDASMEMBERSOFANGULARCOMPILEROPTIONSOBJECTASSHOWNBELOW:", "original": "You can control your app compilation by providing template compiler options in the `tsconfig.json` file along with the options supplied to the TypeScript compiler. The template compiler options are specified as members of\n`\"angularCompilerOptions\"` object as shown below:", "translation": "你可以通过在 `tsconfig.json` 文件中随 TypeScript 编译选项一起提供模板编译选项来控制应用的编译方式。\n这些模板编译选项都是作为 `\"angularCompilerOptions\"` 对象的成员指定的,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONTELLSTHECOMPILERNOTTOPRODUCEMETADATAJSONFILESTHEOPTIONISFALSEBYDEFAULT", "original": "This option tells the compiler not to produce `.metadata.json` files.\nThe option is `false` by default.", "translation": "这个选项告诉编译器不要生成 `.metadata.json` 文件,它默认是 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { - "original": "`.metadata.json` files contain information needed by the template compiler from a `.ts`\nfile that is not included in the `.d.ts` file produced by the TypeScript compiler. This information contains,\nfor example, the content of annotations (such as a component's template) which TypeScript\nemits to the `.js` file but not to the `.d.ts` file.", + "key": "METADATAJSONFILESCONTAININFOMRATIONNEEDEDBYTHETEMPLATECOMPILERFROMATSFILETHATISNOTINCLUDEDINTHEDTSFILEPRODUCEDBYTHETYPESCRIPTCOMPILERTHISINFORMATIONCONTAINSFOREXAMPLETHECONTENTOFANNOTATIONSSUCHASACOMPONENTSTEMPLATEWHICHTYPESCRIPTEMITSTOTHEJSFILEBUTNOTTOTHEDTSFILE", + "original": "`.metadata.json` files contain infomration needed by the template compiler from a `.ts`\nfile that is not included in the `.d.ts` file produced by the TypeScript compiler. This information contains,\nfor example, the content of annotations (such as a component's template) which TypeScript\nemits to the `.js` file but not to the `.d.ts` file.", "translation": "`.metadata.json` 文件中包含模板编译器所需的信息,这些信息来自于 `.ts` 文件中,但是没有包含在由 TypeScript 编译器生成的 `.d.ts` 文件中。\n比如,这个信息包括 TypeScript 发出的注解内容(如组件的模板),TypeScript 把它生成到了 `.js` 文件中,但是没有生成到 `.d.ts` 文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONSHOULDBESETTOTRUEIFUSINGTYPESCRIPTSOUTFILEOPTIONASTHEMETADATAFILESARENOTVALIDFORTHISSTYLEOFTYPESCRIPTOUTPUTITISNOTRECOMMEDEDTOUSEOUTFILEWITHANGULARUSEABUNDLERSUCHASWEBPACKHTTPS:WEBPACKJSORGINSTEAD", "original": "This option should be set to `true` if using TypeScript's `--outFile` option, as the metadata files\nare not valid for this style of TypeScript output. It is not recommeded to use `--outFile` with\nAngular. Use a bundler, such as [webpack](https://webpack.js.org/), instead.", "translation": "如果使用了 TypeScript 的 `--outFile` 选项,那就要同时设置这个选项。因为在 TypeScript 的这种输出方式下,metadata 文件是无效的。\nAngular 中不建议使用 `--outFile`,请改用 [webpack](https://webpack.js.org/) 之类的打包器代替。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONCANALSOBESETTOTRUEWHENUSINGFACTORYSUMMARIESASTHEFACTORYSUMMARIESINCLUDEACOPYOFTHEINFORMATIONTHATISINTHEMETADATAJSONFILE", "original": "This option can also be set to `true` when using factory summaries as the factory summaries\ninclude a copy of the information that is in the `.metadata.json` file.", "translation": "当使用工厂汇总器(factory summary)时,这个选项也要设置为 `true`,因为工厂汇总器在自己的 `.metadata.json` 中也包含了这些信息的一个副本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONTELLSTHETEMPLATECOMPILERTOREPORTANERRORTOTHEMETADATAJSONFILEIFSKIPMETADATAEMITISFALSETHISOPTIONISFALSEBYDEFAULTTHISSHOULDONLYBEUSEDWHENSKIPMETADATAEMITISFALSEANDSKIPTEMPLATECODEGENISTRUE", "original": "This option tells the template compiler to report an error to the `.metadata.json`\nfile if `\"skipMetadataEmit\"` is `false` . This option is `false` by default. This should only be used when `\"skipMetadataEmit\"` is `false` and `\"skipTemplateCodeGen\"` is `true`.", - "translation": "<!-- 这里整节都不太确定 -->", + "translation": "这个选项告诉模板编译器如果 `\"skipMetadataEmit\"` 为 `false`,那就把错误信息汇报到 `.metadata.json` 中。\n只有当 `\"skipMetadataEmit\"` 为 `false` 且 `\"skipTemplateCodeGen\"` 为 `true` 时才应该使用这个选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ITISINTENDEDTOVALIDATETHEMETADATAJSONFILESEMITTEDFORBUNDLINGWITHANNPMPACKAGETHEVALIDATIONISOVERLYSTRICTANDCANEMITERRORSFORMETADATATHATWOULDNEVERPRODUCEANERRORWHENUSEDBYTHETEMPLATECOMPILERYOUCANCHOOSETOSUPPRESSTHEERROREMITTEDBYTHISOPTIONFORANEXPORTEDSYMBOLBYINCLUDINGDYNAMICINTHECOMMENTDOCUMENTINGTHESYMBOL", "original": "It is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package. The validation is overly strict and can emit errors for metadata that would never produce an error when used by the template compiler. You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol.", "translation": "它的设计意图是要验证为打包 `npm` 而生成的 `.metadata.json` 文件。\n这种验证过于严格,在使用模板编译器时甚至可能会对那些铁定不会出错的元数据文件报告一些错误。\n你可以用 `@dynamic` 在注释中指定一些要导出的符号,来禁止对它们报告错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ITISVALIDFORMETADATAJSONFILESTOCONTAINERRORSTHETEMPLATECOMPILERREPORTSTHESEERRORSIFTHEMETADATAISUSEDTODETERMINETHECONTENTSOFANANNOTATIONTHEMETADATACOLLECTORCANNOTPREDICTTHESYMBOLSTHATAREDESIGNEDTOUSEINANANNOTATIONSOITWILLPREEMPTIVELYINCLUDEERRORNODESINTHEMETADATAFORTHEEXPORTEDSYMBOLSTHETEMPLATECOMPILERCANTHENUSETHEERRORNODESTOREPORTANERRORIFTHESESYMBOLSAREUSEDIFTHECLIENTOFALIBRARYINTENDSTOUSEASYMBOLINANANNOTATIONTHETEMPLATECOMPILERWILLNOTNORMALLYREPORTTHISUNTILTHECLIENTUSESTHESYMBOLTHISOPTIONALLOWSDETECTINGTHESEERRORSDURINGTHEBUILDPHASEOFTHELIBRARYANDISUSEDFOREXAMPLEINPRODUCINGANGULARLIBRARIESTHEMSELVES", "original": "It is valid for `.metadata.json` files to contain errors. The template compiler reports these errors\nif the metadata is used to determine the contents of an annotation. The metadata\ncollector cannot predict the symbols that are designed to use in an annotation, so it will preemptively\ninclude error nodes in the metadata for the exported symbols. The template compiler can then use the error\nnodes to report an error if these symbols are used. If the client of a library intends to use a symbol in an annotation, the template compiler will not normally report\nthis until the client uses the symbol. This option allows detecting these errors during the build phase of\nthe library and is used, for example, in producing Angular libraries themselves.", "translation": "对于 `.metadata.json` 文件来说,包含错误是正常的。如果这些元数据被用来确定注解的内容,模板编译器就会报告这些错误。\n元数据收集器无法判断这些符号的设计目的是用在注解中,所以它将会自作主张,在元数据中为这些导出的符号添加错误节点。\n如果这些符号被用到了,模板编译器就会根据这些错误节点报告错误。\n如果某个库的使用者只是在注解中(而不是普通代码中)使用这些符号,模板编译器通常不会报错。\n这个选项允许在该库(比如 Angular 自身这些库)的构建和使用过程中检测这类错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONTELLSTHECOMPILERTOSUPPRESSEMITTINGNGFACTORYJSANDNGSTYLEJSFILESWHENSETTHISTURNSOFFMOSTOFTHETEMPLATECOMPILERANDDISABLESREPORTINGTEMPLATEDIAGNOSTICSTHISOPTIONCANBEUSEDTOINSTRUCTTHETEMPLATECOMPILERTOPRODUCEMETADATAJSONFILESFORDISTRIBUTIONWITHANNPMPACKAGEWHILEAVOIDINGTHEPRODUCTIONOFNGFACTORYJSANDNGSTYLEJSFILESTHATCANNOTBEDISTRIBUTEDTONPM", "original": "This option tells the compiler to suppress emitting `.ngfactory.js` and `.ngstyle.js` files. When set,\nthis turns off most of the template compiler and disables reporting template diagnostics.\nThis option can be used to instruct the\ntemplate compiler to produce `.metadata.json` files for distribution with an `npm` package while\navoiding the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to\n`npm`.", "translation": "这个选项告诉编译器忽略从 `.ngfactory.js` 和 `.ngstyle.js` 文件中发出的错误。\n如果为 `true`,它就会关闭大多数的模板编译器,并禁止汇报模板诊断信息。\n这个选项用于指示模板编译器为通过 `npm` 包分发而生成 `.metadata.json` 文件,同时避免生成无法分发到 `npm` 的 `.ngfactory.js` 和 `.ngstyle.js` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "WHENSETTOTRUETHISOPTIONSTELLSTHECOMPILERTOREPORTANERRORFORAPARAMETERSUPPLIEDWHOSEINJECTIONTYPECANNOTBEDETERMINEDWHENTHISVALUEOPTIONISNOTPROVIDEDORISFALSECONSTRUCTORPARAMETERSOFCLASSESMARKEDWITHINJECTABLEWHOSETYPECANNOTBERESOLVEDWILLPRODUCEAWARNING", "original": "When set to `true`, this options tells the compiler to report an error for a parameter supplied\nwhose injection type cannot be determined. When this value option is not provided or is `false`, constructor parameters of classes marked with `@Injectable` whose type cannot be resolved will\nproduce a warning.", "translation": "当设置为 `true` 时,该选项会告诉编译器为那些无法确定其类型的注入参数报告错误。\n当该值没有提供或未 `false` 时,那些带有 `@Injectable` 的类,如果其构造参数的类型无法解析,就会生成一个警告。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "NOTE:ITISRECOMMENDEDTOCHANGETHISOPTIONEXPLICITLYTOTRUEASTHISOPTIONWILLDEFAULTTOTRUEINTHEFUTURE", "original": "*Note*: It is recommended to change this option explicitly to `true` as this option will default to `true` in the future.", "translation": "*注意*:建议把该选项显式改为 `true`,因为将来这个选项的默认值会是 `true`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "WHENSETTOTRUETHISOPTIONTELLSTHETEMPLATECOMPILERTOGENERATEAFLATMODULEINDEXOFTHEGIVENFILENAMEANDTHECORRESPONDINGFLATMODULEMETADATAUSETHISOPTIONWHENCREATINGFLATMODULESTHATAREPACKAGEDSIMILARLYTOANGULARCOREANDANGULARCOMMONWHENTHISOPTIONISUSEDTHEPACKAGEJSONFORTHELIBRARYSHOULDREFERTOTHEGENERATEDFLATMODULEINDEXINSTEADOFTHELIBRARYINDEXFILEWITHTHISOPTIONONLYONEMETADATAJSONFILEISPRODUCEDTHATCONTAINSALLTHEMETADATANECESSARYFORSYMBOLSEXPORTEDFROMTHELIBRARYINDEXINTHEGENERATEDNGFACTORYJSFILESTHEFLATMODULEINDEXISUSEDTOIMPORTSYMBOLSTHATINCLUDESBOTHTHEPUBLICAPIFROMTHELIBRARYINDEXASWELLASSHROWDEDINTERNALSYMBOLS", "original": "When set to `true`, this option tells the template compiler to generate a flat module\nindex of the given file name and the corresponding flat module metadata. Use this option when creating\nflat modules that are packaged similarly to `@angular/core` and `@angular/common`. When this option\nis used, the `package.json` for the library should refer\nto the generated flat module index instead of the library index file. With this\noption only one `.metadata.json` file is produced that contains all the metadata necessary\nfor symbols exported from the library index. In the generated `.ngfactory.js` files, the flat\nmodule index is used to import symbols that includes both the public API from the library index\nas well as shrowded internal symbols.", "translation": "当为 `true` 时,该选项告诉模板编译器生成一个指定名字的扁平模块索引和相应的扁平模块元数据。\n当要创建像 `@angular/core` 和 `@angular/common` 这样的扁平模块包时,请使用本选项。\n当使用本选项时,库的 `package.json` 文件就会引用生成的扁平模块索引,而不是库的索引文件。\n当使用本选项时,只会生成一个 `.metadata.json` 文件,其中包含从库索引中导出的符号所需的全部元数据。\n在生成的 `.ngfactory.js` 文件中,扁平模块索会用来导入包括库的公共 API 和隐藏的内部符号在内的全部符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "BYDEFAULTTHETSFILESUPPLIEDINTHEFILESFIELDISASSUMEDTOBELIBRARYINDEXIFMORETHANONETSFILEISSPECIFIEDLIBRARYINDEXISUSEDTOSELECTTHEFILETOUSEIFMORETHANONETSFILEISSUPPLIEDWITHOUTALIBRARYINDEXANERRORISPRODUCEDAFLATMODULEINDEXDTSANDJSWILLBECREATEDWITHTHEGIVENFLATMODULEOUTFILENAMEINTHESAMELOCATIONASTHELIBRARYINDEXDTSFILEFOREXAMPLEIFALIBRARYUSESPUBLICAPITSFILEASTHELIBRARYINDEXOFTHEMODULETHETSCONFIGJSONFILESFIELDWOULDBEPUBLICAPITSTHEFLATMODULEOUTFILEOPTIONSCOULDTHENBESETTOFOREXAMPLEINDEXJSWHICHPRODUCESINDEXDTSANDINDEXMETADATAJSONFILESTHELIBRARYSPACKAGEJSONSMODULEFIELDWOULDBEINDEXJSANDTHETYPINGSFIELDWOULDBEINDEXDTS", "original": "By default the `.ts` file supplied in the `files` field is assumed to be library index.\nIf more than one `.ts` file is specified, `libraryIndex` is used to select the file to use.\nIf more than one `.ts` file is supplied without a `libraryIndex`, an error is produced. A flat module\nindex `.d.ts` and `.js` will be created with the given `flatModuleOutFile` name in the same\nlocation as the library index `.d.ts` file. For example, if a library uses\n`public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field\nwould be `[\"public_api.ts\"]`. The `flatModuleOutFile` options could then be set to, for\nexample `\"index.js\"`, which produces `index.d.ts` and `index.metadata.json` files. The\nlibrary's `package.json`'s `module` field would be `\"index.js\"` and the `typings` field\nwould be `\"index.d.ts\"`.", "translation": "默认情况下,`files` 字段中提供的 `.ts` 文件会被当做库索引。\n如果指定了多个 `.ts` 文件,就要用 `libraryIndex` 来选择要作为库索引的文件。\n扁平模块索引会用 `flatModuleOutFile` 中给出的名字创建 `.d.ts` 和 `.js` 文件,并放在和库索引的 `.d.ts` 文件相同的位置。\n比如,如果某个库使用 `public_api.ts` 文件作为该模块的库索引,那么 `tsconfig.json` 的 `files` 字段就应该是 `[\"public_api.ts\"]`。\n然后可以把 `flatModuleOutFile` 选项设置为 `\"index.js\"`,它就会生成 `index.d.ts` 和 `index.metadata.json` 文件。\n该库的 `package.json` 文件的 `module` 字段将会是 `\"index.js\"`,而 `typings` 字段会是 `\"index.d.ts\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONSPECIFIESTHEPREFERREDMODULEIDTOUSEFORIMPORTINGAFLATMODULEREFERENCESGENERATEDBYTHETEMPLATECOMPILERWILLUSETHISMODULENAMEWHENIMPORTINGSYMBOLSFROMTHEFLATMODULETHISISONLYMEANINGFULWHENFLATMODULEOUTFILEISALSOSUPPLIEDOTHERWISETHECOMPILERIGNORESTHISOPTION", "original": "This option specifies the preferred module id to use for importing a flat module.\nReferences generated by the template compiler will use this module name when importing symbols\nfrom the flat module.\nThis is only meaningful when `flatModuleOutFile` is also supplied. Otherwise the compiler ignores\nthis option.", "translation": "该选项指定建议的模块 ID,这个 ID 用于导入扁平模块。\n从扁平模块中导入符号时,由模板编译器生成的引用将使用这个模块名称。\n它仅在同时提供了 `flatModuleOutFile` 选项时才有意义,否则,编译器将忽略此选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONTELLSTHETEMPLATECOMPILERTOGENERATEFACTORYFILESNGFACTORYJSANDNGSTYLEJSFORDTSFILESWITHACORRESPONDINGMETADATAJSONFILETHISOPTIONDEFAULTSTOTRUEWHENTHISOPTIONISFALSEFACTORYFILESAREGENERATEDONLYFORTSFILES", "original": "This option tells the template compiler to generate factory files (`.ngfactory.js` and `.ngstyle.js`)\nfor `.d.ts` files with a corresponding `.metadata.json` file. This option defaults to\n`true`. When this option is `false`, factory files are generated only for `.ts` files.", "translation": "这个选项告诉模板编译器也为与 `.metadata.json` 文件对应的 `.d.ts` 文件生成工厂文件(`.ngfactory.js` 和 `.ngstyle.js`)。\n这个选项默认为 `true`。当该选项为 `false` 时,只会为 `.ts` 文件生成工厂文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONSHOULDBESETTOFALSEWHENUSINGFACTORYSUMMARIES", "original": "This option should be set to `false` when using factory summaries.", "translation": "当使用工厂汇总器时,这个选项应该设置为 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONTELLSTHECOMPILERTOENABLETHEBINDINGEXPRESSIONVALIDATION#BINDINGEXPRESIONVALIDATIONPHASEOFTHETEMPLATECOMPILERWHICHUSESTYPESCRIPTTOVALIDATEBINDINGEXPRESSIONS", "original": "This option tells the compiler to enable the [binding expression validation](#binding-expresion-validation)\nphase of the template compiler which uses TypeScript to validate binding expressions.", "translation": "该选项告诉编译器要为模板编译器启用[绑定表达式验证](#binding-expresion-validation)阶段,它会使用 TypeScript 来验证绑定表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONISFALSEBYDEFAULT", "original": "This option is `false` by default.", "translation": "该选项默认是 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "NOTE:ITISRECOMMENDEDTOSETTHISTOTRUEASTHISOPTIONWILLDEFAULTTOTRUEINTHEFUTURE", "original": "*Note*: It is recommended to set this to `true` as this option will default to `true` in the future.", "translation": "*注意*:建议把它设置为 `true`,因为将来它会默认为 `true`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONTELLSTHECOMPILERTOUSETSICKLEHTTPS:GITHUBCOMANGULARTSICKLETOANNOTATETHEEMITTEDJAVASCRIPTWITHJSDOCHTTP:USEJSDOCORGCOMMENTSNEEDEDBYTHECLOSURECOMPILERHTTPS:GITHUBCOMGOOGLECLOSURECOMPILERTHISOPTIONDEFAULTSTOFALSE", "original": "This option tells the compiler to use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted\nJavaScript with [JsDoc](http://usejsdoc.org/) comments needed by the\n[Closure Compiler](https://github.com/google/closure-compiler). This option defaults to `false`.", "translation": "该选项告诉编译器使用 [Tsickle](https://github.com/angular/tsickle) 来为生成的 JavaScript 添加供 [Closure Compiler](https://github.com/google/closure-compiler) 使用的 [JsDoc](http://usejsdoc.org/) 注解。\n该选项默认为 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { - "original": "Use this option to modify how the Angular specific annotations are emitted to improve tree-shaking. Non-Angular\nannotations and decorators are unnaffected. Default is `static fields`.", + "key": "USETHISOPTIONTOMODIFYHOWTHEANGULARSPECIFICANNOTATIONSAREEMITTEDTOIMPROVETREESHAKINGNONANGULARANNOTATIONSANDDECORATORSAREUNAFFECTEDDEFAULTISSTATICFIELDS", + "original": "Use this option to modify how the Angular specific annotations are emitted to improve tree-shaking. Non-Angular\nannotations and decorators are unaffected. Default is `static fields`.", "translation": "使用这个选项来修改生成 Angular 特有注解的方式,以提升摇树优化(tree-shaking)的效果。它对 Angular 自身之外的注解和装饰器无效。\n默认值是 `static fields`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "VALUEDESCRIPTIONDECORATORSLEAVETHEDECORATORSINPLACETHISMAKESCOMPILATIONFASTERTYPESCRIPTWILLEMITCALLSTOTHEDECORATEHELPERUSEEMITDECORATORMETADATAFORRUNTIMEREFLECTIONHOWEVERTHERESULTINGCODEWILLNOTPROPERLYTREESHAKESTATICFIELDSREPLACEDECORATORSWITHASTATICFIELDINTHECLASSALLOWSADVANCEDTREESHAKERSLIKECLOSURECOMPILERHTTPS:GITHUBCOMGOOGLECLOSURECOMPILERTOREMOVEUNUSEDCLASSES", + "original": "value | description\n----------------|-------------------------------------------------------------\n`decorators` | Leave the Decorators in-place. This makes compilation faster. TypeScript will emit calls to the `__decorate` helper. Use `--emitDecoratorMetadata` for runtime reflection. However, the resulting code will not properly tree-shake.\n`static fields` | Replace decorators with a static field in the class. Allows advanced tree-shakers like [Closure Compiler](https://github.com/google/closure-compiler) to remove unused classes.", + "translation": "<t>value</t><t>值</t> | <t>description</t><t>说明</t>\n----------------|-------------------------------------------------------------\n`decorators` | <t>Leave the Decorators in-place. This makes compilation faster. TypeScript will emit calls to the `__decorate` helper. Use `--emitDecoratorMetadata` for runtime reflection. However, the resulting code will not properly tree-shake.</t> <t>原地保留装饰器。这会让编译过程更快。TypeScript 将会生成对 `__decorate` 助手函数的调用。使用 `--emitDecoratorMetadata` 进行运行时反射。不过,生成的代码将无法正常进行摇树优化。</t>\n`static fields` | <t>Replace decorators with a static field in the class. Allows advanced tree-shakers like [Closure Compiler](https://github.com/google/closure-compiler) to remove unused classes.</t><t>使用类的静态字段代替装饰器。它允许像 [Closure Compiler](https://github.com/google/closure-compiler) 这样的高级摇树优化器移除未使用的类。</t>", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" + }, + { + "key": "THISTELLSTHECOMPILERTOPRINTEXTRAINFORMATIONWHILECOMPILINGTEMPLATES", "original": "This tells the compiler to print extra information while compiling templates.", "translation": "它告诉编译器在编译模板时打印额外的信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { - "original": "The use of `<template>` element was deprecated starting in Angular 4.0 in favor of using\n`<ng-template>` to avoid colliding with the DOM's element of the same name. Setting this option to\n`true` enables the use of the deprecated `<template>` element . This option\nis `false` by default. This option might be required by some third-party Angular libraries.", - "translation": "从 Angular 4.0 开始,`<template>` 元素已经被废弃了,要改用 `<ng-template>` 以避免和同名 DOM 元素的冲突。把该选项设置为 `true` 将会允许使用已废弃的 `<template>` 元素。\n该选项默认为 `false`。某些第三方 Angular 库可能会需要该选项。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" - }, - { + "key": "THEANGULARTEMPLATECOMPILERTRANSFORMSCODETHATISUSEDORCOULDBEUSEDINANANNOTATIONTOALLOWITTOBEIMPORTEDFROMTEMPLATEFACTORYMODULESSEEMETADATAREWRITING#METADATAREWRITINGFORMOREINFORMATION", "original": "The Angular template compiler transforms code that is used, or could be used, in an annotation\nto allow it to be imported from template factory modules. See\n[metadata rewriting](#metadata-rewriting) for more information.", "translation": "Angular 的模板编译器会转换注解中使用或可能使用的代码,以便能从模板的工厂模块中导入它。\n参见[元数据重写](#metadata-rewriting)以了解更多信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "SETTINGTHISOPTIONTOFALSEDISABLESTHISREWRITINGREQUIRINGTHEREWRITINGTOBEDONEMANUALLY", "original": "Setting this option to `false` disables this rewriting, requiring the rewriting to be\ndone manually.", "translation": "把该选项设置为 `false` 将会禁止这种重写,如果需要重写就去得人工完成了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISOPTIONTELLSTHECOMPILERWHETHERTOREMOVEBLANKTEXTNODESFROMCOMPILEDTEMPLATESASOFV6THISOPTIONISFALSEBYDEFAULTWHICHRESULTSINSMALLEREMITTEDTEMPLATEFACTORYMODULES", "original": "This option tells the compiler whether to remove blank text nodes from compiled templates.\nAs of v6, this option is `false` by default, which results in smaller emitted template factory modules.", "translation": "该选项会告诉编译器是否要从编译后的模板中移除空白的文本节点。\n对于 Angular v6,该选项默认为 `false`,它会移除空白节点,以生成更小的模板工厂模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "TELLSTHECOMPILERTOGENERATEALLTHEPOSSIBLEGENERATEDFILESEVENIFTHEYAREEMPTYTHISOPTIONISFALSEBYDEFAULTTHISISANOPTIONUSEDBYBAZELBUILDRULESANDISNEEDEDTOSIMPLIFYHOWBAZELRULESTRACKFILEDEPENDENCIESITISNOTRECOMMENDEDTOUSETHISOPTIONOUTSIDEOFTHEBAZELRULES", "original": "Tells the compiler to generate all the possible generated files even if they are empty. This option is\n`false` by default. This is an option used by `bazel` build rules and is needed to simplify\nhow `bazel` rules track file dependencies. It is not recommended to use this option outside of the `bazel`\nrules.", "translation": "告诉编译器生成所有可能生成的文件 —— 即使是空文件。\n该选项默认为 `false`。\n这是供 `bazel` 构建规则使用的选项,它用于简化 `bazel` 规则跟踪文件依赖的方式。\n除了 `bazel` 规则之外不建议使用该选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "TELLSTHECOMPILERTOGENERATEDEFINITIONSUSINGTHERENDER3STYLECODEGENERATIONTHISOPTIONDEFAULTSTOFALSE", "original": "Tells the compiler to generate definitions using the Render3 style code generation. This option defaults to `false`.", "translation": "告诉编译器使用 Render3 风格的代码生成器来来生成各种定义。\n该选项默认为 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { - "original": "Not all features are supported with this option enabled. It is only supported\nfor experimentation and testing of Render3 style code generation.", + "key": "NOTALLFEATURESARESUPPORTEDWITHTHISOPTIONENABLEDITISONLYSUPPORTEDFOREXPERIMENTATIONANDTESTINGOFRENDER3STYLECODEGENERATION", + "original": "Not all features are supported with this option enabled. It is only supported\n for experimentation and testing of Render3 style code generation.", "translation": "当开启该选项时,有些特性不受支持。它仅仅用来为试验和测试 Render3 风格的代码生成提供支持。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "NOTE:ISITNOTRECOMMENDEDTOUSETHISOPTIONASITISNOTYETFEATURECOMPLETEWITHTHERENDER2CODEGENERATION", "original": "*Note*: Is it not recommended to use this option as it is not yet feature complete with the Render2 code generation.", "translation": "*注意*:不建议使用该选项,因为它在使用 Render2 的代码生成器时还缺少一些特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##ANGULARMETADATAANDAOT", "original": "## Angular Metadata and AOT", "translation": "## Angular 元数据与 AOT", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEANGULARAOTCOMPILEREXTRACTSANDINTERPRETSMETADATAABOUTTHEPARTSOFTHEAPPLICATIONTHATANGULARISSUPPOSEDTOMANAGE", "original": "The Angular **AOT compiler** extracts and interprets **metadata** about the parts of the application that Angular is supposed to manage.", "translation": "Angular 的 **AOT 编译器**会提取并解释应用中由 Angular 管理的各个部件的**元数据**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANGULARMETADATATELLSANGULARHOWTOCONSTRUCTINSTANCESOFYOURAPPLICATIONCLASSESANDINTERACTWITHTHEMATRUNTIME", "original": "Angular metadata tells Angular how to construct instances of your application classes and interact with them at runtime.", "translation": "Angular 的元数据会告诉 Angular 如何创建应用中类的实例以及如何在运行期间与它们交互。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUSPECIFYTHEMETADATAWITHDECORATORSSUCHASCOMPONENTANDINPUTYOUALSOSPECIFYMETADATAIMPLICITLYINTHECONSTRUCTORDECLARATIONSOFTHESEDECORATEDCLASSES", "original": "You specify the metadata with **decorators** such as `@Component()` and `@Input()`.\nYou also specify metadata implicitly in the constructor declarations of these decorated classes.", "translation": "你通过**装饰器**来指定元数据,比如 `@Component()` 和 `@Input()`。\n你还可以在这些带装饰器的类的构造函数中隐式指定元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "INTHEFOLLOWINGEXAMPLETHECOMPONENTMETADATAOBJECTANDTHECLASSCONSTRUCTORTELLANGULARHOWTOCREATEANDDISPLAYANINSTANCEOFTYPICALCOMPONENT", "original": "In the following example, the `@Component()` metadata object and the class constructor tell Angular how to create and display an instance of `TypicalComponent`.", "translation": "在下列范例中,`@Component()` 元数据对象和类的构造函数会告诉 Angular 如何创建和显示 `TypicalComponent` 的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { - "original": "The Anglar compiler extracts the metadata _once_ and generates a _factory_ for `TypicalComponent`.\nWhen it needs to create a `TypicalComponent` instance, Angular calls the factory, which produces a new visual element, bound to a new instance of the component class with its injected dependency.", + "key": "THEANGULARCOMPILEREXTRACTSTHEMETADATAONCEANDGENERATESAFACTORYFORTYPICALCOMPONENTWHENITNEEDSTOCREATEATYPICALCOMPONENTINSTANCEANGULARCALLSTHEFACTORYWHICHPRODUCESANEWVISUALELEMENTBOUNDTOANEWINSTANCEOFTHECOMPONENTCLASSWITHITSINJECTEDDEPENDENCY", + "original": "The Angular compiler extracts the metadata _once_ and generates a _factory_ for `TypicalComponent`.\nWhen it needs to create a `TypicalComponent` instance, Angular calls the factory, which produces a new visual element, bound to a new instance of the component class with its injected dependency.", "translation": "Angular 编译器只提取**一次**元数据,并且为 `TypicalComponent` 生成一个**工厂**。\n当它需要创建 `TypicalComponent` 的实例时,Angular 调用这个工厂,工厂会生成一个新的可视元素,并且把它(及其依赖)绑定到组件类的一个新实例上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##METADATARESTRICTIONS", "original": "## Metadata restrictions", "translation": "## 元数据的限制", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUWRITEMETADATAINASUBSETOFTYPESCRIPTTHATMUSTCONFORMTOTHEFOLLOWINGGENERALCONSTRAINTS:", "original": "You write metadata in a _subset_ of TypeScript that must conform to the following general constraints:", "translation": "你只能使用 TypeScript 的一个**子集**书写元数据,它必须满足下列限制:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "1LIMITEXPRESSIONSYNTAX#EXPRESSIONSYNTAXTOTHESUPPORTEDSUBSETOFJAVASCRIPT", "original": "1. Limit [expression syntax](#expression-syntax) to the supported subset of JavaScript.", "translation": "[表达式语法](#expression-syntax)只支持 JavaScript 的一个有限的子集。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "2ONLYREFERENCEEXPORTEDSYMBOLSAFTERCODEFOLDING#FOLDING", "original": "2. Only reference exported symbols after [code folding](#folding).", "translation": "只能引用[代码收缩](#folding)后导出的符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "3ONLYCALLFUNCTIONSSUPPORTED#SUPPORTEDFUNCTIONSBYTHECOMPILER", "original": "3. Only call [functions supported](#supported-functions) by the compiler.", "translation": "只能调用编译器[支持的那些函数](#supported-functions)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "4DECORATEDANDDATABOUNDCLASSMEMBERSMUSTBEPUBLIC", "original": "4. Decorated and data-bound class members must be public.", "translation": "被装饰和用于数据绑定的类成员必须是公共(public)的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THENEXTSECTIONSELABORATEONTHESEPOINTS", "original": "The next sections elaborate on these points.", "translation": "下一节将会详细解释这些问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##HOWAOTWORKS", "original": "## How AOT works", "translation": "## AOT 工作原理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ITHELPSTOTHINKOFTHEAOTCOMPILERASHAVINGTWOPHASES:ACODEANALYSISPHASEINWHICHITSIMPLYRECORDSAREPRESENTATIONOFTHESOURCEANDACODEGENERATIONPHASEINWHICHTHECOMPILERSSTATICREFLECTORHANDLESTHEINTERPRETATIONASWELLASPLACESRESTRICTIONSONWHATITINTERPRETS", "original": "It helps to think of the AOT compiler as having two phases: a code analysis phase in which it simply records a representation of the source; and a code generation phase in which the compiler's `StaticReflector` handles the interpretation as well as places restrictions on what it interprets.", "translation": "可以把 AOT 编译器看做两个阶段:在代码分析阶段,它只记录源代码,而在代码生成阶段,编译器的 `StaticReflector` 会解释这些结果,并为这些结果加上限制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##PHASE1:ANALYSIS", "original": "## Phase 1: analysis", "translation": "## 阶段 1:分析", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THETYPESCRIPTCOMPILERDOESSOMEOFTHEANALYTICWORKOFTHEFIRSTPHASEITEMITSTHEDTSTYPEDEFINITIONFILESWITHTYPEINFORMATIONTHATTHEAOTCOMPILERNEEDSTOGENERATEAPPLICATIONCODE", "original": "The TypeScript compiler does some of the analytic work of the first phase. It emits the `.d.ts` _type definition files_ with type information that the AOT compiler needs to generate application code.", "translation": "TypeScript 编译器会做一些初步的分析工作,它会生成**类型定义文件**`.d.ts`,其中带有类型信息,Angular 编译器需要借助它们来生成代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ATTHESAMETIMETHEAOTCOLLECTORANALYZESTHEMETADATARECORDEDINTHEANGULARDECORATORSANDOUTPUTSMETADATAINFORMATIONINMETADATAJSONFILESONEPERDTSFILE", "original": "At the same time, the AOT **_collector_** analyzes the metadata recorded in the Angular decorators and outputs metadata information in **`.metadata.json`** files, one per `.d.ts` file.", "translation": "同时,AOT **收集器(collector)** 会记录 Angular 装饰器中的元数据,并把它们输出到**`.metadata.json`**文件中,和每个 `.d.ts` 文件相对应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUCANTHINKOFMETADATAJSONASADIAGRAMOFTHEOVERALLSTRUCTUREOFADECORATORSMETADATAREPRESENTEDASANABSTRACTSYNTAXTREEASTHTTPS:ENWIKIPEDIAORGWIKIABSTRACTSYNTAXTREE", "original": "You can think of `.metadata.json` as a diagram of the overall structure of a decorator's metadata, represented as an [abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree).", "translation": "你可以把 `.metadata.json` 文件看做一个包括全部装饰器的元数据的全景图,就像[抽象语法树 (AST) ](https://en.wikipedia.org/wiki/Abstract_syntax_tree)一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANGULARSSCHEMATSHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERPACKAGESCOMPILERCLISRCMETADATASCHEMATSDESCRIBESTHEJSONFORMATASACOLLECTIONOFTYPESCRIPTINTERFACES", "original": "Angular's [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts)\ndescribes the JSON format as a collection of TypeScript interfaces.", "translation": "Angular 的 [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts) 把这个 JSON 格式表示成了一组 TypeScript 接口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###EXPRESSIONSYNTAX", "original": "### Expression syntax", "translation": "### 表达式语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOLLECTORONLYUNDERSTANDSASUBSETOFJAVASCRIPTDEFINEMETADATAOBJECTSWITHTHEFOLLOWINGLIMITEDSYNTAX:", "original": "The _collector_ only understands a subset of JavaScript.\nDefine metadata objects with the following limited syntax:", "translation": "这个**收集器**只能理解 JavaScript 的一个子集。\n请使用下列受限语法定义元数据对象:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "SYNTAXEXAMPLELITERALOBJECTCHERRY:TRUEAPPLE:TRUEMINCEMEAT:FALSELITERALARRAYCHERRIESFLOURSUGARSPREADINLITERALARRAYAPPLESFLOURTHERESTCALLSBAKEINGREDIENTSNEWNEWOVENPROPERTYACCESSPIESLICEARRAYINDEXINGREDIENTS0IDENTIFIERREFERENCECOMPONENTATEMPLATESTRINGCODE#96PIEISMULTIPLIERTIMESBETTERTHANCAKE#96CODELITERALSTRINGPILITERALNUMBER314153265LITERALBOOLEANTRUELITERALNULLNULLSUPPORTEDPREFIXOPERATORCAKESUPPORTEDBINARYOPERATORABCONDITIONALOPERATORAB:CPARENTHESESAB", + "original": "Syntax | Example\n----------------------------------- | -----------------------------------\nLiteral object | `{cherry: true, apple: true, mincemeat: false}`\nLiteral array | `['cherries', 'flour', 'sugar']`\nSpread in literal array | `['apples', 'flour', ...the_rest]`\nCalls | `bake(ingredients)`\nNew | `new Oven()`\nProperty access | `pie.slice`\nArray index | `ingredients[0]`\nIdentifier reference | `Component`\nA template string | <code>`pie is ${multiplier} times better than cake`</code>\nLiteral string | `'pi'`\nLiteral number | `3.14153265`\nLiteral boolean | `true`\nLiteral null | `null`\nSupported prefix operator | `!cake`\nSupported Binary operator | `a + b`\nConditional operator | `a ? b : c`\nParentheses | `(a + b)`", + "translation": "<t>Syntax</t><t>语法</t> | <t>Example</t><t>范例</t>\n----------------------------------- | -----------------------------------\n<t>Literal object</t><t>对象字面量</t> | `{cherry: true, apple: true, mincemeat: false}`\n<t>Literal array</t><t>数组字面量</t> | `['cherries', 'flour', 'sugar']`\n<t>Spread in literal array</t><t>字面量数组展开</t> | `['apples', 'flour', ...the_rest]`\n<t>Calls</t><t>调用</t> | `bake(ingredients)`\n<t>New</t><t>创建对象</t> | `new Oven()`\n<t>Property access</t><t>属性访问</t> | `pie.slice`\n<t>Array index</t><t>数组索引</t> | `ingredients[0]`\n<t>Identifier reference</t><t>标识符引用</t> | `Component`\n<t>A template string</t><t>模板字符串</t> | <code>`pie is ${multiplier} times better than cake`</code>\n<t>Literal string</t><t>字符串字面量</t> | `'pi'`\n<t>Literal number</t><t>数字字面量</t> | `3.14153265`\n<t>Literal boolean</t><t>逻辑字面量</t> | `true`\n<t>Literal null</t><t>空字面量</t> | `null`\n<t>Supported prefix operator</t><t>受支持的前缀操作符</t> | `!cake`\n<t>Supported Binary operator</t><t>受支持的二元操作符</t> | `a + b`\n<t>Conditional operator</t><t>条件操作符</t> | `a ? b : c`\n<t>Parentheses</t><t>括号</t> | `(a + b)`", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" + }, + { + "key": "IFANEXPRESSIONUSESUNSUPPORTEDSYNTAXTHECOLLECTORWRITESANERRORNODETOTHEMETADATAJSONFILETHECOMPILERLATERREPORTSTHEERRORIFITNEEDSTHATPIECEOFMETADATATOGENERATETHEAPPLICATIONCODE", "original": "If an expression uses unsupported syntax, the _collector_ writes an error node to the `.metadata.json` file. The compiler later reports the error if it needs that\npiece of metadata to generate the application code.", "translation": "如果表达式使用了不支持的语法,**收集器**就会往 `.metadata.json` 文件中写入一个错误节点。稍后,如果编译器用到元数据中的这部分内容来生成应用代码,它就会报告这个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "IFYOUWANTNGCTOREPORTSYNTAXERRORSIMMEDIATELYRATHERTHANPRODUCEAMETADATAJSONFILEWITHERRORSSETTHESTRICTMETADATAEMITOPTIONINTSCONFIG", "original": "If you want `ngc` to report syntax errors immediately rather than produce a `.metadata.json` file with errors, set the `strictMetadataEmit` option in `tsconfig`.", "translation": "如果你希望 `ngc` 立即汇报这些语法错误,而不要生成带有错误信息的 `.metadata.json` 文件,可以到 `tsconfig` 中设置 `strictMetadataEmit` 选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANGULARLIBRARIESHAVETHISOPTIONTOENSURETHATALLANGULARMETADATAJSONFILESARECLEANANDITISABESTPRACTICETODOTHESAMEWHENBUILDINGYOUROWNLIBRARIES", "original": "Angular libraries have this option to ensure that all Angular `.metadata.json` files are clean and it is a best practice to do the same when building your own libraries.", "translation": "Angular 库通过这个选项来确保所有的 `.metadata.json` 文件都是干净的。当你要构建自己的代码库时,这也同样是一项最佳实践。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###NOARROWFUNCTIONS", "original": "### No arrow functions", "translation": "### 不要有箭头函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEAOTCOMPILERDOESNOTSUPPORTFUNCTIONEXPRESSIONSHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCEOPERATORSFUNCTIONANDARROWFUNCTIONSHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCEFUNCTIONSARROWFUNCTIONSALSOCALLEDLAMBDAFUNCTIONS", "original": "The AOT compiler does not support [function expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function)\nand [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), also called _lambda_ functions.", "translation": "AOT 编译器不支持 [函数表达式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function)\n和 [箭头函数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)(也叫 *Lambda* 函数)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "CONSIDERTHEFOLLOWINGCOMPONENTDECORATOR:", "original": "Consider the following component decorator:", "translation": "考虑如下组件装饰器:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEAOTCOLLECTORDOESNOTSUPPORTTHEARROWFUNCTIONNEWSERVERINAMETADATAEXPRESSIONITGENERATESANERRORNODEINPLACEOFTHEFUNCTION", "original": "The AOT _collector_ does not support the arrow function, `() => new Server()`, in a metadata expression.\nIt generates an error node in place of the function.", "translation": "AOT 的*收集器*不支持在元数据表达式中出现箭头函数 `() => new Server()`。\n它会在该函数中就地生成一个错误节点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "WHENTHECOMPILERLATERINTERPRETSTHISNODEITREPORTSANERRORTHATINVITESYOUTOTURNTHEARROWFUNCTIONINTOANEXPORTEDFUNCTION", "original": "When the compiler later interprets this node, it reports an error that invites you to turn the arrow function into an _exported function_.", "translation": "稍后,当编译器解释该节点时,它就会报告一个错误,让你把这个箭头函数转换成一个*导出的函数*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUCANFIXTHEERRORBYCONVERTINGTOTHIS:", "original": "You can fix the error by converting to this:", "translation": "你可以把它改写成这样来修复这个错误:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "BEGINNINGINVERSION5THECOMPILERAUTOMATICALLYPERFORMSTHISREWRITTINGWHILEEMITTINGTHEJSFILE", "original": "Beginning in version 5, the compiler automatically performs this rewritting while emitting the `.js` file.", "translation": "从 Angular v5 开始,编译器会在生成 `.js` 文件时自动执行这种改写。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###LIMITEDFUNCTIONCALLS", "original": "### Limited function calls", "translation": "### 受限函数调用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOLLECTORCANREPRESENTAFUNCTIONCALLOROBJECTCREATIONWITHNEWASLONGASTHESYNTAXISVALIDTHECOLLECTORONLYCARESABOUTPROPERSYNTAX", "original": "The _collector_ can represent a function call or object creation with `new` as long as the syntax is valid. The _collector_ only cares about proper syntax.", "translation": "只要语法有效,*收集器*就可以支持函数调用或使用 `new` 来创建对象。*收集器*只在乎语法是否正确。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "BUTBEWARETHECOMPILERMAYLATERREFUSETOGENERATEACALLTOAPARTICULARFUNCTIONORCREATIONOFAPARTICULAROBJECTTHECOMPILERONLYSUPPORTSCALLSTOASMALLSETOFFUNCTIONSANDWILLUSENEWFORONLYAFEWDESIGNATEDCLASSESTHESEFUNCTIONSANDCLASSESAREINATABLEOFBELOW#SUPPORTEDFUNCTIONS", "original": "But beware. The compiler may later refuse to generate a call to a _particular_ function or creation of a _particular_ object.\nThe compiler only supports calls to a small set of functions and will use `new` for only a few designated classes. These functions and classes are in a table of [below](#supported-functions).", "translation": "但要注意。编译器稍后可能拒绝调用*特定的*函数或拒绝创建*特定的*对象。\n编译器值仅支持调用一小部分函数,也只能 `new` 一小部分类。这些函数和类列在了[后面](#supported-functions)的表格中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###FOLDING", "original": "### Folding", "translation": "### 折叠(fold)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERCANONLYRESOLVEREFERENCESTOEXPORTEDSYMBOLSFORTUNATELYTHECOLLECTORENABLESLIMITEDUSEOFNONEXPORTEDSYMBOLSTHROUGHFOLDING", "original": "The compiler can only resolve references to **_exported_** symbols.\nFortunately, the _collector_ enables limited use of non-exported symbols through _folding_.", "translation": "编译器只能解析对***导出***的符号的引用。\n幸运的是,*收集器*支持通过*折叠*来有限的使用那些未导出的符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOLLECTORMAYBEABLETOEVALUATEANEXPRESSIONDURINGCOLLECTIONANDRECORDTHERESULTINTHEMETADATAJSONINSTEADOFTHEORIGINALEXPRESSION", "original": "The _collector_ may be able to evaluate an expression during collection and record the result in the `.metadata.json` instead of the original expression.", "translation": "*收集器*可以在收集期间执行表达式,并用其结果代替原始表达式,记录到 `.metadata.json` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FOREXAMPLETHECOLLECTORCANEVALUATETHEEXPRESSION1234ANDREPLACEITWITHTHERESULT10", "original": "For example, the _collector_ can evaluate the expression `1 + 2 + 3 + 4` and replace it with the result, `10`.", "translation": "比如,*收集器*可以执行表达式 `1 + 2 + 3 + 4`,并使用它的结果 `10` 替换它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISPROCESSISCALLEDFOLDINGANEXPRESSIONTHATCANBEREDUCEDINTHISMANNERISFOLDABLE", "original": "This process is called _folding_. An expression that can be reduced in this manner is _foldable_.", "translation": "这个过程被称为*折叠*。能用这种方式进行简化的表达式就是*可折叠的*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOLLECTORCANEVALUATEREFERENCESTOMODULELOCALCONSTDECLARATIONSANDINITIALIZEDVARANDLETDECLARATIONSEFFECTIVELYREMOVINGTHEMFROMTHEMETADATAJSONFILE", "original": "The collector can evaluate references to\nmodule-local `const` declarations and initialized `var` and `let` declarations, effectively removing them from the `.metadata.json` file.", "translation": "收集器可以计算对模块局部变量的 `const` 声明和初始化过的 `var` 和 `let` 声明,并从 `.metadata.json` 文件中移除它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "CONSIDERTHEFOLLOWINGCOMPONENTDEFINITION:", "original": "Consider the following component definition:", "translation": "考虑下列组件定义:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERCOULDNOTREFERTOTHETEMPLATECONSTANTBECAUSEITISNTEXPORTED", "original": "The compiler could not refer to the `template` constant because it isn't exported.", "translation": "编译器不能引用 `template` 常量,因为它是未导出的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "BUTTHECOLLECTORCANFOLDTHETEMPLATECONSTANTINTOTHEMETADATADEFINITIONBYINLININGITSCONTENTSTHEEFFECTISTHESAMEASIFYOUHADWRITTEN:", "original": "But the _collector_ can _fold_ the `template` constant into the metadata definition by inlining its contents.\nThe effect is the same as if you had written:", "translation": "但是*折叠器*可以通过内联 `template` 常量的方式把它*折叠*进元数据定义中。\n最终的结果和你以前的写法是一样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEREISNOLONGERAREFERENCETOTEMPLATEANDTHEREFORENOTHINGTOTROUBLETHECOMPILERWHENITLATERINTERPRETSTHECOLLECTORSOUTPUTINMETADATAJSON", "original": "There is no longer a reference to `template` and, therefore, nothing to trouble the compiler when it later interprets the _collector's_ output in `.metadata.json`.", "translation": "这里没有对 `template` 的引用,因此,当编译器稍后对位于 `.metadata.json` 中的*收集器*输出进行解释时,不会再出问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUCANTAKETHISEXAMPLEASTEPFURTHERBYINCLUDINGTHETEMPLATECONSTANTINANOTHEREXPRESSION:", "original": "You can take this example a step further by including the `template` constant in another expression:", "translation": "你还可以通过把 `template` 常量包含在其它表达式中来让这个例子深入一点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOLLECTORREDUCESTHISEXPRESSIONTOITSEQUIVALENTFOLDEDSTRING:", "original": "The _collector_ reduces this expression to its equivalent _folded_ string:", "translation": "*收集器*把该表达式缩减成其等价的*已折叠*字符串:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "####FOLDABLESYNTAX", "original": "#### Foldable syntax", "translation": "#### 可折叠的语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEFOLLOWINGTABLEDESCRIBESWHICHEXPRESSIONSTHECOLLECTORCANANDCANNOTFOLD:", "original": "The following table describes which expressions the _collector_ can and cannot fold:", "translation": "下表中描述了哪些表达式是否能被*收集器*折叠:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "SYNTAXFOLDABLELITERALOBJECTYESLITERALARRAYYESSPREADINLITERALARRAYNOCALLSNONEWNOPROPERTYACCESSYESIFTARGETISFOLDABLEARRAYINDEXYESIFTARGETANDINDEXAREFOLDABLEIDENTIFIERREFERENCEYESIFITISAREFERENCETOALOCALATEMPLATEWITHNOSUBSTITUTIONSYESATEMPLATEWITHSUBSTITUTIONSYESIFTHESUBSTITUTIONSAREFOLDABLELITERALSTRINGYESLITERALNUMBERYESLITERALBOOLEANYESLITERALNULLYESSUPPORTEDPREFIXOPERATORYESIFOPERANDISFOLDABLESUPPORTEDBINARYOPERATORYESIFBOTHLEFTANDRIGHTAREFOLDABLECONDITIONALOPERATORYESIFCONDITIONISFOLDABLEPARENTHESESYESIFTHEEXPRESSIONISFOLDABLE", + "original": "Syntax | Foldable\n----------------------------------- | -----------------------------\nLiteral object | yes\nLiteral array | yes\nSpread in literal array | no\nCalls | no\nNew | no\nProperty access | yes, if target is foldable\nArray index | yes, if target and index are foldable\nIdentifier reference | yes, if it is a reference to a local\nA template with no substitutions | yes\nA template with substitutions | yes, if the substitutions are foldable\nLiteral string | yes\nLiteral number | yes\nLiteral boolean | yes\nLiteral null | yes\nSupported prefix operator | yes, if operand is foldable\nSupported binary operator | yes, if both left and right are foldable\nConditional operator | yes, if condition is foldable\nParentheses | yes, if the expression is foldable", + "translation": "<t>Syntax</t><t>语法</t> | <t>Foldable</t><t>可折叠的</t>\n----------------------------------- | -----------------------------\n<t>Literal object</t><t>对象字面量</t> | <t>yes</t> <t>是</t>\n<t>Literal array</t><t>数组字面量</t> | <t>yes</t> <t>是</t>\n<t>Spread in literal array</t><t>字面量数组展开</t> | <t>no</t> <t>否</t>\n<t>Calls</t><t>调用</t> | <t>no</t> <t>否</t>\n<t>New</t><t>创建对象</t> | <t>no</t> <t>否</t>\n<t>Property access</t><t>属性访问</t> | <t>yes, if target is foldable</t> <t>是(如果目标也是可折叠的)</t>\n<t>Array index</t><t>数组索引</t> | <t>yes, if target and index are foldable</t> <t>是(如果目标和索引也是可折叠的)</t>\n<t>Identifier reference</t><t>标识符引用</t> | <t>yes, if it is a reference to a local</t> <t>是(如果引用的是局部变量)</t>\n<t>A template with no substitutions</t><t>没有内嵌表达式的模板</t> | <t>yes</t> <t>是</t>\n<t>A template with substitutions</t><t>带内嵌表达式的模板</t> | <t>yes, if the substitutions are foldable</t> <t>是(如果内嵌表达式是可折叠的)</t>\n<t>Literal string</t><t>字符串字面量</t> | <t>yes</t> <t>是</t>\n<t>Literal number</t><t>数字字面量</t> | <t>yes</t> <t>是</t>\n<t>Literal boolean</t><t>逻辑字面量</t> | <t>yes</t> <t>是</t>\n<t>Literal null</t><t>空字面量</t> | <t>yes</t> <t>是</t>\n<t>Supported prefix operator</t><t>受支持的前缀操作符</t> | <t>yes, if operand is foldable</t> <t>是(如果运算数是可折叠的)</t>\n<t>Supported binary operator</t><t>受支持的二元操作符</t> | <t>yes, if both left and right are foldable</t> <t>是(如果左右运算数都是可折叠的)</t>\n<t>Conditional operator</t><t>条件操作符</t> | <t>yes, if condition is foldable</t> <t>是(如果条件是可折叠的)</t>\n<t>Parentheses</t><t>括号</t> | <t>yes, if the expression is foldable</t> <t>是(如果表达式是可折叠的)</t>", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" + }, + { + "key": "IFANEXPRESSIONISNOTFOLDABLETHECOLLECTORWRITESITTOMETADATAJSONASANASTHTTPS:ENWIKIPEDIAORGWIKIABSTRACTSYNTAXTREEFORTHECOMPILERTORESOLVE", "original": "If an expression is not foldable, the collector writes it to `.metadata.json` as an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) for the compiler to resolve.", "translation": "如果表达式是不可折叠的,那么收集器就会把它作为一个 [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)(抽象语法树) 写入 `.metadata.json` 中,留给编译器去解析。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##PHASE2:CODEGENERATION", "original": "## Phase 2: code generation", "translation": "## 阶段 2:代码生成", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOLLECTORMAKESNOATTEMPTTOUNDERSTANDTHEMETADATATHATITCOLLECTSANDOUTPUTSTOMETADATAJSONITREPRESENTSTHEMETADATAASBESTITCANANDRECORDSERRORSWHENITDETECTSAMETADATASYNTAXVIOLATION", "original": "The _collector_ makes no attempt to understand the metadata that it collects and outputs to `.metadata.json`. It represents the metadata as best it can and records errors when it detects a metadata syntax violation.", "translation": "*收集器*不会试图理解它收集并输出到 `.metadata.json` 中的元数据,它所能做的只是尽可能准确的表述这些元数据,并在检测到元数据中的语法违规时记录这些错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ITSTHECOMPILERSJOBTOINTERPRETTHEMETADATAJSONINTHECODEGENERATIONPHASE", "original": "It's the compiler's job to interpret the `.metadata.json` in the code generation phase.", "translation": "解释这些 `.metadata.json` 是编译器在代码生成阶段要承担的工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERUNDERSTANDSALLSYNTAXFORMSTHATTHECOLLECTORSUPPORTSBUTITMAYREJECTSYNTACTICALLYCORRECTMETADATAIFTHESEMANTICSVIOLATECOMPILERRULES", "original": "The compiler understands all syntax forms that the _collector_ supports, but it may reject _syntactically_ correct metadata if the _semantics_ violate compiler rules.", "translation": "编译器理解*收集器*支持的所有语法形式,但是它也可能拒绝那些虽然*语法正确*但*语义*违反了编译器规则的元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERCANONLYREFERENCEEXPORTEDSYMBOLS", "original": "The compiler can only reference _exported symbols_.", "translation": "编译器只能引用*已导出的符号*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "DECORATEDCOMPONENTCLASSMEMBERSMUSTBEPUBLICYOUCANNOTMAKEANINPUTPROPERTYPRIVATEORINTERNAL", "original": "Decorated component class members must be public. You cannot make an `@Input()` property private or internal.", "translation": "带有装饰器的类成员必须是公开的。你不可能制作一个私有或内部使用的 `@Input()` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "DATABOUNDPROPERTIESMUSTALSOBEPUBLIC", "original": "Data bound properties must also be public.", "translation": "数据绑定的属性同样必须是公开的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "MOSTIMPORTANTLYTHECOMPILERONLYGENERATESCODETOCREATEINSTANCESOFCERTAINCLASSESSUPPORTCERTAINDECORATORSANDCALLCERTAINFUNCTIONSFROMTHEFOLLOWINGLISTS", "original": "Most importantly, the compiler only generates code to create instances of certain classes, support certain decorators, and call certain functions from the following lists.", "translation": "最重要的是,编译器生成代码时,只支持为下面列出的某些类创建实例、只支持某些装饰器、只会调用某些函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###NEWINSTANCES", "original": "### New instances", "translation": "### 新建实例", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERONLYALLOWSMETADATATHATCREATEINSTANCESOFTHECLASSINJECTIONTOKENFROMANGULARCORE", "original": "The compiler only allows metadata that create instances of the class `InjectionToken` from `@angular/core`.", "translation": "编译器只允许创建来自 `@angular/core` 的 `InjectionToken` 类创建实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###ANNOTATIONSDECORATORS", "original": "### Annotations/Decorators", "translation": "### 注解 / 装饰器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERONLYSUPPORTSMETADATAFORTHESEANGULARDECORATORS", "original": "The compiler only supports metadata for these Angular decorators.", "translation": "编译器只支持下列 Angular 装饰器的元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "DECORATORMODULEATTRIBUTEANGULARCORECOMPONENTANGULARCORECONTENTCHILDANGULARCORECONTENTCHILDRENANGULARCOREDIRECTIVEANGULARCOREHOSTANGULARCOREHOSTBINDINGANGULARCOREHOSTLISTENERANGULARCOREINJECTANGULARCOREINJECTABLEANGULARCOREINPUTANGULARCORENGMODULEANGULARCOREOPTIONALANGULARCOREOUTPUTANGULARCOREPIPEANGULARCORESELFANGULARCORESKIPSELFANGULARCOREVIEWCHILDANGULARCORE", + "original": "Decorator | Module\n------------------|--------------\n`Attribute` | `@angular/core`\n`Component` | `@angular/core`\n`ContentChild` | `@angular/core`\n`ContentChildren` | `@angular/core`\n`Directive` | `@angular/core`\n`Host` | `@angular/core`\n`HostBinding` | `@angular/core`\n`HostListener` | `@angular/core`\n`Inject` | `@angular/core`\n`Injectable` | `@angular/core`\n`Input` | `@angular/core`\n`NgModule` | `@angular/core`\n`Optional` | `@angular/core`\n`Output` | `@angular/core`\n`Pipe` | `@angular/core`\n`Self` | `@angular/core`\n`SkipSelf` | `@angular/core`\n`ViewChild` | `@angular/core`", + "translation": "<t>Decorator</t><t>装饰器</t> | <t>Module</t><t>所在模块</t>\n------------------|--------------\n`Attribute` | `@angular/core`\n`Component` | `@angular/core`\n`ContentChild` | `@angular/core`\n`ContentChildren` | `@angular/core`\n`Directive` | `@angular/core`\n`Host` | `@angular/core`\n`HostBinding` | `@angular/core`\n`HostListener` | `@angular/core`\n`Inject` | `@angular/core`\n`Injectable` | `@angular/core`\n`Input` | `@angular/core`\n`NgModule` | `@angular/core`\n`Optional` | `@angular/core`\n`Output` | `@angular/core`\n`Pipe` | `@angular/core`\n`Self` | `@angular/core`\n`SkipSelf` | `@angular/core`\n`ViewChild` | `@angular/core`", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" + }, + { + "key": "###MACROFUNCTIONSANDMACROSTATICMETHODS", "original": "### Macro-functions and macro-static methods", "translation": "### 宏函数或静态宏函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERALSOSUPPORTSMACROSINTHEFORMOFFUNCTIONSORSTATICMETHODSTHATRETURNANEXPRESSION", "original": "The compiler also supports _macros_ in the form of functions or static\nmethods that return an expression.", "translation": "编译器也支持在返回表达式的函数或静态函数中使用*宏*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FOREXAMPLECONSIDERTHEFOLLOWINGFUNCTION:", "original": "For example, consider the following function:", "translation": "考虑下面的函数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUCANCALLTHEWRAPINARRAYINAMETADATADEFINITIONBECAUSEITRETURNSTHEVALUEOFANEXPRESSIONTHATCONFORMSTOTHECOMPILERSRESTRICTIVEJAVASCRIPTSUBSET", "original": "You can call the `wrapInArray` in a metadata definition because it returns the value of an expression that conforms to the compiler's restrictive JavaScript subset.", "translation": "你可以在元数据定义中调用 `wrapInArray`,因为它所返回的表达式的值满足编译器支持的 JavaScript 受限子集。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUMIGHTUSEWRAPINARRAYLIKETHIS:", "original": "You might use `wrapInArray()` like this:", "translation": "你还可以这样使用 `wrapInArray()`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERTREATSTHISUSAGEASIFYOUHADWRITTEN:", "original": "The compiler treats this usage as if you had written:", "translation": "编译器会把这种用法处理成你以前的写法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOLLECTORISSIMPLISTICINITSDETERMINATIONOFWHATQUALIFIESASAMACROFUNCTIONITCANONLYCONTAINASINGLERETURNSTATEMENT", "original": "The collector is simplistic in its determination of what qualifies as a macro\nfunction; it can only contain a single `return` statement.", "translation": "收集器决定哪些函数是宏函数是很简单的 —— 它只能包含一个 `return` 语句。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEANGULARROUTERMODULEAPIROUTERROUTERMODULEEXPORTSTWOMACROSTATICMETHODSFORROOTANDFORCHILDTOHELPDECLAREROOTANDCHILDROUTESREVIEWTHESOURCECODEHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERPACKAGESROUTERSRCROUTERMODULETS#L139ROUTERMODULEFORROOTSOURCECODEFORTHESEMETHODSTOSEEHOWMACROSCANSIMPLIFYCONFIGURATIONOFCOMPLEXNGMODULESGUIDENGMODULES", "original": "The Angular [`RouterModule`](api/router/RouterModule) exports two macro static methods, `forRoot` and `forChild`, to help declare root and child routes.\nReview the [source code](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 \"RouterModule.forRoot source code\")\nfor these methods to see how macros can simplify configuration of complex [NgModules](guide/ngmodules).", "translation": "Angular 的 [`RouterModule`](api/router/RouterModule) 导出了两个静态宏函数 `forRoot` 和 `forChild`,以帮助声明根路由和子路由。\n查看这些方法的[源码](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 \"RouterModule.forRoot source code\"),以了解宏函数是如何简化复杂的 [NgModule](guide/ngmodules) 配置的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###METADATAREWRITING", "original": "### Metadata rewriting", "translation": "### 元数据重写", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERTREATSOBJECTLITERALSCONTAININGTHEFIELDSUSECLASSUSEVALUEUSEFACTORYANDDATASPECIALLYTHECOMPILERCONVERTSTHEEXPRESSIONINITIALIZINGONEOFTHESEFIELDSINTOANEXPORTEDVARIABLEWHICHREPLACESTHEEXPRESSIONTHISPROCESSOFREWRITINGTHESEEXPRESSIONSREMOVESALLTHERESTRICTIONSONWHATCANBEINTHEMBECAUSETHECOMPILERDOESNTNEEDTOKNOWTHEEXPRESSIONSVALUEMDASHITJUSTNEEDSTOBEABLETOGENERATEAREFERENCETOTHEVALUE", "original": "The compiler treats object literals containing the fields `useClass`, `useValue`, `useFactory`, and `data` specially. The compiler converts the expression initializing one of these fields into an exported variable, which replaces the expression. This process of rewriting these expressions removes all the restrictions on what can be in them because\nthe compiler doesn't need to know the expression's value—it just needs to be able to generate a reference to the value.", "translation": "编译器会对含有 `useClass`、`useValue`、`useFactory` 和 `data` 的对象字面量进行特殊处理。\n编译器会把用这些字段之一初始化的表达式转换成一个导出为一个变量,并用它替换该表达式。\n这个重写表达式的过程,会消除它们受到的所有限制,因为编译器并不需要知道该表达式的值,它只要能生成对该值的引用就行了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUMIGHTWRITESOMETHINGLIKE:", "original": "You might write something like:", "translation": "你可以这样写:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "WITHOUTREWRITINGTHISWOULDBEINVALIDBECAUSELAMBDASARENOTSUPPORTEDANDTYPICALSERVERISNOTEXPORTED", "original": "Without rewriting, this would be invalid because lambdas are not supported and `TypicalServer` is not exported.", "translation": "如果不重写,这就是无效的,因为这里不支持 Lambda 表达式,而且 `TypicalServer` 也没有被导出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "TOALLOWTHISTHECOMPILERAUTOMATICALLYREWRITESTHISTOSOMETHINGLIKE:", "original": "To allow this, the compiler automatically rewrites this to something like:", "translation": "为了允许这种写法,编译器自动把它重写成了这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISALLOWSTHECOMPILERTOGENERATEAREFERENCETO0INTHEFACTORYWITHOUTHAVINGTOKNOWWHATTHEVALUEOF0CONTAINS", "original": "This allows the compiler to generate a reference to `ɵ0` in the\nfactory without having to know what the value of `ɵ0` contains.", "translation": "这就让编译器能在工厂中生成一个对 `ɵ0` 的引用,而不用知道 `ɵ0` 中包含的值到底是什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERDOESTHEREWRITINGDURINGTHEEMITOFTHEJSFILETHISDOESNTREWRITETHEDTSFILEHOWEVERSOTYPESCRIPTDOESNTRECOGNIZEITASBEINGANEXPORTTHUSITDOESNOTPOLLUTETHEESMODULESEXPORTEDAPI", "original": "The compiler does the rewriting during the emit of the `.js` file. This doesn't rewrite the `.d.ts` file, however, so TypeScript doesn't recognize it as being an export. Thus, it does not pollute the ES module's exported API.", "translation": "编译器会在生成 `.js` 文件期间进行这种重写。它不会重写 `.d.ts` 文件,所以 TypeScript 也不会把这个变量当做一项导出,因此也就不会污染 ES 模块中导出的 API。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##METADATAERRORS", "original": "## Metadata Errors", "translation": "## 元数据错误", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEFOLLOWINGAREMETADATAERRORSYOUMAYENCOUNTERWITHEXPLANATIONSANDSUGGESTEDCORRECTIONS", "original": "The following are metadata errors you may encounter, with explanations and suggested corrections.", "translation": "你可能遇到一些元数据错误,下面是对它们的解释和纠正建议。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "EXPRESSIONFORMNOTSUPPORTED#EXPRESSIONFORMNOTSUPPORTEDBRREFERENCETOALOCALNONEXPORTEDSYMBOL#REFERENCETOALOCALSYMBOLBRONLYINITIALIZEDVARIABLESANDCONSTANTS#ONLYINITIALIZEDVARIABLESBRREFERENCETOANONEXPORTEDCLASS#REFERENCETOANONEXPORTEDCLASSBRREFERENCETOANONEXPORTEDFUNCTION#REFERENCETOANONEXPORTEDFUNCTIONBRFUNCTIONCALLSARENOTSUPPORTED#FUNCTIONCALLSNOTSUPPORTEDBRDESTRUCTUREDVARIABLEORCONSTANTNOTSUPPORTED#DESTRUCTUREDVARIABLENOTSUPPORTEDBRCOULDNOTRESOLVETYPE#COULDNOTRESOLVETYPEBRNAMEEXPECTED#NAMEEXPECTEDBRUNSUPPORTEDENUMMEMBERNAME#UNSUPPORTEDENUMMEMBERNAMEBRTAGGEDTEMPLATEEXPRESSIONSARENOTSUPPORTED#TAGGEDTEMPLATEEXPRESSIONSNOTSUPPORTEDBRSYMBOLREFERENCEEXPECTED#SYMBOLREFERENCEEXPECTEDBR", + "original": "[Expression form not supported](#expression-form-not-supported)<br>\n[Reference to a local (non-exported) symbol](#reference-to-a-local-symbol)<br>\n[Only initialized variables and constants](#only-initialized-variables)<br>\n[Reference to a non-exported class](#reference-to-a-non-exported-class)<br>\n[Reference to a non-exported function](#reference-to-a-non-exported-function)<br>\n[Function calls are not supported](#function-calls-not-supported)<br>\n[Destructured variable or constant not supported](#destructured-variable-not-supported)<br>\n[Could not resolve type](#could-not-resolve-type)<br>\n[Name expected](#name-expected)<br>\n[Unsupported enum member name](#unsupported-enum-member-name)<br>\n[Tagged template expressions are not supported](#tagged-template-expressions-not-supported)<br>\n[Symbol reference expected](#symbol-reference-expected)<br>", + "translation": "[<t>Expression form not supported</t><t>【不支持此表达式格式】</t>](#expression-form-not-supported)<br>\n[<t>Reference to a local (non-exported) symbol</t><t>【引用了局部(未导出的)符号】</t>](#reference-to-a-local-symbol)<br>\n[<t>Only initialized variables and constants</t><t>【只允许初始化过的变量和常量】</t>](#only-initialized-variables)<br>\n[<t>Reference to a non-exported class</t><t>【引用了未导出的类】</t>](#reference-to-a-non-exported-class)<br>\n[<t>Reference to a non-exported function</t><t>【引用了未导出的函数】</t>](#reference-to-a-non-exported-function)<br>\n[<t>Function calls are not supported</t><t>【不支持函数调用】</t>](#function-calls-not-supported)<br>\n[<t>Destructured variable or constant not supported</t><t>【不支持解构变量或常量】</t>](#destructured-variable-not-supported)<br>\n[<t>Could not resolve type</t><t>【不能解析此类型】</t>](#could-not-resolve-type)<br>\n[<t>Name expected</t><t>【期待是名字】</t>](#name-expected)<br>\n[<t>Unsupported enum member name</t><t>【不支持的枚举成员名】</t>](#unsupported-enum-member-name)<br>\n[<t>Tagged template expressions are not supported</t><t>【不支持带标签函数的模板表达式】</t>](#tagged-template-expressions-not-supported)<br>\n[<t>Symbol reference expected</t><t>【期待是符号引用】</t>](#symbol-reference-expected)<br>", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" + }, + { + "key": "H3CLASSNOTOCEXPRESSIONFORMNOTSUPPORTEDH3", "original": "<h3 class=\"no-toc\">Expression form not supported</h3>", "translation": "<h3 class=\"no-toc\">不支持这种表达式格式</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERENCOUNTEREDANEXPRESSIONITDIDNTUNDERSTANDWHILEEVALUTATINGANGULARMETADATA", "original": "The compiler encountered an expression it didn't understand while evalutating Angular metadata.", "translation": "编译器在对 Angular 元数据求值时遇到了一个它不能理解的表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "LANGUAGEFEATURESOUTSIDEOFTHECOMPILERSRESTRICTEDEXPRESSIONSYNTAX#EXPRESSIONSYNTAXCANPRODUCETHISERRORASSEENINTHEFOLLOWINGEXAMPLE:", "original": "Language features outside of the compiler's [restricted expression syntax](#expression-syntax)\ncan produce this error, as seen in the following example:", "translation": "除编译器[允许的表达式语法](#expression-syntax)之外的语言特性可能导致这个错误,比如下面的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUCANUSETYPEOFANDBRACKETNOTATIONINNORMALAPPLICATIONCODEYOUJUSTCANTUSETHOSEFEATURESWITHINEXPRESSIONSTHATDEFINEANGULARMETADATA", "original": "You can use `typeof` and bracket notation in normal application code.\nYou just can't use those features within expressions that define Angular metadata.", "translation": "你可以在普通的应用代码中使用 `typeof` 和方括号标记法来指定属性名,但是这些特性不能在定义 Angular 元数据的表达式中使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "AVOIDTHISERRORBYSTICKINGTOTHECOMPILERSRESTRICTEDEXPRESSIONSYNTAX#EXPRESSIONSYNTAXWHENWRITINGANGULARMETADATAANDBEWARYOFNEWORUNUSUALTYPESCRIPTFEATURES", "original": "Avoid this error by sticking to the compiler's [restricted expression syntax](#expression-syntax)\nwhen writing Angular metadata\nand be wary of new or unusual TypeScript features.", "translation": "在写 Angular 的元数据时,严格遵循编译器的[受限表达式语法](#expression-syntax)可以避免这个错误,此外还要小心那些新的或罕见的 TypeScript 特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCREFERENCETOALOCALNONEXPORTEDSYMBOLH3", "original": "<h3 class=\"no-toc\">Reference to a local (non-exported) symbol</h3>", "translation": "<h3 class=\"no-toc\">引用了局部(未导出的)符号</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERENCOUNTEREDAREFERENCEDTOALOCALLYDEFINEDSYMBOLTHATEITHERWASNTEXPORTEDORWASNTINITIALIZED", "original": "The compiler encountered a referenced to a locally defined symbol that either wasn't exported or wasn't initialized.", "translation": "编译器遇到了局部定义的未导出或未初始化的符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "HERESAPROVIDEREXAMPLEOFTHEPROBLEM", "original": "Here's a `provider` example of the problem.", "translation": "下面就是存在该问题的 `provider` 范例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERGENERATESTHECOMPONENTFACTORYWHICHINCLUDESTHEUSEVALUEPROVIDERCODEINASEPARATEMODULETHATFACTORYMODULECANTREACHBACKTOTHISSOURCEMODULETOACCESSTHELOCALNONEXPORTEDFOOVARIABLE", "original": "The compiler generates the component factory, which includes the `useValue` provider code, in a separate module. _That_ factory module can't reach back to _this_ source module to access the local (non-exported) `foo` variable.", "translation": "编译器会在单独的模块中生成这个 `userValue` 提供商的代码。*那个*工厂模块不能访问*这个*源码模块,无法访问这个(未导出的)`foo` 变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUCOULDFIXTHEPROBLEMBYINITIALIZINGFOO", "original": "You could fix the problem by initializing `foo`.", "translation": "你可以通过初始化 `foo` 来修正这个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERWILLFOLD#FOLDINGTHEEXPRESSIONINTOTHEPROVIDERASIFYOUHADWRITTENTHIS", "original": "The compiler will [fold](#folding) the expression into the provider as if you had written this.", "translation": "编译器将会把这个表达式[折叠](#folding)进 `providers` 中,就像你以前的写法一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ALTERNATIVELYYOUCANFIXITBYEXPORTINGFOOWITHTHEEXPECTATIONTHATFOOWILLBEASSIGNEDATRUNTIMEWHENYOUACTUALLYKNOWITSVALUE", "original": "Alternatively, you can fix it by exporting `foo` with the expectation that `foo` will be assigned at runtime when you actually know its value.", "translation": "另外,你也可以通过导出 `foo` 来解决它,这样 `foo` 将会在运行期间你真正知道它的值的时候被赋值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ADDINGEXPORTOFTENWORKSFORVARIABLESREFERENCEDINMETADATASUCHASPROVIDERSANDANIMATIONSBECAUSETHECOMPILERCANGENERATEREFERENCESTOTHEEXPORTEDVARIABLESINTHESEEXPRESSIONSITDOESNTNEEDTHEVALUESOFTHOSEVARIABLES", "original": "Adding `export` often works for variables referenced in metadata such as `providers` and `animations` because the compiler can generate _references_ to the exported variables in these expressions. It doesn't need the _values_ of those variables.", "translation": "添加 `export` 的方式通常用于需要在元数据中引用变量时,如 `providers` 和 `animations`,这样编译器就可以在这些表达式中生成对已导出变量的引用了。它不需要知道这些变量的*值*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ADDINGEXPORTDOESNTWORKWHENTHECOMPILERNEEDSTHEACTUALVALUEINORDERTOGENERATECODEFOREXAMPLEITDOESNTWORKFORTHETEMPLATEPROPERTY", "original": "Adding `export` doesn't work when the compiler needs the _actual value_\nin order to generate code.\nFor example, it doesn't work for the `template` property.", "translation": "当编译器需要知道*真正的值*已生成代码时,添加 `export` 的方式就是无效的。比如这里的 `template` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERNEEDSTHEVALUEOFTHETEMPLATEPROPERTYRIGHTNOWTOGENERATETHECOMPONENTFACTORYTHEVARIABLEREFERENCEALONEISINSUFFICIENTPREFIXINGTHEDECLARATIONWITHEXPORTMERELYPRODUCESANEWERRORONLYINITIALIZEDVARIABLESANDCONSTANTSCANBEREFERENCED#ONLYINITIALIZEDVARIABLES", "original": "The compiler needs the value of the `template` property _right now_ to generate the component factory.\nThe variable reference alone is insufficient.\nPrefixing the declaration with `export` merely produces a new error, \"[`Only initialized variables and constants can be referenced`](#only-initialized-variables)\".", "translation": "编译器*现在就*需要 `template` 属性的值来生成组件工厂。\n仅仅有对该变量的引用是不够的。\n给这个声明加上 `export` 前缀只会生成一个新的错误 \"[`Only initialized variables and constants can be referenced`【只能引用初始化过的变量和常量】](#only-initialized-variables)\"。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCONLYINITIALIZEDVARIABLESANDCONSTANTSH3", "original": "<h3 class=\"no-toc\">Only initialized variables and constants</h3>", "translation": "<h3 class=\"no-toc\">只允许使用初始化过的变量和常量</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERFOUNDAREFERENCETOANEXPORTEDVARIABLEORSTATICFIELDTHATWASNTINITIALIZEDITNEEDSTHEVALUEOFTHATVARIABLETOGENERATECODE", "original": "The compiler found a reference to an exported variable or static field that wasn't initialized.\nIt needs the value of that variable to generate code.", "translation": "编译器发现某个到已导出的变量或静态字段的引用是没有初始化过的。而它需要根据那个变量的值来生成代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEFOLLOWINGEXAMPLETRIESTOSETTHECOMPONENTSTEMPLATEPROPERTYTOTHEVALUEOFTHEEXPORTEDSOMETEMPLATEVARIABLEWHICHISDECLAREDBUTUNASSIGNED", "original": "The following example tries to set the component's `template` property to the value of\nthe exported `someTemplate` variable which is declared but _unassigned_.", "translation": "下面的例子试图把组件的 ` template` 属性设置为已导出的 `someTemplate` 变量的值,而这个值虽然声明过,却没有初始化过。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUDALSOGETTHISERRORIFYOUIMPORTEDSOMETEMPLATEFROMSOMEOTHERMODULEANDNEGLECTEDTOINITIALIZEITTHERE", "original": "You'd also get this error if you imported `someTemplate` from some other module and neglected to initialize it there.", "translation": "如果你从其它模块中导入了 `someTemplate`,但那个模块中忘了初始化它,就会看到这个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERCANNOTWAITUNTILRUNTIMETOGETTHETEMPLATEINFORMATIONITMUSTSTATICALLYDERIVETHEVALUEOFTHESOMETEMPLATEVARIABLEFROMTHESOURCECODESOTHATITCANGENERATETHECOMPONENTFACTORYWHICHINCLUDESINSTRUCTIONSFORBUILDINGTHEELEMENTBASEDONTHETEMPLATE", "original": "The compiler cannot wait until runtime to get the template information.\nIt must statically derive the value of the `someTemplate` variable from the source code\nso that it can generate the component factory, which includes\ninstructions for building the element based on the template.", "translation": "编译器不能等到运行时才得到该模板的信息。\n它必须从源码中静态获得这个 `someTemplate` 变量的值,以便生成组件工厂,组件工厂中需要包含根据这个模板来生成元素的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "TOCORRECTTHISERRORPROVIDETHEINITIALVALUEOFTHEVARIABLEINANINITIALIZERCLAUSEONTHESAMELINE", "original": "To correct this error, provide the initial value of the variable in an initializer clause _on the same line_.", "translation": "要纠正这个错误,请在*同一行*的初始化子句中初始化这个变量的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCREFERENCETOANONEXPORTEDCLASSH3", "original": "<h3 class=\"no-toc\">Reference to a non-exported class</h3>", "translation": "<h3 class=\"no-toc\">引用了未导出的类</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "METADATAREFERENCEDACLASSTHATWASNTEXPORTED", "original": "Metadata referenced a class that wasn't exported.", "translation": "元数据引用了一个未导出的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FOREXAMPLEYOUMAYHAVEDEFINEDACLASSANDUSEDITASANINJECTIONTOKENINAPROVIDERSARRAYBUTNEGLECTEDTOEXPORTTHATCLASS", "original": "For example, you may have defined a class and used it as an injection token in a providers array\nbut neglected to export that class.", "translation": "比如,你可能定义了一个类并在某个 `providers` 数组中把它用作了依赖注入令牌,但是忘了导出这个类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANGULARGENERATESACLASSFACTORYINASEPARATEMODULEANDTHATFACTORYCANONLYACCESSEXPORTEDCLASSES#EXPORTEDSYMBOLSTOCORRECTTHISERROREXPORTTHEREFERENCEDCLASS", "original": "Angular generates a class factory in a separate module and that\nfactory [can only access exported classes](#exported-symbols).\nTo correct this error, export the referenced class.", "translation": "Angular 会在一个单独的模块中生成类工厂,而那个工厂[只能访问已导出的类](#exported-symbols)。\n要纠正这个问题,就要导出所引用的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCREFERENCETOANONEXPORTEDFUNCTIONH3", "original": "<h3 class=\"no-toc\">Reference to a non-exported function</h3>", "translation": "<h3 class=\"no-toc\">引用了未导出的函数</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "METADATAREFERENCEDAFUNCTIONTHATWASNTEXPORTED", "original": "Metadata referenced a function that wasn't exported.", "translation": "元数据中引用了未导出的函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FOREXAMPLEYOUMAYHAVESETAPROVIDERSUSEFACTORYPROPERTYTOALOCALLYDEFINEDFUNCTIONTHATYOUNEGLECTEDTOEXPORT", "original": "For example, you may have set a providers `useFactory` property to a locally defined function that you neglected to export.", "translation": "比如,你可能已经把某个服务提供商的 `useFactory` 属性设置成了一个局部定义但忘了导出的函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANGULARGENERATESACLASSFACTORYINASEPARATEMODULEANDTHATFACTORYCANONLYACCESSEXPORTEDFUNCTIONS#EXPORTEDSYMBOLSTOCORRECTTHISERROREXPORTTHEFUNCTION", "original": "Angular generates a class factory in a separate module and that\nfactory [can only access exported functions](#exported-symbols).\nTo correct this error, export the function.", "translation": "Angular 会在一个单独的模块中生成类工厂,那个工厂[只能访问已导出的函数](#exported-symbols)。\n要纠正这个错误,请导出该函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCFUNCTIONCALLSARENOTSUPPORTEDH3", "original": "<h3 class=\"no-toc\">Function calls are not supported</h3>", "translation": "<h3 class=\"no-toc\">不支持函数调用</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERDOESNOTCURRENTLYSUPPORTFUNCTIONEXPRESSIONSORLAMBDAFUNCTIONS#FUNCTIONEXPRESSIONFOREXAMPLEYOUCANNOTSETAPROVIDERSUSEFACTORYTOANANONYMOUSFUNCTIONORARROWFUNCTIONLIKETHIS", "original": "The compiler does not currently support [function expressions or lambda functions](#function-expression).\nFor example, you cannot set a provider's `useFactory` to an anonymous function or arrow function like this.", "translation": "编译器目前不支持[函数表达式或 Lambda 表达式](#function-expression)。\n比如,你不能把某个服务提供商的 `useFactory` 设置成如下匿名函数或函数表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOUALSOGETTHISERRORIFYOUCALLAFUNCTIONORMETHODINAPROVIDERSUSEVALUE", "original": "You also get this error if you call a function or method in a provider's `useValue`.", "translation": "如果你在某个提供商的 `useValue` 中调用函数或方法,也会导致这个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "TOCORRECTTHISERROREXPORTAFUNCTIONFROMTHEMODULEANDREFERTOTHEFUNCTIONINAUSEFACTORYPROVIDERINSTEAD", "original": "To correct this error, export a function from the module and refer to the function in a `useFactory` provider instead.", "translation": "要改正这个问题,就要从模块中导出这个函数,并改成在服务提供商的 `useFactory` 中引用该函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCDESTRUCTUREDVARIABLEORCONSTANTNOTSUPPORTEDH3", "original": "<h3 class=\"no-toc\">Destructured variable or constant not supported</h3>", "translation": "<h3 class=\"no-toc\">不支持解构变量或常量</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERDOESNOTSUPPORTREFERENCESTOVARIABLESASSIGNEDBYDESTRUCTURINGHTTPS:WWWTYPESCRIPTLANGORGDOCSHANDBOOKVARIABLEDECLARATIONSHTML#DESTRUCTURING", "original": "The compiler does not support references to variables assigned by [destructuring](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#destructuring).", "translation": "编译器不支持引用通过[解构](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#destructuring)赋值的方式得到的变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FOREXAMPLEYOUCANNOTWRITESOMETHINGLIKETHIS:", "original": "For example, you cannot write something like this:", "translation": "比如,你不能这么写:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "TOCORRECTTHISERRORREFERTONONDESTRUCTUREDVALUES", "original": "To correct this error, refer to non-destructured values.", "translation": "要纠正这个错误,就要引用非解构方式的变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCCOULDNOTRESOLVETYPEH3", "original": "<h3 class=\"no-toc\">Could not resolve type</h3>", "translation": "<h3 class=\"no-toc\">不能解析类型</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERENCOUNTEREDATYPEANDCANTDETERMINEWHICHMODULEEXPORTSTHATTYPE", "original": "The compiler encountered a type and can't determine which module exports that type.", "translation": "编译器遇到了某个类型,但是不知道它是由哪个模块导出的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISCANHAPPENIFYOUREFERTOANAMBIENTTYPEFOREXAMPLETHEWINDOWTYPEISANAMBIANTTYPEDECLAREDINTHEGLOBALDTSFILE", "original": "This can happen if you refer to an ambient type.\nFor example, the `Window` type is an ambiant type declared in the global `.d.ts` file.", "translation": "这通常会发生在你引用环境类型时。\n比如,`Window` 类型就是在全局 `.d.ts` 文件中声明的环境类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "YOULLGETANERRORIFYOUREFERENCEITINTHECOMPONENTCONSTRUCTORWHICHTHECOMPILERMUSTSTATICALLYANALYZE", "original": "You'll get an error if you reference it in the component constructor,\nwhich the compiler must statically analyze.", "translation": "如果你在组件的构造函数中引用它就会导致一个错误,因为编译器必须对构造函数进行静态分析。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "TYPESCRIPTUNDERSTANDSAMBIANTTYPESSOYOUDONTIMPORTTHEMTHEANGULARCOMPILERDOESNOTUNDERSTANDATYPETHATYOUNEGLECTTOEXPORTORIMPORT", "original": "TypeScript understands ambiant types so you don't import them.\nThe Angular compiler does not understand a type that you neglect to export or import.", "translation": "TypeScript 能理解这些环境类型,所以你不用导入它们。\n但 Angular 编译器不理解你没有导入或导出过的类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "INTHISCASETHECOMPILERDOESNTUNDERSTANDHOWTOINJECTSOMETHINGWITHTHEWINDOWTOKEN", "original": "In this case, the compiler doesn't understand how to inject something with the `Window` token.", "translation": "这种情况下,编译器就无法理解如何使用这个 `Window` 令牌来进行注入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "DONOTREFERTOAMBIENTTYPESINMETADATAEXPRESSIONS", "original": "Do not refer to ambient types in metadata expressions.", "translation": "不要在元数据表达式中引用环境类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "IFYOUMUSTINJECTANINSTANCEOFANAMBIANTTYPEYOUCANFINESSETHEPROBLEMINFOURSTEPS:", "original": "If you must inject an instance of an ambiant type,\nyou can finesse the problem in four steps:", "translation": "如果你必须注入某个环境类型的实例,可以用以下四步来巧妙解决这个问题:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "1CREATEANINJECTIONTOKENFORANINSTANCEOFTHEAMBIANTTYPE", "original": "1. Create an injection token for an instance of the ambiant type.", "translation": "为环境类型的实例创建一个注入令牌。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "1CREATEAFACTORYFUNCTIONTHATRETURNSTHATINSTANCE", "original": "1. Create a factory function that returns that instance.", "translation": "创建一个返回该实例的工厂函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "1ADDAUSEFACTORYPROVIDERWITHTHATFACTORYFUNCTION", "original": "1. Add a `useFactory` provider with that factory function.", "translation": "使用该工厂函数添加一个 `useFactory` 提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "1USEINJECTTOINJECTTHEINSTANCE", "original": "1. Use `@Inject` to inject the instance.", "translation": "使用 `@Inject` 来注入这个实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "HERESANILLUSTRATIVEEXAMPLE", "original": "Here's an illustrative example.", "translation": "下面的例子说明了这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEWINDOWTYPEINTHECONSTRUCTORISNOLONGERAPROBLEMFORTHECOMPILERBECAUSEITUSESTHEINJECTWINDOWTOGENERATETHEINJECTIONCODE", "original": "The `Window` type in the constructor is no longer a problem for the compiler because it\nuses the `@Inject(WINDOW)` to generate the injection code.", "translation": "对于编译器来说,构造函数中出现 `Window` 类型已不再是个问题,因为它现在使用 `@Inject(WINDOW)` 来生成注入代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANGULARDOESSOMETHINGSIMILARWITHTHEDOCUMENTTOKENSOYOUCANINJECTTHEBROWSERSDOCUMENTOBJECTORANABSTRACTIONOFITDEPENDINGUPONTHEPLATFORMINWHICHTHEAPPLICATIONRUNS", "original": "Angular does something similar with the `DOCUMENT` token so you can inject the browser's `document` object (or an abstraction of it, depending upon the platform in which the application runs).", "translation": "Angular 也用 `DOCUMENT` 令牌做了类似的事情,所以你也可以注入浏览器的 `document` 对象(或它的一个抽象层,取决于该应用运行在哪个平台)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCNAMEEXPECTEDH3", "original": "<h3 class=\"no-toc\">Name expected</h3>", "translation": "<h3 class=\"no-toc\">期待是名字</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILEREXPECTEDANAMEINANEXPRESSIONITWASEVALUATINGTHISCANHAPPENIFYOUUSEANUMBERASAPROPERTYNAMEASINTHEFOLLOWINGEXAMPLE", "original": "The compiler expected a name in an expression it was evaluating.\nThis can happen if you use a number as a property name as in the following example.", "translation": "编译器期待它正在求值的表达式中是一个名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "CHANGETHENAMEOFTHEPROPERTYTOSOMETHINGNONNUMERIC", "original": "Change the name of the property to something non-numeric.", "translation": "把该属性的名字改为非数字类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCUNSUPPORTEDENUMMEMBERNAMEH3", "original": "<h3 class=\"no-toc\">Unsupported enum member name</h3>", "translation": "<h3 class=\"no-toc\">不支持的枚举成员名</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "ANGULARCOULDNTDETERMINETHEVALUEOFTHEENUMMEMBERHTTPS:WWWTYPESCRIPTLANGORGDOCSHANDBOOKENUMSHTMLTHATYOUREFERENCEDINMETADATA", "original": "Angular couldn't determine the value of the [enum member](https://www.typescriptlang.org/docs/handbook/enums.html)\nthat you referenced in metadata.", "translation": "Angular 不能确定你在元数据中引用的[枚举成员](https://www.typescriptlang.org/docs/handbook/enums.html)的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERCANUNDERSTANDSIMPLEENUMVALUESBUTNOTCOMPLEXVALUESSUCHASTHOSEDERIVEDFROMCOMPUTEDPROPERTIES", "original": "The compiler can understand simple enum values but not complex values such as those derived from computed properties.", "translation": "编译器可以理解简单的枚举值,但不能理解复杂的,比如从那些计算属性中派生出来的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "AVOIDREFERRINGTOENUMSWITHCOMPLICATEDINITIALIZERSORCOMPUTEDPROPERTIES", "original": "Avoid referring to enums with complicated initializers or computed properties.", "translation": "避免引用那些使用了复杂初始化对象或计算属性的枚举。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCTAGGEDTEMPLATEEXPRESSIONSARENOTSUPPORTEDH3", "original": "<h3 class=\"no-toc\">Tagged template expressions are not supported</h3>", "translation": "<h3 class=\"no-toc\">不支持带标签函数的模板表达式</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILERENCOUNTEREDAJAVASCRIPTES2015TAGGEDTEMPLATEEXPRESSIONHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCETEMPLATELITERALS#TAGGEDTEMPLATELITERALSSUCHAS", "original": "The compiler encountered a JavaScript ES2015 [tagged template expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals) such as,", "translation": "当编译器遇到这样的[带标签函数的模板表达式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals) 时:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "STRINGRAWHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCEGLOBALOBJECTSSTRINGRAWISATAGFUNCTIONNATIVETOJAVASCRIPTES2015", "original": "[`String.raw()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw)\nis a _tag function_ native to JavaScript ES2015.", "translation": "[`String.raw()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw) 是一个 ES2015 原生的*标签函数*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEAOTCOMPILERDOESNOTSUPPORTTAGGEDTEMPLATEEXPRESSIONSAVOIDTHEMINMETADATAEXPRESSIONS", "original": "The AOT compiler does not support tagged template expressions; avoid them in metadata expressions.", "translation": "AOT 编译器不支持带标签函数的模板表达式,避免在元数据表达式中使用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "H3CLASSNOTOCSYMBOLREFERENCEEXPECTEDH3", "original": "<h3 class=\"no-toc\">Symbol reference expected</h3>", "translation": "<h3 class=\"no-toc\">期待是符号引用</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THECOMPILEREXPECTEDAREFERENCETOASYMBOLATTHELOCATIONSPECIFIEDINTHEERRORMESSAGE", "original": "The compiler expected a reference to a symbol at the location specified in the error message.", "translation": "编译器期待在错误信息指出的位置是一个符号引用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISERRORCANOCCURIFYOUUSEANEXPRESSIONINTHEEXTENDSCLAUSEOFACLASS", "original": "This error can occur if you use an expression in the `extends` clause of a class.", "translation": "当你在类的 `extends` 子句中使用表达式时就会出现这个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##PHASE3:BINDINGEXPRESSIONVALIDATION", "original": "## Phase 3: binding expression validation", "translation": "## 阶段 3:验证绑定表达式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "INTHEVALIDATIONPHASETHEANGULARTEMPLATECOMPILERUSESTHETYPESCRIPTCOMPILERTOVALIDATETHEBINDINGEXPRESSIONSINTEMPLATESENABLETHISPHASEEXPLICITYBYADDINGTHECOMPILEROPTIONFULLTEMPLATETYPECHECKINTHEANGULARCOMPILEROPTIONSOFTHEPROJECTSTSCONFIGJSONSEEANGULARCOMPILEROPTIONS#COMPILEROPTIONS", "original": "In the validation phase, the Angular template compiler uses the TypeScript compiler to validate the\n binding expressions in templates. Enable this phase explicity by adding the compiler\n option `\"fullTemplateTypeCheck\"` in the `\"angularCompilerOptions\"` of the project's `tsconfig.json` (see\n [Angular Compiler Options](#compiler-options)).", "translation": "在验证阶段,Angular 的模板编译器会使用 TypeScript 编译器来验证模板中的绑定表达式。\n 通过在项目的 `tsconfig.json`(参见 [Angular Compiler Options](#compiler-options))的 `\"angularCompilerOptions\"` 中添加编译选项 `\"fullTemplateTypeCheck\"` 可以启用这个阶段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "TEMPLATEVALIDATIONPRODUCESERRORMESSAGESWHENATYPEERRORISDETECTEDINATEMPLATEBINDINGEXPRESSIONSIMILARTOHOWTYPEERRORSAREREPORTEDBYTHETYPESCRIPTCOMPILERAGAINSTCODEINATSFILE", "original": "Template validation produces error messages when a type error is detected in a template binding\n expression, similar to how type errors are reported by the TypeScript compiler against code in a `.ts`\n file.", "translation": "当模板绑定表达式中检测到类型错误时,进行模板验证时就会生成错误。这和 TypeScript 编译器在处理 `.ts` 文件中的代码时报告错误很相似。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "FOREXAMPLECONSIDERTHEFOLLOWINGCOMPONENT:", "original": "For example, consider the following component:", "translation": "比如,考虑下列组件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISWILLPRODUCETHEFOLLOWINGERROR:", "original": "This will produce the following error:", "translation": "这会生成如下错误:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEFILENAMEREPORTEDINTHEERRORMESSAGEMYCOMPONENTTSMYCOMPONENTHTMLISASYNTHETICFILEGENERATEDBYTHETEMPLATECOMPILERTHATHOLDSCONTENTSOFTHEMYCOMPONENTCLASSTEMPLATECOMPILERNEVERWRITESTHISFILETODISKTHELINEANDCOLUMNNUMBERSARERELATIVETOTHETEMPLATESTRINGINTHECOMPONENTANNOTATIONOFTHECLASSMYCOMPONENTINTHISCASEIFACOMPONENTUSESTEMPLATEURLINSTEADOFTEMPLATETHEERRORSAREREPORTEDINTHEHTMLFILEREFERENECEDBYTHETEMPLATEURLINSTEADOFASYNTHETICFILE", "original": "The file name reported in the error message, `my.component.ts.MyComponent.html`, is a synthetic file\n generated by the template compiler that holds contents of the `MyComponent` class template.\n Compiler never writes this file to disk. The line and column numbers are relative to the template string\n in the `@Component` annotation of the class, `MyComponent` in this case. If a component uses\n `templateUrl` instead of `template`, the errors are reported in the HTML file refereneced by the\n `templateUrl` instead of a synthetic file.", "translation": "错误信息中汇报的文件名 `my.component.ts.MyComponent.html` 是一个由模板编译器生成出的虚拟文件,\n 用于保存 `MyComponent` 类的模板内容。\n 编译器永远不会把这个文件写入磁盘。这个例子中,这里的行号和列号都是相对于 `MyComponent` 的 `@Component` 注解中的模板字符串的。\n 如果组件使用 `templateUrl` 来代替 `template`,这些错误就会在 `templateUrl` 引用的 HTML 文件中汇报,而不是这个虚拟文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEERRORLOCATIONISTHEBEGINNINGOFTHETEXTNODETHATCONTAINSTHEINTERPOLATIONEXPRESSIONWITHTHEERRORIFTHEERRORISINANATTRIBUTEBINDINGSUCHASVALUEPERSONADDRESSSTREETTHEERRORLOCATIONISTHELOCATIONOFTHEATTRIBUTETHATCONTAINSTHEERROR", "original": "The error location is the beginning of the text node that contains the interpolation expression with\n the error. If the error is in an attribute binding such as `[value]=\"person.address.street\"`, the error\n location is the location of the attribute that contains the error.", "translation": "错误的位置是从包含出错的插值表达式的那个文本节点开始的。\n 如果错误是一个属性绑定,比如 `[value]=\"person.address.street\"` ,错误的位置就是那个包含错误的属性的位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEVALIDATIONUSESTHETYPESCRIPTTYPECHECKERANDTHEOPTIONSSUPPLIEDTOTHETYPESCRIPTCOMPILERTOCONTROLHOWDETAILEDTHETYPEVALIDATIONISFOREXAMPLEIFTHESTRICTTYPECHECKSISSPECIFIEDTHEERRORMYCOMPONENTTSMYCOMPONENTHTML11::OBJECTISPOSSIBLYUNDEFINEDISREPORTEDASWELLASTHEABOVEERRORMESSAGE", "original": "The validation uses the TypeScript type checker and the options supplied to the TypeScript compiler to control\n how detailed the type validation is. For example, if the `strictTypeChecks` is specified, the error ```my.component.ts.MyComponent.html(1,1): : Object is possibly 'undefined'``` is reported as well as the above error message.", "translation": "这个验证过程使用 TypeScript 的类型检查器,这些选项也会提供给 TypeScript 编译器以控制类型验证的详细程度。\n 比如,如果指定了 `strictTypeChecks`,就会像上面的错误信息一样报告 ```my.component.ts.MyComponent.html(1,1): : Object is possibly 'undefined'``` 错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###TYPENARROWING", "original": "### Type narrowing", "translation": "### 类型窄化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THEEXPRESSIONUSEDINANNGIFDIRECTIVEISUSEDTONARROWTYPEUNIONSINTHEANGULARTEMPLATECOMPILERTHESAMEWAYTHEIFEXPRESSIONDOESINTYPESCRIPTFOREXAMPLETOAVOIDOBJECTISPOSSIBLYUNDEFINEDERRORINTHETEMPLATEABOVEMODIFYITTOONLYEMITTHEINTERPOLATIONIFTHEVALUEOFPERSONISINITIALIZEDASSHOWNBELOW:", "original": "The expression used in an `ngIf` directive is used to narrow type unions in the Angular\n template compiler, the same way the `if` expression does in TypeScript. For example, to avoid\n `Object is possibly 'undefined'` error in the template above, modify it to only emit the\n interpolation if the value of `person` is initialized as shown below:", "translation": "在 `ngIf` 指令中使用的表达式用来在 Angular 模板编译器中窄化联合类型,就像 TypeScript 中的 `if` 表达式一样。\n 比如,要在上述模板中消除 `Object is possibly 'undefined'` 错误,可以把它改成只在 `person` 的值初始化过的时候才生成这个插值表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "USINGNGIFALLOWSTHETYPESCRIPTCOMPILERTOINFERTHATTHEPERSONUSEDINTHEBINDINGEXPRESSIONWILLNEVERBEUNDEFINED", "original": "Using `*ngIf` allows the TypeScript compiler to infer that the `person` used in the\n binding expression will never be `undefined`.", "translation": "使用 `*ngIf` 能让 TypeScript 编译器推断出这个绑定表达式中使用的 `person` 永远不会是 `undefined`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "####CUSTOMNGIFLIKEDIRECTIVES", "original": "#### Custom `ngIf` like directives", "translation": "#### 类似于的 `ngIf` 的自定义指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "DIRECTIVESTHATBEHAVELIKENGIFCANDECLARETHATTHEYWANTTHESAMETREATMENTBYINCLUDINGASTATICMEMBERMARKERTHATISASIGNALTOTHETEMPLATECOMPILERTOTREATTHEMLIKENGIFTHISSTATICMEMBERFORNGIFIS:", "original": "Directives that behave like `*ngIf` can declare that they want the same treatment by including\n a static member marker that is a signal to the template compiler to treat them\n like `*ngIf`. This static member for `*ngIf` is:", "translation": "那些行为与 `*ngIf` 类似的指令可以通过包含一个静态成员作为标记,来告诉模板编译器它们希望和 `*ngIf` 享受同等待遇。这个 `*ngIf` 的静态成员就是:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THISDECLARESTHATTHEINPUTPROPERTYNGIFOFTHENGIFDIRECTIVESHOULDBETREATEDASAGUARDTOTHEUSEOFITSTEMPLATEIMPLYINGTHATTHETEMPLATEWILLONLYBEINSTANTIATEDIFTHENGIFINPUTPROPERTYISTRUE", "original": "This declares that the input property `ngIf` of the `NgIf` directive should be treated as a\n guard to the use of its template, implying that the template will only be instantiated if\n the `ngIf` input property is true.", "translation": "它声明了 `NgIf` 指令的 `ngIf` 属性应该在用到它的模板中看做一个守卫,以表明只有当 `ngIf` 这个输入属性为 `true` 时,才应该生成那个模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###NONNULLTYPEASSERTIONOPERATOR", "original": "### Non-null type assertion operator", "translation": "### 非空类型断言操作符", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "USETHENONNULLTYPEASSERTIONOPERATORGUIDETEMPLATESYNTAX#NONNULLASSERTIONOPERATORTOSUPPRESSTHEOBJECTISPOSSIBLYUNDEFINEDERRORWHENITISINCOVIENENTTOUSENGIFORWHENSOMECONSTRAINTINTHECOMPONENTENSURESTHATTHEEXPRESSIONISALWAYSNONNULLWHENTHEBINDINGEXPRESSIONISINTERPOLATED", "original": "Use the [non-null type assertion operator](guide/template-syntax#non-null-assertion-operator)\n to suppress the `Object is possibly 'undefined'` error when it is incovienent to use\n `*ngIf` or when some constraint in the component ensures that the expression is always\n non-null when the binding expression is interpolated.", "translation": "使用 [非空类型断言操作符](guide/template-syntax#non-null-assertion-operator)可以在不方便使用 `*ngIf` 或\n 当组件中的某些约束可以确保这个绑定表达式在求值时永远不会为空时,防止出现 `Object is possibly 'undefined'` 错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "INTHEFOLLOWINGEXAMPLETHEPERSONANDADDRESSPROPERTIESAREALWAYSSETTOGETHERIMPLYINGTHATADDRESSISALWAYSNONNULLIFPERSONISNONNULLTHEREISNOCONVENIENTWAYTODESCRIBETHISCONSTRAINTTOTYPESCRIPTANDTHETEMPLATECOMPILERBUTTHEERRORISSUPPRESSEDINTHEEXAMPLEBYUSINGADDRESSSTREET", "original": "In the following example, the `person` and `address` properties are always set together,\n implying that `address` is always non-null if `person` is non-null. There is no convenient\n way to describe this constraint to TypeScript and the template compiler, but the error\n is suppressed in the example by using `address!.street`.", "translation": "在下列例子中,`person` 和 `address` 属性总是一起出现的,如果 `person` 非空,则 `address` 也一定非空。没有一种简便的写法可以向 TypeScript 和模板编译器描述这种约束。但是这个例子中使用 `address!.street` 避免了报错。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "THENONNULLASSERTIONOPERATORSHOULDBEUSEDSPARINGLYASREFACTORINGOFTHECOMPONENTMIGHTBREAKTHISCONSTRAINT", "original": "The non-null assertion operator should be used sparingly as refactoring of the component\n might break this constraint.", "translation": "应该保守点使用非空断言操作符,因为将来对组件的重构可能会破坏这个约束。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "INTHISEXAMPLEITISRECOMMENDEDTOINCLUDETHECHECKINGOFADDRESSINTHENGIFASSHOWNBELOW:", "original": "In this example it is recommended to include the checking of `address`\n in the `*ngIf`as shown below:", "translation": "这个例子中,更建议在 `*ngIf` 中包含对 `address` 的检查,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "###DISABLINGTYPECHECKINGUSINGANY", "original": "### Disabling type checking using `$any()`", "translation": "### 使用 `$any()` 禁用类型检查", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "DISABLECHECKINGOFABINDINGEXPRESSIONBYSURROUNDINGTHEEXPRESSIONINACALLTOTHEANYCASTPSEUDOFUNCTIONGUIDETEMPLATESYNTAXTHECOMPILERTREATSITASACASTTOTHEANYTYPEJUSTLIKEINTYPESCRIPTWHENAANYORASANYCASTISUSED", "original": "Disable checking of a binding expression by surrounding the expression\n in a call to the [`$any()` cast pseudo-function](guide/template-syntax).\n The compiler treats it as a cast to the `any` type just like in TypeScript when a `<any>`\n or `as any` cast is used.", "translation": "可以通过把绑定表达式包含在[类型转换伪函数 `$any()` ](guide/template-syntax) 中来禁用类型检查。\n 编译器会像在 TypeScript 中使用 `<any>` 或 `as any` 进行类型转换一样对待它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "INTHEFOLLOWINGEXAMPLETHEERRORPROPERTYADDRESSSDOESNOTEXISTISSUPPRESSEDBYCASTINGPERSONTOTHEANYTYPE", "original": "In the following example, the error `Property addresss does not exist` is suppressed\n by casting `person` to the `any` type.", "translation": "下面的例子中,通过把 `person` 转换成 `any` 类型,忽略了 `Property addresss does not exist` 错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "WHATTHEAOTCOMPILERDOESANDWHYITISIMPORTANT", "original": "* What the AOT compiler does and why it is important.", "translation": "什么是 AOT 编译器,以及它为什么如此重要。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "WHYMETADATAMUSTBEWRITTENINASUBSETOFJAVASCRIPT", "original": "* Why metadata must be written in a subset of JavaScript.", "translation": "为何元数据必须使用 JavaScript 的一个子集来书写。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "WHATTHATSUBSETIS", "original": "* What that subset is.", "translation": "这个子集是什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "OTHERRESTRICTIONSONMETADATADEFINITION", "original": "* Other restrictions on metadata definition.", "translation": "定义元数据时的其它限制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "MACROFUNCTIONSANDMACROSTATICMETHODS", "original": "* Macro-functions and macro-static methods.", "translation": "宏函数和静态宏函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "COMPILERERRORSRELATEDTOMETADATA", "original": "* Compiler errors related to metadata.", "translation": "与元数据有关的编译器错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "VALIDATIONOFBINDINGEXPRESSIONS", "original": "* Validation of binding expressions", "translation": "验证绑定表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/aot-compiler.md" }, { + "key": "PROPERTY", "original": "Property", "translation": "属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/api-page-class.md" }, { + "key": "TYPE", "original": "Type", "translation": "绑定类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/api-page-class.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/api-page-class.md" }, { + "key": "TYPE", "original": "Type", "translation": "绑定类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/api-page-class.md" }, { + "key": "TYPE", "original": "Type", "translation": "绑定类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/api-page-class.md" }, { - "original": "# Architecture Overview", + "key": "THEAPPROOTWITHTHENAVIGATIONLINKS", + "original": "* The app root with the navigation links.", + "translation": "带有导航链接的应用根组件。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "THELISTOFHEROES", + "original": "* The list of heroes.", + "translation": "英雄列表。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "THEHEROEDITOR", + "original": "* The hero editor.", + "translation": "英雄编辑器。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "YOUDEFINEACOMPONENTSAPPLICATIONLOGICMDASHWHATITDOESTOSUPPORTTHEVIEWMDASHINSIDEACLASSTHECLASSINTERACTSWITHTHEVIEWTHROUGHANAPIOFPROPERTIESANDMETHODS", + "original": "You define a component's application logic—what it does to support the view—inside a class. The class interacts with the view through an API of properties and methods.", + "translation": "你在类中定义组件的应用逻辑,为视图提供支持。\n组件通过一些由属性和方法组成的 API 与视图交互。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "THEHERONAMEINTERPOLATIONGUIDEDISPLAYINGDATA#INTERPOLATIONDISPLAYSTHECOMPONENTSHERONAMEPROPERTYVALUEWITHINTHELIELEMENT", + "original": "* The `{{hero.name}}` [*interpolation*](guide/displaying-data#interpolation)\ndisplays the component's `hero.name` property value within the `<li>` element.", + "translation": "`{{hero.name}}`[*插值表达式*](guide/displaying-data#interpolation)在 `<li>` 标签中显示组件的 `hero.name` 属性的值。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "THEHEROPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDINGPASSESTHEVALUEOFSELECTEDHEROFROMTHEPARENTHEROLISTCOMPONENTTOTHEHEROPROPERTYOFTHECHILDHERODETAILCOMPONENT", + "original": "* The `[hero]` [*property binding*](guide/template-syntax#property-binding) passes the value of `selectedHero` from\nthe parent `HeroListComponent` to the `hero` property of the child `HeroDetailComponent`.", + "translation": "`[hero]`[*属性绑定*](guide/template-syntax#property-binding)把父组件 `HeroListComponent` 的 `selectedHero` 的值传到子组件 `HeroDetailComponent` 的 `hero` 属性中。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "INTWOWAYBINDINGADATAPROPERTYVALUEFLOWSTOTHEINPUTBOXFROMTHECOMPONENTASWITHPROPERTYBINDINGTHEUSERSCHANGESALSOFLOWBACKTOTHECOMPONENTRESETTINGTHEPROPERTYTOTHELATESTVALUEASWITHEVENTBINDING", + "original": "In two-way binding, a data property value flows to the input box from the component as with property binding.\nThe user's changes also flow back to the component, resetting the property to the latest value,\nas with event binding.", + "translation": "在双向绑定中,数据属性值通过属性绑定从组件流到输入框。用户的修改通过事件绑定流回组件,把属性值设置为最新的值。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "ANGULARPROCESSESALLDATABINDINGSONCEPERJAVASCRIPTEVENTCYCLEFROMTHEROOTOFTHEAPPLICATIONCOMPONENTTREETHROUGHALLCHILDCOMPONENTS", + "original": "Angular processes *all* data bindings once per JavaScript event cycle,\nfrom the root of the application component tree through all child components.", + "translation": "Angular 在每个 JavaScript 事件循环中处理*所有的*数据绑定,它会从组件树的根部开始,递归处理全部子组件。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "###PIPES", + "original": "### Pipes", + "translation": "### 管道", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "THENGMODELDIRECTIVEWHICHIMPLEMENTSTWOWAYDATABINDINGISANEXAMPLEOFANATTRIBUTEDIRECTIVENGMODELMODIFIESTHEBEHAVIOROFANEXISTINGELEMENTTYPICALLYANINPUTBYSETTINGITSDISPLAYVALUEPROPERTYANDRESPONDINGTOCHANGEEVENTS", + "original": "The `ngModel` directive, which implements two-way data binding, is an example of an attribute directive. `ngModel` modifies the behavior of an existing element (typically an `<input>`) by setting its display value property and responding to change events.", + "translation": "`ngModel` 指令就是属性型指令的一个例子,它实现了双向数据绑定。\n`ngModel` 修改现有元素(一般是 `<input>`)的行为:设置其显示属性值,并响应 change 事件。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-components.md" + }, + { + "key": "##NGMODULEMETADATA", + "original": "## NgModule metadata", + "translation": "## `@NgModule` 元数据", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-modules.md" + }, + { + "key": "INJAVASCRIPTEACHFILEISAMODULEANDALLOBJECTSDEFINEDINTHEFILEBELONGTOTHATMODULETHEMODULEDECLARESSOMEOBJECTSTOBEPUBLICBYMARKINGTHEMWITHTHEEXPORTKEYWORDOTHERJAVASCRIPTMODULESUSEIMPORTSTATEMENTSTOACCESSPUBLICOBJECTSFROMOTHERMODULES", + "original": "In JavaScript each _file_ is a module and all objects defined in the file belong to that module.\nThe module declares some objects to be public by marking them with the `export` key word.\nOther JavaScript modules use *import statements* to access public objects from other modules.", + "translation": "JavaScript 中,每个*文件*是一个模块,文件中定义的所有对象都从属于那个模块。\n通过 `export` 关键字,模块可以把它的某些对象声明为公共的。\n其它 JavaScript 模块可以使用*import 语句*来访问这些公共对象。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-modules.md" + }, + { + "key": "AHREFHTTP:EXPLORINGJSCOMES6CHMODULESHTMLLEARNMOREABOUTTHEJAVASCRIPTMODULESYSTEMONTHEWEBA", + "original": "<a href=\"http://exploringjs.com/es6/ch_modules.html\">Learn more about the JavaScript module system on the web.</a>", + "translation": "<a href=\"http://exploringjs.com/es6/ch_modules.html\">学习更多关于 JavaScript 模块的知识。</a>", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-modules.md" + }, + { + "key": "FOREXAMPLEIMPORTANGULARSCOMPONENTDECORATORFROMTHEANGULARCORELIBRARYLIKETHIS:", + "original": "For example, import Angular's `Component` decorator from the `@angular/core` library like this:", + "translation": "例如,象下面这样,从 `@angular/core` 库中导入 `Component` 装饰器:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-modules.md" + }, + { + "key": "YOUALSOIMPORTNGMODULESFROMANGULARLIBRARIESUSINGJAVASCRIPTIMPORTSTATEMENTS:", + "original": "You also import NgModules from Angular _libraries_ using JavaScript import statements:", + "translation": "还可以使用 JavaScript 的导入语句从 Angular *库*中导入 Angular *模块*:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-modules.md" + }, + { + "key": "LEARNMOREFROMTHENGMODULESGUIDENGMODULESPAGE", + "original": "Learn more from the [NgModules](guide/ngmodules) page.", + "translation": "更多信息,参见 [NgModules](guide/ngmodules)。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-modules.md" + }, + { + "key": "HERESANEXAMPLEOFASERVICECLASSTHATLOGSTOTHEBROWSERCONSOLE:", + "original": "Here's an example of a service class that logs to the browser console:", + "translation": "下面是一个服务类的范例,用于把日志记录到浏览器的控制台:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-services.md" + }, + { + "key": "##DEPENDENCYINJECTION", + "original": "## Dependency injection", + "translation": "## 依赖注入(dependency injection)", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture-services.md" + }, + { + "key": "#ARCHITECTUREOVERVIEW", + "original": "# Architecture overview", "translation": "# 架构概览", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" }, { - "original": "Angular is a framework for building client applications in HTML and\neither JavaScript or a language like TypeScript that compiles to JavaScript.", - "translation": "Angular 是一个用 HTML 和 JavaScript 或者一个可以编译成 JavaScript 的语言(例如 Dart 或者 TypeScript ),来构建客户端应用的框架。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The framework consists of several libraries, some of them core and some optional.", - "translation": "该框架包括一系列库,有些是核心库,有些是可选库。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "You write Angular applications by composing HTML *templates* with Angularized markup,\nwriting *component* classes to manage those templates, adding application logic in *services*,\nand boxing components and services in *modules*.", - "translation": "你是这样编写 Angular 应用的:用 Angular 扩展语法编写 HTML *模板*,\n用*组件*类管理这些模板,用*服务*添加应用逻辑,\n用*模块*打包发布组件与服务。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Then you launch the app by *bootstrapping* the _root module_.\nAngular takes over, presenting your application content in a browser and\nresponding to user interactions according to the instructions you've provided.", - "translation": "然后,你通过*引导**根模块*来启动该应用。\nAngular 在浏览器中接管、展现应用的内容,并根据你提供的操作指令响应用户的交互。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Of course, there is more to it than this.\nYou'll learn the details in the pages that follow. For now, focus on the big picture.", - "translation": "当然,这只是冰山一角。后面你还会学到更多的细节。不过,目前还是先关注全景图吧。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The code referenced on this page is available as a <live-example></live-example>.", - "translation": "本章所引用的代码见<live-example></live-example>。", + "key": "ANGULARISAPLATFORMANDFRAMEWORKFORBUILDINGCLIENTAPPLICATIONSINHTMLANDTYPESCRIPTANGULARISITSELFWRITTENINTYPESCRIPTITIMPLEMENTSCOREANDOPTIONALFUNCTIONALITYASASETOFTYPESCRIPTLIBRARIESTHATYOUIMPORTINTOYOURAPPS", + "original": "Angular is a platform and framework for building client applications in HTML and TypeScript.\nAngular is itself written in TypeScript. It implements core and optional functionality as a set of TypeScript libraries that you import into your apps.", + "translation": "Angular 是一个用 HTML 和 JavaScript 或者一个可以编译成 JavaScript 的语言(例如 Dart 或者 TypeScript ),来构建客户端应用的平台和框架。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" }, { + "key": "##MODULES", "original": "## Modules", "translation": "## 模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" }, { - "original": "Angular apps are modular and Angular has its own modularity system called _NgModules_.", - "translation": "Angular 应用是模块化的,并且 Angular 有自己的模块系统,它被称为 *Angular 模块*或 *NgModules*。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "NgModules are a big deal.\nThis page introduces modules; the [NgModules](guide/ngmodules) pages \nrelating to NgModules covers them in detail.", - "translation": "NgModules 很重要。这里只是简单介绍,在 [NgModules](guide/ngmodules)中会做深入讲解。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Every Angular app has at least one NgModule class, [the _root module_](guide/bootstrapping \"Bootstrapping\"),\nconventionally named `AppModule`.", - "translation": "每个 Angular 应用至少有一个模块([*根模块*](guide/bootstrapping \"引导启动\")),习惯上命名为 `AppModule`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "While the _root module_ may be the only module in a small application, most apps have many more\n_feature modules_, each a cohesive block of code dedicated to an application domain,\na workflow, or a closely related set of capabilities.", - "translation": "*根模块*在一些小型应用中可能是唯一的模块,大多数应用会有很多*特性模块*,每个模块都是一个内聚的代码块专注于某个应用领域、工作流或紧密相关的功能。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "An NgModule, whether a _root_ or _feature_, is a class with an `@NgModule` decorator.", - "translation": "Angular 模块(无论是*根模块*还是*特性模块*)都是一个带有 `@NgModule` 装饰器的类。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Decorators are functions that modify JavaScript classes.\n Angular has many decorators that attach metadata to classes so that it knows\n what those classes mean and how they should work.\n <a href=\"https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.x5c2ndtx0\">\n Learn more</a> about decorators on the web.", - "translation": "装饰器是用来修饰 JavaScript 类的函数。\nAngular 有很多装饰器,它们负责把元数据附加到类上,以了解那些类的设计意图以及它们应如何工作。\n关于装饰器的<a href=\"https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.x5c2ndtx0\" target=\"_blank\">更多信息</a>。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "`NgModule` is a decorator function that takes a single metadata object whose properties describe the module.\nThe most important properties are:", - "translation": "`NgModule` 是一个装饰器函数,它接收一个用来描述模块属性的元数据对象。其中最重要的属性是:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* `declarations` - the _view classes_ that belong to this module.\nAngular has three kinds of view classes: [components](guide/architecture#components), [directives](guide/architecture#directives), and [pipes](guide/pipes).", - "translation": "`declarations` - 声明本模块中拥有的*视图类*。Angular 有三种视图类:[组件](guide/architecture#components)、[指令](guide/architecture#directives)和[管道](guide/pipes)。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* `exports` - the subset of declarations that should be visible and usable in the component [templates](guide/architecture#templates) of other modules.", - "translation": "`exports` - declarations 的子集,可用于其它模块的组件[模板](guide/architecture#templates)。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* `imports` - other modules whose exported classes are needed by component templates declared in _this_ module.", - "translation": "`imports` - *本*模块声明的组件模板需要的类所在的其它模块。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* `providers` - creators of [services](guide/architecture#services) that this module contributes to\nthe global collection of services; they become accessible in all parts of the app.", - "translation": "`providers` - [服务](guide/architecture#services)的创建者,并加入到全局服务列表中,可用于应用任何部分。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* `bootstrap` - the main application view, called the _root component_,\nthat hosts all other app views. Only the _root module_ should set this `bootstrap` property.", - "translation": "`bootstrap` - 指定应用的主视图(称为*根组件*),它是所有其它视图的宿主。只有*根模块*才能设置 `bootstrap` 属性。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Here's a simple root module:", - "translation": "下面是一个简单的根模块:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The `export` of `AppComponent` is just to show how to use the `exports` array to export a component; it isn't actually necessary in this example. A root module has no reason to _export_ anything because other components don't need to _import_ the root module.", - "translation": "`AppComponent` 的 `export` 语句只是用于演示如何导出的,它在这个例子中并不是必须的。根模块不需要*导出*任何东西,因为其它组件不需要导入根模块。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Launch an application by _bootstrapping_ its root module.\nDuring development you're likely to bootstrap the `AppModule` in a `main.ts` file like this one.", - "translation": "通过*引导*根模块来启动应用。\n在开发期间,你通常在一个 `main.ts` 文件中引导 `AppModule`,就像这样:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "### NgModules vs. JavaScript modules", - "translation": "### NgModules vs. JavaScript 模块", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The NgModule — a class decorated with `@NgModule` — is a fundamental feature of Angular.", - "translation": "NgModule(一个带 `@NgModule` 装饰器的类)是 Angular 的基础特性之一。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "JavaScript also has its own module system for managing collections of JavaScript objects.\nIt's completely different and unrelated to the NgModule system.", - "translation": "JavaScript 也有自己的模块系统,用来管理一组 JavaScript 对象。\n它与 Angular 的模块系统完全不同且完全无关。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In JavaScript each _file_ is a module and all objects defined in the file belong to that module.\nThe module declares some objects to be public by marking them with the `export` key word.\nOther JavaScript modules use *import statements* to access public objects from other modules.", - "translation": "JavaScript 中,每个*文件*是一个模块,文件中定义的所有对象都从属于那个模块。\n通过 `export` 关键字,模块可以把它的某些对象声明为公共的。\n其它 JavaScript 模块可以使用*import 语句*来访问这些公共对象。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "<a href=\"http://exploringjs.com/es6/ch_modules.html\">Learn more about the JavaScript module system on the web.</a>", - "translation": "<a href=\"http://exploringjs.com/es6/ch_modules.html\">学习更多关于 JavaScript 模块的知识。</a>", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "These are two different and _complementary_ module systems. Use them both to write your apps.", - "translation": "这两个模块化系统是不同但*互补*的,你在写程序时都会用到。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "### Angular libraries", - "translation": "### Angular 模块库", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular ships as a collection of JavaScript modules. You can think of them as library modules.", - "translation": "Angular 提供了一组 JavaScript 模块。可以把它们看做库模块。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Each Angular library name begins with the `@angular` prefix.", - "translation": "每个 Angular 库的名字都带有 `@angular` 前缀。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "You install them with the **npm** package manager and import parts of them with JavaScript `import` statements.", - "translation": "用 **npm** 包管理工具安装它们,用 JavaScript 的 `import` 语句导入其中某些部件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "For example, import Angular's `Component` decorator from the `@angular/core` library like this:", - "translation": "例如,象下面这样,从 `@angular/core` 库中导入 `Component` 装饰器:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "You also import NgModules from Angular _libraries_ using JavaScript import statements:", - "translation": "还可以使用 JavaScript 的导入语句从 Angular *库*中导入 Angular *模块*:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In the example of the simple root module above, the application module needs material from within that `BrowserModule`. To access that material, add it to the `@NgModule` metadata `imports` like this.", - "translation": "在上面那个简单的根模块的例子中,应用模块需要 `BrowserModule` 的某些素材。要访问这些素材,就得把它加入 `@NgModule` 元数据的 `imports` 中,就像这样:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In this way you're using both the Angular and JavaScript module systems _together_.", - "translation": "这种情况下,你同时使用了 Angular 和 JavaScript 的模块化系统。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "It's easy to confuse the two systems because they share the common vocabulary of \"imports\" and \"exports\".\nHang in there. The confusion yields to clarity with time and experience.", - "translation": "这两个系统比较容易混淆,因为它们共享相同的词汇 “imports” 和 “exports”。不过没关系,先放一放,随着时间和经验的增长,自然就清楚了。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Learn more from the [NgModules](guide/ngmodules) page.", - "translation": "更多信息,参见 [NgModules](guide/ngmodules)。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { + "key": "##COMPONENTS", "original": "## Components", "translation": "## 组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" }, { - "original": "A _component_ controls a patch of screen called a *view*.", - "translation": "*组件*负责控制屏幕上的一小块区域叫做*视图*。", + "key": "ENTERAURLINTHEADDRESSBARANDTHEBROWSERNAVIGATESTOACORRESPONDINGPAGE", + "original": "* Enter a URL in the address bar and the browser navigates to a corresponding page.", + "translation": "在地址栏输入 URL,浏览器就会导航到相应的页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" }, { - "original": "For example, the following views are controlled by components:", - "translation": "例如,下列视图都是由组件控制的:", + "key": "CLICKLINKSONTHEPAGEANDTHEBROWSERNAVIGATESTOANEWPAGE", + "original": "* Click links on the page and the browser navigates to a new page.", + "translation": "在页面中点击链接,浏览器就会导航到一个新页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" }, { - "original": "* The app root with the navigation links.", - "translation": "带有导航链接的应用根组件。", + "key": "CLICKTHEBROWSERSBACKANDFORWARDBUTTONSANDTHEBROWSERNAVIGATESBACKWARDANDFORWARDTHROUGHTHEHISTORYOFPAGESYOUVESEEN", + "original": "* Click the browser's back and forward buttons and the browser navigates backward and forward through the history of pages you've seen.", + "translation": "点击浏览器的前进和后退按钮,浏览器就会在你的浏览历史中向前或向后导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" }, { - "original": "* The list of heroes.", - "translation": "英雄列表。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* The hero editor.", - "translation": "英雄编辑器。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "You define a component's application logic—what it does to support the view—inside a class.\nThe class interacts with the view through an API of properties and methods.", - "translation": "你在类中定义组件的应用逻辑,为视图提供支持。\n组件通过一些由属性和方法组成的 API 与视图交互。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "For example, this `HeroListComponent` has a `heroes` property that returns an array of heroes\nthat it acquires from a service.\n`HeroListComponent` also has a `selectHero()` method that sets a `selectedHero` property when the user clicks to choose a hero from that list.", - "translation": "例如,`HeroListComponent` 有一个 `heroes` 属性,它返回一个英雄数组,这个数组从一个服务获得。\n`HeroListComponent` 还有一个当用户从列表中点选一个英雄时设置 `selectedHero` 属性的 `selectHero()` 方法。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular creates, updates, and destroys components as the user moves through the application.\nYour app can take action at each moment in this lifecycle through optional [lifecycle hooks](guide/lifecycle-hooks), like `ngOnInit()` declared above.", - "translation": "当用户在这个应用中漫游时, Angular 会创建、更新和销毁组件。\n应用可以通过[生命周期钩子](guide/lifecycle-hooks)在组件生命周期的各个时间点上插入自己的操作,例如上面声明的 `ngOnInit()`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "## Templates", - "translation": "## 模板", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "You define a component's view with its companion **template**. A template is a form of HTML\nthat tells Angular how to render the component.", - "translation": "你通过组件的自带的**模板**来定义组件视图。模板以 HTML 形式存在,告诉 Angular 如何渲染组件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "A template looks like regular HTML, except for a few differences. Here is a\ntemplate for our `HeroListComponent`:", - "translation": "多数情况下,模板看起来很像标准 HTML,当然也有一点不同的地方。下面是 `HeroListComponent` 组件的一个模板:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Although this template uses typical HTML elements like `<h2>` and `<p>`, it also has some differences. Code like `*ngFor`, `{{hero.name}}`, `(click)`, `[hero]`, and `<app-hero-detail>` uses Angular's [template syntax](guide/template-syntax).", - "translation": "模板除了可以使用像 `<h2>` 和 `<p>` 这样的典型的 HTML 元素,还能使用其它元素。\n例如,像 `*ngFor`、`{{hero.name}}`、`(click)`、`[hero]` 和 `<app-hero-detail>` 这样的代码使用了 Angular 的[模板语法](guide/template-syntax)。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In the last line of the template, the `<app-hero-detail>` tag is a custom element that represents a new component, `HeroDetailComponent`.", - "translation": "在模板的最后一行,`<app-hero-detail>` 标签就是一个用来表示新组件 `HeroDetailComponent` 的自定义元素。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The `HeroDetailComponent` is a *different* component than the `HeroListComponent` you've been reviewing.\nThe `HeroDetailComponent` (code not shown) presents facts about a particular hero, the\nhero that the user selects from the list presented by the `HeroListComponent`.\nThe `HeroDetailComponent` is a **child** of the `HeroListComponent`.", - "translation": "`HeroDetailComponent` 跟以前见到过的 `HeroListComponent` 是*不同*的组件。\n`HeroDetailComponent`(代码未显示)用于展现一个特定英雄的情况,这个英雄是用户从 `HeroListComponent` 列表中选择的。\n`HeroDetailComponent` 是 `HeroListComponent` 的*子组件*。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Notice how `<app-hero-detail>` rests comfortably among native HTML elements. Custom components mix seamlessly with native HTML in the same layouts.", - "translation": "注意到了吗?`<app-hero-detail>` 舒适地躺在原生 HTML 元素之间。\n自定义组件和原生 HTML 在同一布局中融合得天衣无缝。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "## Metadata", - "translation": "## 元数据", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Metadata tells Angular how to process a class.", - "translation": "元数据告诉 Angular 如何处理一个类。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "[Looking back at the code](guide/architecture#component-code) for `HeroListComponent`, you can see that it's just a class.\nThere is no evidence of a framework, no \"Angular\" in it at all.", - "translation": "[回头看看](guide/architecture#component-code)`HeroListComponent` 就会明白:它只是一个类。\n一点框架的痕迹也没有,里面完全没有出现 \"Angular\" 的字样。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In fact, `HeroListComponent` really is *just a class*. It's not a component until you *tell Angular about it*.", - "translation": "实际上,`HeroListComponent` 真的*只是一个类*。直到你*告诉 Angular* 它是一个组件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "To tell Angular that `HeroListComponent` is a component, attach **metadata** to the class.", - "translation": "要告诉 Angular `HeroListComponent` 是个组件,只要把**元数据**附加到这个类。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In TypeScript, you attach metadata by using a **decorator**.\nHere's some metadata for `HeroListComponent`:", - "translation": "在 TypeScript 中,你要用**装饰器 (decorator) **来附加元数据。\n下面就是 `HeroListComponent` 的一些元数据。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Here is the `@Component` decorator, which identifies the class\nimmediately below it as a component class.", - "translation": "这里看到 `@Component` 装饰器,它把紧随其后的类标记成了组件类。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The `@Component` decorator takes a required configuration object with the\ninformation Angular needs to create and present the component and its view.", - "translation": "`@Component` 装饰器能接受一个配置对象, Angular 会基于这些信息创建和展示组件及其视图。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Here are a few of the most useful `@Component` configuration options:", - "translation": "`@Component` 的配置项包括:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* `selector`: CSS selector that tells Angular to create and insert an instance of this component\nwhere it finds a `<app-hero-list>` tag in *parent* HTML.\nFor example, if an app's HTML contains `<app-hero-list></app-hero-list>`, then\nAngular inserts an instance of the `HeroListComponent` view between those tags.", - "translation": "`selector`: CSS 选择器,它告诉 Angular 在*父级* HTML 中查找 `<app-hero-list>` 标签,创建并插入该组件。\n 例如,如果应用的 HTML 包含 `<app-hero-list></app-hero-list>`, Angular 就会把 `HeroListComponent` 的一个实例插入到这个标签中。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* `templateUrl`: module-relative address of this component's HTML template, shown [above](guide/architecture#templates).", - "translation": "`templateUrl`:组件 HTML 模板的模块相对地址,[如前所示](guide/architecture#templates)。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* `providers`: array of **dependency injection providers** for services that the component requires.\nThis is one way to tell Angular that the component's constructor requires a `HeroService`\nso it can get the list of heroes to display.", - "translation": "`providers` - 组件所需服务的*依赖注入提供商*数组。\n这是在告诉 Angular:该组件的构造函数需要一个 `HeroService` 服务,这样组件就可以从服务中获得英雄数据。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The metadata in the `@Component` tells Angular where to get the major building blocks you specify for the component.", - "translation": "`@Component` 里面的元数据会告诉 Angular 从哪里获取你为组件指定的主要的构建块。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The template, metadata, and component together describe a view.", - "translation": "模板、元数据和组件共同描绘出这个视图。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Apply other metadata decorators in a similar fashion to guide Angular behavior.\n`@Injectable`, `@Input`, and `@Output` are a few of the more popular decorators.", - "translation": "其它元数据装饰器用类似的方式来指导 Angular 的行为。\n例如 `@Injectable`、`@Input` 和 `@Output` 等是一些最常用的装饰器。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The architectural takeaway is that you must add metadata to your code\nso that Angular knows what to do.", - "translation": "这种架构处理方式是:你向代码中添加元数据,以便 Angular 知道该怎么做。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "## Data binding", - "translation": "## 数据绑定 (data binding)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Without a framework, you would be responsible for pushing data values into the HTML controls and turning user responses\ninto actions and value updates. Writing such push/pull logic by hand is tedious, error-prone, and a nightmare to\nread as any experienced jQuery programmer can attest.", - "translation": "如果没有框架,你就得自己把数据值推送到 HTML 控件中,并把用户的反馈转换成动作和值更新。\n如果手工写代码来实现这些推/拉逻辑,肯定会枯燥乏味、容易出错,读起来简直是噩梦 —— 写过 jQuery 的程序员大概都对此深有体会。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular supports **data binding**,\na mechanism for coordinating parts of a template with parts of a component.\nAdd binding markup to the template HTML to tell Angular how to connect both sides.", - "translation": "Angular 支持**数据绑定**,一种让模板的各部分与组件的各部分相互合作的机制。\n往模板 HTML 中添加绑定标记,来告诉 Angular 如何把二者联系起来。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "As the diagram shows, there are four forms of data binding syntax. Each form has a direction — to the DOM, from the DOM, or in both directions.", - "translation": "如图所示,数据绑定的语法有四种形式。每种形式都有一个方向 —— 绑定到 DOM 、绑定自 DOM 以及双向绑定。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The `HeroListComponent` [example](guide/architecture#templates) template has three forms:", - "translation": "`HeroListComponent`[示例](guide/architecture#templates)模板中有三种形式:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* The `{{hero.name}}` [*interpolation*](guide/displaying-data#interpolation)\ndisplays the component's `hero.name` property value within the `<li>` element.", - "translation": "`{{hero.name}}`[*插值表达式*](guide/displaying-data#interpolation)在 `<li>` 标签中显示组件的 `hero.name` 属性的值。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* The `[hero]` [*property binding*](guide/template-syntax#property-binding) passes the value of `selectedHero` from\nthe parent `HeroListComponent` to the `hero` property of the child `HeroDetailComponent`.", - "translation": "`[hero]`[*属性绑定*](guide/template-syntax#property-binding)把父组件 `HeroListComponent` 的 `selectedHero` 的值传到子组件 `HeroDetailComponent` 的 `hero` 属性中。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* The `(click)` [*event binding*](guide/user-input#click) calls the component's `selectHero` method when the user clicks a hero's name.", - "translation": "`(click)` [*事件绑定*](guide/user-input#click)在用户点击英雄的名字时调用组件的 `selectHero` 方法。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "**Two-way data binding** is an important fourth form\nthat combines property and event binding in a single notation, using the `ngModel` directive.\nHere's an example from the `HeroDetailComponent` template:", - "translation": "**双向数据绑定**是重要的第四种绑定形式,它使用 `ngModel` 指令组合了属性绑定和事件绑定的功能。\n下面是 `HeroDetailComponent` 模板的范例:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In two-way binding, a data property value flows to the input box from the component as with property binding.\nThe user's changes also flow back to the component, resetting the property to the latest value,\nas with event binding.", - "translation": "在双向绑定中,数据属性值通过属性绑定从组件流到输入框。用户的修改通过事件绑定流回组件,把属性值设置为最新的值。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular processes *all* data bindings once per JavaScript event cycle,\nfrom the root of the application component tree through all child components.", - "translation": "Angular 在每个 JavaScript 事件循环中处理*所有的*数据绑定,它会从组件树的根部开始,递归处理全部子组件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Data binding plays an important role in communication between a template and its component.", - "translation": "数据绑定在模板与对应组件的交互中扮演了重要的角色。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Data binding is also important for communication between parent and child components.", - "translation": "数据绑定在父组件与子组件的通讯中也同样重要。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "## Directives", - "translation": "## 指令", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular templates are *dynamic*. When Angular renders them, it transforms the DOM\naccording to the instructions given by **directives**.", - "translation": "Angular 模板是*动态的*。当 Angular 渲染它们时,它会根据**指令**提供的操作对 DOM 进行转换。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "A directive is a class with a `@Directive` decorator.\nA component is a *directive-with-a-template*;\na `@Component` decorator is actually a `@Directive` decorator extended with template-oriented features.", - "translation": "组件是一个*带模板的指令*;`@Component` 装饰器实际上就是一个 `@Directive` 装饰器,只是扩展了一些面向模板的特性。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "While **a component is technically a directive**,\n components are so distinctive and central to Angular applications that this architectural overview separates components from directives.", - "translation": "虽然**严格来说组件就是一个指令**,但是组件非常独特,并在 Angular 中位于中心地位,所以在架构概览中把组件从指令中独立了出来。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Two *other* kinds of directives exist: _structural_ and _attribute_ directives.", - "translation": "还有两种*其它*类型的指令:*结构型*指令和*属性 (attribute) 型*指令。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "They tend to appear within an element tag as attributes do,\nsometimes by name but more often as the target of an assignment or a binding.", - "translation": "它们往往像属性 (attribute) 一样出现在元素标签中,\n偶尔会以名字的形式出现,但多数时候还是作为赋值目标或绑定目标出现。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "**Structural** directives alter layout by adding, removing, and replacing elements in DOM.", - "translation": "**结构型**指令通过在 DOM 中添加、移除和替换元素来修改布局。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The [example template](guide/architecture#templates) uses two built-in structural directives:", - "translation": "下面的[范例模板](guide/architecture#templates)中用到了两个内置的结构型指令:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [`*ngFor`](guide/displaying-data#ngFor) tells Angular to stamp out one `<li>` per hero in the `heroes` list.", - "translation": "[`*ngFor`](guide/displaying-data#ngFor)告诉 Angular 为 `heroes` 列表中的每个英雄生成一个 `<li>` 标签。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [`*ngIf`](guide/displaying-data#ngIf) includes the `HeroDetail` component only if a selected hero exists.", - "translation": "[`*ngIf`](guide/displaying-data#ngIf)表示只有在选择的英雄存在时,才会包含 `HeroDetail` 组件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "**Attribute** directives alter the appearance or behavior of an existing element.\nIn templates they look like regular HTML attributes, hence the name.", - "translation": "**属性型** 指令修改一个现有元素的外观或行为。\n在模板中,它们看起来就像是标准的 HTML 属性,故名。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The `ngModel` directive, which implements two-way data binding, is\nan example of an attribute directive. `ngModel` modifies the behavior of\nan existing element (typically an `<input>`)\nby setting its display value property and responding to change events.", - "translation": "`ngModel` 指令就是属性型指令的一个例子,它实现了双向数据绑定。\n`ngModel` 修改现有元素(一般是 `<input>`)的行为:设置其显示属性值,并响应 change 事件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular has a few more directives that either alter the layout structure\n(for example, [ngSwitch](guide/template-syntax#ngSwitch))\nor modify aspects of DOM elements and components\n(for example, [ngStyle](guide/template-syntax#ngStyle) and [ngClass](guide/template-syntax#ngClass)).", - "translation": "Angular 还有少量指令,它们或者修改结构布局(例如 [ngSwitch](guide/template-syntax#ngSwitch)),\n或者修改 DOM 元素和组件的各个方面(例如 [ngStyle](guide/template-syntax#ngStyle)和 [ngClass](guide/template-syntax#ngClass))。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Of course, you can also write your own directives. Components such as\n`HeroListComponent` are one kind of custom directive.", - "translation": "当然,你也能编写自己的指令。像 `HeroListComponent` 这样的组件就是一种自定义指令。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "## Services", - "translation": "## 服务", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "_Service_ is a broad category encompassing any value, function, or feature that your application needs.", - "translation": "*服务*是一个广义范畴,包括:值、函数,或应用所需的特性。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Almost anything can be a service.\nA service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.", - "translation": "几乎任何东西都可以是一个服务。\n典型的服务是一个类,具有专注的、明确的用途。它应该做一件特定的事情,并把它做好。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Examples include:", - "translation": "例如:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* logging service", - "translation": "日志服务", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* data service", - "translation": "数据服务", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* message bus", - "translation": "消息总线", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* tax calculator", - "translation": "税款计算器", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* application configuration", - "translation": "应用程序配置", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "There is nothing specifically _Angular_ about services. Angular has no definition of a service.\nThere is no service base class, and no place to register a service.", - "translation": "服务没有什么特别属于 *Angular* 的特性。 Angular 对于服务也没有什么定义。\n它甚至都没有定义服务的基类,也没有地方注册一个服务。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Yet services are fundamental to any Angular application. Components are big consumers of services.", - "translation": "即便如此,服务仍然是任何 Angular 应用的基础。组件就是最大的*服务*消费者。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Here's an example of a service class that logs to the browser console:", - "translation": "下面是一个服务类的范例,用于把日志记录到浏览器的控制台:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Here's a `HeroService` that uses a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to fetch heroes.\nThe `HeroService` depends on the `Logger` service and another `BackendService` that handles the server communication grunt work.", - "translation": "下面是 `HeroService` 类,用于获取英雄数据,并通过一个已解析的[承诺 (Promise)](http://exploringjs.com/es6/ch_promises.html) 返回它们。\n`HeroService` 还依赖于 `Logger` 服务和另一个用于处理服务器通讯的 `BackendService` 服务。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Services are everywhere.", - "translation": "服务无处不在。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Component classes should be lean. They don't fetch data from the server,\nvalidate user input, or log directly to the console.\nThey delegate such tasks to services.", - "translation": "组件类应保持精简。组件本身不从服务器获得数据、不进行验证输入,也不直接往控制台写日志。\n它们把这些任务委托给服务。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "A component's job is to enable the user experience and nothing more. It mediates between the view (rendered by the template)\nand the application logic (which often includes some notion of a _model_).\nA good component presents properties and methods for data binding.\nIt delegates everything nontrivial to services.", - "translation": "组件的任务就是提供用户体验,仅此而已。它介于视图(由模板渲染)和应用逻辑(通常包括*模型*的某些概念)之间。\n设计良好的组件为数据绑定提供属性和方法,把其它琐事都委托给服务。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular doesn't *enforce* these principles.\nIt won't complain if you write a \"kitchen sink\" component with 3000 lines.", - "translation": "Angular 不会*强行保障*这些原则。\n即使你花 3000 行代码写了一个“厨房洗碗槽”组件,它也不会抱怨什么。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular does help you *follow* these principles by making it easy to factor your\napplication logic into services and make those services available to components through *dependency injection*.", - "translation": "Angular 帮助你*遵循*这些原则 —— 它让你能轻易地把应用逻辑拆分到服务,并通过*依赖注入*来在组件中使用这些服务。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "## Dependency injection", - "translation": "## 依赖注入(dependency injection)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "_Dependency injection_ is a way to supply a new instance of a class\nwith the fully-formed dependencies it requires. Most dependencies are services.\nAngular uses dependency injection to provide new components with the services they need.", - "translation": "“依赖注入”是提供类的新实例的一种方式,还负责处理好类所需的全部依赖。大多数依赖都是服务。\nAngular 使用依赖注入来提供新组件以及组件所需的服务。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Angular can tell which services a component needs by looking at the types of its constructor parameters.\nFor example, the constructor of your `HeroListComponent` needs a `HeroService`:", - "translation": "Angular 通过查看构造函数的参数类型得知组件需要哪些服务。\n例如,`HeroListComponent` 组件的构造函数需要一个 `HeroService` 服务:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "When Angular creates a component, it first asks an **injector** for\nthe services that the component requires.", - "translation": "当 Angular 创建组件时,会首先为组件所需的服务请求一个**注入器 (injector)**。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "An injector maintains a container of service instances that it has previously created.\nIf a requested service instance is not in the container, the injector makes one and adds it to the container\nbefore returning the service to Angular.\nWhen all requested services have been resolved and returned,\nAngular can call the component's constructor with those services as arguments.\nThis is *dependency injection*.", - "translation": "注入器维护了一个服务实例的容器,存放着以前创建的实例。\n如果所请求的服务实例不在容器中,注入器就会创建一个服务实例,并且添加到容器中,然后把这个服务返回给 Angular。\n当所有请求的服务都被解析完并返回时,Angular 会以这些服务为参数去调用组件的构造函数。\n这就是*依赖注入* 。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "The process of `HeroService` injection looks a bit like this:", - "translation": "`HeroService` 注入的过程差不多是这样的:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "If the injector doesn't have a `HeroService`, how does it know how to make one?", - "translation": "如果注入器还没有 `HeroService`,它怎么知道该如何创建一个呢?", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In brief, you must have previously registered a **provider** of the `HeroService` with the injector.\nA provider is something that can create or return a service, typically the service class itself.", - "translation": "简单点说,你必须先用注入器(injector)为 `HeroService` 注册一个**提供商(provider)**。\n提供商用来创建或返回服务,通常就是这个服务类本身(相当于 `new HeroService()`)。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "You can register providers in modules or in components.", - "translation": "你可以在模块中或组件中注册提供商。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "In general, add providers to the [root module](guide/architecture#modules) so that\nthe same instance of a service is available everywhere.", - "translation": "但通常会把提供商添加到[根模块](guide/architecture#modules)上,以便在任何地方都使用服务的同一个实例。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Alternatively, register at a component level in the `providers` property of the `@Component` metadata:", - "translation": "或者,也可以在 `@Component` 元数据中的 `providers` 属性中把它注册在组件层:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Registering at a component level means you get a new instance of the\nservice with each new instance of that component.", - "translation": "把它注册在组件级表示该组件的每一个新实例都会有一个服务的新实例。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "<!-- We've vastly oversimplified dependency injection for this overview.\nThe full story is in the [dependency injection](guide/dependency-injection) page. -->", - "translation": "<!--在这个概览中,我们过度简化了依赖注入机制。\n详见[依赖注入](guide/dependency-injection)页 -->", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Points to remember about dependency injection:", - "translation": "需要记住的关于依赖注入的要点是:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* Dependency injection is wired into the Angular framework and used everywhere.", - "translation": "依赖注入渗透在整个 Angular 框架中,被到处使用。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* The *injector* is the main mechanism.", - "translation": "**注入器 (injector)** 是本机制的核心。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* An injector maintains a *container* of service instances that it created.", - "translation": "注入器负责维护一个*容器*,用于存放它创建过的服务实例。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* An injector can create a new service instance from a *provider*.", - "translation": "注入器能使用*提供商*创建一个新的服务实例。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* A *provider* is a recipe for creating a service.", - "translation": "*提供商*是一个用于创建服务的配方。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* Register *providers* with injectors.", - "translation": "把*提供商*注册到注入器。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "## Wrap up", - "translation": "## 总结", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "You've learned the basics about the eight main building blocks of an Angular application:", - "translation": "你学到的这些只是关于 Angular 应用程序的八个主要构造块的基础知识:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [Modules](guide/architecture#modules)", - "translation": "[模块](guide/architecture#modules)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [Components](guide/architecture#components)", - "translation": "[组件](guide/architecture#components)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [Templates](guide/architecture#templates)", - "translation": "[模板](guide/architecture#templates)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [Metadata](guide/architecture#metadata)", - "translation": "[元数据](guide/architecture#metadata)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [Data binding](guide/architecture#data-binding)", - "translation": "[数据绑定](guide/architecture#data-binding)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [Directives](guide/architecture#directives)", - "translation": "[指令](guide/architecture#directives)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [Services](guide/architecture#services)", - "translation": "[服务](guide/architecture#services)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "* [Dependency injection](guide/architecture#dependency-injection)", - "translation": "[依赖注入](guide/architecture#dependency-injection)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "That's a foundation for everything else in an Angular application,\nand it's more than enough to get going.\nBut it doesn't include everything you need to know.", - "translation": "这是 Angular 应用程序中所有其它东西的基础,要使用 Angular,以这些作为开端就绰绰有余了。\n但它仍然没有包含你需要知道的一切。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "Here is a brief, alphabetical list of other important Angular features and services.\nMost of them are covered in this documentation (or soon will be).", - "translation": "这里是一个简短的、按字母排序的列表,列出了其它重要的 Angular 特性和服务。\n它们大多数已经(或即将)包括在这份开发文档中:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "> [**Animations**](guide/animations): Animate component behavior\nwithout deep knowledge of animation techniques or CSS with Angular's animation library.", - "translation": "> [**动画**](guide/animations):用 Angular 的动画库让组件动起来,而不需要对动画技术或 CSS 有深入的了解。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "> **Change detection**: The change detection documentation will cover how Angular decides that a component property value has changed,\nwhen to update the screen, and how it uses **zones** to intercept asynchronous activity and run its change detection strategies.", - "translation": "> **变更检测**:变更检测文档会告诉你 Angular 是如何决定组件的属性值变化,什么时候该更新到屏幕,\n以及它是如何利用**区域 (zone)** 来拦截异步活动并执行变更检测策略。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "> **Events**: The events documentation will cover how to use components and services to raise events with mechanisms for\npublishing and subscribing to events.", - "translation": "> **事件**:事件文档会告诉你如何使用组件和服务触发支持发布和订阅的事件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "> [**Forms**](guide/forms): Support complex data entry scenarios with HTML-based validation and dirty checking.", - "translation": "> [**表单**](guide/forms):通过基于 HTML 的验证和脏检查机制支持复杂的数据输入场景。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "> [**HTTP**](guide/http): Communicate with a server to get data, save data, and invoke server-side actions with an HTTP client.", - "translation": "> [**HTTP**](guide/http):通过 HTTP 客户端,可以与服务器通讯,以获得数据、保存数据和触发服务端动作。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "> [**Lifecycle hooks**](guide/lifecycle-hooks): Tap into key moments in the lifetime of a component, from its creation to its destruction,\nby implementing the lifecycle hook interfaces.", - "translation": "> [**生命周期钩子**](guide/lifecycle-hooks):通过实现生命周期钩子接口,可以切入组件生命中的几个关键点:从创建到销毁。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "> [**Router**](guide/router): Navigate from page to page within the client\n application and never leave the browser.", - "translation": "> [**路由器**](guide/router):在应用程序客户端的页面间导航,并且不离开浏览器。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" - }, - { - "original": "> [**Testing**](guide/testing): Run unit tests on your application parts as they interact with the Angular framework\nusing the _Angular Testing Platform_.", - "translation": "> [**测试**](guide/testing):使用 _Angular 测试平台_,在你的应用部件与 Angular 框架交互时进行单元测试。", + "key": "##WHATSNEXT", + "original": "## What's next", + "translation": "## 接下来呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/architecture.md" }, { + "key": "#ATTRIBUTEDIRECTIVES", "original": "# Attribute Directives", "translation": "# 属性型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ANATTRIBUTEDIRECTIVECHANGESTHEAPPEARANCEORBEHAVIOROFADOMELEMENT", "original": "An **Attribute** directive changes the appearance or behavior of a DOM element.", "translation": "**属性**型指令用于改变一个 DOM 元素的外观或行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "TRYTHELIVEEXAMPLETITLEATTRIBUTEDIRECTIVEEXAMPLELIVEEXAMPLE", "original": "Try the <live-example title=\"Attribute Directive example\"></live-example>.", "translation": "你可以到这里试试:<live-example title=\"属性型指令范例\"></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "##DIRECTIVESOVERVIEW", "original": "## Directives overview", "translation": "## 指令概览", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEREARETHREEKINDSOFDIRECTIVESINANGULAR:", "original": "There are three kinds of directives in Angular:", "translation": "在 Angular 中有三种类型的指令:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "1COMPONENTSMDASHDIRECTIVESWITHATEMPLATE", "original": "1. Components—directives with a template.", "translation": "组件 — 拥有模板的指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "1STRUCTURALDIRECTIVESMDASHCHANGETHEDOMLAYOUTBYADDINGANDREMOVINGDOMELEMENTS", "original": "1. Structural directives—change the DOM layout by adding and removing DOM elements.", "translation": "结构型指令 — 通过添加和移除 DOM 元素改变 DOM 布局的指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "1ATTRIBUTEDIRECTIVESMDASHCHANGETHEAPPEARANCEORBEHAVIOROFANELEMENTCOMPONENTORANOTHERDIRECTIVE", "original": "1. Attribute directives—change the appearance or behavior of an element, component, or another directive.", "translation": "属性型指令 — 改变元素、组件或其它指令的外观和行为的指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "COMPONENTSARETHEMOSTCOMMONOFTHETHREEDIRECTIVESYOUSAWACOMPONENTFORTHEFIRSTTIMEINTHEQUICKSTARTGUIDEQUICKSTARTGUIDE", "original": "*Components* are the most common of the three directives.\nYou saw a component for the first time in the [QuickStart](guide/quickstart) guide.", "translation": "*组件*是这三种指令中最常用的。\n你在[快速上手](guide/quickstart)例子中第一次见到组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "STRUCTURALDIRECTIVESCHANGETHESTRUCTUREOFTHEVIEWTWOEXAMPLESARENGFORGUIDETEMPLATESYNTAX#NGFORANDNGIFGUIDETEMPLATESYNTAX#NGIFLEARNABOUTTHEMINTHESTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVESGUIDE", "original": "*Structural Directives* change the structure of the view.\nTwo examples are [NgFor](guide/template-syntax#ngFor) and [NgIf](guide/template-syntax#ngIf).\nLearn about them in the [Structural Directives](guide/structural-directives) guide.", "translation": "*结构型*指令修改视图的结构。例如,[NgFor](guide/template-syntax#ngFor) 和 [NgIf](guide/template-syntax#ngIf)。\n要了解更多,参见[结构型指令](guide/structural-directives) guide。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ATTRIBUTEDIRECTIVESAREUSEDASATTRIBUTESOFELEMENTSTHEBUILTINNGSTYLEGUIDETEMPLATESYNTAX#NGSTYLEDIRECTIVEINTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXGUIDEFOREXAMPLECANCHANGESEVERALELEMENTSTYLESATTHESAMETIME", "original": "*Attribute directives* are used as attributes of elements.\nThe built-in [NgStyle](guide/template-syntax#ngStyle) directive in the\n[Template Syntax](guide/template-syntax) guide, for example,\ncan change several element styles at the same time.", "translation": "*属性型*指令改变一个元素的外观或行为。例如,内置的 [NgStyle](guide/template-syntax#ngStyle) 指令可以同时修改元素的多个样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "##BUILDASIMPLEATTRIBUTEDIRECTIVE", "original": "## Build a simple attribute directive", "translation": "## 创建一个简单的属性型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ANATTRIBUTEDIRECTIVEMINIMALLYREQUIRESBUILDINGACONTROLLERCLASSANNOTATEDWITHDIRECTIVEWHICHSPECIFIESTHESELECTORTHATIDENTIFIESTHEATTRIBUTETHECONTROLLERCLASSIMPLEMENTSTHEDESIREDDIRECTIVEBEHAVIOR", "original": "An attribute directive minimally requires building a controller class annotated with\n`@Directive`, which specifies the selector that identifies\nthe attribute.\nThe controller class implements the desired directive behavior.", "translation": "属性型指令至少需要一个带有 `@Directive` 装饰器的控制器类。该装饰器指定了一个用于标识属性的选择器。\n控制器类实现了指令需要的指令行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THISPAGEDEMONSTRATESBUILDINGASIMPLEAPPHIGHLIGHTATTRIBUTEDIRECTIVETOSETANELEMENTSBACKGROUNDCOLORWHENTHEUSERHOVERSOVERTHATELEMENTYOUCANAPPLYITLIKETHIS:", "original": "This page demonstrates building a simple _appHighlight_ attribute\ndirective to set an element's background color\nwhen the user hovers over that element. You can apply it like this:", "translation": "本章展示了如何创建一个简单的属性型指令 _myHighlight_ ,当用户把鼠标悬停在一个元素上时,改变它的背景色。你可以这样用它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "###WRITETHEDIRECTIVECODE", "original": "### Write the directive code", "translation": "### 编写指令代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "CREATETHEDIRECTIVECLASSFILEINATERMINALWINDOWWITHTHISCLICOMMAND", "original": "Create the directive class file in a terminal window with this CLI command.", "translation": "在命令行窗口下用 CLI 命令创建指令类文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THECLICREATESSRCAPPHIGHLIGHTDIRECTIVETSACORRESPONDINGTESTFILESPECTSANDDECLARESTHEDIRECTIVECLASSINTHEROOTAPPMODULE", "original": "The CLI creates `src/app/highlight.directive.ts`, a corresponding test file (`.../spec.ts`, and _declares_ the directive class in the root `AppModule`.", "translation": "CLI 会创建 `src/app/highlight.directive.ts` 及相应的测试文件(`.../spec.ts`),并且在根模块 `AppModule` 中声明这个指令类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "DIRECTIVESMUSTBEDECLAREDINANGULARMODULESGUIDENGMODULESINTHESAMEMANNERASCOMPONENTS", "original": "_Directives_ must be declared in [Angular Modules](guide/ngmodules) in the same manner as _components_.", "translation": "和**组件**一样,这些**指令**也必须在[Angular 模块](guide/ngmodules)中进行声明。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEGENERATEDSRCAPPHIGHLIGHTDIRECTIVETSISASFOLLOWS:", "original": "The generated `src/app/highlight.directive.ts` is as follows:", "translation": "生成的 `src/app/highlight.directive.ts` 文件如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEIMPORTEDDIRECTIVESYMBOLPROVIDESTHEANGULARTHEDIRECTIVEDECORATOR", "original": "The imported `Directive` symbol provides the Angular the `@Directive` decorator.", "translation": "这里导入的 `Directive` 符号提供了 Angular 的 `@Directive` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEDIRECTIVEDECORATORSLONECONFIGURATIONPROPERTYSPECIFIESTHEDIRECTIVESCSSATTRIBUTESELECTORHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBCSSATTRIBUTESELECTORSAPPHIGHLIGHT", "original": "The `@Directive` decorator's lone configuration property specifies the directive's\n[CSS attribute selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors), `[appHighlight]`.", "translation": "`@Directive` 装饰器的配置属性中指定了该指令的 [CSS 属性型选择器](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) `[appHighlight]`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ITSTHEBRACKETSTHATMAKEITANATTRIBUTESELECTORANGULARLOCATESEACHELEMENTINTHETEMPLATETHATHASANATTRIBUTENAMEDAPPHIGHLIGHTANDAPPLIESTHELOGICOFTHISDIRECTIVETOTHATELEMENT", "original": "It's the brackets (`[]`) that make it an attribute selector.\nAngular locates each element in the template that has an attribute named `appHighlight` and applies the logic of this directive to that element.", "translation": "这里的方括号(`[]`)表示它的属性型选择器。\nAngular 会在模板中定位每个名叫 `appHighlight` 的元素,并且为这些元素加上本指令的逻辑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEATTRIBUTESELECTORPATTERNEXPLAINSTHENAMEOFTHISKINDOFDIRECTIVE", "original": "The _attribute selector_ pattern explains the name of this kind of directive.", "translation": "正因如此,这类指令被称为 **属性选择器** 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "####WHYNOTHIGHLIGHT", "original": "#### Why not \"highlight\"?", "translation": "#### 为什么不直接叫做 \"highlight\"?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THOUGHHIGHLIGHTWOULDBEAMORECONCISESELECTORTHANAPPHIGHLIGHTANDITWOULDWORKTHEBESTPRACTICEISTOPREFIXSELECTORNAMESTOENSURETHEYDONTCONFLICTWITHSTANDARDHTMLATTRIBUTESTHISALSOREDUCESTHERISKOFCOLLIDINGWITHTHIRDPARTYDIRECTIVENAMESTHECLIADDEDTHEAPPPREFIXFORYOU", "original": "Though *highlight* would be a more concise selector than *appHighlight* and it would work,\nthe best practice is to prefix selector names to ensure\nthey don't conflict with standard HTML attributes.\nThis also reduces the risk of colliding with third-party directive names.\nThe CLI added the `app` prefix for you.", "translation": "尽管 *highlight* 是一个比 *myHighlight* 更简洁的名字,而且它确实也能工作。\n但是最佳实践是在选择器名字前面添加前缀,以确保它们不会与标准 HTML 属性冲突。\n它同时减少了与第三方指令名字发生冲突的危险。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "MAKESUREYOUDONOTPREFIXTHEHIGHLIGHTDIRECTIVENAMEWITHNGBECAUSETHATPREFIXISRESERVEDFORANGULARANDUSINGITCOULDCAUSEBUGSTHATAREDIFFICULTTODIAGNOSE", "original": "Make sure you do **not** prefix the `highlight` directive name with **`ng`** because\nthat prefix is reserved for Angular and using it could cause bugs that are difficult to diagnose.", "translation": "确认你**没有**给 `highlight` 指令添加**`ng`**前缀。\n那个前缀属于 Angular,使用它可能导致难以诊断的 bug。例如,这个简短的前缀 `my` 可以帮助你区分自定义指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "AFTERTHEDIRECTIVEMETADATACOMESTHEDIRECTIVESCONTROLLERCLASSCALLEDHIGHLIGHTDIRECTIVEWHICHCONTAINSTHECURRENTLYEMPTYLOGICFORTHEDIRECTIVEEXPORTINGHIGHLIGHTDIRECTIVEMAKESTHEDIRECTIVEACCESSIBLE", "original": "After the `@Directive` metadata comes the directive's controller class,\ncalled `HighlightDirective`, which contains the (currently empty) logic for the directive.\nExporting `HighlightDirective` makes the directive accessible.", "translation": "紧跟在 `@Directive` 元数据之后的就是该指令的控制器类,名叫 `HighlightDirective`,它包含了该指令的逻辑(目前为空逻辑)。然后导出 `HighlightDirective`,以便它能在别处访问到。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "NOWEDITTHEGENERATEDSRCAPPHIGHLIGHTDIRECTIVETSTOLOOKASFOLLOWS:", "original": "Now edit the generated `src/app/highlight.directive.ts` to look as follows:", "translation": "现在,把刚才生成的 `src/app/highlight.directive.ts` 编辑成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEIMPORTSTATEMENTSPECIFIESANADDITIONALELEMENTREFSYMBOLFROMTHEANGULARCORELIBRARY:", "original": "The `import` statement specifies an additional `ElementRef` symbol from the Angular `core` library:", "translation": "`import` 语句还从 Angular 的 `core` 库中导入了一个 `ElementRef` 符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "YOUUSETHEELEMENTREFINTHEDIRECTIVESCONSTRUCTORTOINJECTGUIDEDEPENDENCYINJECTIONAREFERENCETOTHEHOSTDOMELEMENTTHEELEMENTTOWHICHYOUAPPLIEDAPPHIGHLIGHT", "original": "You use the `ElementRef`in the directive's constructor\nto [inject](guide/dependency-injection) a reference to the host DOM element, \nthe element to which you applied `appHighlight`.", "translation": "你可以在指令的构造函数中注入 `ElementRef`,来引用宿主 DOM 元素,", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ELEMENTREFGRANTSDIRECTACCESSTOTHEHOSTDOMELEMENTTHROUGHITSNATIVEELEMENTPROPERTY", "original": "`ElementRef` grants direct access to the host DOM element\nthrough its `nativeElement` property.", "translation": "`ElementRef` 通过其 `nativeElement` 属性给你了直接访问宿主 DOM 元素的能力。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THISFIRSTIMPLEMENTATIONSETSTHEBACKGROUNDCOLOROFTHEHOSTELEMENTTOYELLOW", "original": "This first implementation sets the background color of the host element to yellow.", "translation": "这里的第一个实现把宿主元素的背景色设置为了黄色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "##APPLYTHEATTRIBUTEDIRECTIVE", "original": "## Apply the attribute directive", "translation": "## 使用属性型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "TOUSETHENEWHIGHLIGHTDIRECTIVEADDAPARAGRAPHPELEMENTTOTHETEMPLATEOFTHEROOTAPPCOMPONENTANDAPPLYTHEDIRECTIVEASANATTRIBUTE", "original": "To use the new `HighlightDirective`, add a paragraph (`<p>`) element to the template of the root `AppComponent` and apply the directive as an attribute.", "translation": "要想使用这个新的 `HighlightDirective`,就往根组件 `AppComponent` 的模板中添加一个 `<p>` 元素,并把该指令作为一个属性使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "NOWRUNTHEAPPLICATIONTOSEETHEHIGHLIGHTDIRECTIVEINACTION", "original": "Now run the application to see the `HighlightDirective` in action.", "translation": "运行这个应用以查看 `HighlightDirective` 的实际效果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "TOSUMMARIZEANGULARFOUNDTHEAPPHIGHLIGHTATTRIBUTEONTHEHOSTPELEMENTITCREATEDANINSTANCEOFTHEHIGHLIGHTDIRECTIVECLASSANDINJECTEDAREFERENCETOTHEPELEMENTINTOTHEDIRECTIVESCONSTRUCTORWHICHSETSTHEPELEMENTSBACKGROUNDSTYLETOYELLOW", "original": "To summarize, Angular found the `appHighlight` attribute on the **host** `<p>` element.\nIt created an instance of the `HighlightDirective` class and\ninjected a reference to the `<p>` element into the directive's constructor\nwhich sets the `<p>` element's background style to yellow.", "translation": "总结:Angular 在**宿主**元素 `<p>` 上发现了一个 `appHighlight` 属性。\n然后它创建了一个 `HighlightDirective` 类的实例,并把所在元素的引用注入到了指令的构造函数中。\n在构造函数中,该指令把 `<p>` 元素的背景设置为了黄色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "##RESPONDTOUSERINITIATEDEVENTS", "original": "## Respond to user-initiated events", "translation": "## 响应用户引发的事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "CURRENTLYAPPHIGHLIGHTSIMPLYSETSANELEMENTCOLORTHEDIRECTIVECOULDBEMOREDYNAMICITCOULDDETECTWHENTHEUSERMOUSESINTOOROUTOFTHEELEMENTANDRESPONDBYSETTINGORCLEARINGTHEHIGHLIGHTCOLOR", "original": "Currently, `appHighlight` simply sets an element color.\nThe directive could be more dynamic.\nIt could detect when the user mouses into or out of the element\nand respond by setting or clearing the highlight color.", "translation": "当前,`appHighlight` 只是简单的设置元素的颜色。\n这个指令应该在用户鼠标悬浮一个元素时,设置它的颜色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "BEGINBYADDINGHOSTLISTENERTOTHELISTOFIMPORTEDSYMBOLS", "original": "Begin by adding `HostListener` to the list of imported symbols.", "translation": "先把 `HostListener` 加进导入列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THENADDTWOEVENTHANDLERSTHATRESPONDWHENTHEMOUSEENTERSORLEAVESEACHADORNEDBYTHEHOSTLISTENERDECORATOR", "original": "Then add two eventhandlers that respond when the mouse enters or leaves,\neach adorned by the `HostListener` decorator.", "translation": "然后使用 `HostListener` 装饰器添加两个事件处理器,它们会在鼠标进入或离开时进行响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEHOSTLISTENERDECORATORLETSYOUSUBSCRIBETOEVENTSOFTHEDOMELEMENTTHATHOSTSANATTRIBUTEDIRECTIVETHEPINTHISCASE", "original": "The `@HostListener` decorator lets you subscribe to events of the DOM\nelement that hosts an attribute directive, the `<p>` in this case.", "translation": "`@HostListener` 装饰器引用属性型指令的宿主元素,在这个例子中就是 `<p>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "OFCOURSEYOUCOULDREACHINTOTHEDOMWITHSTANDARDJAVASCRIPTANDATTACHEVENTLISTENERSMANUALLYTHEREAREATLEASTTHREEPROBLEMSWITHTHATAPPROACH:", "original": "Of course you could reach into the DOM with standard JavaScript and attach event listeners manually.\nThere are at least three problems with _that_ approach:", "translation": "当然,你可以通过标准的 JavaScript 方式手动给宿主 DOM 元素附加一个事件监听器。\n但这种方法至少有三个问题:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "1YOUHAVETOWRITETHELISTENERSCORRECTLY", "original": "1. You have to write the listeners correctly.", "translation": "必须正确的书写事件监听器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "1THECODEMUSTDETACHTHELISTENERWHENTHEDIRECTIVEISDESTROYEDTOAVOIDMEMORYLEAKS", "original": "1. The code must *detach* the listener when the directive is destroyed to avoid memory leaks.", "translation": "当指令被销毁的时候,必须*拆卸*事件监听器,否则会导致内存泄露。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "1TALKINGTODOMAPIDIRECTLYISNTABESTPRACTICE", "original": "1. Talking to DOM API directly isn't a best practice.", "translation": "必须直接和 DOM API 打交道,应该避免这样做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEHANDLERSDELEGATETOAHELPERMETHODTHATSETSTHECOLORONTHEHOSTDOMELEMENTEL", "original": "The handlers delegate to a helper method that sets the color on the host DOM element, `el`.", "translation": "这些处理器委托了一个辅助方法来为 DOM 元素(`el`)设置颜色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEHELPERMETHODHIGHLIGHTWASEXTRACTEDFROMTHECONSTRUCTORTHEREVISEDCONSTRUCTORSIMPLYDECLARESTHEINJECTEDEL:ELEMENTREF", "original": "The helper method, `highlight`, was extracted from the constructor.\nThe revised constructor simply declares the injected `el: ElementRef`.", "translation": "这个辅助方法(`highlight`)被从构造函数中提取了出来。\n修改后的构造函数只负责声明要注入的元素 `el: ElementRef`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "HERESTHEUPDATEDDIRECTIVEINFULL:", "original": "Here's the updated directive in full:", "translation": "下面是修改后的指令代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "RUNTHEAPPANDCONFIRMTHATTHEBACKGROUNDCOLORAPPEARSWHENTHEMOUSEHOVERSOVERTHEPANDDISAPPEARSASITMOVESOUT", "original": "Run the app and confirm that the background color appears when\nthe mouse hovers over the `p` and disappears as it moves out.", "translation": "运行本应用并确认:当把鼠标移到 `p` 上的时候,背景色就出现了,而移开的时候,它消失了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "##PASSVALUESINTOTHEDIRECTIVEWITHANINPUTDATABINDING", "original": "## Pass values into the directive with an _@Input_ data binding", "translation": "## 使用 `@Input` 数据绑定向指令传递值", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "CURRENTLYTHEHIGHLIGHTCOLORISHARDCODEDWITHINTHEDIRECTIVETHATSINFLEXIBLEINTHISSECTIONYOUGIVETHEDEVELOPERTHEPOWERTOSETTHEHIGHLIGHTCOLORWHILEAPPLYINGTHEDIRECTIVE", "original": "Currently the highlight color is hard-coded _within_ the directive. That's inflexible.\nIn this section, you give the developer the power to set the highlight color while applying the directive.", "translation": "高亮的颜色目前是硬编码在指令中的,这不够灵活。\n在这一节中,你应该让指令的使用者可以指定要用哪种颜色进行高亮。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "BEGINBYADDINGINPUTTOTHELISTOFSYMBOLSIMPORTEDFROMANGULARCORE", "original": "Begin by adding `Input` to the list of symbols imported from `@angular/core`.", "translation": "先从 `@angular/core` 中导入 `Input`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ADDAHIGHLIGHTCOLORPROPERTYTOTHEDIRECTIVECLASSLIKETHIS:", "original": "Add a `highlightColor` property to the directive class like this:", "translation": "然后把 `highlightColor` 属性添加到指令类中,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "###BINDINGTOANINPUTPROPERTY", "original": "### Binding to an _@Input_ property", "translation": "### 绑定到 *@Input* 属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "NOTICETHEINPUTDECORATORITADDSMETADATATOTHECLASSTHATMAKESTHEDIRECTIVESHIGHLIGHTCOLORPROPERTYAVAILABLEFORBINDING", "original": "Notice the `@Input` decorator. It adds metadata to the class that makes the directive's `highlightColor` property available for binding.", "translation": "注意看 `@Input` 装饰器。它往类上添加了一些元数据,从而让该指令的 `highlightColor` 能用于绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ITSCALLEDANINPUTPROPERTYBECAUSEDATAFLOWSFROMTHEBINDINGEXPRESSIONINTOTHEDIRECTIVEWITHOUTTHATINPUTMETADATAANGULARREJECTSTHEBINDINGSEEBELOWGUIDEATTRIBUTEDIRECTIVES#WHYINPUTWHYADDINPUTFORMOREABOUTTHAT", "original": "It's called an *input* property because data flows from the binding expression _into_ the directive.\nWithout that input metadata, Angular rejects the binding; see [below](guide/attribute-directives#why-input \"Why add @Input?\") for more about that.", "translation": "它之所以称为*输入*属性,是因为数据流是从绑定表达式流向指令内部的。\n如果没有这个元数据,Angular 就会拒绝绑定,参见[稍后](guide/attribute-directives#why-input \"为什么要添加@Input?\")了解更多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "TRYITBYADDINGTHEFOLLOWINGDIRECTIVEBINDINGVARIATIONSTOTHEAPPCOMPONENTTEMPLATE:", "original": "Try it by adding the following directive binding variations to the `AppComponent` template:", "translation": "试试把下列指令绑定变量添加到 `AppComponent` 的模板中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ADDACOLORPROPERTYTOTHEAPPCOMPONENT", "original": "Add a `color` property to the `AppComponent`.", "translation": "把 `color` 属性添加到 `AppComponent` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "LETITCONTROLTHEHIGHLIGHTCOLORWITHAPROPERTYBINDING", "original": "Let it control the highlight color with a property binding.", "translation": "让它通过属性绑定来控制高亮颜色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THATSGOODBUTITWOULDBENICETOSIMULTANEOUSLYAPPLYTHEDIRECTIVEANDSETTHECOLORINTHESAMEATTRIBUTELIKETHIS", "original": "That's good, but it would be nice to _simultaneously_ apply the directive and set the color _in the same attribute_ like this.", "translation": "很不错,但如果可以在应用该指令时在*同一个属性*中设置颜色就更好了,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEAPPHIGHLIGHTATTRIBUTEBINDINGBOTHAPPLIESTHEHIGHLIGHTINGDIRECTIVETOTHEPELEMENTANDSETSTHEDIRECTIVESHIGHLIGHTCOLORWITHAPROPERTYBINDINGYOUREREUSINGTHEDIRECTIVESATTRIBUTESELECTORAPPHIGHLIGHTTODOBOTHJOBSTHATSACRISPCOMPACTSYNTAX", "original": "The `[appHighlight]` attribute binding both applies the highlighting directive to the `<p>` element\nand sets the directive's highlight color with a property binding.\nYou're re-using the directive's attribute selector (`[appHighlight]`) to do both jobs.\nThat's a crisp, compact syntax.", "translation": "`[appHighlight]` 属性同时做了两件事:把这个高亮指令应用到了 `<p>` 元素上,并且通过属性绑定设置了该指令的高亮颜色。\n你复用了该指令的属性选择器 `[appHighlight]` 来同时完成它们。\n这是清爽、简约的语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "YOULLHAVETORENAMETHEDIRECTIVESHIGHLIGHTCOLORPROPERTYTOAPPHIGHLIGHTBECAUSETHATSNOWTHECOLORPROPERTYBINDINGNAME", "original": "You'll have to rename the directive's `highlightColor` property to `appHighlight` because that's now the color property binding name.", "translation": "你还要把该指令的 `highlightColor` 改名为 `myHighlight`,因为它是颜色属性目前的绑定名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THISISDISAGREEABLETHEWORDAPPHIGHLIGHTISATERRIBLEPROPERTYNAMEANDITDOESNTCONVEYTHEPROPERTYSINTENT", "original": "This is disagreeable. The word, `appHighlight`, is a terrible property name and it doesn't convey the property's intent.", "translation": "这可不好。因为 `appHighlight` 是一个糟糕的属性名,而且不能反映该属性的意图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "###BINDTOANINPUTALIAS", "original": "### Bind to an _@Input_ alias", "translation": "### 绑定到 *@Input* 别名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "FORTUNATELYYOUCANNAMETHEDIRECTIVEPROPERTYWHATEVERYOUWANTANDALIASITFORBINDINGPURPOSES", "original": "Fortunately you can name the directive property whatever you want _and_ **_alias it_** for binding purposes.", "translation": "幸运的是,你可以随意命名该指令的属性,并且**给它指定一个用于绑定的别名**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "RESTORETHEORIGINALPROPERTYNAMEANDSPECIFYTHESELECTORASTHEALIASINTHEARGUMENTTOINPUT", "original": "Restore the original property name and specify the selector as the alias in the argument to `@Input`.", "translation": "恢复原始属性名,并在 `@Input` 的参数中把选择器 `myHighlight` 指定为别名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "INSIDETHEDIRECTIVETHEPROPERTYISKNOWNASHIGHLIGHTCOLOROUTSIDETHEDIRECTIVEWHEREYOUBINDTOITITSKNOWNASAPPHIGHLIGHT", "original": "_Inside_ the directive the property is known as `highlightColor`.\n_Outside_ the directive, where you bind to it, it's known as `appHighlight`.", "translation": "在指令内部,该属性叫 `highlightColor`,在外部,你绑定到它地方,它叫 `appHighlight`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "YOUGETTHEBESTOFBOTHWORLDS:THEPROPERTYNAMEYOUWANTANDTHEBINDINGSYNTAXYOUWANT:", "original": "You get the best of both worlds: the property name you want and the binding syntax you want:", "translation": "这是最好的结果:理想的内部属性名,理想的绑定语法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "NOWTHATYOUREBINDINGVIATHEALIASTOTHEHIGHLIGHTCOLORMODIFYTHEONMOUSEENTERMETHODTOUSETHATPROPERTYIFSOMEONENEGLECTSTOBINDTOAPPHIGHLIGHTCOLORHIGHLIGHTTHEHOSTELEMENTINRED:", "original": "Now that you're binding via the alias to the `highlightColor`, modify the `onMouseEnter()` method to use that property.\nIf someone neglects to bind to `appHighlightColor`, highlight the host element in red:", "translation": "现在,你通过别名绑定到了 `highlightColor` 属性,并修改 `onMouseEnter()` 方法来使用它。\n如果有人忘了绑定到 `appHighlightColor`,那就用红色进行高亮。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "HERESTHELATESTVERSIONOFTHEDIRECTIVECLASS", "original": "Here's the latest version of the directive class.", "translation": "这是最终版本的指令类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "##WRITEAHARNESSTOTRYIT", "original": "## Write a harness to try it", "translation": "## 写个测试程序试验下", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ITMAYBEDIFFICULTTOIMAGINEHOWTHISDIRECTIVEACTUALLYWORKSINTHISSECTIONYOULLTURNAPPCOMPONENTINTOAHARNESSTHATLETSYOUPICKTHEHIGHLIGHTCOLORWITHARADIOBUTTONANDBINDYOURCOLORCHOICETOTHEDIRECTIVE", "original": "It may be difficult to imagine how this directive actually works.\nIn this section, you'll turn `AppComponent` into a harness that\nlets you pick the highlight color with a radio button and bind your color choice to the directive.", "translation": "凭空想象该指令如何工作可不容易。\n在本节,你将把 `AppComponent` 改成一个测试程序,它让你可以通过单选按钮来选取高亮颜色,并且把你选取的颜色绑定到指令中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "UPDATECODEAPPCOMPONENTHTMLCODEASFOLLOWS:", "original": "Update <code>app.component.html</code> as follows:", "translation": "把 `app.component.html` 修改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "REVISETHEAPPCOMPONENTCOLORSOTHATITHASNOINITIALVALUE", "original": "Revise the `AppComponent.color` so that it has no initial value.", "translation": "修改 `AppComponent.color`,让它不再有初始值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "HEREARETHEHARNESSANDDIRECTIVEINACTION", "original": "Here are the harness and directive in action.", "translation": "下面是测试程序和指令的动图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "##BINDTOASECONDPROPERTY", "original": "## Bind to a second property", "translation": "## 绑定到第二个属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THISHIGHLIGHTDIRECTIVEHASASINGLECUSTOMIZABLEPROPERTYINAREALAPPITMAYNEEDMORE", "original": "This highlight directive has a single customizable property. In a real app, it may need more.", "translation": "本例的指令只有一个可定制属性,真实的应用通常需要更多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ATTHEMOMENTTHEDEFAULTCOLORMDASHTHECOLORTHATPREVAILSUNTILTHEUSERPICKSAHIGHLIGHTCOLORMDASHISHARDCODEDASREDLETTHETEMPLATEDEVELOPERSETTHEDEFAULTCOLOR", "original": "At the moment, the default color—the color that prevails until\nthe user picks a highlight color—is hard-coded as \"red\".\nLet the template developer set the default color.", "translation": "目前,默认颜色(它在用户选取了高亮颜色之前一直有效)被硬编码为红色。应该允许模板的开发者设置默认颜色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ADDASECONDINPUTPROPERTYTOHIGHLIGHTDIRECTIVECALLEDDEFAULTCOLOR:", "original": "Add a second **input** property to `HighlightDirective` called `defaultColor`:", "translation": "把第二个名叫 `defaultColor` 的**输入**属性添加到 `HighlightDirective` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "REVISETHEDIRECTIVESONMOUSEENTERSOTHATITFIRSTTRIESTOHIGHLIGHTWITHTHEHIGHLIGHTCOLORTHENWITHTHEDEFAULTCOLORANDFALLSBACKTOREDIFBOTHPROPERTIESAREUNDEFINED", "original": "Revise the directive's `onMouseEnter` so that it first tries to highlight with the `highlightColor`,\nthen with the `defaultColor`, and falls back to \"red\" if both properties are undefined.", "translation": "修改该指令的 `onMouseEnter`,让它首先尝试使用 `highlightColor` 进行高亮,然后用 `defaultColor`,如果它们都没有指定,那就用红色作为后备。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "HOWDOYOUBINDTOASECONDPROPERTYWHENYOUREALREADYBINDINGTOTHEAPPHIGHLIGHTATTRIBUTENAME", "original": "How do you bind to a second property when you're already binding to the `appHighlight` attribute name?", "translation": "当已经绑定过 `appHighlight` 属性时,要如何绑定到第二个属性呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ASWITHCOMPONENTSYOUCANADDASMANYDIRECTIVEPROPERTYBINDINGSASYOUNEEDBYSTRINGINGTHEMALONGINTHETEMPLATETHEDEVELOPERSHOULDBEABLETOWRITETHEFOLLOWINGTEMPLATEHTMLTOBOTHBINDTOTHEAPPCOMPONENTCOLORANDFALLBACKTOVIOLETASTHEDEFAULTCOLOR", "original": "As with components, you can add as many directive property bindings as you need by stringing them along in the template.\nThe developer should be able to write the following template HTML to both bind to the `AppComponent.color`\nand fall back to \"violet\" as the default color.", "translation": "像组件一样,你也可以绑定到指令的很多属性,只要把它们依次写在模板中就行了。\n开发者可以绑定到 `AppComponent.color`,并且用紫罗兰色作为默认颜色,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "ANGULARKNOWSTHATTHEDEFAULTCOLORBINDINGBELONGSTOTHEHIGHLIGHTDIRECTIVEBECAUSEYOUMADEITPUBLICWITHTHEINPUTDECORATOR", "original": "Angular knows that the `defaultColor` binding belongs to the `HighlightDirective`\nbecause you made it _public_ with the `@Input` decorator.", "translation": "Angular 之所以知道 `defaultColor` 绑定属于 `HighlightDirective`,是因为你已经通过 `@Input` 装饰器把它设置成了*公共*属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "HERESHOWTHEHARNESSSHOULDWORKWHENYOUREDONECODING", "original": "Here's how the harness should work when you're done coding.", "translation": "当这些代码完成时,测试程序工作时的动图如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THISPAGECOVEREDHOWTO:", "original": "This page covered how to:", "translation": "本章介绍了如何:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "BUILDANATTRIBUTEDIRECTIVEGUIDEATTRIBUTEDIRECTIVES#WRITEDIRECTIVETHATMODIFIESTHEBEHAVIOROFANELEMENT", "original": "* [Build an **attribute directive**](guide/attribute-directives#write-directive) that modifies the behavior of an element.", "translation": "[构建一个**属性型指令**](guide/attribute-directives#write-directive),它用于修改一个元素的行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "APPLYTHEDIRECTIVEGUIDEATTRIBUTEDIRECTIVES#APPLYDIRECTIVETOANELEMENTINATEMPLATE", "original": "* [Apply the directive](guide/attribute-directives#apply-directive) to an element in a template.", "translation": "[把一个指令应用到](guide/attribute-directives#apply-directive)模板中的某个元素上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "RESPONDTOEVENTSGUIDEATTRIBUTEDIRECTIVES#RESPONDTOUSERTHATCHANGETHEDIRECTIVESBEHAVIOR", "original": "* [Respond to **events**](guide/attribute-directives#respond-to-user) that change the directive's behavior.", "translation": "[响应**事件**](guide/attribute-directives#respond-to-user)以改变指令的行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "BINDVALUESTOTHEDIRECTIVEGUIDEATTRIBUTEDIRECTIVES#BINDINGS", "original": "* [**Bind** values to the directive](guide/attribute-directives#bindings).", "translation": "[把值**绑定**到指令中](guide/attribute-directives#bindings)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEFINALSOURCECODEFOLLOWS:", "original": "The final source code follows:", "translation": "最终的源码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "YOUCANALSOEXPERIENCEANDDOWNLOADTHELIVEEXAMPLETITLEATTRIBUTEDIRECTIVEEXAMPLELIVEEXAMPLE", "original": "You can also experience and download the <live-example title=\"Attribute Directive example\"></live-example>.", "translation": "你还可以体验和下载<live-example title=\"属性型指令范例\"></live-example>.", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "###APPENDIX:WHYADDINPUT", "original": "### Appendix: Why add _@Input_?", "translation": "### 附录:为什么要加*@Input*?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "INTHISDEMOTHEHIGHLIGHTCOLORPROPERTYISANINPUTPROPERTYOFTHEHIGHLIGHTDIRECTIVEYOUVESEENITAPPLIEDWITHOUTANALIAS:", "original": "In this demo, the `highlightColor` property is an ***input*** property of\nthe `HighlightDirective`. You've seen it applied without an alias:", "translation": "在这个例子中 `hightlightColor` 是 `HighlightDirective` 的一个***输入型***属性。你见过它没有用别名时的代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "YOUVESEENITWITHANALIAS:", "original": "You've seen it with an alias:", "translation": "也见过用别名时的代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "EITHERWAYTHEINPUTDECORATORTELLSANGULARTHATTHISPROPERTYISPUBLICANDAVAILABLEFORBINDINGBYAPARENTCOMPONENTWITHOUTINPUTANGULARREFUSESTOBINDTOTHEPROPERTY", "original": "Either way, the `@Input` decorator tells Angular that this property is\n_public_ and available for binding by a parent component.\nWithout `@Input`, Angular refuses to bind to the property.", "translation": "无论哪种方式,`@Input` 装饰器都告诉 Angular,该属性是*公共的*,并且能被父组件绑定。\n如果没有 `@Input`,Angular 就会拒绝绑定到该属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "YOUVEBOUNDTEMPLATEHTMLTOCOMPONENTPROPERTIESBEFOREANDNEVERUSEDINPUTWHATSDIFFERENT", "original": "You've bound template HTML to component properties before and never used `@Input`.\nWhat's different?", "translation": "但你以前也曾经把模板 HTML 绑定到组件的属性,而且从来没有用过 `@Input`。\n差异何在?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEDIFFERENCEISAMATTEROFTRUSTANGULARTREATSACOMPONENTSTEMPLATEASBELONGINGTOTHECOMPONENTTHECOMPONENTANDITSTEMPLATETRUSTEACHOTHERIMPLICITLYTHEREFORETHECOMPONENTSOWNTEMPLATEMAYBINDTOANYPROPERTYOFTHATCOMPONENTWITHORWITHOUTTHEINPUTDECORATOR", "original": "The difference is a matter of trust.\nAngular treats a component's template as _belonging_ to the component.\nThe component and its template trust each other implicitly.\nTherefore, the component's own template may bind to _any_ property of that component,\nwith or without the `@Input` decorator.", "translation": "差异在于信任度不同。\nAngular 把组件的模板看做*从属于*该组件的。\n组件和它的模板默认会相互信任。\n这也就是意味着,组件自己的模板可以绑定到组件的*任意*属性,无论是否使用了 `@Input` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "BUTACOMPONENTORDIRECTIVESHOULDNTBLINDLYTRUSTOTHERCOMPONENTSANDDIRECTIVESTHEPROPERTIESOFACOMPONENTORDIRECTIVEAREHIDDENFROMBINDINGBYDEFAULTTHEYAREPRIVATEFROMANANGULARBINDINGPERSPECTIVEWHENADORNEDWITHTHEINPUTDECORATORTHEPROPERTYBECOMESPUBLICFROMANANGULARBINDINGPERSPECTIVEONLYTHENCANITBEBOUNDBYSOMEOTHERCOMPONENTORDIRECTIVE", "original": "But a component or directive shouldn't blindly trust _other_ components and directives.\nThe properties of a component or directive are hidden from binding by default.\nThey are _private_ from an Angular binding perspective.\nWhen adorned with the `@Input` decorator, the property becomes _public_ from an Angular binding perspective.\nOnly then can it be bound by some other component or directive.", "translation": "但组件或指令不应该盲目的信任其它组件或指令。\n因此组件或指令的属性默认是不能被绑定的。\n从 Angular 绑定机制的角度来看,它们是*私有*的,而当添加了 `@Input` 时,它们变成了*公共*的\n只有这样,它们才能被其它组件或属性绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "YOUCANTELLIFINPUTISNEEDEDBYTHEPOSITIONOFTHEPROPERTYNAMEINABINDING", "original": "You can tell if `@Input` is needed by the position of the property name in a binding.", "translation": "你可以根据属性名在绑定中出现的位置来判定是否要加 `@Input`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "WHENITAPPEARSINTHETEMPLATEEXPRESSIONTOTHERIGHTOFTHEEQUALSITBELONGSTOTHETEMPLATESCOMPONENTANDDOESNOTREQUIRETHEINPUTDECORATOR", "original": "* When it appears in the template expression to the ***right*** of the equals (=),\n it belongs to the template's component and does not require the `@Input` decorator.", "translation": "当它出现在等号***右侧***的模板表达式中时,它属于模板所在的组件,不需要 `@Input` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "WHENITAPPEARSINSQUAREBRACKETSTOTHELEFTOFTHEEQUALSTHEPROPERTYBELONGSTOSOMEOTHERCOMPONENTORDIRECTIVETHATPROPERTYMUSTBEADORNEDWITHTHEINPUTDECORATOR", "original": "* When it appears in **square brackets** ([ ]) to the **left** of the equals (=),\n the property belongs to some _other_ component or directive;\n that property must be adorned with the `@Input` decorator.", "translation": "当它出现在等号**左边**的**方括号([ ])**中时,该属性属于*其它*组件或指令,它必须带有 `@Input` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "NOWAPPLYTHATREASONINGTOTHEFOLLOWINGEXAMPLE:", "original": "Now apply that reasoning to the following example:", "translation": "试用此原理分析下列范例:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THECOLORPROPERTYINTHEEXPRESSIONONTHERIGHTBELONGSTOTHETEMPLATESCOMPONENTTHETEMPLATEANDITSCOMPONENTTRUSTEACHOTHERTHECOLORPROPERTYDOESNTREQUIRETHEINPUTDECORATOR", "original": "* The `color` property in the expression on the right belongs to the template's component.\n The template and its component trust each other.\n The `color` property doesn't require the `@Input` decorator.", "translation": "`color` 属性位于右侧的绑定表达式中,它属于模板所在的组件。\n 该模板和组件相互信任。因此 `color` 不需要 `@Input` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "THEAPPHIGHLIGHTPROPERTYONTHELEFTREFERSTOANALIASEDPROPERTYOFTHEHIGHLIGHTDIRECTIVENOTAPROPERTYOFTHETEMPLATESCOMPONENTTHEREARETRUSTISSUESTHEREFORETHEDIRECTIVEPROPERTYMUSTCARRYTHEINPUTDECORATOR", "original": "* The `appHighlight` property on the left refers to an _aliased_ property of the `HighlightDirective`,\n not a property of the template's component. There are trust issues.\n Therefore, the directive property must carry the `@Input` decorator.", "translation": "`appHighlight` 属性位于左侧,它引用了 `HighlightDirective` 中一个*带别名的*属性,它不是模板所属组件的一部分,因此存在信任问题。\n所以,该属性必须带 `@Input` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/attribute-directives.md" }, { + "key": "#BOOTSTRAPPING", "original": "# Bootstrapping", "translation": "# 启动过程", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWING:", "original": "A basic understanding of the following:", "translation": "对下列知识有基本的了解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "JAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", - "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule).", + "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "ANNGMODULEDESCRIBESHOWTHEAPPLICATIONPARTSFITTOGETHEREVERYAPPLICATIONHASATLEASTONEANGULARMODULETHEROOTMODULETHATYOUBOOTSTRAPTOLAUNCHTHEAPPLICATIONBYCONVENTIONITISUSUALLYCALLEDAPPMODULE", "original": "An NgModule describes how the application parts fit together.\nEvery application has at least one Angular module, the _root_ module\nthat you bootstrap to launch the application.\nBy convention, it is usually called `AppModule`.", "translation": "NgModule 用于描述应用的各个部分如何组织在一起。\n每个应用又至少一个 Angular 模块,*根*模块就是你用来启动此应用的模块。\n按照惯例,它通常命名为 `AppModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "IFYOUUSETHECLITOGENERATEANAPPTHEDEFAULTAPPMODULEISASFOLLOWS:", "original": "If you use the CLI to generate an app, the default `AppModule` is as follows:", "translation": "如果你使用 CLI 来生成一个应用,其默认的 `AppModule` 是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "AFTERTHEIMPORTSTATEMENTSISACLASSWITHTHENGMODULEDECORATORGUIDEGLOSSARY#DECORATORDECORATOREXPLAINED", "original": "After the import statements is a class with the\n**`@NgModule`** [decorator](guide/glossary#decorator '\"Decorator\" explained').", "translation": "在 `import` 语句之后,是一个带有 **`@NgModule`** [装饰器](guide/glossary#decorator '\"Decorator\" explained')的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THENGMODULEDECORATORIDENTIFIESAPPMODULEASANNGMODULECLASSNGMODULETAKESAMETADATAOBJECTTHATTELLSANGULARHOWTOCOMPILEANDLAUNCHTHEAPPLICATION", "original": "The `@NgModule` decorator identifies `AppModule` as an `NgModule` class.\n`@NgModule` takes a metadata object that tells Angular how to compile and launch the application.", "translation": "`@NgModule` 装饰器表明 `AppModule` 是一个 `NgModule` 类。\n`@NgModule` 获取一个元数据对象,它会告诉 Angular 如何编译和启动本应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "DECLARATIONSMDASHTHISAPPLICATIONSLONECOMPONENT", "original": "* **_declarations_**—this application's lone component.", "translation": "**_declarations_** —— 该应用所拥有的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "IMPORTSMDASHIMPORTBROWSERMODULETOHAVEBROWSERSPECIFICSERVICESSUCHASDOMRENDERINGSANITIZATIONANDLOCATION", "original": "* **_imports_**—import `BrowserModule` to have browser specific services such as DOM rendering, sanitization, and location.", "translation": "**_imports_** —— 导入 `BrowserModule` 以获取浏览器特有的服务,比如 DOM 渲染、无害化处理和位置(location)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "PROVIDERSMDASHTHESERVICEPROVIDERS", "original": "* **_providers_**—the service providers.", "translation": "**_providers_** —— 各种服务提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "BOOTSTRAPMDASHTHEROOTCOMPONENTTHATANGULARCREATESANDINSERTSINTOTHEINDEXHTMLHOSTWEBPAGE", "original": "* **_bootstrap_**—the _root_ component that Angular creates and inserts\ninto the `index.html` host web page.", "translation": "**_bootstrap_** —— *根*组件,Angular 创建它并插入 `index.html` 宿主页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THEDEFAULTCLIAPPLICATIONONLYHASONECOMPONENTAPPCOMPONENTSOITISINBOTHTHEDECLARATIONSANDTHEBOOTSTRAPARRAYS", "original": "The default CLI application only has one component, `AppComponent`, so it\nis in both the `declarations` and the `bootstrap` arrays.", "translation": "默认的 CLI 应用只有一个组件 `AppComponent`,所以它会同时出现在 `declarations` 和 `bootstrap` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "##THEDECLARATIONSARRAY", "original": "## The `declarations` array", "translation": "## `declarations` 数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THEMODULESDECLARATIONSARRAYTELLSANGULARWHICHCOMPONENTSBELONGTOTHATMODULEASYOUCREATEMORECOMPONENTSADDTHEMTODECLARATIONS", "original": "The module's `declarations` array tells Angular which components belong to that module.\nAs you create more components, add them to `declarations`.", "translation": "该模块的 `declarations` 数组告诉 Angular 哪些组件属于该模块。\n当你创建更多组件时,也要把它们添加到 `declarations` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "YOUMUSTDECLAREEVERYCOMPONENTINEXACTLYONENGMODULECLASSIFYOUUSEACOMPONENTWITHOUTDECLARINGITANGULARRETURNSANERRORMESSAGE", "original": "You must declare every component in exactly one `NgModule` class.\nIf you use a component without declaring it, Angular returns an\nerror message.", "translation": "每个组件都应该(且只能)声明(declare)在一个 `NgModule` 类中。 如果你使用了未声明过的组件,Angular 就会报错。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THEDECLARATIONSARRAYONLYTAKESDECLARABLESDECLARABLESARECOMPONENTSDIRECTIVESGUIDEATTRIBUTEDIRECTIVESANDPIPESGUIDEPIPESALLOFAMODULESDECLARABLESMUSTBEINTHEDECLARATIONSARRAYDECLARABLESMUSTBELONGTOEXACTLYONEMODULETHECOMPILEREMITSANERRORIFYOUTRYTODECLARETHESAMECLASSINMORETHANONEMODULE", "original": "The `declarations` array only takes declarables. Declarables\nare components, [directives](guide/attribute-directives) and [pipes](guide/pipes).\nAll of a module's declarables must be in the `declarations` array.\nDeclarables must belong to exactly one module. The compiler emits\nan error if you try to declare the same class in more than one module.", "translation": "`declarations` 数组只能接受可声明对象。可声明对象包括组件、[指令](guide/attribute-directives)和[管道](guide/pipes)。\n一个模块的所有可声明对象都必须放在 `declarations` 数组中。\n可声明对象必须只能属于一个模块,如果同一个类被声明在了多个模块中,编译器就会报错。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THESEDECLAREDCLASSESAREVISIBLEWITHINTHEMODULEBUTINVISIBLETOCOMPONENTSINADIFFERENTMODULEUNLESSTHEYAREEXPORTEDFROMTHISMODULEANDTHEOTHERMODULEIMPORTSTHISONE", "original": "These declared classes are visible within the module but invisible\nto components in a different module unless they are exported from\nthis module and the other module imports this one.", "translation": "这些可声明的类在当前模块中是可见的,但是对其它模块中的组件是不可见的 —— 除非把它们从当前模块导出,\n并让对方模块导入本模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "ANEXAMPLEOFWHATGOESINTOADECLARATIONSARRAYFOLLOWS:", "original": "An example of what goes into a declarations array follows:", "translation": "下面是哪些类可以添加到 `declarations` 数组中的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "ADECLARABLECANONLYBELONGTOONEMODULESOONLYDECLAREITINONENGMODULEWHENYOUNEEDITELSEWHEREIMPORTTHEMODULETHATHASTHEDECLARABLEYOUNEEDINIT", "original": "A declarable can only belong to one module, so only declare it in\none `@NgModule`. When you need it elsewhere,\nimport the module that has the declarable you need in it.", "translation": "每个可声明对象都只能属于一个模块,所以只能把它声明在一个 `@NgModule` 中。当你需要在其它模块中使用它时,就要在那里导入包含这个可声明对象的模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "ONLYNGMODULEREFERENCESGOINTHEIMPORTSARRAY", "original": "**Only `@NgModule` references** go in the `imports` array.", "translation": "**只有 `@NgModule`** 可以出现在 `imports` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "###USINGDIRECTIVESWITHNGMODULE", "original": "### Using directives with `@NgModule`", "translation": "### 通过 `@NgModule` 使用指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "USETHEDECLARATIONSARRAYFORDIRECTIVESTOUSEADIRECTIVECOMPONENTORPIPEINAMODULEYOUMUSTDOAFEWTHINGS:", "original": "Use the `declarations` array for directives.\nTo use a directive, component, or pipe in a module, you must do a few things:", "translation": "使用 `declarations` 数组声明指令。在模块中使用指令、组件或管道的步骤如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "1EXPORTITFROMTHEFILEWHEREYOUWROTEIT", "original": "1. Export it from the file where you wrote it.", "translation": "从你编写它的文件中导出它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "2IMPORTITINTOTHEAPPROPRIATEMODULE", "original": "2. Import it into the appropriate module.", "translation": "把它导入到适当的模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "3DECLAREITINTHENGMODULEDECLARATIONSARRAY", "original": "3. Declare it in the `@NgModule` `declarations` array.", "translation": "在 `@NgModule` 的 `declarations` 数组中声明它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THOSETHREESTEPSLOOKLIKETHEFOLLOWINGINTHEFILEWHEREYOUCREATEYOURDIRECTIVEEXPORTITTHEFOLLOWINGEXAMPLENAMEDITEMDIRECTIVEISTHEDEFAULTDIRECTIVESTRUCTURETHATTHECLIGENERATESINITSOWNFILEITEMDIRECTIVETS:", "original": "Those three steps look like the following. In the file where you create your directive, export it.\nThe following example, named `ItemDirective` is the default directive structure that the CLI generates in its own file, `item.directive.ts`:", "translation": "这三步的结果如下所示。在你创建指令的文件中导出它。\n下面的例子中,`item.directive.ts` 中的 `ItemDirective` 是 CLI 自动生成的默认指令结构。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THEKEYPOINTHEREISTHATYOUHAVETOEXPORTITSOYOUCANIMPORTITELSEWHERENEXTIMPORTITINTOTHENGMODULEINTHISEXAMPLEAPPMODULETSWITHAJAVASCRIPTIMPORTSTATEMENT:", "original": "The key point here is that you have to export it so you can import it elsewhere. Next, import it\ninto the NgModule, in this example `app.module.ts`, with a JavaScript import statement:", "translation": "重点在于你要先在这里导出它才能在别处导入它。接下来,使用 JavaScript 的 `import` 语句把它导入到 NgModule 中(这里是 `app.module.ts`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "ANDINTHESAMEFILEADDITTOTHENGMODULEDECLARATIONSARRAY:", "original": "And in the same file, add it to the `@NgModule` `declarations` array:", "translation": "同样在这个文件中,把它添加到 `@NgModule` 的 `declarations` 数组中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "NOWYOUCOULDUSEYOURITEMDIRECTIVEINACOMPONENTTHISEXAMPLEUSESAPPMODULEBUTYOUDDOITTHESAMEWAYFORAFEATUREMODULEFORMOREABOUTDIRECTIVESSEEATTRIBUTEDIRECTIVESGUIDEATTRIBUTEDIRECTIVESANDSTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVESYOUDALSOUSETHESAMETECHNIQUEFORPIPESGUIDEPIPESANDCOMPONENTS", "original": "Now you could use your `ItemDirective` in a component. This example uses `AppModule`, but you'd do it the same way for a feature module. For more about directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives). You'd also use the same technique for [pipes](guide/pipes) and components.", "translation": "现在,你就可以在组件中使用 `ItemDirective` 了。这个例子中使用的是 `AppModule`,但是在特性模块中你也可以这么做。\n要进一步了解指令,参见[属性型指令](guide/attribute-directives)和[结构型指令](guide/structural-directives)。\n这些也同样适用于[管道](guide/pipes)和组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "REMEMBERCOMPONENTSDIRECTIVESANDPIPESBELONGTOONEMODULEONLYYOUONLYNEEDTODECLARETHEMONCEINYOURAPPBECAUSEYOUSHARETHEMBYIMPORTINGTHENECESSARYMODULESTHISSAVESYOUTIMEANDHELPSKEEPYOURAPPLEAN", "original": "Remember, components, directives, and pipes belong to one module only. You only need to declare them once in your app because you share them by importing the necessary modules. This saves you time and helps keep your app lean.", "translation": "记住:组件、指令和管道都只能属于一个模块。你在应用中也只需要声明它们一次,因为你还可以通过导入必要的模块来使用它们。这能节省你的时间,并且帮助你的应用保持精简。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "##THEIMPORTSARRAY", "original": "## The `imports` array", "translation": "## `imports` 数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THEMODULESIMPORTSARRAYAPPEARSEXCLUSIVELYINTHENGMODULEMETADATAOBJECTITTELLSANGULARABOUTOTHERNGMODULESTHATTHISPARTICULARMODULENEEDSTOFUNCTIONPROPERLY", "original": "The module's `imports` array appears exclusively in the `@NgModule` metadata object.\nIt tells Angular about other NgModules that this particular module needs to function properly.", "translation": "模块的 `imports` 数组只会出现在 `@NgModule` 元数据对象中。\n它告诉 Angular 该模块想要正常工作,还需要哪些模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THISLISTOFMODULESARETHOSETHATEXPORTCOMPONENTSDIRECTIVESORPIPESTHATTHECOMPONENTTEMPLATESINTHISMODULEREFERENCEINTHISCASETHECOMPONENTISAPPCOMPONENTWHICHREFERENCESCOMPONENTSDIRECTIVESORPIPESINBROWSERMODULEFORMSMODULEORHTTPMODULEACOMPONENTTEMPLATECANREFERENCEANOTHERCOMPONENTDIRECTIVEORPIPEWHENTHEREFERENCEDCLASSISDECLAREDINTHISMODULEORTHECLASSWASIMPORTEDFROMANOTHERMODULE", "original": "This list of modules are those that export components, directives, or pipes\nthat the component templates in this module reference. In this case, the component is\n`AppComponent`, which references components, directives, or pipes in `BrowserModule`,\n`FormsModule`, or `HttpModule`.\nA component template can reference another component, directive,\nor pipe when the referenced class is declared in this module or\nthe class was imported from another module.", "translation": "列表中的模块导出了本模块中的各个组件模板中所引用的各个组件、指令或管道。在这个例子中,当前组件是 `AppComponent`,它引用了导出自 `BrowserModule`、`FormsModule` 或 `HttpModule` 的组件、指令或管道。\n总之,组件的模板中可以引用在当前模块中声明的或从其它模块中导入的组件、指令、管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "YOUDONTHAVEANYSERVICESTOPROVIDEYETBUTYOUWILLCREATESOMEBEFORELONGANDYOUMAYCHOSETOPROVIDEMANYOFTHEMHERE", "original": "You don't have any services to provide yet.\nBut you will create some before long and you may chose to provide many of them here.", "translation": "你还没有提供任何服务,但是很快就会创建一些,而且可能也会选择在这里提供它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "##THEPROVIDERSARRAY", "original": "## The `providers` array", "translation": "## `providers` 数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THEPROVIDERSARRAYISWHEREYOULISTTHESERVICESTHEAPPNEEDSWHENYOULISTSERVICESHERETHEYAREAVAILABLEAPPWIDEYOUCANSCOPETHEMWHENUSINGFEATUREMODULESANDLAZYLOADINGFORMOREINFORMATIONSEEPROVIDERSGUIDEPROVIDERS", "original": "The providers array is where you list the services the app needs. When\nyou list services here, they are available app-wide. You can scope\nthem when using feature modules and lazy loading. For more information, see\n[Providers](guide/providers).", "translation": "`providers` 数组中列出了该应用所需的服务。当直接把服务列在这里时,它们是全应用范围的。\n当你使用特性模块和惰性加载时,它们是范围化的。要了解更多,参见[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "##THEBOOTSTRAPARRAY", "original": "## The `bootstrap` array", "translation": "## `bootstrap` 数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THEAPPLICATIONLAUNCHESBYBOOTSTRAPPINGTHEROOTAPPMODULEWHICHISALSOREFERREDTOASANENTRYCOMPONENTAMONGOTHERTHINGSTHEBOOTSTRAPPINGPROCESSCREATESTHECOMPONENTSLISTEDINTHEBOOTSTRAPARRAYANDINSERTSEACHONEINTOTHEBROWSERDOM", "original": "The application launches by bootstrapping the root `AppModule`, which is\nalso referred to as an `entryComponent`.\nAmong other things, the bootstrapping process creates the component(s) listed in the `bootstrap` array\nand inserts each one into the browser DOM.", "translation": "应用是通过引导根模块 `AppModule` 来启动的,根模块还引用了 `entryComponent`。\n此外,引导过程还会创建 `bootstrap` 数组中列出的组件,并把它们逐个插入到浏览器的 DOM 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "EACHBOOTSTRAPPEDCOMPONENTISTHEBASEOFITSOWNTREEOFCOMPONENTSINSERTINGABOOTSTRAPPEDCOMPONENTUSUALLYTRIGGERSACASCADEOFCOMPONENTCREATIONSTHATFILLOUTTHATTREE", "original": "Each bootstrapped component is the base of its own tree of components.\nInserting a bootstrapped component usually triggers a cascade of\ncomponent creations that fill out that tree.", "translation": "每个被引导的组件都是它自己的组件树的根。\n插入一个被引导的组件通常触发一系列组件的创建并形成组件树。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "WHILEYOUCANPUTMORETHANONECOMPONENTTREEONAHOSTWEBPAGEMOSTAPPLICATIONSHAVEONLYONECOMPONENTTREEANDBOOTSTRAPASINGLEROOTCOMPONENT", "original": "While you can put more than one component tree on a host web page,\nmost applications have only one component tree and bootstrap a single root component.", "translation": "虽然也可以在宿主页面中放多个组件,但是大多数应用只有一个组件树,并且只从一个根组件开始引导。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "THISONEROOTCOMPONENTISUSUALLYCALLEDAPPCOMPONENTANDISINTHEROOTMODULESBOOTSTRAPARRAY", "original": "This one root component is usually called `AppComponent` and is in the\nroot module's `bootstrap` array.", "translation": "这个根组件通常叫做 `AppComponent`,并且位于根模块的 `bootstrap` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "##MOREABOUTANGULARMODULES", "original": "## More about Angular Modules", "translation": "## 关于 Angular 模块的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "FORMOREONNGMODULESYOURELIKELYTOSEEFREQUENTLYINAPPSSEEFREQUENTLYUSEDMODULES#", "original": "For more on NgModules you're likely to see frequently in apps,\nsee [Frequently Used Modules](#).", "translation": "要进一步了解常见的 NgModules 知识,参见 [关于模块的常见问题](#)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/bootstrapping.md" }, { + "key": "#BROWSERSUPPORT", "original": "# Browser support", "translation": "# 浏览器支持", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ANGULARSUPPORTSMOSTRECENTBROWSERSTHISINCLUDESTHEFOLLOWINGSPECIFICVERSIONS:", "original": "Angular supports most recent browsers. This includes the following specific versions:", "translation": "Angular 支持大多数常用浏览器,包括下列版本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "BROWSER", "original": "Browser", "translation": "浏览器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "SUPPORTEDVERSIONS", "original": "Supported versions", "translation": "支持的版本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "LATEST", "original": "latest", "translation": "最新版", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "LATEST", "original": "latest", "translation": "最新版", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "2MOSTRECENTMAJORVERSIONS", "original": "2 most recent major versions", "translation": "最近的两个主版本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "2MOSTRECENTMAJORVERSIONS", "original": "2 most recent major versions", "translation": "最近的两个主版本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "2MOSTRECENTMAJORVERSIONS", "original": "2 most recent major versions", "translation": "最近的两个主版本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ANGULARSCONTINUOUSINTEGRATIONPROCESSRUNSUNITTESTSOFTHEFRAMEWORKONALLOFTHESEBROWSERSFOREVERYPULLREQUESTUSINGAHREFHTTPS:SAUCELABSCOMSAUCELABSAANDAHREFHTTPS:WWWBROWSERSTACKCOMBROWSERSTACKA", "original": "Angular's continuous integration process runs unit tests of the framework on all of these browsers for every pull request,\nusing <a href=\"https://saucelabs.com/\">SauceLabs</a> and\n<a href=\"https://www.browserstack.com\">Browserstack</a>.", "translation": "Angular 在持续集成过程中,对每一个提交都会使用 <a href=\"https://saucelabs.com/\" target=\"_blank\">SauceLabs</a> 和\n<a href=\"https://www.browserstack.com\" target=\"_blank\">Browserstack</a> 在上述所有浏览器上执行单元测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "##POLYFILLS", "original": "## Polyfills", "translation": "## 腻子脚本 (polyfill)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ANGULARISBUILTONTHELATESTSTANDARDSOFTHEWEBPLATFORMTARGETINGSUCHAWIDERANGEOFBROWSERSISCHALLENGINGBECAUSETHEYDONOTSUPPORTALLFEATURESOFMODERNBROWSERS", "original": "Angular is built on the latest standards of the web platform.\nTargeting such a wide range of browsers is challenging because they do not support all features of modern browsers.", "translation": "Angular 构建于 Web 平台的最新标准之上。\n要支持这么多浏览器是一个不小的挑战,因为它们不支持现代浏览器的所有特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "YOUCOMPENSATEBYLOADINGPOLYFILLSCRIPTSPOLYFILLSFORTHEBROWSERSTHATYOUMUSTSUPPORTTHETABLEBELOW#POLYFILLLIBSIDENTIFIESMOSTOFTHEPOLYFILLSYOUMIGHTNEED", "original": "You compensate by loading polyfill scripts (\"polyfills\") for the browsers that you must support.\nThe [table below](#polyfill-libs) identifies most of the polyfills you might need.", "translation": "你可以通过加载腻子脚本(\"polyfills\")来为想要支持的浏览器弥补这些特性。\n[下表](#polyfill-libs) 列出了可能用到的大多数腻子脚本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "THESUGGESTEDPOLYFILLSARETHEONESTHATRUNFULLANGULARAPPLICATIONSYOUMAYNEEDADDITIONALPOLYFILLSTOSUPPORTFEATURESNOTCOVEREDBYTHISLISTNOTETHATPOLYFILLSCANNOTMAGICALLYTRANSFORMANOLDSLOWBROWSERINTOAMODERNFASTONE", "original": "The suggested polyfills are the ones that run full Angular applications.\nYou may need additional polyfills to support features not covered by this list.\nNote that polyfills cannot magically transform an old, slow browser into a modern, fast one.", "translation": "这些建议的腻子脚本是运行完整 Angular 应用所需的。\n你可能还会需要另一些的腻子脚本来支持没有出现在此列表中的哪些特性。\n注意,这些腻子脚本并没有神奇的魔力来把老旧、慢速的浏览器变成现代、快速的浏览器,它只是填充了 API。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "##ENABLINGPOLYFILLS", "original": "## Enabling polyfills", "translation": "## 启用腻子脚本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ANGULARCLIHTTPS:GITHUBCOMANGULARANGULARCLIWIKIUSERSENABLEPOLYFILLSTHROUGHTHESRCPOLYFILLSTSFILETHATTHECLICREATEDWITHYOURPROJECT", "original": "[Angular CLI](https://github.com/angular/angular-cli/wiki) users enable polyfills through the `src/polyfills.ts` file that\nthe CLI created with your project.", "translation": "[Angular CLI](https://github.com/angular/angular-cli/wiki) 的用户可以通过自动创建的 `src/polyfills.ts` 文件来启用这些腻子脚本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "THISFILEINCORPORATESTHEMANDATORYANDMANYOFTHEOPTIONALPOLYFILLSASJAVASCRIPTIMPORTSTATEMENTS", "original": "This file incorporates the mandatory and many of the optional polyfills as JavaScript `import` statements.", "translation": "这个文件把强制的和很多可选的腻子脚本组织成 JavaScript 的 `import` 语句。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "THENPMPACKAGESFORTHEMANDATORYPOLYFILLSSUCHASZONEJSWEREINSTALLEDAUTOMATICALLYFORYOUWHENYOUCREATEDYOURPROJECTANDTHEIRCORRESPONDINGIMPORTSTATEMENTSAREREADYTOGOYOUPROBABLYWONTTOUCHTHESE", "original": "The npm packages for the _mandatory_ polyfills (such as `zone.js`) were installed automatically for you when you created your project and their corresponding `import` statements are ready to go. You probably won't touch these.", "translation": "**强制性** 腻子脚本(如 `zone.js`)的 npm 包在创建项目时就已经自动安装了,相应的 `import` 语句也都加好了。你一般不用动它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "BUTIFYOUNEEDANOPTIONALPOLYFILLYOULLHAVETOINSTALLITSNPMPACKAGEFOREXAMPLEIFYOUNEEDTHEWEBANIMATIONSPOLYFILLHTTP:CANIUSECOM#FEATWEBANIMATIONYOUCOULDINSTALLITWITHNPMUSINGTHEFOLLOWINGCOMMANDORTHEYARNEQUIVALENT:", "original": "But if you need an optional polyfill, you'll have to install its npm package.\nFor example, [if you need the web animations polyfill](http://caniuse.com/#feat=web-animation), you could install it with `npm`, using the following command (or the `yarn` equivalent):", "translation": "但是如果要用一个可选的腻子脚本,就要通过 `npm` 或 `yarn` 来安装它们的 npm 包了。\n比如,[如果你需要 web 动画的腻子脚本](http://caniuse.com/#feat=web-animation),就要通过下列命令之一来安装它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "THENOPENTHEPOLYFILLSTSFILEANDUNCOMMENTTHECORRESPONDINGIMPORTSTATEMENTASINTHEFOLLOWINGEXAMPLE:", "original": "Then open the `polyfills.ts` file and un-comment the corresponding `import` statement as in the following example:", "translation": "然后打开 `polyfills.ts` 文件,并反注释对应的 `import` 语句,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "IFYOUCANTFINDTHEPOLYFILLYOUWANTINPOLYFILLSTSADDITYOURSELFFOLLOWINGTHESAMEPATTERN:", "original": "If you can't find the polyfill you want in `polyfills.ts`,\nadd it yourself, following the same pattern:", "translation": "如果在 `polyfills.ts` 中找不到要使用的腻子脚本,就可以仿照下列模式自行添加它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "1INSTALLTHENPMPACKAGE", "original": "1. install the npm package", "translation": "安装 npm 包", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "1IMPORTTHEFILEINPOLYFILLSTS", "original": "1. `import` the file in `polyfills.ts`", "translation": "在 `polyfills.ts` 中 `import` 这个文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "NONCLIUSERSSHOULDFOLLOWTHEINSTRUCTIONSBELOW#NONCLI", "original": "Non-CLI users should follow the instructions [below](#non-cli).", "translation": "不使用 CLI 的用户可以遵循[下列](#non-cli)步骤自行操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "###MANDATORYPOLYFILLS", "original": "### Mandatory polyfills", "translation": "### 强制性腻子脚本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "THESEARETHEPOLYFILLSREQUIREDTORUNANANGULARAPPLICATIONONEACHSUPPORTEDBROWSER:", "original": "These are the polyfills required to run an Angular application on each supported browser:", "translation": "下表中的腻子脚本是每个浏览器都要用到的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "BROWSERSDESKTOPMOBILE", "original": "Browsers (Desktop & Mobile)", "translation": "浏览器(桌面和移动)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "POLYFILLSREQUIRED", "original": "Polyfills Required", "translation": "需要的腻子脚本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ES7REFLECTGUIDEBROWSERSUPPORT#COREES7REFLECTJITONLY", "original": "[ES7/reflect](guide/browser-support#core-es7-reflect) (JIT only)", "translation": "[ES7/reflect](guide/browser-support#core-es7-reflect) (仅 JIT)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "###OPTIONALBROWSERFEATURESTOPOLYFILL", "original": "### Optional browser features to polyfill", "translation": "### 可选浏览器特性的腻子脚本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "SOMEFEATURESOFANGULARMAYREQUIREADDITIONALPOLYFILLS", "original": "Some features of Angular may require additional polyfills.", "translation": "有些 Angular 特性可能需要额外的腻子脚本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "FOREXAMPLETHEANIMATIONSLIBRARYRELIESONTHESTANDARDWEBANIMATIONAPIWHICHISONLYAVAILABLEINCHROMEANDFIREFOXTODAYNOTETHATTHEDEPENDENCYOFWEBANIMATIONSJSINANGULARISONLYNECESSARYIFANIMATIONBUILDERISUSED", "original": "For example, the animations library relies on the standard web animation API, which is only available in Chrome and Firefox today.\n(note that the dependency of web-animations-js in Angular is only necessary if `AnimationBuilder` is used.)", "translation": "例如,动画库依赖于标准的 web 动画 API,目前它只在 Chrome 和 Firefox 上可用。你可能需要一个腻子脚本来在其它浏览器上使用动画功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "HEREARETHEFEATURESWHICHMAYREQUIREADDITIONALPOLYFILLS:", "original": "Here are the features which may require additional polyfills:", "translation": "下列特性可能需要更多腻子脚本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "FEATURE", "original": "Feature", "translation": "特性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "POLYFILL", "original": "Polyfill", "translation": "腻子脚本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "BROWSERSDESKTOPMOBILE", "original": "Browsers (Desktop & Mobile)", "translation": "浏览器(桌面和移动)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "JITCOMPILATIONGUIDEAOTCOMPILER", "original": "[JIT compilation](guide/aot-compiler).", - "translation": "[JIT 编译](guide/aot-compiler)", + "translation": "[JIT 编译](guide/aot-compiler)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "REQUIREDTOREFLECTFORMETADATA", "original": "Required to reflect for metadata.", "translation": "需要 reflect 来提供元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ALLCURRENTBROWSERSENABLEDBYDEFAULTCANREMOVEIFYOUALWAYSUSEAOTANDONLYUSEANGULARDECORATORS", "original": "All current browsers. Enabled by default.\n Can remove if you always use AOT and only use Angular decorators.", "translation": "默认对目前的所有浏览器都启用了。如果总是使用 AOT 模式,并且只使用 Angular 自带的装饰器,那么可以移除它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ANIMATIONSGUIDEANIMATIONSBRONLYIFANIMATIONBUILDERISUSEDWITHINTHEAPPLICATIONSTANDARDANIMATIONSUPPORTINANGULARDOESNTREQUIREANYPOLYFILLSASOFNG6", "original": "[Animations](guide/animations)\n <br>Only if `Animation Builder` is used within the application--standard\n animation support in Angular doesn't require any polyfills (as of NG6).", "translation": "[动画](guide/animations)\n <br>只有在应用中用到了 `Animation Builder` 时才需要;Angular 标准的动画支持是不需要任何腻子脚本的(截至 NG6)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "WEBANIMATIONSGUIDEBROWSERSUPPORT#WEBANIMATIONS", "original": "[Web Animations](guide/browser-support#web-animations)", "translation": "[Web 动画](guide/browser-support#web-animations)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "PIFANIMATIONBUILDERISUSEDTHENTHEPOLYFILLWILLENABLESCRUBBINGSUPPORTFORIEEDGEANDSAFARICHROMEANDFIREFOXSUPPORTTHISNATIVELYP", "original": "<p>If AnimationBuilder is used then the polyfill will enable scrubbing\n support for IE/Edge and Safari (Chrome and Firefox support this natively).</p>", "translation": "<p>如果使用了 AnimationBuilder,那么腻子脚本将为 IE/Edge 和 Safari 启用擦除(scrubbing)支持(Chrome 和 Firefox 原生支持此特性)</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "IFYOUUSETHEFOLLOWINGDEPRECATEDI18NPIPES:", "original": "If you use the following deprecated i18n pipes:", "translation": "如果你使用下列已废弃的 i18n 管道:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ALLBUTCHROMEFIREFOXEDGEIE11ANDSAFARI10", "original": "All but Chrome, Firefox, Edge, IE11 and Safari 10", "translation": "除了 Chrome、Firefox、Edge、IE11 和 Safari 10 外的所有浏览器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "ONSVGELEMENTS", "original": "on SVG elements", "translation": "在 SVG 元素上应用时", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "WHENSENDINGANDRECEIVINGBINARYDATA", "original": "when sending and receiving binary data", "translation": "用 [Http](guide/http) 发送和接收二进制数据时", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "###SUGGESTEDPOLYFILLS##", "original": "### Suggested polyfills ##", "translation": "### 建议的腻子脚本 ##", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "BELOWARETHEPOLYFILLSWHICHAREUSEDTOTESTTHEFRAMEWORKITSELFTHEYAREAGOODSTARTINGPOINTFORANAPPLICATION", "original": "Below are the polyfills which are used to test the framework itself. They are a good starting point for an application.", "translation": "下表中是用来测试框架本身的腻子脚本,它们是应用程序的优质起点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "POLYFILL", "original": "Polyfill", "translation": "腻子脚本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "LICENSE", "original": "License", "translation": "授权方式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "SIZE", "original": "Size*", "translation": "大小*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "PUBLICDOMAIN", "original": "Public domain", "translation": "公共域", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "FIGURESAREFORMINIFIEDANDGZIPPEDCODECOMPUTEDWITHTHEAHREFHTTP:CLOSURECOMPILERAPPSPOTCOMHOMECLOSURECOMPILERA", "original": "\\* Figures are for minified and gzipped code,\ncomputed with the <a href=\"http://closure-compiler.appspot.com/home\">closure compiler</a>.", "translation": "\\* 这里的数据都按最小化并且 gzip 压缩后的版本算,是由<a href=\"http://closure-compiler.appspot.com/home\">closure compiler</a>计算出的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "##POLYFILLSFORNONCLIUSERS", "original": "## Polyfills for non-CLI users", "translation": "## 非 CLI 的用户的腻子脚本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "IFYOUARENOTUSINGTHECLIYOUSHOULDADDYOURPOLYFILLSCRIPTSDIRECTLYTOTHEHOSTWEBPAGEINDEXHTMLPERHAPSLIKETHIS", "original": "If you are not using the CLI, you should add your polyfill scripts directly to the host web page (`index.html`), perhaps like this.", "translation": "如果你不使用 CLI,就要直接把腻子脚本添加到宿主页(`index.html`)中,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/browser-support.md" }, { + "key": "#CHANGELOG", "original": "# Change Log", "translation": "# 变更记录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEANGULARDOCUMENTATIONISALIVINGDOCUMENTWITHCONTINUOUSIMPROVEMENTSTHISLOGCALLSATTENTIONTORECENTSIGNIFICANTCHANGES", "original": "The Angular documentation is a living document with continuous improvements.\nThis log calls attention to recent significant changes.", "translation": "Angular 的文档将持续不断的更新和改进。本日志记录了近期最重要的变更。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##UPDATEDTOANGULAR40DOCUMENTATIONFORANGULAR2XCANBEFOUNDATV2ANGULARIOHTTPS:V2ANGULARIO", "original": "## Updated to Angular 4.0. Documentation for Angular 2.x can be found at [v2.angular.io](https://v2.angular.io).", "translation": "## 更新到 Angular 4.0 。Angular 2.x 的文档在 [v2.angular.io](https://v2.angular.io) 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##ALLMENTIONOFMODULEIDREMOVEDCOMPONENTRELATIVEPATHSGUIDEDELETED20170313", "original": "## All mention of moduleId removed. \"Component relative paths\" guide deleted (2017-03-13)", "translation": "## 移除了所有的 moduleId 引用。移除了“组件相对路径” 的指南。(2017-03-13)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "WEADDEDANEWSYSTEMJSPLUGINSYSTEMJSANGULARLOADERJSTOOURRECOMMENDEDSYSTEMJSCONFIGURATIONTHISPLUGINDYNAMICALLYCONVERTSCOMPONENTRELATIVEPATHSINTEMPLATEURLANDSTYLEURLSTOABSOLUTEPATHSFORYOU", "original": "We added a new SystemJS plugin (systemjs-angular-loader.js) to our recommended SystemJS configuration.\nThis plugin dynamically converts \"component-relative\" paths in templateUrl and styleUrls to \"absolute paths\" for you.", "translation": "我们往建议的 SystemJS 配置中新增了一个 SystemJS 插件 (systemjs-angular-loader.js) 。\n这个插件可以帮你把 templateUrl 和 styleUrls 中的组件相对路径动态转换为绝对路径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "WESTRONGLYENCOURAGEYOUTOONLYWRITECOMPONENTRELATIVEPATHSTHATISTHEONLYFORMOFURLDISCUSSEDINTHESEDOCSYOUNOLONGERNEEDTOWRITECOMPONENTMODULEID:MODULEIDNORSHOULDYOU", "original": "We strongly encourage you to only write component-relative paths.\nThat is the only form of URL discussed in these docs. You no longer need to write @Component({ moduleId: module.id }), nor should you.", "translation": "我们强烈建议你只写组件相对路径。\n这也是本文档中所使用的唯一形式。你不必再写 `@Component({ moduleId: module.id })`,而且也不应该再这么写。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##NEW:DOWNLOADABLEEXAMPLESFOREACHGUIDE20170228", "original": "## NEW: Downloadable examples for each guide (2017-02-28)", "translation": "## 新增:每篇指南都增加了可下载的范例程序 (2017-02-28)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "NOWYOUCANDOWNLOADTHESAMPLECODEFORANYGUIDEANDRUNITLOCALLYLOOKFORTHENEWDOWNLOADLINKSNEXTTOTHELIVEEXAMPLELINKS", "original": "Now you can download the sample code for any guide and run it locally.\nLook for the new download links next to the \"live example\" links.", "translation": "现在你可以为任何一篇指南下载范例程序,并且在本地运行它了。\n请在“在线例子”的链接后面查找新的下载链接。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##TEMPLATESYNTAXSTRUCTURALDIRECTIVES:REFRESHED20170206", "original": "## Template Syntax/Structural Directives: refreshed (2017-02-06)", "translation": "## 模板语法/结构型指令:更新了 (2017-02-06)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THETEMPLATESYNTAXGUIDETEMPLATESYNTAXANDSTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVESGUIDESWERESIGNIFICANTLYREVISEDFORCLARITYACCURACYANDCURRENTRECOMMENDEDPRACTICESDISCUSSESNGCONTAINERREVISEDSAMPLESAREMORECLEARANDCOVERALLTOPICSDISCUSSED", "original": "The [_Template-Syntax_](guide/template-syntax) and [_Structural Directives_](guide/structural-directives)\nguides were significantly revised for clarity, accuracy, and current recommended practices.\nDiscusses `<ng-container>`.\nRevised samples are more clear and cover all topics discussed.", "translation": "对[模板语法](guide/template-syntax) 和 [结构型指令](guide/structural-directives)这两篇指南做了大幅修改,来让它们更加清晰、准确,并符合当前的最佳实践。\n讨论了 `<ng-container>`。\n修改了例子,来让它们更清晰,并且涵盖了所有讨论到的主题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##NEW:SAMPLESRESTRUCTUREDWITHSRCFOLDER20170202", "original": "## NEW: Samples re-structured with `src/` folder (2017-02-02)", "translation": "## 新增:调整了范例程序的结构,移到了 `src/` 文件夹 (2017-02-02)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ALLDOCUMENTATIONSAMPLESHAVEBEENREALIGNEDWITHTHEDEFAULTFOLDERSTRUCTUREOFTHEANGULARCLITHATSASTEPALONGTHEROADTOBASINGTHESAMPLEINTHEANGULARCLIBUTITSALSOGOODINITSOWNRIGHTITHELPSCLEARLYSEPARATEAPPCODEFROMSETUPANDCONFIGURATIONFILES", "original": "All documentation samples have been realigned with the default folder structure of the Angular CLI.\nThat's a step along the road to basing the sample in the Angular CLI.\nBut it's also good in its own right.\nIt helps clearly separate app code from setup and configuration files.", "translation": "所有的文档范例都已经向 Angular CLI 的默认文件夹结构看齐了。\n这是把范例迁移到 Angular CLI 过程中的一步。\n不过也不仅是为了迁移,它还能把应用代码从环境准备代码和配置代码中清晰地分离出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ALLSAMPLESNOWHAVEASRCFOLDERATTHEPROJECTROOTTHEFORMERAPPFOLDERMOVESUNDERSRCREADABOUTMOVINGYOUREXISTINGPROJECTTOTHISSTRUCTUREINAHREFHTTPS:GITHUBCOMANGULARQUICKSTART#UPDATINGTOANEWERVERSIONOFTHEQUICKSTARTREPOTARGETMIGRATINGSAMPLESQUICKSTARTAPPTOTHESRCFOLDERTHEQUICKSTARTREPOUPDATEINSTRUCTIONSA", "original": "All samples now have a `src/` folder at the project root.\nThe former `app/` folder moves under `src/`.\nRead about moving your existing project to this structure in\n<a href=\"https://github.com/angular/quickstart#updating-to-a-newer-version-of-the-quickstart-repo\" target=\"Migrating samples/quickstart app to the src folder\">\nthe QuickStart repo update instructions</a>.", "translation": "所有的范例都改成了使用项目根目录下的 `src/` 文件夹。\n也就是把以前的 `app/` 文件夹移到了 `src/` 文件夹下面。\n要了解如何对你的现有项目进行这种迁移,请参阅<a href=\"https://github.com/angular/quickstart#updating-to-a-newer-version-of-the-quickstart-repo\" target=\"_blank\" target=\"把范例中的应用迁移到 src 文件夹\">QuickStart 中的迁移指南</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "NOTABLY:", "original": "Notably:", "translation": "要点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "APPMAINTSMOVEDTOSRCMAINTS", "original": "* `app/main.ts` moved to `src/main.ts`.", "translation": "把 `app/main.ts` 移到 `src/main.ts`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "APPMOVEDTOSRCAPP", "original": "* `app/` moved to `src/app/`.", "translation": "把 `app/` 移到 `src/app/`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "INDEXHTMLSTYLESCSSANDTSCONFIGJSONMOVEDINSIDESRC", "original": "* `index.html`, `styles.css` and `tsconfig.json` moved inside `src/`.", "translation": "把 `index.html`、`styles.css` 和 `tsconfig.json` 移到 `src/` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "SYSTEMJSCONFIGJSNOWIMPORTSMAINJSINSTEADOFAPP", "original": "* `systemjs.config.js` now imports `main.js` instead of `app`.", "translation": "`systemjs.config.js` 现在要导入 `main.js` 而不是 `app`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ADDEDLITESERVERCONFIGURATIONBSCONFIGJSONTOSERVESRC", "original": "* Added `lite-server` configuration (`bs-config.json`) to serve `src/`.", "translation": "新增了一个 `lite-server` 配置(`bs-config.json`)以便在 `src/` 下启动开发服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##NEW:REACTIVEFORMSGUIDE20170131", "original": "## NEW: Reactive Forms guide (2017-01-31)", "translation": "## 新增:响应式(Reactive)表单指南 (2017-01-31)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THENEWREACTIVEFORMSGUIDEREACTIVEFORMSGUIDEEXPLAINSHOWANDWHYTOBUILDAREACTIVEFORMREACTIVEFORMSARETHECODEBASEDCOUNTERPARTTOTHEDECLARATIVETEMPLATEDRIVENFORMSAPPROACHINTRODUCEDINTHEFORMSGUIDEFORMSGUIDECHECKITOUTBEFOREYOUDECIDEHOWTOADDFORMSTOYOURAPPREMEMBERALSOTHATYOUCANUSEBOTHTECHNIQUESINTHESAMEAPPCHOOSINGTHEAPPROACHTHATBESTFITSEACHSCENARIO", "original": "The new [**Reactive Forms**](guide/reactive-forms) guide explains how and why to build a \"reactive form\".\n\"Reactive Forms\" are the code-based counterpart to the declarative \"Template Driven\" forms approach\nintroduced in the [Forms](guide/forms) guide.\nCheck it out before you decide how to add forms to your app.\nRemember also that you can use both techniques in the same app,\nchoosing the approach that best fits each scenario.", "translation": "新的[**响应式表单**](guide/reactive-forms)指南解释了如何以及何时构建“响应式表单”。\n“响应式表单”是基于代码的表单构建方式,与[表单](guide/forms)中介绍的声明“模板驱动”表单的方法相对。\n在你决定如何往应用中添加表单之前,建议先读读那一章。\n同时,别忘了你可以在同一个应用中同时使用这两种技术,根据场景来选择最合适的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##NEW:DEPLOYMENTGUIDE20170130", "original": "## NEW: Deployment guide (2017-01-30)", "translation": "## 新增:部署指南 (2017-01-30)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THENEWDEPLOYMENTGUIDEDEPLOYMENTGUIDEDESCRIBESTECHNIQUESFORPUTTINGYOURAPPLICATIONONASERVERITINCLUDESIMPORTANTADVICEONOPTIMIZINGFORPRODUCTION", "original": "The new [Deployment](guide/deployment) guide describes techniques for putting your application on a server.\nIt includes important advice on optimizing for production.", "translation": "新的[部署指南](guide/deployment)讲的是如何把应用放到服务器上。\n其中包括了为生产环境进行优化的重要建议。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##HIERARCHICALDEPENDENCYINJECTION:REFRESHED20170113", "original": "## Hierarchical Dependency Injection: refreshed (2017-01-13)", "translation": "## 多级依赖注入:更新完毕 (2017-01-13)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "HIERARCHICALDEPENDENCYINJECTIONGUIDEHIERARCHICALDEPENDENCYINJECTIONGUIDEISSIGNIFICANTLYREVISEDCLOSESISSUE#3086REVISEDSAMPLESARECLEARERANDCOVERALLTOPICSDISCUSSED", "original": "[Hierarchical Dependency Injection](guide/hierarchical-dependency-injection) guide is significantly revised.\nCloses issue #3086.\nRevised samples are clearer and cover all topics discussed.", "translation": "[多级依赖注入](guide/hierarchical-dependency-injection)做了显著修改。关闭了 issue #3086。修改过的范例更加清晰,而且涵盖了讨论到的全部主题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##MISCELLANEOUS20170105", "original": "## Miscellaneous (2017-01-05)", "translation": "## 杂项 (2017-01-05)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "SETUPGUIDESETUPGUIDE:ADDEDOPTIONALINSTRUCTIONSONHOWTOREMOVENONESSENTIALFILES", "original": "* [Setup](guide/setup) guide:\nadded (optional) instructions on how to remove _non-essential_ files.", "translation": "[环境搭建](guide/setup)指南:\n 添加了(可选的)步骤说明,告诉你如何移除*非核心*文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "NOLONGERCONSOLIDATERXJSOPERATORIMPORTSINRXJSEXTENSIONSFILEEACHFILESHOULDIMPORTWHATITNEEDS", "original": "* No longer consolidate RxJS operator imports in `rxjs-extensions` file; each file should import what it needs.", "translation": "不再在 `rxjs-extensions` 文件中统一导入 RxJS 的操作符,每个文件应该各自导入它自己所需的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ALLSAMPLESPREPENDTEMPLATESTYLEURLSWITHASABESTPRACTICE", "original": "* All samples prepend template/style URLs with `./` as a best practice.", "translation": "所有范例都在模板/样式的 URL 之前添加 `./` 前缀 …… 而且你在实际开发中也应该这么做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "STYLEGUIDEGUIDESTYLEGUIDE:COPYEDITSANDREVISEDRULES", "original": "* [Style Guide](guide/styleguide): copy edits and revised rules.", "translation": "[风格指南](guide/styleguide):复制了编辑过的和修改过的规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##ROUTER:MOREDETAIL20161221", "original": "## Router: more detail (2016-12-21)", "translation": "## 路由:更详细 (2016-12-21)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ADDEDMOREINFORMATIONTOTHEROUTERGUIDEROUTERGUIDEINCLUDINGSECTIONSNAMEDOUTLETSWILDCARDROUTESANDPRELOADSTRATEGIES", "original": "Added more information to the [Router](guide/router) guide\nincluding sections named outlets, wildcard routes, and preload strategies.", "translation": "往[路由指南](guide/router)中添加了更多信息,包括“命名出口(Outlet)”、通配符路由和预加载策略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##HTTP:HOWTOSETDEFAULTREQUESTHEADERSANDOTHERREQUESTOPTIONS20161214", "original": "## HTTP: how to set default request headers (and other request options) (2016-12-14)", "translation": "## Http:如何设置默认的请求头(以及其它配置项) (2016-12-14)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ADDEDSECTIONONHOWTOSETDEFAULTREQUESTHEADERSANDOTHERREQUESTOPTIONSTOHTTPGUIDE", "original": "Added section on how to set default request headers (and other request options) to\nHTTP guide.", "translation": "添加了一节“如何设置默认的请求头(以及其它配置项)”", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##TESTING:ADDEDCOMPONENTTESTPLUNKERS20161202", "original": "## Testing: added component test plunkers (2016-12-02)", "translation": "## 测试:添加了组件测试的 plunker 范例 (2016-12-02)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ADDEDTWOPLUNKERSTHATEACHTESTONESIMPLECOMPONENTSOYOUCANWRITEACOMPONENTTESTPLUNKEROFYOUROWN:LIVEEXAMPLENAMESETUPPLNKRQUICKSTARTSPECSONELIVEEXAMPLEFORTHEQUICKSTARTSEEDSAPPCOMPONENTANDLIVEEXAMPLENAMETESTINGPLNKRBANNERSPECSANOTHERLIVEEXAMPLEFORTHETESTINGGUIDESBANNERCOMPONENTLINKEDTOTHESEPLUNKERSINTESTINGANDSETUPANATOMYGUIDES", "original": "Added two plunkers that each test _one simple component_ so you can write a component test plunker of your own: <live-example name=\"setup\" plnkr=\"quickstart-specs\">one</live-example> for the QuickStart seed's `AppComponent` and <live-example name=\"testing\" plnkr=\"banner-specs\">another</live-example> for the Testing guide's `BannerComponent`.\nLinked to these plunkers in \"Testing\" and \"Setup anatomy\" guides.", "translation": "添加了两个 plunker 例子,每个都测试一个简单的组件,以便你可以自己在 plunker 中写组件测试:<live-example name=\"setup\" plnkr=\"quickstart-specs\">一个</live-example>用于测试快速起步中的 `AppComponent`,<live-example name=\"testing\" plnkr=\"banner-specs\">另一个</live-example>用于测试“测试”章节的 `BannerComponent`。\n并在“测试”和“环境设置剖析”中链接到它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##INTERNATIONALIZATION:PLURALIZATIONANDSELECT20161130", "original": "## Internationalization: pluralization and _select_ (2016-11-30)", "translation": "## 国际化:单复数和 `select` (2016-11-30)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEINTERNATIONALIZATIONI18NGUIDEI18NGUIDEEXPLAINSHOWTOHANDLEPLURALIZATIONANDTRANSLATIONOFALTERNATIVETEXTSWITHSELECTTHESAMPLEDEMONSTRATESTHESEFEATURESTOO", "original": "The [Internationalization (i18n)](guide/i18n) guide explains how to handle pluralization and\ntranslation of alternative texts with `select`.\nThe sample demonstrates these features too.", "translation": "[国际化 (i18n)](guide/i18n)解释了如何处理单复数问题,和如何使用 `select` 来翻译候选内容。\n例子中也演示了这些特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##TESTING:KARMAFILEUPDATES20161130", "original": "## Testing: karma file updates (2016-11-30)", "translation": "## 测试:更新了 karma 文件 (2016-11-30)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "KARMACONFIGKARMATESTSHIMCANHANDLEMULTIPLESPECSOURCEPATHSSEEQUICKSTARTISSUE:ANGULARQUICKSTART#294HTTPS:GITHUBCOMANGULARQUICKSTARTISSUES294", "original": "* `karma.config` + `karma-test-shim` can handle multiple spec source paths;\nsee quickstart issue: [angular/quickstart#294](https://github.com/angular/quickstart/issues/294).", "translation": "`karma.config` + `karma-test-shim` 可以处理多个测试源文件路径了,参见[angular/quickstart#294](https://github.com/angular/quickstart/issues/294)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "DISPLAYSJASMINERUNNEROUTPUTINTHEKARMALAUNCHEDBROWSER", "original": "* Displays Jasmine Runner output in the karma-launched browser.", "translation": "在启动了 karma 的浏览器中显示 Jasmine 的输出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##QUICKSTARTREWRITE20161118", "original": "## QuickStart Rewrite (2016-11-18)", "translation": "## 全新《快速上手》 (2016-11-18)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEQUICKSTARTISCOMPLETELYREWRITTENSOTHATITACTUALLYISQUICKITREFERENCESAMINIMALHELLOANGULARAPPRUNNINGINPLUNKERTHENEWSETUPGUIDESETUPPAGETELLSYOUHOWTOINSTALLALOCALDEVELOPMENTENVIRONMENTBYDOWNLOADINGORCLONINGTHEQUICKSTARTGITHUBREPOSITORYYOUARENOLONGERASKEDTOCOPYANDPASTECODEINTOSETUPFILESTHATWERENOTEXPLAINEDANYWAY", "original": "The QuickStart is completely rewritten so that it actually is quick.\nIt references a minimal \"Hello Angular\" app running in Plunker.\nThe new [Setup](guide/setup) page tells you how to install a local development environment\nby downloading (or cloning) the QuickStart github repository.\nYou are no longer asked to copy-and-paste code into setup files that were not explained anyway.", "translation": "完全重写了《快速上手》,变得更加快速。\n它使用了在 Plunker 中运行的最小化的 “Hello Angular” 应用。\n新添加的[搭建本地开发环境](guide/setup)页面解释了如何通过下载或者克隆 QuickStart github 库来安装本地开发环境。\n你将不再需要拷贝粘贴代码到一些并没有对其解释的配置文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##SYNCWITHANGULARV22020161114", "original": "## Sync with Angular v.2.2.0 (2016-11-14)", "translation": "## 与 Angular v.2.2.0 同步(2016-11-14)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "DOCSANDCODESAMPLESUPDATEDANDTESTEDWITHANGULARV220", "original": "Docs and code samples updated and tested with Angular v.2.2.0.", "translation": "使用 Angular v.2.2.0 更新和测试所有文档和代码例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##UPDATE:NGUPGRADEGUIDEFORTHEAOTFRIENDLYUPGRADESTATICMODULE20161114", "original": "## UPDATE: NgUpgrade Guide for the AOT friendly _upgrade/static_ module (2016-11-14)", "translation": "## 更新:用于 AOT 的 *upgrade/static* 模块 NgUpgrade 指南 (2016-11-14)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEUPDATEDNGUPGRADEGUIDEGUIDEUPGRADEGUIDECOVERSTHENEWAOTFRIENDLYUPGRADESTATICMODULERELEASEDINV220WHICHISTHERECOMMENDEDFACILITYFORMIGRATINGFROMANGULARJSTOANGULARTHEDOCUMENTATIONFORTHEVERSIONPRIORTOV220HASBEENREMOVED", "original": "The updated [NgUpgrade Guide](guide/upgrade) guide covers the\nnew AOT friendly `upgrade/static` module\nreleased in v.2.2.0, which is the recommended\nfacility for migrating from AngularJS to Angular.\nThe documentation for the version prior to v.2.2.0 has been removed.", "translation": "更新的[NgUpgrade 指南](guide/upgrade)涵盖在 v.2.2.0 发布的 AOT`upgrade/static` 模块,\n是从 AngularJS 升级至 Angular 的推荐工具。\n删除早于 v.2.2.0 版本的文档。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##ES6DESCRIBEDINTYPESCRIPTTOJAVASCRIPT20161114", "original": "## ES6 described in \"TypeScript to JavaScript\" (2016-11-14)", "translation": "## 在“从 TypeScript 到 JavaScript”增加 ES6 的描述 (2016-11-14)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEUPDATEDTYPESCRIPTTOJAVASCRIPTGUIDEEXPLAINSHOWTOWRITEAPPSINES67BYTRANSLATINGTHECOMMONIDIOMSINTHETYPESCRIPTDOCUMENTATIONEXAMPLESANDELSEWHEREONTHEWEBTOES67ANDES5", "original": "The updated TypeScript to JavaScript guide explains how to write apps in ES6/7\nby translating the common idioms in the TypeScript documentation examples\n(and elsewhere on the web) to ES6/7 and ES5.", "translation": "更新了“从 TypeScript 到 JavaScript”,以解释如何使用 ES6/7 编写应用。\n将 TypeScript 文档示例中(以及网站其它地方)的习惯用法翻译成 ES6/7 和 ES5。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THISWASREMOVEDINAUGUST2017HTTPS:GITHUBCOMANGULARANGULARPULL18694BUTCANSTILLBEVIEWEDINTHEV2DOCUMENTATIONHTTPS:V2ANGULARIODOCSTSLATESTCOOKBOOKTSTOJSHTML", "original": "This was [removed in August 2017](https://github.com/angular/angular/pull/18694) but can still be\nviewed in the [v2 documentation](https://v2.angular.io/docs/ts/latest/cookbook/ts-to-js.html).", "translation": "本章已经 [于 2017 年 8 月移除](https://github.com/angular/angular/pull/18694),\n不过仍然可以在[第二版的文档中](https://v2.angular.io/docs/ts/latest/cookbook/ts-to-js.html)看到。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##SYNCWITHANGULARV21120161021", "original": "## Sync with Angular v.2.1.1 (2016-10-21)", "translation": "## 与 Angular v.2.1.1 同步(2016-10-21)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "DOCSANDCODESAMPLESUPDATEDANDTESTEDWITHANGULARV211", "original": "Docs and code samples updated and tested with Angular v.2.1.1.", "translation": "使用 Angular v.2.1.1 更新和测试所有文档和代码例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##NPMTYPESPACKAGESREPLACETYPINGS20161020", "original": "## npm _@types_ packages replace _typings_ (2016-10-20)", "translation": "## 使用 npm 的_@types*包替换*typings_ (2016-10-20)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "DOCUMENTATIONSAMPLESNOWGETTYPESCRIPTTYPEINFORMATIONFOR3RDPARTYLIBRARIESFROMNPMTYPESPACKAGESRATHERTHANWITHTHETYPINGSTOOLINGTHETYPINGSJSONFILEISGONE", "original": "Documentation samples now get TypeScript type information for 3rd party libraries\nfrom npm `@types` packages rather than with the _typings_ tooling.\nThe `typings.json` file is gone.", "translation": "文档例子现在从 npm 的 `@types` 第三方库获取 TypeScript 类型信息,不再使用_typings_。\n删除 `typings.json` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEANGULARJSUPGRADEGUIDEUPGRADEGUIDEREFLECTSTHISCHANGETHEPACKAGEJSONINSTALLSTYPESANGULARANDSEVERALTYPESANGULARPACKAGESINSUPPORTOFUPGRADETHESEARENOTNEEDEDFORPUREANGULARDEVELOPMENT", "original": "The [AngularJS Upgrade](guide/upgrade) guide reflects this change.\nThe `package.json` installs `@types/angular` and several `@types/angular-...`\npackages in support of upgrade; these are not needed for pure Angular development.", "translation": "\"[从 AngularJS 升级](guide/upgrade)\"指南反映了这个变化。\n`package.json` 安装 `@types/angular` 和一些 `@types/angular-...` 包来支持升级。它们在纯 Angular 开发中是不需要的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##TEMPLATESYNTAXEXPLAINSTWOWAYDATABINDINGSYNTAX20161020", "original": "## \"Template Syntax\" explains two-way data binding syntax (2016-10-20)", "translation": "## \"模板语法\"添加了双向数据绑定语法的解释(2016-10-20)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "DEMONSTRATESHOWTOTWOWAYDATABINDTOACUSTOMANGULARCOMPONENTANDREEXPLAINSNGMODELINTERMSOFTHEBASICSYNTAX", "original": "Demonstrates how to two-way data bind to a custom Angular component and\nre-explains `[(ngModel)]` in terms of the basic `[()]` syntax.", "translation": "展示了如何在自定义 Angular 组件中双向数据绑定,用基础 `[()]` 重新解释 `[(ngModel)]`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##BREAKINGCHANGE:INMEMORYWEBAPIV0111DELIVEREDASESMUMD20161019", "original": "## BREAKING CHANGE: `in-memory-web-api` (v.0.1.11) delivered as esm umd (2016-10-19)", "translation": "## 破坏性变化:`in-memory-web-api` (v.0.1.11) 以 esm umd 的形式发布 (2016-10-19)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THISCHANGESUPPORTSES6DEVELOPERSANDALIGNSBETTERWITHTYPICALANGULARLIBRARIESITDOESNOTAFFECTTHEMODULESAPIBUTITDOESAFFECTHOWYOULOADANDIMPORTITSEETHEAHREFHTTPS:GITHUBCOMANGULARINMEMORYWEBAPIBLOBMASTERCHANGELOGMD#011320161020CHANGENOTEAINTHEINMEMORYWEBAPIREPO", "original": "This change supports ES6 developers and aligns better with typical Angular libraries.\nIt does not affect the module's API but it does affect how you load and import it.\nSee the <a href=\"https://github.com/angular/in-memory-web-api/blob/master/CHANGELOG.md#0113-2016-10-20\">change note</a>\nin the `in-memory-web-api` repo.", "translation": "这个变化支持 ES6 开发者,并与典型的 Angular 库看齐。\n它不会影响模块的 API,但是它改变了加载和导入它的方式。\n参见 `in-memory-web-api` 库的<a href=\"https://github.com/angular/in-memory-web-api/blob/master/CHANGELOG.md#0113-2016-10-20\" target=\"_blank\">变更记录</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##ROUTERPRELOADSYNTAXAND:ENTER:LEAVEANIMATIONS20161019", "original": "## \"Router\" _preload_ syntax and _:enter_/_:leave_ animations (2016-10-19)", "translation": "## \"路由器\"*预加载*语法和 *:enter*/*:leave* 动画(2016-10-19)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEROUTERCANLAZILYPRELOADMODULESAFTERTHEAPPSTARTSANDBEFORETHEUSERNAVIGATESTOTHEMFORIMPROVEDPERCEIVEDPERFORMANCE", "original": "The router can lazily _preload_ modules _after_ the app starts and\n_before_ the user navigates to them for improved perceived performance.", "translation": "路由器可以在应用启动*之后*和用户导航到惰性加载模块*之前*,预先加载惰性模块,以增强性能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "NEW:ENTERAND:LEAVEALIASESMAKEANIMATIONMORENATURAL", "original": "New `:enter` and `:leave` aliases make animation more natural.", "translation": "新 `:enter` 和 `:leave` 语法,让动画更加自然。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##SYNCWITHANGULARV21020161012", "original": "## Sync with Angular v.2.1.0 (2016-10-12)", "translation": "## 与 Angular v.2.1.0 同步(2016-10-12)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "DOCSANDCODESAMPLESUPDATEDANDTESTEDWITHANGULARV210", "original": "Docs and code samples updated and tested with Angular v.2.1.0.", "translation": "使用 Angular v.2.1.0 更新和测试所有文档和代码例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##NEWAHEADOFTIMEAOTCOMPILATIONGUIDE20161011", "original": "## NEW \"Ahead of time (AOT) Compilation\" guide (2016-10-11)", "translation": "## 添加了新的“预编译(AOT)\" 指南(2016-10-11)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THENEWAHEADOFTIMEAOTCOMPILATIONGUIDEAOTCOMPILERGUIDEEXPLAINSWHATAOTCOMPILATIONISANDWHYYOUDWANTITITDEMONSTRATESTHEBASICSWITHAQUICKSTARTAPPFOLLOWEDBYTHEMOREADVANCEDCONSIDERATIONSOFCOMPILINGANDBUNDLINGTHETOUROFHEROES", "original": "The NEW [Ahead of time (AOT) Compilation](guide/aot-compiler) guide\nexplains what AOT compilation is and why you'd want it.\nIt demonstrates the basics with a QuickStart app\nfollowed by the more advanced considerations of compiling and bundling the Tour of Heroes.", "translation": "全新[预编译(AOT)](guide/aot-compiler)指南介绍了什么是 AOT 编译和为何你需要它。\n它以**快速上手**应用程序开始讲解,接着介绍了编译和构建**英雄指南**的更高级的注意事项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##SYNCWITHANGULARV2022016106", "original": "## Sync with Angular v.2.0.2 (2016-10-6)", "translation": "## 与 Angular v.2.0.2 同步 (2016-10-6)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "DOCSANDCODESAMPLESUPDATEDANDTESTEDWITHANGULARV202", "original": "Docs and code samples updated and tested with Angular v.2.0.2.", "translation": "使用 Angular v.2.0.2 更新和测试所有文档和代码例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##ROUTINGANDNAVIGATIONGUIDEWITHTHEROUTERMODULE2016105", "original": "## \"Routing and Navigation\" guide with the _Router Module_ (2016-10-5)", "translation": "## 在“路由和导航”向导中添加**路由模块** (2016-10-5)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEROUTINGANDNAVIGATIONGUIDEROUTERGUIDENOWLOCATESROUTECONFIGURATIONINAROUTINGMODULETHEROUTINGMODULEREPLACESTHEPREVIOUSROUTINGOBJECTINVOLVINGTHEMODULEWITHPROVIDERS", "original": "The [Routing and Navigation](guide/router) guide now locates route configuration\nin a _Routing Module_.\nThe _Routing Module_ replaces the previous _routing object_ involving the `ModuleWithProviders`.", "translation": "[Routing and Navigation](guide/router)现在在**路由模块**中设置路由配置。\n**路由模块**替换之前的**路由对象**,使用了 `ModuleWithProviders`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ALLGUIDEDSAMPLESWITHROUTINGUSETHEROUTINGMODULEANDPROSECONTENTHASBEENUPDATEDMOSTCONSPICUOUSLYINTHENGMODULEGUIDENGMODULESGUIDEANDNGMODULEFAQGUIDENGMODULEFAQGUIDE", "original": "All guided samples with routing use the _Routing Module_ and prose content has been updated,\nmost conspicuously in the\n[NgModule](guide/ngmodules) guide and [NgModule FAQ](guide/ngmodule-faq) guide.", "translation": "所有使用路由的例子都使用**路由模块**,相关内容也被更新。更新最多的是[Angular 模块(NgModule)](guide/ngmodules)章和[Angular 模块常见问题](guide/ngmodule-faq)指南。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##NEWINTERNATIONALIZATIONGUIDE20160930", "original": "## New \"Internationalization\" guide (2016-09-30)", "translation": "## 全新“国际化”指南(2016-09-30)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "ADDEDANEWINTERNATIONALIZATIONI18NGUIDEI18NGUIDETHATSHOWSHOWTOUSEANGULARI18NFACILITIESTOTRANSLATETEMPLATETEXTINTOMULTIPLELANGUAGES", "original": "Added a new [Internationalization (i18n)](guide/i18n) guide that shows how\nto use Angular \"i18n\" facilities to translate template text into multiple languages.", "translation": "添加了新的[国际化(i18n)](guide/i18n)指南,展示了如何使用 Angular 的“i18n”工具来讲模板文本翻译到多种语言。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##ANGULARINMEMORYWEBAPIPACKAGERENAME20160927", "original": "## \"angular-in-memory-web-api\" package rename (2016-09-27)", "translation": "## 重命名“angular-in-memory-web-api”包(2016-09-27)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "MANYSAMPLESUSETHEANGULARINMEMORYWEBAPITOSIMULATEAREMOTESERVERTHISLIBRARYISALSOUSEFULTOYOUDURINGEARLYDEVELOPMENTBEFOREYOUHAVEASERVERTOTALKTO", "original": "Many samples use the `angular-in-memory-web-api` to simulate a remote server.\nThis library is also useful to you during early development before you have a server to talk to.", "translation": "许多例子使用了 `angular-in-memory-web-api` 来模拟远程服务器。\n这个库在你拥有服务器之前的早期开发阶段也很有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THEPACKAGENAMEWASCHANGEDFROMANGULAR2INMEMORYWEBAPIWHICHISSTILLFROZENINTIMEONNPMTHENEWANGULARINMEMORYWEBAPIHASNEWFEATURESAHREFHTTPS:GITHUBCOMANGULARINMEMORYWEBAPIBLOBMASTERREADMEMDREADABOUTTHEMONGITHUBA", "original": "The package name was changed from \"angular2-in-memory-web-api\" which is still frozen-in-time on npm.\nThe new \"angular-in-memory-web-api\" has new features.\n<a href=\"https://github.com/angular/in-memory-web-api/blob/master/README.md\">Read about them on github</a>.", "translation": "这个包的名字从“angular2-in-memory-web-api”(仍然有效,但不再更新了)重新命名了。\n新的“angular-in-memory-web-api”有新的功能。\n<a href=\"https://github.com/angular/in-memory-web-api/blob/master/README.md\" target=\"_blank\">到 github 获得更多详情</a>.", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##STYLEGUIDEWITHNGMODULES20160927", "original": "## \"Style Guide\" with _NgModules_ (2016-09-27)", "translation": "## “风格指南”中添加了_NgModules_(2016-09-27)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "STYLEGUIDEGUIDESTYLEGUIDEEXPLAINSRECOMMENDEDCONVENTIONSFORNGMODULESBARRELSNOWAREFARLESSUSEFULANDHAVEBEENREMOVEDFROMTHESTYLEGUIDETHEYREMAINVALUABLEBUTARENOTAMATTEROFANGULARSTYLEALSORELAXEDTHERULETHATDISCOURAGEDUSEOFTHECOMPONENTHOSTPROPERTY", "original": "[StyleGuide](guide/styleguide) explains recommended conventions for NgModules.\nBarrels now are far less useful and have been removed from the style guide;\nthey remain valuable but are not a matter of Angular style.\nAlso relaxed the rule that discouraged use of the `@Component.host` property.", "translation": "[StyleGuide](guide/styleguide)解释了 Angular 模块(NgModule)推荐的约定。\n现在,封装桶不再那么重要,风格指南已经移除了它们。\n它们仍然很有价值,但是它们与 Angular 风格无关。\n同时,**不推荐使用 `@Component.host` 属性**的规则也有所放宽。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##MODULEID:MODULEIDEVERYWHERE20160925", "original": "## _moduleId: module.id_ everywhere (2016-09-25)", "translation": "## moduleId:到处添加 module.id(2016-09-25)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "SAMPLECOMPONENTSTHATGETTHEIRTEMPLATESORSTYLESWITHTEMPLATEURLORSTYLEURLSHAVEBEENCONVERTEDTOMODULERELATIVEURLSADDEDTHEMODULEID:MODULEIDPROPERTYANDVALUETOTHEIRCOMPONENTMETADATA", "original": "Sample components that get their templates or styles with `templateUrl` or `styleUrls`\nhave been converted to _module-relative_ URLs.\nAdded the `moduleId: module.id` property-and-value to their `@Component` metadata.", "translation": "在所有使用 `templateUrl` 或者 `styleUrls` 来获取模板或样式的例子组件都被转换为**相对模块**的 URL。\n把 `moduleId: module.id` 添加到了它们的 `@Component` 元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THISCHANGEISAREQUIREMENTFORCOMPILATIONWITHAOTCOMPILERWHENTHEAPPLOADSMODULESWITHSYSTEMJSASTHESAMPLESCURRENTLYDO", "original": "This change is a requirement for compilation with AOT compiler when the app loads\nmodules with SystemJS as the samples currently do.", "translation": "当应用像例子当前使用的方法一样 - 使用 SystemJS 加载模块时,本更新是 AOT 编译器的前提条件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "##LIFECYCLEHOOKSGUIDESIMPLIFIED20160924", "original": "## \"Lifecycle Hooks\" guide simplified (2016-09-24)", "translation": "## 简化了“生命周期钩子”章(2016-09-24)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "THELIFECYCLEHOOKSGUIDELIFECYCLEHOOKSGUIDEISSHORTERSIMPLERANDDRAWSMOREATTENTIONTOTHEORDERINWHICHANGULARCALLSTHEHOOKS", "original": "The [Lifecycle Hooks](guide/lifecycle-hooks) guide is shorter, simpler, and\ndraws more attention to the order in which Angular calls the hooks.", "translation": "[生命周期钩子](guide/lifecycle-hooks)章现在更加简短,并且对强调了 Angular 是以什么顺序来调用钩子方法的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/change-log.md" }, { + "key": "H1CLASSNOTOCCHEATSHEETH1", "original": "<h1 class=\"no-toc\">Cheat Sheet</h1>", "translation": "<h1 class=\"no-toc\">速查表</h1>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "BOOTSTRAPPING", "original": "Bootstrapping", "translation": "引导/启动", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBOOTSTRAPSTHEAPPUSINGTHEROOTCOMPONENTFROMTHESPECIFIEDCODENGMODULECODEP", "original": "<p>Bootstraps the app, using the root component from the specified <code>NgModule</code>. </p>", "translation": "<p>用 <code>NgModule</code> 中指定的根组件进行启动。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PDEFINESAMODULETHATCONTAINSCOMPONENTSDIRECTIVESPIPESANDPROVIDERSP", "original": "<p>Defines a module that contains components, directives, pipes, and providers.</p>", "translation": "<p>定义一个模块,其中可以包含组件、指令、管道和服务提供商。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PLISTOFCOMPONENTSDIRECTIVESANDPIPESTHATBELONGTOTHISMODULEP", "original": "<p>List of components, directives, and pipes that belong to this module.</p>", "translation": "<p>属于当前模块的组件、指令和管道的列表。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PLISTOFMODULESTOIMPORTINTOTHISMODULEEVERYTHINGFROMTHEIMPORTEDMODULESISAVAILABLETOCODEDECLARATIONSCODEOFTHISMODULEP", "original": "<p>List of modules to import into this module. Everything from the imported modules\nis available to <code>declarations</code> of this module.</p>", "translation": "<p>本模块所导入的模块列表</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PLISTOFCOMPONENTSDIRECTIVESANDPIPESVISIBLETOMODULESTHATIMPORTTHISMODULEP", "original": "<p>List of components, directives, and pipes visible to modules that import this module.</p>", "translation": "<p>那些导入了本模块的模块所能看到的组件、指令和管道的列表</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PLISTOFDEPENDENCYINJECTIONPROVIDERSVISIBLEBOTHTOTHECONTENTSOFTHISMODULEANDTOIMPORTERSOFTHISMODULEP", "original": "<p>List of dependency injection providers visible both to the contents of this module and to importers of this module.</p>", "translation": "<p>依赖注入提供商的列表,本模块以及本模块导入的所有模块中的内容都可以看见它们。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PLISTOFCOMPONENTSTOBOOTSTRAPWHENTHISMODULEISBOOTSTRAPPEDP", "original": "<p>List of components to bootstrap when this module is bootstrapped.</p>", "translation": "<p>当本模块启动时,随之启动的组件列表。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "TEMPLATESYNTAX", "original": "Template syntax", "translation": "模板语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSPROPERTYCODEVALUECODETOTHERESULTOFEXPRESSIONCODEFIRSTNAMECODEP", "original": "<p>Binds property <code>value</code> to the result of expression <code>firstName</code>.</p>", "translation": "<p>把<code>value</code>属性绑定到表达式<code>firstName</code></p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSATTRIBUTECODEROLECODETOTHERESULTOFEXPRESSIONCODEMYARIAROLECODEP", "original": "<p>Binds attribute <code>role</code> to the result of expression <code>myAriaRole</code>.</p>", "translation": "<p>把属性(Attribute)<code>role</code>绑定到表达式<code>myAriaRole</code>的结果。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSTHEPRESENCEOFTHECSSCLASSCODEEXTRASPARKLECODEONTHEELEMENTTOTHETRUTHINESSOFTHEEXPRESSIONCODEISDELIGHTFULCODEP", "original": "<p>Binds the presence of the CSS class <code>extra-sparkle</code> on the element to the truthiness of the expression <code>isDelightful</code>.</p>", "translation": "<p>根据<code>isDelightful</code>表达式的结果是否为真,决定 CSS 类<code>extra-sparkle</code>是否出现在当前元素上。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSSTYLEPROPERTYCODEWIDTHCODETOTHERESULTOFEXPRESSIONCODEMYSIZECODEINPIXELSUNITSAREOPTIONALP", "original": "<p>Binds style property <code>width</code> to the result of expression <code>mySize</code> in pixels. Units are optional.</p>", "translation": "<p>把 CSS 样式属性<code>width</code>的 px(像素)值绑定到表达式<code>mySize</code>的结果。单位是可选的。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLSMETHODCODEREADRAINBOWCODEWHENACLICKEVENTISTRIGGEREDONTHISBUTTONELEMENTORITSCHILDRENANDPASSESINTHEEVENTOBJECTP", "original": "<p>Calls method <code>readRainbow</code> when a click event is triggered on this button element (or its children) and passes in the event object.</p>", "translation": "<p>当这个按钮元素(及其子元素)上的 click 事件触发时,调用方法<code>readRainbow</code>,并把这个事件对象作为参数传进去。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSAPROPERTYTOANINTERPOLATEDSTRINGFOREXAMPLEHELLOSEABISCUITEQUIVALENTTO:CODELTDIVTITLEHELLOPONYNAMEGTCODEP", "original": "<p>Binds a property to an interpolated string, for example, \"Hello Seabiscuit\". Equivalent to:\n<code><div [title]=\"'Hello ' + ponyName\"></code></p>", "translation": "<p>把一个属性绑定到插值字符串(如\"Hello Seabiscuit\")。这种写法等价于<code><div [title]=\"'Hello ' + ponyName\"></code></p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSTEXTCONTENTTOANINTERPOLATEDSTRINGFOREXAMPLEHELLOSEABISCUITP", "original": "<p>Binds text content to an interpolated string, for example, \"Hello Seabiscuit\".</p>", "translation": "<p>把文本内容绑定到插值字符串(如\"Hello Seabiscuit\")</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PSETSUPTWOWAYDATABINDINGEQUIVALENTTO:CODELTMYCMPTITLENAMETITLECHANGENAMEEVENTGTCODEP", "original": "<p>Sets up two-way data binding. Equivalent to: <code><my-cmp [title]=\"name\" (titleChange)=\"name=$event\"></code></p>", "translation": "<p>设置双向绑定。等价于<code><my-cmp [title]=\"name\" (titleChange)=\"name=$event\"></code>。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCREATESALOCALVARIABLECODEMOVIEPLAYERCODETHATPROVIDESACCESSTOTHECODEVIDEOCODEELEMENTINSTANCEINDATABINDINGANDEVENTBINDINGEXPRESSIONSINTHECURRENTTEMPLATEP", "original": "<p>Creates a local variable <code>movieplayer</code> that provides access to the <code>video</code> element instance in data-binding and event-binding expressions in the current template.</p>", "translation": "<p>创建一个局部变量<code>movieplayer</code>,支持在当前模板的数据绑定和事件绑定表达式中访问<code>video</code>元素的实例。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PTHECODECODESYMBOLTURNSTHECURRENTELEMENTINTOANEMBEDDEDTEMPLATEEQUIVALENTTO:CODELTNGTEMPLATEMYUNLESSMYEXPRESSIONGTLTPGTLTPGTLTNGTEMPLATEGTCODEP", "original": "<p>The <code>*</code> symbol turns the current element into an embedded template. Equivalent to:\n<code><ng-template [myUnless]=\"myExpression\"><p>...</p></ng-template></code></p>", "translation": "<p>这个 <code>*</code> 符号会把当前元素转换成一个内嵌的模板。它等价于:\n<code><ng-template [myUnless]=\"myExpression\"><p>...</p></ng-template></code></p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PTRANSFORMSTHECURRENTVALUEOFEXPRESSIONCODECARDNUMBERCODEVIATHEPIPECALLEDCODEMYCARDNUMBERFORMATTERCODEP", "original": "<p>Transforms the current value of expression <code>cardNumber</code> via the pipe called <code>myCardNumberFormatter</code>.</p>", "translation": "<p>使用名叫<code>myCardNumberFormatter</code>的管道对表达式<code>cardNumber</code>的当前值进行变幻</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PTHESAFENAVIGATIONOPERATORCODECODEMEANSTHATTHECODEEMPLOYERCODEFIELDISOPTIONALANDIFCODEUNDEFINEDCODETHERESTOFTHEEXPRESSIONSHOULDBEIGNOREDP", "original": "<p>The safe navigation operator (<code>?</code>) means that the <code>employer</code> field is optional and if <code>undefined</code>, the rest of the expression should be ignored.</p>", "translation": "<p>安全导航操作符(<code>?</code>)表示<code>employer</code>字段是可选的,如果它是 <code>undefined</code> ,那么表达式其余的部分就会被忽略,并返回 <code>undefined</code>。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PANSVGSNIPPETTEMPLATENEEDSANCODESVG:CODEPREFIXONITSROOTELEMENTTODISAMBIGUATETHESVGELEMENTFROMANHTMLCOMPONENTP", "original": "<p>An SVG snippet template needs an <code>svg:</code> prefix on its root element to disambiguate the SVG element from an HTML component.</p>", "translation": "<p>模板中的 SVG 片段需要给它的根元素加上<code>svg:</code>前缀,以便把 SVG 元素和 HTML 元素区分开。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PANCODELTSVGGTCODEROOTELEMENTISDETECTEDASANSVGELEMENTAUTOMATICALLYWITHOUTTHEPREFIXP", "original": "<p>An <code><svg></code> root element is detected as an SVG element automatically, without the prefix.</p>", "translation": "<p>以<code><svg></code>作为根元素时会自动识别为 SVG 元素,不需要前缀。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "BUILTINDIRECTIVES", "original": "Built-in directives", "translation": "内置指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PREMOVESORRECREATESAPORTIONOFTHEDOMTREEBASEDONTHECODESHOWSECTIONCODEEXPRESSIONP", "original": "<p>Removes or recreates a portion of the DOM tree based on the <code>showSection</code> expression.</p>", "translation": "<p>根据<code>showSection</code>表达式的结果,移除或重新创建 DOM 树的一部分。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PTURNSTHELIELEMENTANDITSCONTENTSINTOATEMPLATEANDUSESTHATTOINSTANTIATEAVIEWFOREACHITEMINLISTP", "original": "<p>Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list.</p>", "translation": "<p>把 li 元素及其内容变成一个模板,并使用这个模板为列表中的每一个条目实例化一个视图。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCONDITIONALLYSWAPSTHECONTENTSOFTHEDIVBYSELECTINGONEOFTHEEMBEDDEDTEMPLATESBASEDONTHECURRENTVALUEOFCODECONDITIONEXPRESSIONCODEP", "original": "<p>Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of <code>conditionExpression</code>.</p>", "translation": "<p>根据<code>conditionExpression</code>的当前值选择一个嵌入式模板,并用它替换这个 div 的内容。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSTHEPRESENCEOFCSSCLASSESONTHEELEMENTTOTHETRUTHINESSOFTHEASSOCIATEDMAPVALUESTHERIGHTHANDEXPRESSIONSHOULDRETURNCLASSNAME:TRUEFALSEMAPP", "original": "<p>Binds the presence of CSS classes on the element to the truthiness of the associated map values. The right-hand expression should return {class-name: true/false} map.</p>", "translation": "<p>根据 map 中的 value 是否为真,来决定该元素上是否出现与 name 对应的 CSS 类。右侧的表达式应该返回一个形如 <code>{class-name: true/false}</code> 的 map。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PALLOWSYOUTOASSIGNSTYLESTOANHTMLELEMENTUSINGCSSYOUCANUSECSSDIRECTLYASINTHEFIRSTEXAMPLEORYOUCANCALLAMETHODFROMTHECOMPONENTP", "original": "<p>Allows you to assign styles to an HTML element using CSS. You can use CSS directly, as in the first example, or you can call a method from the component.</p>", "translation": "<p>允许你使用 CSS 为 HTML 元素指定样式。你可以像第一个例子那样直接使用 CSS,也可以调用组件中的方法。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "FORMS", "original": "Forms", "translation": "表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PPROVIDESTWOWAYDATABINDINGPARSINGANDVALIDATIONFORFORMCONTROLSP", "original": "<p>Provides two-way data-binding, parsing, and validation for form controls.</p>", "translation": "<p>为表单控件提供双向数据绑定、解析和验证功能。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "CLASSDECORATORS", "original": "Class decorators", "translation": "类装饰器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PDECLARESTHATACLASSISACOMPONENTANDPROVIDESMETADATAABOUTTHECOMPONENTP", "original": "<p>Declares that a class is a component and provides metadata about the component.</p>", "translation": "<p>声明一个类是组件,并提供该组件的元数据。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PDECLARESTHATACLASSISADIRECTIVEANDPROVIDESMETADATAABOUTTHEDIRECTIVEP", "original": "<p>Declares that a class is a directive and provides metadata about the directive.</p>", "translation": "<p>声明一个类是指令,并提供该指令的元数据。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PDECLARESTHATACLASSISAPIPEANDPROVIDESMETADATAABOUTTHEPIPEP", "original": "<p>Declares that a class is a pipe and provides metadata about the pipe.</p>", "translation": "<p>声明一个类是管道,并提供该管道的元数据。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PDECLARESTHATACLASSHASDEPENDENCIESTHATSHOULDBEINJECTEDINTOTHECONSTRUCTORWHENTHEDEPENDENCYINJECTORISCREATINGANINSTANCEOFTHISCLASSP", + "original": "<p>Declares that a class has dependencies that should be injected into the constructor when the dependency injector is creating an instance of this class.</p>", + "translation": "<p>声明某个类具有一些依赖。当依赖注入器要创建这个类的实例时,应该把这些依赖注入到它的构造函数中。</p>", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" + }, + { + "key": "DIRECTIVECONFIGURATION", "original": "Directive configuration", "translation": "指令配置项", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PSPECIFIESACSSSELECTORTHATIDENTIFIESTHISDIRECTIVEWITHINATEMPLATESUPPORTEDSELECTORSINCLUDECODEELEMENTCODECODEATTRIBUTECODECODECLASSCODEANDCODE:NOTCODEP", "original": "<p>Specifies a CSS selector that identifies this directive within a template. Supported selectors include <code>element</code>,\n<code>[attribute]</code>, <code>.class</code>, and <code>:not()</code>.</p>", "translation": "<p>指定一个 CSS 选择器,用于在模板中标记出该指令。支持的选择器类型包括:<code>元素名</code>、<code>[属性名]</code>, <code>.类名</code> 和 <code>:not()</code>。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PDOESNOTSUPPORTPARENTCHILDRELATIONSHIPSELECTORSP", "original": "<p>Does not support parent-child relationship selectors.</p>", "translation": "<p>但不支持指定父子关系的选择器。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PLISTOFDEPENDENCYINJECTIONPROVIDERSFORTHISDIRECTIVEANDITSCHILDRENP", "original": "<p>List of dependency injection providers for this directive and its children.</p>", "translation": "<p>该指令及其子指令的依赖注入提供商列表。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "COMPONENTCONFIGURATION", "original": "Component configuration", "translation": "组件配置项", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { - "original": "<p><code>@Component</code> extends <code>@Directive</code>,\nso the <code>@Directive</code> configuration applies to components as well</p>", - "translation": "<p><code>@Component</code> 继承自 <code>@Directive</code>,\n因此,<code>@Directive</code> 的这些配置项也同样适用于组件。</p>", + "key": "PCODECOMPONENTCODEEXTENDSCODEDIRECTIVECODESOTHECODEDIRECTIVECODECONFIGURATIONAPPLIESTOCOMPONENTSASWELLP", + "original": "<p>\n<code>@Component</code> extends <code>@Directive</code>,\nso the <code>@Directive</code> configuration applies to components as well</p>", + "translation": "<p><code>@Component</code> 继承自 <code>@Directive</code>,\n 因此,<code>@Directive</code> 的这些配置项也同样适用于组件。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PIFSETTHECODETEMPLATEURLCODEANDCODESTYLEURLCODEARERESOLVEDRELATIVETOTHECOMPONENTP", "original": "<p>If set, the <code>templateUrl</code> and <code>styleUrl</code> are resolved relative to the component.</p>", "translation": "<p>如果设置了,那么 <code>templateUrl</code> 和 <code>styleUrl</code> 的路径就会相对于当前组件进行解析。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PLISTOFDEPENDENCYINJECTIONPROVIDERSSCOPEDTOTHISCOMPONENTSVIEWP", "original": "<p>List of dependency injection providers scoped to this component's view.</p>", "translation": "<p>依赖注入提供商列表,但它们的范围被限定为当前组件的视图。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PINLINETEMPLATEOREXTERNALTEMPLATEURLOFTHECOMPONENTSVIEWP", "original": "<p>Inline template or external template URL of the component's view.</p>", "translation": "<p>当前组件视图的内联模板或外部模板的 URL 。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PLISTOFINLINECSSSTYLESOREXTERNALSTYLESHEETURLSFORSTYLINGTHECOMPONENTSVIEWP", "original": "<p>List of inline CSS styles or external stylesheet URLs for styling the component’s view.</p>", "translation": "<p>用于为当前组件的视图提供样式的内联 CSS 或外部样式表 URL 的列表。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "CLASSFIELDDECORATORSFORDIRECTIVESANDCOMPONENTS", "original": "Class field decorators for directives and components", "translation": "给指令和组件使用的类属性配置项", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PDECLARESANINPUTPROPERTYTHATYOUCANUPDATEVIAPROPERTYBINDINGEXAMPLE:CODELTMYCMPMYPROPERTYSOMEEXPRESSIONGTCODEP", "original": "<p>Declares an input property that you can update via property binding (example:\n<code><my-cmp [myProperty]=\"someExpression\"></code>).</p>", "translation": "<p>声明一个输入属性,你可以通过属性绑定来更新它,如 <code><my-cmp [myProperty]=\"someExpression\"></code>。 </p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PDECLARESANOUTPUTPROPERTYTHATFIRESEVENTSTHATYOUCANSUBSCRIBETOWITHANEVENTBINDINGEXAMPLE:CODELTMYCMPMYEVENTDOSOMETHINGGTCODEP", "original": "<p>Declares an output property that fires events that you can subscribe to with an event binding (example: <code><my-cmp (myEvent)=\"doSomething()\"></code>).</p>", "translation": "<p>声明一个输出属性,它发出事件,你可以用事件绑定来订阅它们(如:<code><my-cmp (myEvent)=\"doSomething()\"></code>)。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSAHOSTELEMENTPROPERTYHERETHECSSCLASSCODEVALIDCODETOADIRECTIVECOMPONENTPROPERTYCODEISVALIDCODEP", "original": "<p>Binds a host element property (here, the CSS class <code>valid</code>) to a directive/component property (<code>isValid</code>).</p>", "translation": "<p>把宿主元素的一个属性(这里是 CSS 类 <code>valid</code>)绑定到指令或组件上的 <code>isValid</code> 属性。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PSUBSCRIBESTOAHOSTELEMENTEVENTCODECLICKCODEWITHADIRECTIVECOMPONENTMETHODCODEONCLICKCODEOPTIONALLYPASSINGANARGUMENTCODEEVENTCODEP", "original": "<p>Subscribes to a host element event (<code>click</code>) with a directive/component method (<code>onClick</code>), optionally passing an argument (<code>$event</code>).</p>", "translation": "<p>用指令或组件上的<code>onClick</code>方法订阅宿主元素上的<code>click</code>事件,并从中获取<code>$event</code>参数(可选)</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSTHEFIRSTRESULTOFTHECOMPONENTCONTENTQUERYCODEMYPREDICATECODETOAPROPERTYCODEMYCHILDCOMPONENTCODEOFTHECLASSP", "original": "<p>Binds the first result of the component content query (<code>myPredicate</code>) to a property (<code>myChildComponent</code>) of the class.</p>", "translation": "<p>把组件内容查询(<code>myPredicate</code>)的第一个结果绑定到该类的 <code>myChildComponent</code> 属性上。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSTHERESULTSOFTHECOMPONENTCONTENTQUERYCODEMYPREDICATECODETOAPROPERTYCODEMYCHILDCOMPONENTSCODEOFTHECLASSP", "original": "<p>Binds the results of the component content query (<code>myPredicate</code>) to a property (<code>myChildComponents</code>) of the class.</p>", "translation": "<p>把组件内容查询(<code>myPredicate</code>)的全部结果绑定到该类的 <code>myChildComponents</code> 属性上</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSTHEFIRSTRESULTOFTHECOMPONENTVIEWQUERYCODEMYPREDICATECODETOAPROPERTYCODEMYCHILDCOMPONENTCODEOFTHECLASSNOTAVAILABLEFORDIRECTIVESP", "original": "<p>Binds the first result of the component view query (<code>myPredicate</code>) to a property (<code>myChildComponent</code>) of the class. Not available for directives.</p>", "translation": "<p>把组件视图查询(<code>myPredicate</code>)的第一个结果绑定到该类的 <code>myChildComponent</code> 属性上。对指令无效。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PBINDSTHERESULTSOFTHECOMPONENTVIEWQUERYCODEMYPREDICATECODETOAPROPERTYCODEMYCHILDCOMPONENTSCODEOFTHECLASSNOTAVAILABLEFORDIRECTIVESP", "original": "<p>Binds the results of the component view query (<code>myPredicate</code>) to a property (<code>myChildComponents</code>) of the class. Not available for directives.</p>", "translation": "<p>把组件视图查询(<code>myPredicate</code>)的全部结果绑定到该类的 <code>myChildComponents</code> 属性上。对指令无效。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "DIRECTIVEANDCOMPONENTCHANGEDETECTIONANDLIFECYCLEHOOKS", "original": "Directive and component change detection and lifecycle hooks", "translation": "指令与组件的变更检测与生命周期钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PIMPLEMENTEDASCLASSMETHODSP", + "original": "<p>(implemented as class methods)</p>", + "translation": "<p>由类的方法实现。</p>", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" + }, + { + "key": "PCALLEDBEFOREANYOTHERLIFECYCLEHOOKUSEITTOINJECTDEPENDENCIESBUTAVOIDANYSERIOUSWORKHEREP", "original": "<p>Called before any other lifecycle hook. Use it to inject dependencies, but avoid any serious work here.</p>", "translation": "<p>在任何其它生命周期钩子之前调用。可以用它来注入依赖项,但不要在这里做正事。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLEDAFTEREVERYCHANGETOINPUTPROPERTIESANDBEFOREPROCESSINGCONTENTORCHILDVIEWSP", "original": "<p>Called after every change to input properties and before processing content or child views.</p>", "translation": "<p>每当输入属性发生变化时就会调用,但位于处理内容(<code>ng-content</code>)或子视图之前。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLEDAFTERTHECONSTRUCTORINITIALIZINGINPUTPROPERTIESANDTHEFIRSTCALLTOCODENGONCHANGESCODEP", "original": "<p>Called after the constructor, initializing input properties, and the first call to <code>ngOnChanges</code>.</p>", "translation": "<p>在调用完构造函数、初始化完所有输入属性并首次调用过<code>ngOnChanges</code>之后调用。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLEDEVERYTIMETHATTHEINPUTPROPERTIESOFACOMPONENTORADIRECTIVEARECHECKEDUSEITTOEXTENDCHANGEDETECTIONBYPERFORMINGACUSTOMCHECKP", "original": "<p>Called every time that the input properties of a component or a directive are checked. Use it to extend change detection by performing a custom check.</p>", "translation": "<p>每当对组件或指令的输入属性进行变更检测时就会调用。可以用它来扩展变更检测逻辑,执行自定义的检测逻辑。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLEDAFTERCODENGONINITCODEWHENTHECOMPONENTSORDIRECTIVESCONTENTHASBEENINITIALIZEDP", "original": "<p>Called after <code>ngOnInit</code> when the component's or directive's content has been initialized.</p>", "translation": "<p><code>ngOnInit</code>完成之后,当组件或指令的内容(<code>ng-content</code>)已经初始化完毕时调用。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLEDAFTEREVERYCHECKOFTHECOMPONENTSORDIRECTIVESCONTENTP", "original": "<p>Called after every check of the component's or directive's content.</p>", "translation": "<p>每当组件或指令的内容(<code>ng-content</code>)做变更检测时调用。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLEDAFTERCODENGAFTERCONTENTINITCODEWHENTHECOMPONENTSVIEWHASBEENINITIALIZEDAPPLIESTOCOMPONENTSONLYP", "original": "<p>Called after <code>ngAfterContentInit</code> when the component's view has been initialized. Applies to components only.</p>", "translation": "<p>当<code>ngAfterContentInit</code>完毕,并且组件的视图已经初始化完毕时调用。只适用于组件。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLEDAFTEREVERYCHECKOFTHECOMPONENTSVIEWAPPLIESTOCOMPONENTSONLYP", "original": "<p>Called after every check of the component's view. Applies to components only.</p>", "translation": "<p>当组件视图每次执行变更检测时调用。只适用于组件。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCALLEDONCEBEFORETHEINSTANCEISDESTROYEDP", "original": "<p>Called once, before the instance is destroyed.</p>", "translation": "<p>只在实例被销毁前调用一次。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "DEPENDENCYINJECTIONCONFIGURATION", "original": "Dependency injection configuration", "translation": "依赖注入配置项", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PSETSOROVERRIDESTHEPROVIDERFORCODEMYSERVICECODETOTHECODEMYMOCKSERVICECODECLASSP", "original": "<p>Sets or overrides the provider for <code>MyService</code> to the <code>MyMockService</code> class.</p>", "translation": "<p>把 <code>MyService</code> 的服务提供商设置或改写为 <code>MyMockService</code> 类。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PSETSOROVERRIDESTHEPROVIDERFORCODEMYSERVICECODETOTHECODEMYFACTORYCODEFACTORYFUNCTIONP", "original": "<p>Sets or overrides the provider for <code>MyService</code> to the <code>myFactory</code> factory function.</p>", "translation": "<p>把 <code>MyService</code> 的服务提供商设置或改写为 <code>myFactory</code> 工厂函数。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PSETSOROVERRIDESTHEPROVIDERFORCODEMYVALUECODETOTHEVALUECODE41CODEP", "original": "<p>Sets or overrides the provider for <code>MyValue</code> to the value <code>41</code>.</p>", "translation": "<p>把 <code>MyValue</code> 的服务提供商改写为一个特定的值 <code>41</code> 。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "ROUTINGANDNAVIGATION", "original": "Routing and navigation", "translation": "路由与导航", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCONFIGURESROUTESFORTHEAPPLICATIONSUPPORTSSTATICPARAMETERIZEDREDIRECTANDWILDCARDROUTESALSOSUPPORTSCUSTOMROUTEDATAANDRESOLVEP", "original": "<p>Configures routes for the application. Supports static, parameterized, redirect, and wildcard routes. Also supports custom route data and resolve.</p>", "translation": "<p>为该应用配置路由。支持静态、参数化、重定向和通配符路由。也支持自定义路由数据和解析(resolve)函数。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PMARKSTHELOCATIONTOLOADTHECOMPONENTOFTHEACTIVEROUTEP", "original": "<p>Marks the location to load the component of the active route.</p>", "translation": "<p>标记出一个位置,用来加载活动路由的组件。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PCREATESALINKTOADIFFERENTVIEWBASEDONAROUTEINSTRUCTIONCONSISTINGOFAROUTEPATHREQUIREDANDOPTIONALPARAMETERSQUERYPARAMETERSANDAFRAGMENTTONAVIGATETOAROOTROUTEUSETHECODECODEPREFIXFORACHILDROUTEUSETHECODECODEPREFIXFORASIBLINGORPARENTUSETHECODECODEPREFIXP", "original": "<p>Creates a link to a different view based on a route instruction consisting of a route path, required and optional parameters, query parameters, and a fragment. To navigate to a root route, use the <code>/</code> prefix; for a child route, use the <code>./</code>prefix; for a sibling or parent, use the <code>../</code> prefix.</p>", "translation": "<p>使用路由体系创建一个到其它视图的链接。路由体系由路由路径、必要参数、可选参数、查询参数和文档片段组成。要导航到根路由,请使用<code>/</code>前缀;要导航到子路由,使用<code>./</code>前缀;要导航到兄弟路由或父级路由,使用<code>../</code>前缀。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PTHEPROVIDEDCLASSESAREADDEDTOTHEELEMENTWHENTHECODEROUTERLINKCODEBECOMESTHECURRENTACTIVEROUTEP", "original": "<p>The provided classes are added to the element when the <code>routerLink</code> becomes the current active route.</p>", "translation": "<p>当 <code>routerLink</code> 指向的路由变成活动路由时,为当前元素添加一些类(比如这里的 <code>active</code>)。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PANINTERFACEFORDEFININGACLASSTHATTHEROUTERSHOULDCALLFIRSTTODETERMINEIFITSHOULDACTIVATETHISCOMPONENTSHOULDRETURNABOOLEANORANOBSERVABLEPROMISETHATRESOLVESTOABOOLEANP", "original": "<p>An interface for defining a class that the router should call first to determine if it should activate this component. Should return a boolean or an Observable/Promise that resolves to a boolean.</p>", "translation": "<p>用来定义类的接口。路由器会首先调用本接口来决定是否激活该路由。应该返回一个 <code>boolean</code> 或能解析成 <code>boolean</code> 的 <code>Observable/Promise</code>。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PANINTERFACEFORDEFININGACLASSTHATTHEROUTERSHOULDCALLFIRSTTODETERMINEIFITSHOULDDEACTIVATETHISCOMPONENTAFTERANAVIGATIONSHOULDRETURNABOOLEANORANOBSERVABLEPROMISETHATRESOLVESTOABOOLEANP", "original": "<p>An interface for defining a class that the router should call first to determine if it should deactivate this component after a navigation. Should return a boolean or an Observable/Promise that resolves to a boolean.</p>", "translation": "<p>用来定义类的接口。路由器会在导航离开前首先调用本接口以决定是否取消激活本路由。应该返回一个 <code>boolean</code> 或能解析成 <code>boolean</code> 的 <code>Observable/Promise</code>。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PANINTERFACEFORDEFININGACLASSTHATTHEROUTERSHOULDCALLFIRSTTODETERMINEIFITSHOULDACTIVATETHECHILDROUTESHOULDRETURNABOOLEANORANOBSERVABLEPROMISETHATRESOLVESTOABOOLEANP", "original": "<p>An interface for defining a class that the router should call first to determine if it should activate the child route. Should return a boolean or an Observable/Promise that resolves to a boolean.</p>", "translation": "<p>用来定义类的接口。路由器会首先调用本接口来决定是否激活一个子路由。应该返回一个 <code>boolean</code> 或能解析成 <code>boolean</code> 的 <code>Observable/Promise</code>。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PANINTERFACEFORDEFININGACLASSTHATTHEROUTERSHOULDCALLFIRSTTORESOLVEROUTEDATABEFORERENDERINGTHEROUTESHOULDRETURNAVALUEORANOBSERVABLEPROMISETHATRESOLVESTOAVALUEP", "original": "<p>An interface for defining a class that the router should call first to resolve route data before rendering the route. Should return a value or an Observable/Promise that resolves to a value.</p>", "translation": "<p>用来定义类的接口。路由器会在渲染该路由之前,首先调用它来解析路由数据。应该返回一个值或能解析成值的 <code>Observable/Promise</code>。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "PANINTERFACEFORDEFININGACLASSTHATTHEROUTERSHOULDCALLFIRSTTOCHECKIFTHELAZYLOADEDMODULESHOULDBELOADEDSHOULDRETURNABOOLEANORANOBSERVABLEPROMISETHATRESOLVESTOABOOLEANP", "original": "<p>An interface for defining a class that the router should call first to check if the lazy loaded module should be loaded. Should return a boolean or an Observable/Promise that resolves to a boolean.</p>", "translation": "<p>用来定义类的接口。路由器会首先调用它来决定是否应该加载一个惰性加载模块。应该返回一个 <code>boolean</code> 或能解析成 <code>boolean</code> 的 <code>Observable/Promise</code>。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/cheatsheet.md" }, { + "key": "#OBSERVABLESCOMPAREDTOOTHERTECHNIQUES", "original": "# Observables compared to other techniques", "translation": "# 可观察对象与其它技术的比较", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "YOUCANOFTENUSEOBSERVABLESINSTEADOFPROMISESTODELIVERVALUESASYNCHRONOUSLYSIMILARLYOBSERVABLESCANTAKETHEPLACEOFEVENTHANDLERSFINALLYBECAUSEOBSERVABLESDELIVERMULTIPLEVALUESYOUCANUSETHEMWHEREYOUMIGHTOTHERWISEBUILDANDOPERATEONARRAYS", "original": "You can often use observables instead of promises to deliver values asynchronously. Similarly, observables can take the place of event handlers. Finally, because observables deliver multiple values, you can use them where you might otherwise build and operate on arrays.", "translation": "你可以经常使用可观察对象(Observable)而不是承诺(Promise)来异步传递值。\n类似的,可观察对象也可以取代事件处理器的位置。最后,由于可观察对象传递多个值,所以你可以在任何可能构建和操作数组的地方使用可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESBEHAVESOMEWHATDIFFERENTLYFROMTHEALTERNATIVETECHNIQUESINEACHOFTHESESITUATIONSBUTOFFERSOMESIGNIFICANTADVANTAGESHEREAREDETAILEDCOMPARISONSOFTHEDIFFERENCES", "original": "Observables behave somewhat differently from the alternative techniques in each of these situations, but offer some significant advantages. Here are detailed comparisons of the differences.", "translation": "在这些情况下,可观察对象的行为与其替代技术有一些差异,不过也提供了一些显著的优势。下面是对这些差异的详细比较。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "##OBSERVABLESCOMPAREDTOPROMISES", "original": "## Observables compared to promises", "translation": "## 可观察对象 vs. 承诺", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESAREOFTENCOMPAREDTOPROMISESHEREARESOMEKEYDIFFERENCES:", "original": "Observables are often compared to promises. Here are some key differences:", "translation": "可观察对象经常拿来和承诺进行对比。有一些关键的不同点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESAREDECLARATIVECOMPUTATIONDOESNOTSTARTUNTILSUBSCRIPTIONPROMISESEXECUTEIMMEDIATELYONCREATIONTHISMAKESOBSERVABLESUSEFULFORDEFININGRECIPESTHATCANBERUNWHENEVERYOUNEEDTHERESULT", "original": "* Observables are declarative; computation does not start until subscription. Promises execute immediately on creation. This makes observables useful for defining recipes that can be run whenever you need the result.", "translation": "可观察对象是声明式的,在被订阅之前,它不会开始执行。承诺是在创建时就立即执行的。这让可观察对象可用于定义那些应该按需执行的菜谱。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESPROVIDEMANYVALUESPROMISESPROVIDEONETHISMAKESOBSERVABLESUSEFULFORGETTINGMULTIPLEVALUESOVERTIME", "original": "* Observables provide many values. Promises provide one. This makes observables useful for getting multiple values over time.", "translation": "可观察对象能提供多个值。承诺只提供一个。这让可观察对象可用于随着时间的推移获取多个值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESDIFFERENTIATEBETWEENCHAININGANDSUBSCRIPTIONPROMISESONLYHAVETHENCLAUSESTHISMAKESOBSERVABLESUSEFULFORCREATINGCOMPLEXTRANSFORMATIONRECIPESTOBEUSEDBYOTHERPARTOFTHESYSTEMWITHOUTCAUSINGTHEWORKTOBEEXECUTED", "original": "* Observables differentiate between chaining and subscription. Promises only have `.then()` clauses. This makes observables useful for creating complex transformation recipes to be used by other part of the system, without causing the work to be executed.", "translation": "可观察对象会区分串联处理和订阅语句。承诺只有 `.then()` 语句。这让可观察对象可用于创建供系统的其它部分使用而不希望立即执行的复杂菜谱。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESSUBSCRIBEISRESPONSIBLEFORHANDLINGERRORSPROMISESPUSHERRORSTOTHECHILDPROMISESTHISMAKESOBSERVABLESUSEFULFORCENTRALIZEDANDPREDICTABLEERRORHANDLING", "original": "* Observables `subscribe()` is responsible for handling errors. Promises push errors to the child promises. This makes observables useful for centralized and predictable error handling.", "translation": "可观察对象的 `subscribe()` 会负责处理错误。承诺会把错误推送给它的子承诺。这让可观察对象可用于进行集中式、可预测的错误处理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "###CREATIONANDSUBSCRIPTION", "original": "### Creation and subscription", "translation": "### 创建与订阅", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { - "original": "* Observables are not executed until a consumer subscribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.", + "key": "OBSERVABLESARENOTEXECUTEDUNTILACONSUMERSUBCRIBESTHESUBSCRIBEEXECUTESTHEDEFINEDBEHAVIORONCEANDITCANBECALLEDAGAINEACHSUBSCRIPTIONHASITSOWNCOMPUTATIONRESUBSCRIPTIONCAUSESRECOMPUTATIONOFVALUES", + "original": "* Observables are not executed until a consumer subcribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.", "translation": "在有消费者订阅之前,可观察对象不会执行。`subscribe()` 会执行一次定义好的行为,并且可以再次调用它。每次订阅都是单独计算的。重新订阅会导致重新计算这些值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "PROMISESEXECUTEIMMEDIATELYANDJUSTONCETHECOMPUTATIONOFTHERESULTISINITIATEDWHENTHEPROMISEISCREATEDTHEREISNOWAYTORESTARTWORKALLTHENCLAUSESSUBSCRIPTIONSSHARETHESAMECOMPUTATION", "original": "* Promises execute immediately, and just once. The computation of the result is initiated when the promise is created. There is no way to restart work. All `then` clauses (subscriptions) share the same computation.", "translation": "承诺会立即执行,并且只执行一次。当承诺创建时,会立即计算出结果。没有办法重新做一次。所有的 `then` 语句(订阅)都会共享同一次计算。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "###CHAINING", "original": "### Chaining", "translation": "### 串联", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESDIFFERENTIATEBETWEENTRANSFORMATIONFUNCTIONSUCHASAMAPANDSUBSCRIPTIONONLYSUBSCRIPTIONACTIVATESTHESUBSCRIBERFUNCTIONTOSTARTCOMPUTINGTHEVALUES", "original": "* Observables differentiate between transformation function such as a map and subscription. Only subscription activates the subscriber function to start computing the values.", "translation": "可观察对象会区分各种转换函数,比如映射和订阅。只有订阅才会激活订阅者函数,以开始计算那些值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "PROMISESDONOTDIFFERENTIATEBETWEENTHELASTTHENCLAUSESEQUIVALENTTOSUBSCRIPTIONANDINTERMEDIATETHENCLAUSESEQUIVALENTTOMAP", "original": "* Promises do not differentiate between the last `.then` clauses (equivalent to subscription) and intermediate `.then` clauses (equivalent to map).", "translation": "承诺并不区分最后的 `.then()` 语句(等价于订阅)和中间的 `.then()` 语句(等价于映射)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "###CANCELLATION", "original": "### Cancellation", "translation": "### 可取消", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESUBSCRIPTIONSARECANCELLABLEUNSUBSCRIBINGREMOVESTHELISTENERFROMRECEIVINGFURTHERVALUESANDNOTIFIESTHESUBSCRIBERFUNCTIONTOCANCELWORK", "original": "* Observable subscriptions are cancellable. Unsubscribing removes the listener from receiving further values, and notifies the subscriber function to cancel work.", "translation": "可观察对象的订阅是可取消的。取消订阅会移除监听器,使其不再接受将来的值,并通知订阅者函数取消正在进行的工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "PROMISESARENOTCANCELLABLE", "original": "* Promises are not cancellable.", "translation": "承诺是不可取消的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "###ERRORHANDLING", "original": "### Error handling", "translation": "### 错误处理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLEEXECUTIONERRORSAREDELIVEREDTOTHESUBSCRIBERSERRORHANDLERANDTHESUBSCRIBERAUTOMATICALLYUNSUBSCRIBESFROMTHEOBSERVABLE", "original": "* Observable execution errors are delivered to the subscriber's error handler, and the subscriber automatically unsubscribes from the observable.", "translation": "可观察对象的错误处理是交给订阅者的错误处理器的,并且该订阅者会自动取消对这个可观察对象的订阅。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "PROMISESPUSHERRORSTOTHECHILDPROMISES", "original": "* Promises push errors to the child promises.", "translation": "承诺会把错误推给其子承诺。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "###CHEATSHEET", "original": "### Cheat sheet", "translation": "### 速查表", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "THEFOLLOWINGCODESNIPPETSILLUSTRATEHOWTHESAMEKINDOFOPERATIONISDEFINEDUSINGOBSERVABLESANDPROMISES", "original": "The following code snippets illustrate how the same kind of operation is defined using observables and promises.", "translation": "下列代码片段揭示了同样的操作要如何分别使用可观察对象和承诺进行实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OPERATION", "original": "Operation", "translation": "操作", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLE", "original": "Observable", "translation": "可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "PROMISE", "original": "Promise", "translation": "承诺", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "CREATION", "original": "Creation", "translation": "创建", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "TRANSFORM", "original": "Transform", "translation": "转换", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "SUBSCRIBE", "original": "Subscribe", "translation": "订阅", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "UNSUBSCRIBE", "original": "Unsubscribe", "translation": "取消订阅", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "IMPLIEDBYPROMISERESOLUTION", "original": "Implied by promise resolution.", "translation": "承诺被解析时隐式完成。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "##OBSERVABLESCOMPAREDTOEVENTSAPI", "original": "## Observables compared to events API", "translation": "## 可观察对象 vs. 事件 API", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLESAREVERYSIMILARTOEVENTHANDLERSTHATUSETHEEVENTSAPIBOTHTECHNIQUESDEFINENOTIFICATIONHANDLERSANDUSETHEMTOPROCESSMULTIPLEVALUESDELIVEREDOVERTIMESUBSCRIBINGTOANOBSERVABLEISEQUIVALENTTOADDINGANEVENTLISTENERONESIGNIFICANTDIFFERENCEISTHATYOUCANCONFIGUREANOBSERVABLETOTRANSFORMANEVENTBEFOREPASSINGTHEEVENTTOTHEHANDLER", "original": "Observables are very similar to event handlers that use the events API. Both techniques define notification handlers, and use them to process multiple values delivered over time. Subscribing to an observable is equivalent to adding an event listener. One significant difference is that you can configure an observable to transform an event before passing the event to the handler.", "translation": "可观察对象和事件 API 中的事件处理器很像。这两种技术都会定义通知处理器,并使用它们来处理一段时间内传递的多个值。订阅可观察对象与添加事件处理器是等价的。一个显著的不同是你可以配置可观察对象,使其在把事件传给事件处理器之间先进行转换。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "USINGOBSERVABLESTOHANDLEEVENTSANDASYNCHRONOUSOPERATIONSCANHAVETHEADVANTAGEOFGREATERCONSISTENCYINCONTEXTSSUCHASHTTPREQUESTS", "original": "Using observables to handle events and asynchronous operations can have the advantage of greater consistency in contexts such as HTTP requests.", "translation": "使用可观察对象来处理错误和异步操作在 HTTP 请求这样的场景下更加具有一致性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "HEREARESOMECODESAMPLESTHATILLUSTRATEHOWTHESAMEKINDOFOPERATIONISDEFINEDUSINGOBSERVABLESANDTHEEVENTSAPI", "original": "Here are some code samples that illustrate how the same kind of operation is defined using observables and the events API.", "translation": "下列代码片段揭示了同样的操作要如何分别使用可观察对象和事件 API 进行实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLE", "original": "Observable", "translation": "可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "EVENTSAPI", "original": "Events API", "translation": "事件 API", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "CREATIONCANCELLATION", "original": "Creation & cancellation", "translation": "创建与取消", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "SUBSCRIPTION", "original": "Subscription", "translation": "订阅", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "CONFIGURATION", "original": "Configuration", "translation": "配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "LISTENFORKEYSTROKESBUTPROVIDEASTREAMREPRESENTINGTHEVALUEINTHEINPUT", "original": "Listen for keystrokes, but provide a stream representing the value in the input.", "translation": "监听按键,提供一个流来表示这些输入的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "DOESNOTSUPPORTCONFIGURATION", "original": "Does not support configuration.", "translation": "不支持配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "##OBSERVABLESCOMPAREDTOARRAYS", "original": "## Observables compared to arrays", "translation": "## 可观察对象 vs. 数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "ANOBSERVABLEPRODUCESVALUESOVERTIMEANARRAYISCREATEDASASTATICSETOFVALUESINASENSEOBSERVABLESAREASYNCHRONOUSWHEREARRAYSARESYNCHRONOUSINTHEFOLLOWINGEXAMPLESIMPLIESASYNCHRONOUSVALUEDELIVERY", "original": "An observable produces values over time. An array is created as a static set of values. In a sense, observables are asynchronous where arrays are synchronous. In the following examples, ➞ implies asynchronous value delivery.", "translation": "可观察对象会随时间生成值。数组是用一组静态的值创建的。某种意义上,可观察对象是异步的,而数组是同步的。\n在下列例子中,➞ 符号表示异步传递值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "OBSERVABLE", "original": "Observable", "translation": "可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "ARRAY", "original": "Array", "translation": "数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "GIVEN", "original": "Given", "translation": "给出值", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/comparing-observables.md" }, { + "key": "#COMPONENTINTERACTION", "original": "# Component Interaction", "translation": "# 组件之间的交互", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THISCOOKBOOKCONTAINSRECIPESFORCOMMONCOMPONENTCOMMUNICATIONSCENARIOSINWHICHTWOORMORECOMPONENTSSHAREINFORMATION", "original": "This cookbook contains recipes for common component communication scenarios\nin which two or more components share information.", "translation": "本烹饪宝典包含了常见的组件通讯场景,也就是让两个或多个组件之间共享信息的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "#CONTENTS", "original": "# Contents", "translation": "# 目录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "PASSDATAFROMPARENTTOCHILDWITHINPUTBINDINGGUIDECOMPONENTINTERACTION#PARENTTOCHILD", "original": "* [Pass data from parent to child with input binding](guide/component-interaction#parent-to-child)", "translation": "[使用输入绑定把数据从父组件传给子组件](guide/component-interaction#parent-to-child)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "INTERCEPTINPUTPROPERTYCHANGESWITHASETTERGUIDECOMPONENTINTERACTION#PARENTTOCHILDSETTER", "original": "* [Intercept input property changes with a setter](guide/component-interaction#parent-to-child-setter)", "translation": "[使用赋值器(setter)拦截输入属性的变化](guide/component-interaction#parent-to-child-setter)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "INTERCEPTINPUTPROPERTYCHANGESWITHNGONCHANGESGUIDECOMPONENTINTERACTION#PARENTTOCHILDONCHANGES", "original": "* [Intercept input property changes with `ngOnChanges()`](guide/component-interaction#parent-to-child-on-changes)", "translation": "[使用 `ngOnChanges()` 拦截输入属性的变化](guide/component-interaction#parent-to-child-on-changes)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "PARENTCALLSANVIEWCHILDGUIDECOMPONENTINTERACTION#PARENTTOVIEWCHILD", "original": "* [Parent calls an `@ViewChild()`](guide/component-interaction#parent-to-view-child)", "translation": "[在父组件中调用 `@ViewChild()`](guide/component-interaction#parent-to-view-child)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "PARENTANDCHILDRENCOMMUNICATEVIAASERVICEGUIDECOMPONENTINTERACTION#BIDIRECTIONALSERVICE", "original": "* [Parent and children communicate via a service](guide/component-interaction#bidirectional-service)", "translation": "[通过服务进行父子通讯](guide/component-interaction#bidirectional-service)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "SEETHELIVEEXAMPLENAMECOMPONENTINTERACTIONLIVEEXAMPLE", "original": "**See the <live-example name=\"component-interaction\"></live-example>**.", "translation": "**参见<live-example name=\"component-interaction\"></live-example>**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "##PASSDATAFROMPARENTTOCHILDWITHINPUTBINDING", "original": "## Pass data from parent to child with input binding", "translation": "## 通过输入型绑定把数据从父组件传到子组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "HEROCHILDCOMPONENTHASTWOINPUTPROPERTIESTYPICALLYADORNEDWITHINPUTDECORATIONSGUIDETEMPLATESYNTAX#INPUTSOUTPUTS", "original": "`HeroChildComponent` has two ***input properties***,\ntypically adorned with [@Input decorations](guide/template-syntax#inputs-outputs).", "translation": "`HeroChildComponent` 有两个***输入型属性***,它们通常带[@Input 装饰器](guide/template-syntax#inputs-outputs)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THESECONDINPUTALIASESTHECHILDCOMPONENTPROPERTYNAMEMASTERNAMEASMASTER", "original": "The second `@Input` aliases the child component property name `masterName` as `'master'`.", "translation": "第二个 `@Input` 为子组件的属性名 `masterName` 指定一个别名 `master`(译者注:不推荐为起别名,请参见风格指南).", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEHEROPARENTCOMPONENTNESTSTHECHILDHEROCHILDCOMPONENTINSIDEANNGFORREPEATERBINDINGITSMASTERSTRINGPROPERTYTOTHECHILDSMASTERALIASANDEACHITERATIONSHEROINSTANCETOTHECHILDSHEROPROPERTY", "original": "The `HeroParentComponent` nests the child `HeroChildComponent` inside an `*ngFor` repeater,\nbinding its `master` string property to the child's `master` alias,\nand each iteration's `hero` instance to the child's `hero` property.", "translation": "父组件 `HeroParentComponent` 把子组件的 `HeroChildComponent` 放到 `*ngFor` 循环器中,把自己的 `master` 字符串属性绑定到子组件的 `master` 别名上,并把每个循环的 `hero` 实例绑定到子组件的 `hero` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THERUNNINGAPPLICATIONDISPLAYSTHREEHEROES:", "original": "The running application displays three heroes:", "translation": "运行应用程序会显示三个英雄:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "H3CLASSNOTOCTESTITH3", "original": "<h3 class=\"no-toc\">Test it</h3>", "translation": "<h3 class=\"no-toc\">测试一下!</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "E2ETESTTHATALLCHILDRENWEREINSTANTIATEDANDDISPLAYEDASEXPECTED:", "original": "E2E test that all children were instantiated and displayed as expected:", "translation": "端到端测试,用于确保所有的子组件都像所期待的那样被初始化并显示出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "BACKTOTOPGUIDECOMPONENTINTERACTION#TOP", "original": "[Back to top](guide/component-interaction#top)", "translation": "[回到顶部](guide/component-interaction#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "##INTERCEPTINPUTPROPERTYCHANGESWITHASETTER", "original": "## Intercept input property changes with a setter", "translation": "## 通过 setter 截听输入属性值的变化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "USEANINPUTPROPERTYSETTERTOINTERCEPTANDACTUPONAVALUEFROMTHEPARENT", "original": "Use an input property setter to intercept and act upon a value from the parent.", "translation": "使用一个输入属性的 setter,以拦截父组件中值的变化,并采取行动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THESETTEROFTHENAMEINPUTPROPERTYINTHECHILDNAMECHILDCOMPONENTTRIMSTHEWHITESPACEFROMANAMEANDREPLACESANEMPTYVALUEWITHDEFAULTTEXT", "original": "The setter of the `name` input property in the child `NameChildComponent`\ntrims the whitespace from a name and replaces an empty value with default text.", "translation": "子组件 `NameChildComponent` 的输入属性 `name` 上的这个 setter,会 trim 掉名字里的空格,并把空值替换成默认字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "HERESTHENAMEPARENTCOMPONENTDEMONSTRATINGNAMEVARIATIONSINCLUDINGANAMEWITHALLSPACES:", "original": "Here's the `NameParentComponent` demonstrating name variations including a name with all spaces:", "translation": "下面的 `NameParentComponent` 展示了各种名字的处理方式,包括一个全是空格的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "H3CLASSNOTOCTESTITH3", "original": "<h3 class=\"no-toc\">Test it</h3>", "translation": "<h3 class=\"no-toc\">测试一下!</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "E2ETESTSOFINPUTPROPERTYSETTERWITHEMPTYANDNONEMPTYNAMES:", "original": "E2E tests of input property setter with empty and non-empty names:", "translation": "端到端测试:输入属性的 setter,分别使用空名字和非空名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "BACKTOTOPGUIDECOMPONENTINTERACTION#TOP", "original": "[Back to top](guide/component-interaction#top)", "translation": "[回到顶部](guide/component-interaction#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "##INTERCEPTINPUTPROPERTYCHANGESWITHNGONCHANGES", "original": "## Intercept input property changes with *ngOnChanges()*", "translation": "## 通过*ngOnChanges()*来截听输入属性值的变化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "DETECTANDACTUPONCHANGESTOINPUTPROPERTYVALUESWITHTHENGONCHANGESMETHODOFTHEONCHANGESLIFECYCLEHOOKINTERFACE", "original": "Detect and act upon changes to input property values with the `ngOnChanges()` method of the `OnChanges` lifecycle hook interface.", "translation": "使用 `OnChanges` 生命周期钩子接口的 `ngOnChanges()` 方法来监测输入属性值的变化并做出回应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "YOUMAYPREFERTHISAPPROACHTOTHEPROPERTYSETTERWHENWATCHINGMULTIPLEINTERACTINGINPUTPROPERTIES", "original": "You may prefer this approach to the property setter when watching multiple, interacting input properties.", "translation": "当需要监视多个、交互式输入属性的时候,本方法比用属性的 setter 更合适。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "LEARNABOUTNGONCHANGESINTHELIFECYCLEHOOKSGUIDELIFECYCLEHOOKSCHAPTER", "original": "Learn about `ngOnChanges()` in the [LifeCycle Hooks](guide/lifecycle-hooks) chapter.", "translation": "学习关于 `ngOnChanges()` 的更多知识,参见[生命周期钩子](guide/lifecycle-hooks)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THISVERSIONCHILDCOMPONENTDETECTSCHANGESTOTHEMAJORANDMINORINPUTPROPERTIESANDCOMPOSESALOGMESSAGEREPORTINGTHESECHANGES:", "original": "This `VersionChildComponent` detects changes to the `major` and `minor` input properties and composes a log message reporting these changes:", "translation": "这个 `VersionChildComponent` 会监测输入属性 `major` 和 `minor` 的变化,并把这些变化编写成日志以报告这些变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEVERSIONPARENTCOMPONENTSUPPLIESTHEMINORANDMAJORVALUESANDBINDSBUTTONSTOMETHODSTHATCHANGETHEM", "original": "The `VersionParentComponent` supplies the `minor` and `major` values and binds buttons to methods that change them.", "translation": "`VersionParentComponent` 提供 `minor` 和 `major` 值,把修改它们值的方法绑定到按钮上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "HERESTHEOUTPUTOFABUTTONPUSHINGSEQUENCE:", "original": "Here's the output of a button-pushing sequence:", "translation": "下面是点击按钮的结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "H3CLASSNOTOCTESTITH3", "original": "<h3 class=\"no-toc\">Test it</h3>", "translation": "<h3 class=\"no-toc\">测试一下!</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "TESTTHATBOTHINPUTPROPERTIESARESETINITIALLYANDTHATBUTTONCLICKSTRIGGERTHEEXPECTEDNGONCHANGESCALLSANDVALUES:", "original": "Test that ***both*** input properties are set initially and that button clicks trigger\nthe expected `ngOnChanges` calls and values:", "translation": "测试确保***这两个***输入属性值都被初始化了,当点击按钮后,`ngOnChanges` 应该被调用,属性的值也符合预期。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "BACKTOTOPGUIDECOMPONENTINTERACTION#TOP", "original": "[Back to top](guide/component-interaction#top)", "translation": "[回到顶部](guide/component-interaction#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "##PARENTLISTENSFORCHILDEVENT", "original": "## Parent listens for child event", "translation": "## 父组件监听子组件的事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THECHILDCOMPONENTEXPOSESANEVENTEMITTERPROPERTYWITHWHICHITEMITSEVENTSWHENSOMETHINGHAPPENSTHEPARENTBINDSTOTHATEVENTPROPERTYANDREACTSTOTHOSEEVENTS", "original": "The child component exposes an `EventEmitter` property with which it `emits` events when something happens.\nThe parent binds to that event property and reacts to those events.", "translation": "子组件暴露一个 `EventEmitter` 属性,当事件发生时,子组件利用该属性 `emits`(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THECHILDSEVENTEMITTERPROPERTYISANOUTPUTPROPERTYTYPICALLYADORNEDWITHANOUTPUTDECORATIONGUIDETEMPLATESYNTAX#INPUTSOUTPUTSASSEENINTHISVOTERCOMPONENT:", "original": "The child's `EventEmitter` property is an ***output property***,\n typically adorned with an [@Output decoration](guide/template-syntax#inputs-outputs)\n as seen in this `VoterComponent`:", "translation": "子组件的 `EventEmitter` 属性是一个**输出属性**,通常带有[@Output 装饰器](guide/template-syntax#inputs-outputs),就像在 `VoterComponent` 中看到的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "CLICKINGABUTTONTRIGGERSEMISSIONOFATRUEORFALSETHEBOOLEANPAYLOAD", "original": "Clicking a button triggers emission of a `true` or `false`, the boolean *payload*.", "translation": "点击按钮会触发 `true` 或 `false`(布尔型*有效载荷*)的事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEPARENTVOTETAKERCOMPONENTBINDSANEVENTHANDLERCALLEDONVOTEDTHATRESPONDSTOTHECHILDEVENTPAYLOADEVENTANDUPDATESACOUNTER", "original": "The parent `VoteTakerComponent` binds an event handler called `onVoted()` that responds to the child event\npayload `$event` and updates a counter.", "translation": "父组件 `VoteTakerComponent` 绑定了一个事件处理器(`onVoted()`),用来响应子组件的事件(`$event`)并更新一个计数器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEFRAMEWORKPASSESTHEEVENTARGUMENTMDASHREPRESENTEDBYEVENTMDASHTOTHEHANDLERMETHODANDTHEMETHODPROCESSESIT:", "original": "The framework passes the event argument—represented by `$event`—to the handler method,\nand the method processes it:", "translation": "框架(Angular)把事件参数(用 `$event` 表示)传给事件处理方法,这个方法会处理:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "H3CLASSNOTOCTESTITH3", "original": "<h3 class=\"no-toc\">Test it</h3>", "translation": "<h3 class=\"no-toc\">测试一下!</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "TESTTHATCLICKINGTHEAGREEANDDISAGREEBUTTONSUPDATETHEAPPROPRIATECOUNTERS:", "original": "Test that clicking the *Agree* and *Disagree* buttons update the appropriate counters:", "translation": "测试确保点击 *Agree* 和 *Disagree* 按钮时,计数器被正确更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "BACKTOTOPGUIDECOMPONENTINTERACTION#TOP", "original": "[Back to top](guide/component-interaction#top)", "translation": "[回到顶部](guide/component-interaction#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "##PARENTINTERACTSWITHCHILDVIALOCALVARIABLE", "original": "## Parent interacts with child via *local variable*", "translation": "## 父组件与子组件通过*本地变量*互动", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "APARENTCOMPONENTCANNOTUSEDATABINDINGTOREADCHILDPROPERTIESORINVOKECHILDMETHODSYOUCANDOBOTHBYCREATINGATEMPLATEREFERENCEVARIABLEFORTHECHILDELEMENTANDTHENREFERENCETHATVARIABLEWITHINTHEPARENTTEMPLATEASSEENINTHEFOLLOWINGEXAMPLE", "original": "A parent component cannot use data binding to read child properties\nor invoke child methods. You can do both\nby creating a template reference variable for the child element\nand then reference that variable *within the parent template*\nas seen in the following example.", "translation": "父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法,如下例所示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEFOLLOWINGISACHILDCOUNTDOWNTIMERCOMPONENTTHATREPEATEDLYCOUNTSDOWNTOZEROANDLAUNCHESAROCKETITHASSTARTANDSTOPMETHODSTHATCONTROLTHECLOCKANDITDISPLAYSACOUNTDOWNSTATUSMESSAGEINITSOWNTEMPLATE", "original": "The following is a child `CountdownTimerComponent` that repeatedly counts down to zero and launches a rocket.\nIt has `start` and `stop` methods that control the clock and it displays a\ncountdown status message in its own template.", "translation": "子组件 `CountdownTimerComponent` 进行倒计时,归零时发射一个导弹。`start` 和 `stop` 方法负责控制时钟并在模板里显示倒计时的状态信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THECOUNTDOWNLOCALVARPARENTCOMPONENTTHATHOSTSTHETIMERCOMPONENTISASFOLLOWS:", "original": "The `CountdownLocalVarParentComponent` that hosts the timer component is as follows:", "translation": "计时器组件的宿主组件 `CountdownLocalVarParentComponent` 如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEPARENTCOMPONENTCANNOTDATABINDTOTHECHILDSSTARTANDSTOPMETHODSNORTOITSSECONDSPROPERTY", "original": "The parent component cannot data bind to the child's\n`start` and `stop` methods nor to its `seconds` property.", "translation": "父组件不能通过数据绑定使用子组件的 `start` 和 `stop` 方法,也不能访问子组件的 `seconds` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "YOUCANPLACEALOCALVARIABLE#TIMERONTHETAGCOUNTDOWNTIMERREPRESENTINGTHECHILDCOMPONENTTHATGIVESYOUAREFERENCETOTHECHILDCOMPONENTANDTHEABILITYTOACCESSANYOFITSPROPERTIESORMETHODSFROMWITHINTHEPARENTTEMPLATE", "original": "You can place a local variable, `#timer`, on the tag `<countdown-timer>` representing the child component.\nThat gives you a reference to the child component and the ability to access\n*any of its properties or methods* from within the parent template.", "translation": "把本地变量(`#timer`)放到(`<countdown-timer>`)标签中,用来代表子组件。这样父组件的模板就得到了子组件的引用,于是可以在父组件的模板中访问子组件的所有属性和方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THISEXAMPLEWIRESPARENTBUTTONSTOTHECHILDSSTARTANDSTOPANDUSESINTERPOLATIONTODISPLAYTHECHILDSSECONDSPROPERTY", "original": "This example wires parent buttons to the child's `start` and `stop` and\nuses interpolation to display the child's `seconds` property.", "translation": "这个例子把父组件的按钮绑定到子组件的 `start` 和 `stop` 方法,并用插值表达式来显示子组件的 `seconds` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "HEREWESEETHEPARENTANDCHILDWORKINGTOGETHER", "original": "Here we see the parent and child working together.", "translation": "下面是父组件和子组件一起工作时的效果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "H3CLASSNOTOCTESTITH3", "original": "<h3 class=\"no-toc\">Test it</h3>", "translation": "<h3 class=\"no-toc\">测试一下!</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "TESTTHATTHESECONDSDISPLAYEDINTHEPARENTTEMPLATEMATCHTHESECONDSDISPLAYEDINTHECHILDSSTATUSMESSAGETESTALSOTHATCLICKINGTHESTOPBUTTONPAUSESTHECOUNTDOWNTIMER:", "original": "Test that the seconds displayed in the parent template\nmatch the seconds displayed in the child's status message.\nTest also that clicking the *Stop* button pauses the countdown timer:", "translation": "测试确保在父组件模板中显示的秒数和子组件状态信息里的秒数同步。它还会点击 *Stop* 按钮来停止倒计时:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "BACKTOTOPGUIDECOMPONENTINTERACTION#TOP", "original": "[Back to top](guide/component-interaction#top)", "translation": "[回到顶部](guide/component-interaction#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "##PARENTCALLSANVIEWCHILD", "original": "## Parent calls an _@ViewChild()_", "translation": "## 父组件调用*@ViewChild()*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THELOCALVARIABLEAPPROACHISSIMPLEANDEASYBUTITISLIMITEDBECAUSETHEPARENTCHILDWIRINGMUSTBEDONEENTIRELYWITHINTHEPARENTTEMPLATETHEPARENTCOMPONENTITSELFHASNOACCESSTOTHECHILD", "original": "The *local variable* approach is simple and easy. But it is limited because\nthe parent-child wiring must be done entirely within the parent template.\nThe parent component *itself* has no access to the child.", "translation": "这个*本地变量*方法是个简单便利的方法。但是它也有局限性,因为父组件-子组件的连接必须全部在父组件的模板中进行。父组件本身的代码对子组件没有访问权。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "YOUCANTUSETHELOCALVARIABLETECHNIQUEIFANINSTANCEOFTHEPARENTCOMPONENTCLASSMUSTREADORWRITECHILDCOMPONENTVALUESORMUSTCALLCHILDCOMPONENTMETHODS", "original": "You can't use the *local variable* technique if an instance of the parent component *class*\nmust read or write child component values or must call child component methods.", "translation": "如果父组件的*类*需要读取子组件的属性值或调用子组件的方法,就不能使用*本地变量*方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "WHENTHEPARENTCOMPONENTCLASSREQUIRESTHATKINDOFACCESSINJECTTHECHILDCOMPONENTINTOTHEPARENTASAVIEWCHILD", "original": "When the parent component *class* requires that kind of access,\n***inject*** the child component into the parent as a *ViewChild*.", "translation": "当父组件*类*需要这种访问时,可以把子组件作为 *ViewChild*,***注入***到父组件里面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEFOLLOWINGEXAMPLEILLUSTRATESTHISTECHNIQUEWITHTHESAMECOUNTDOWNTIMERGUIDECOMPONENTINTERACTION#COUNTDOWNTIMEREXAMPLEEXAMPLENEITHERITSAPPEARANCENORITSBEHAVIORWILLCHANGETHECHILDCOUNTDOWNTIMERCOMPONENTGUIDECOMPONENTINTERACTION#COUNTDOWNTIMEREXAMPLEISTHESAMEASWELL", "original": "The following example illustrates this technique with the same\n[Countdown Timer](guide/component-interaction#countdown-timer-example) example.\nNeither its appearance nor its behavior will change.\nThe child [CountdownTimerComponent](guide/component-interaction#countdown-timer-example) is the same as well.", "translation": "下面的例子用与[倒计时](guide/component-interaction#countdown-timer-example)相同的范例来解释这种技术。\n它的外观或行为没有变化。子组件[CountdownTimerComponent](guide/component-interaction#countdown-timer-example)也和原来一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THESWITCHFROMTHELOCALVARIABLETOTHEVIEWCHILDTECHNIQUEISSOLELYFORTHEPURPOSEOFDEMONSTRATION", "original": "The switch from the *local variable* to the *ViewChild* technique\nis solely for the purpose of demonstration.", "translation": "由*本地变量*切换到 *ViewChild* 技术的唯一目的就是做示范。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "HEREISTHEPARENTCOUNTDOWNVIEWCHILDPARENTCOMPONENT:", "original": "Here is the parent, `CountdownViewChildParentComponent`:", "translation": "下面是父组件 `CountdownViewChildParentComponent`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "ITTAKESABITMOREWORKTOGETTHECHILDVIEWINTOTHEPARENTCOMPONENTCLASS", "original": "It takes a bit more work to get the child view into the parent component *class*.", "translation": "把子组件的视图插入到父组件类需要做一点额外的工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "FIRSTYOUHAVETOIMPORTREFERENCESTOTHEVIEWCHILDDECORATORANDTHEAFTERVIEWINITLIFECYCLEHOOK", "original": "First, you have to import references to the `ViewChild` decorator and the `AfterViewInit` lifecycle hook.", "translation": "首先,你要使用 `ViewChild` 装饰器导入这个引用,并挂上 `AfterViewInit` 生命周期钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "NEXTINJECTTHECHILDCOUNTDOWNTIMERCOMPONENTINTOTHEPRIVATETIMERCOMPONENTPROPERTYVIATHEVIEWCHILDPROPERTYDECORATION", "original": "Next, inject the child `CountdownTimerComponent` into the private `timerComponent` property\nvia the `@ViewChild` property decoration.", "translation": "接着,通过 `@ViewChild` 属性装饰器,将子组件 `CountdownTimerComponent` 注入到私有属性 `timerComponent` 里面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THE#TIMERLOCALVARIABLEISGONEFROMTHECOMPONENTMETADATAINSTEADBINDTHEBUTTONSTOTHEPARENTCOMPONENTSOWNSTARTANDSTOPMETHODSANDPRESENTTHETICKINGSECONDSINANINTERPOLATIONAROUNDTHEPARENTCOMPONENTSSECONDSMETHOD", "original": "The `#timer` local variable is gone from the component metadata.\nInstead, bind the buttons to the parent component's own `start` and `stop` methods and\npresent the ticking seconds in an interpolation around the parent component's `seconds` method.", "translation": "组件元数据里就不再需要 `#timer` 本地变量了。而是把按钮绑定到父组件自己的 `start` 和 `stop` 方法,使用父组件的 `seconds` 方法的插值表达式来展示秒数变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THESEMETHODSACCESSTHEINJECTEDTIMERCOMPONENTDIRECTLY", "original": "These methods access the injected timer component directly.", "translation": "这些方法可以直接访问被注入的计时器组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THENGAFTERVIEWINITLIFECYCLEHOOKISANIMPORTANTWRINKLETHETIMERCOMPONENTISNTAVAILABLEUNTILAFTERANGULARDISPLAYSTHEPARENTVIEWSOITDISPLAYS0SECONDSINITIALLY", "original": "The `ngAfterViewInit()` lifecycle hook is an important wrinkle.\nThe timer component isn't available until *after* Angular displays the parent view.\nSo it displays `0` seconds initially.", "translation": "`ngAfterViewInit()` 生命周期钩子是非常重要的一步。被注入的计时器组件只有在 Angular 显示了父组件视图之后才能访问,所以它先把秒数显示为 0.", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THENANGULARCALLSTHENGAFTERVIEWINITLIFECYCLEHOOKATWHICHTIMEITISTOOLATETOUPDATETHEPARENTVIEWSDISPLAYOFTHECOUNTDOWNSECONDSANGULARSUNIDIRECTIONALDATAFLOWRULEPREVENTSUPDATINGTHEPARENTVIEWSINTHESAMECYCLETHEAPPHASTOWAITONETURNBEFOREITCANDISPLAYTHESECONDS", "original": "Then Angular calls the `ngAfterViewInit` lifecycle hook at which time it is *too late*\nto update the parent view's display of the countdown seconds.\nAngular's unidirectional data flow rule prevents updating the parent view's\nin the same cycle. The app has to *wait one turn* before it can display the seconds.", "translation": "然后 Angular 会调用 `ngAfterViewInit` 生命周期钩子,但这时候再更新父组件视图的倒计时就已经太晚了。Angular 的单向数据流规则会阻止在同一个周期内更新父组件视图。应用在显示秒数之前会被迫*再等一轮*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "USESETTIMEOUTTOWAITONETICKANDTHENREVISETHESECONDSMETHODSOTHATITTAKESFUTUREVALUESFROMTHETIMERCOMPONENT", "original": "Use `setTimeout()` to wait one tick and then revise the `seconds()` method so\nthat it takes future values from the timer component.", "translation": "使用 `setTimeout()` 来等下一轮,然后改写 `seconds()` 方法,这样它接下来就会从注入的这个计时器组件里获取秒数的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "H3CLASSNOTOCTESTITH3", "original": "<h3 class=\"no-toc\">Test it</h3>", "translation": "<h3 class=\"no-toc\">测试一下!</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "USETHESAMECOUNTDOWNTIMERTESTSGUIDECOMPONENTINTERACTION#COUNTDOWNTESTSASBEFORE", "original": "Use [the same countdown timer tests](guide/component-interaction#countdown-tests) as before.", "translation": "使用和之前[一样的倒计时测试](guide/component-interaction#countdown-tests)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "BACKTOTOPGUIDECOMPONENTINTERACTION#TOP", "original": "[Back to top](guide/component-interaction#top)", "translation": "[回到顶部](guide/component-interaction#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "##PARENTANDCHILDRENCOMMUNICATEVIAASERVICE", "original": "## Parent and children communicate via a service", "translation": "## 父组件和子组件通过服务来通讯", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "APARENTCOMPONENTANDITSCHILDRENSHAREASERVICEWHOSEINTERFACEENABLESBIDIRECTIONALCOMMUNICATIONWITHINTHEFAMILY", "original": "A parent component and its children share a service whose interface enables bi-directional communication\n*within the family*.", "translation": "父组件和它的子组件共享同一个服务,利用该服务*在家庭内部*实现双向通讯。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THESCOPEOFTHESERVICEINSTANCEISTHEPARENTCOMPONENTANDITSCHILDRENCOMPONENTSOUTSIDETHISCOMPONENTSUBTREEHAVENOACCESSTOTHESERVICEORTHEIRCOMMUNICATIONS", "original": "The scope of the service instance is the parent component and its children.\nComponents outside this component subtree have no access to the service or their communications.", "translation": "该服务实例的作用域被限制在父组件和其子组件内。这个组件子树之外的组件将无法访问该服务或者与它们通讯。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THISMISSIONSERVICECONNECTSTHEMISSIONCONTROLCOMPONENTTOMULTIPLEASTRONAUTCOMPONENTCHILDREN", "original": "This `MissionService` connects the `MissionControlComponent` to multiple `AstronautComponent` children.", "translation": "这个 `MissionService` 把 `MissionControlComponent` 和多个 `AstronautComponent` 子组件连接起来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEMISSIONCONTROLCOMPONENTBOTHPROVIDESTHEINSTANCEOFTHESERVICETHATITSHARESWITHITSCHILDRENTHROUGHTHEPROVIDERSMETADATAARRAYANDINJECTSTHATINSTANCEINTOITSELFTHROUGHITSCONSTRUCTOR:", "original": "The `MissionControlComponent` both provides the instance of the service that it shares with its children\n(through the `providers` metadata array) and injects that instance into itself through its constructor:", "translation": "`MissionControlComponent` 提供服务的实例,并将其共享给它的子组件(通过 `providers` 元数据数组),子组件可以通过构造函数将该实例注入到自身。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEASTRONAUTCOMPONENTALSOINJECTSTHESERVICEINITSCONSTRUCTOREACHASTRONAUTCOMPONENTISACHILDOFTHEMISSIONCONTROLCOMPONENTANDTHEREFORERECEIVESITSPARENTSSERVICEINSTANCE:", "original": "The `AstronautComponent` also injects the service in its constructor.\nEach `AstronautComponent` is a child of the `MissionControlComponent` and therefore receives its parent's service instance:", "translation": "`AstronautComponent` 也通过自己的构造函数注入该服务。由于每个 `AstronautComponent` 都是 `MissionControlComponent` 的子组件,所以它们获取到的也是父组件的这个服务实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "NOTICETHATTHISEXAMPLECAPTURESTHESUBSCRIPTIONANDUNSUBSCRIBEWHENTHEASTRONAUTCOMPONENTISDESTROYEDTHISISAMEMORYLEAKGUARDSTEPTHEREISNOACTUALRISKINTHISAPPBECAUSETHELIFETIMEOFAASTRONAUTCOMPONENTISTHESAMEASTHELIFETIMEOFTHEAPPITSELFTHATWOULDNOTALWAYSBETRUEINAMORECOMPLEXAPPLICATION", "original": "Notice that this example captures the `subscription` and `unsubscribe()` when the `AstronautComponent` is destroyed.\nThis is a memory-leak guard step. There is no actual risk in this app because the\nlifetime of a `AstronautComponent` is the same as the lifetime of the app itself.\nThat *would not* always be true in a more complex application.", "translation": "注意,这个例子保存了 `subscription` 变量,并在 `AstronautComponent` 被销毁时调用 `unsubscribe()` 退订。\n这是一个用于防止内存泄漏的保护措施。实际上,在这个应用程序中并没有这个风险,因为 `AstronautComponent` 的生命期和应用程序的生命期一样长。但在更复杂的应用程序环境中就不一定了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "YOUDONTADDTHISGUARDTOTHEMISSIONCONTROLCOMPONENTBECAUSEASTHEPARENTITCONTROLSTHELIFETIMEOFTHEMISSIONSERVICE", "original": "You don't add this guard to the `MissionControlComponent` because, as the parent,\nit controls the lifetime of the `MissionService`.", "translation": "不需要在 `MissionControlComponent` 中添加这个保护措施,因为它作为父组件,控制着 `MissionService` 的生命期。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "THEHISTORYLOGDEMONSTRATESTHATMESSAGESTRAVELINBOTHDIRECTIONSBETWEENTHEPARENTMISSIONCONTROLCOMPONENTANDTHEASTRONAUTCOMPONENTCHILDRENFACILITATEDBYTHESERVICE:", "original": "The *History* log demonstrates that messages travel in both directions between\nthe parent `MissionControlComponent` and the `AstronautComponent` children,\nfacilitated by the service:", "translation": "*History* 日志证明了:在父组件 `MissionControlComponent` 和子组件 `AstronautComponent` 之间,信息通过该服务实现了双向传递。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "H3CLASSNOTOCTESTITH3", "original": "<h3 class=\"no-toc\">Test it</h3>", "translation": "<h3 class=\"no-toc\">测试一下!</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "TESTSCLICKBUTTONSOFBOTHTHEPARENTMISSIONCONTROLCOMPONENTANDTHEASTRONAUTCOMPONENTCHILDRENANDVERIFYTHATTHEHISTORYMEETSEXPECTATIONS:", "original": "Tests click buttons of both the parent `MissionControlComponent` and the `AstronautComponent` children\nand verify that the history meets expectations:", "translation": "测试确保点击父组件 `MissionControlComponent` 和子组件 `AstronautComponent` 两个的组件的按钮时,*History* 日志和预期的一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "BACKTOTOPGUIDECOMPONENTINTERACTION#TOP", "original": "[Back to top](guide/component-interaction#top)", "translation": "[回到顶部](guide/component-interaction#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-interaction.md" }, { + "key": "#COMPONENTSTYLES", "original": "# Component Styles", "translation": "# 组件样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "ANGULARAPPLICATIONSARESTYLEDWITHSTANDARDCSSTHATMEANSYOUCANAPPLYEVERYTHINGYOUKNOWABOUTCSSSTYLESHEETSSELECTORSRULESANDMEDIAQUERIESDIRECTLYTOANGULARAPPLICATIONS", "original": "Angular applications are styled with standard CSS. That means you can apply\neverything you know about CSS stylesheets, selectors, rules, and media queries\ndirectly to Angular applications.", "translation": "Angular 应用使用标准的 CSS 来设置样式。这意味着你可以把关于 CSS\n的那些知识和技能直接用于 Angular 程序中,例如:样式表、选择器、规则以及媒体查询等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "ADDITIONALLYANGULARCANBUNDLECOMPONENTSTYLESWITHCOMPONENTSENABLINGAMOREMODULARDESIGNTHANREGULARSTYLESHEETS", "original": "Additionally, Angular can bundle *component styles*\nwith components, enabling a more modular design than regular stylesheets.", "translation": "另外,Angular 还能把*组件样式*捆绑在组件上,以实现比标准样式表更加模块化的设计。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THISPAGEDESCRIBESHOWTOLOADANDAPPLYTHESECOMPONENTSTYLES", "original": "This page describes how to load and apply these component styles.", "translation": "本章将会讲解如何加载和使用这些*组件样式*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANRUNTHELIVEEXAMPLELIVEEXAMPLEINSTACKBLITZANDDOWNLOADTHECODEFROMTHERE", "original": "You can run the <live-example></live-example> in Stackblitz and download the code from there.", - "translation": "你可以运行<live-example></live-example>来在 Stackblitz 中试用并下载本页的代码。", + "translation": "你可以运行<live-example></live-example>,在 Stackblitz 中试用并下载本页的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "##USINGCOMPONENTSTYLES", "original": "## Using component styles", "translation": "## 使用组件样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "FOREVERYANGULARCOMPONENTYOUWRITEYOUMAYDEFINENOTONLYANHTMLTEMPLATEBUTALSOTHECSSSTYLESTHATGOWITHTHATTEMPLATESPECIFYINGANYSELECTORSRULESANDMEDIAQUERIESTHATYOUNEED", "original": "For every Angular component you write, you may define not only an HTML template,\nbut also the CSS styles that go with that template,\nspecifying any selectors, rules, and media queries that you need.", "translation": "对你编写的每个 Angular 组件来说,除了定义 HTML 模板之外,还要定义用于模板的 CSS 样式、\n指定任意的选择器、规则和媒体查询。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "ONEWAYTODOTHISISTOSETTHESTYLESPROPERTYINTHECOMPONENTMETADATATHESTYLESPROPERTYTAKESANARRAYOFSTRINGSTHATCONTAINCSSCODEUSUALLYYOUGIVEITONESTRINGASINTHEFOLLOWINGEXAMPLE:", "original": "One way to do this is to set the `styles` property in the component metadata.\nThe `styles` property takes an array of strings that contain CSS code.\nUsually you give it one string, as in the following example:", "translation": "实现方式之一,是在组件的元数据中设置 `styles` 属性。\n`styles` 属性可以接受一个包含 CSS 代码的字符串数组。\n通常你只给它一个字符串就行了,如同下例:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "##STYLESCOPE", "original": "## Style scope", "translation": "## 范围化的样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THESTYLESSPECIFIEDINCOMPONENTMETADATAAPPLYONLYWITHINTHETEMPLATEOFTHATCOMPONENT", "original": "The styles specified in `@Component` metadata _apply only within the template of that component_.", "translation": "在 `@Component` 的元数据中指定的样式只会对该组件的模板生效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THEYARENOTINHERITEDBYANYCOMPONENTSNESTEDWITHINTHETEMPLATENORBYANYCONTENTPROJECTEDINTOTHECOMPONENT", "original": "They are _not inherited_ by any components nested within the template nor by any content projected into the component.", "translation": "它们既不会被模板中嵌入的组件继承,也不会被通过内容投影(如 ng-content)嵌进来的组件继承。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "INTHISEXAMPLETHEH1STYLEAPPLIESONLYTOTHEHEROAPPCOMPONENTNOTTOTHENESTEDHEROMAINCOMPONENTNORTOH1TAGSANYWHEREELSEINTHEAPPLICATION", "original": "In this example, the `h1` style applies only to the `HeroAppComponent`,\nnot to the nested `HeroMainComponent` nor to `<h1>` tags anywhere else in the application.", "translation": "在这个例子中,`h1` 的样式只对 `HeroAppComponent` 生效,既不会作用于内嵌的 `HeroMainComponent` ,也不会作用于应用中其它任何地方的 `<h1>` 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THISSCOPINGRESTRICTIONISASTYLINGMODULARITYFEATURE", "original": "This scoping restriction is a ***styling modularity feature***.", "translation": "这种范围限制就是所谓的***样式模块化***特性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANUSETHECSSCLASSNAMESANDSELECTORSTHATMAKETHEMOSTSENSEINTHECONTEXTOFEACHCOMPONENT", "original": "* You can use the CSS class names and selectors that make the most sense in the context of each component.", "translation": "可以使用对每个组件最有意义的 CSS 类名和选择器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "CLASSNAMESANDSELECTORSARELOCALTOTHECOMPONENTANDDONTCOLLIDEWITHCLASSESANDSELECTORSUSEDELSEWHEREINTHEAPPLICATION", "original": "* Class names and selectors are local to the component and don't collide with\n classes and selectors used elsewhere in the application.", "translation": "类名和选择器是仅属于组件内部的,它不会和应用中其它地方的类名和选择器出现冲突。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "CHANGESTOSTYLESELSEWHEREINTHEAPPLICATIONDONTAFFECTTHECOMPONENTSSTYLES", "original": "* Changes to styles elsewhere in the application don't affect the component's styles.", "translation": "组件的样式*不会*因为别的地方修改了样式而被意外改变。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANCOLOCATETHECSSCODEOFEACHCOMPONENTWITHTHETYPESCRIPTANDHTMLCODEOFTHECOMPONENTWHICHLEADSTOANEATANDTIDYPROJECTSTRUCTURE", "original": "* You can co-locate the CSS code of each component with the TypeScript and HTML code of the component,\n which leads to a neat and tidy project structure.", "translation": "你可以让每个组件的 CSS 代码和它的 TypeScript、HTML 代码放在一起,这将促成清爽整洁的项目结构。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANCHANGEORREMOVECOMPONENTCSSCODEWITHOUTSEARCHINGTHROUGHTHEWHOLEAPPLICATIONTOFINDWHEREELSETHECODEISUSED", "original": "* You can change or remove component CSS code without searching through the\n whole application to find where else the code is used.", "translation": "将来你可以修改或移除组件的 CSS 代码,而不用遍历整个应用来看它有没有被别处用到,只要看看当前组件就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "##SPECIALSELECTORS", "original": "## Special selectors", "translation": "## 特殊的选择器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "COMPONENTSTYLESHAVEAFEWSPECIALSELECTORSFROMTHEWORLDOFSHADOWDOMSTYLESCOPINGDESCRIBEDINTHECSSSCOPINGMODULELEVEL1HTTPS:WWWW3ORGTRCSSSCOPING1PAGEONTHEW3CHTTPS:WWWW3ORGSITETHEFOLLOWINGSECTIONSDESCRIBETHESESELECTORS", "original": "Component styles have a few special *selectors* from the world of shadow DOM style scoping\n(described in the [CSS Scoping Module Level 1](https://www.w3.org/TR/css-scoping-1) page on the\n[W3C](https://www.w3.org) site).\nThe following sections describe these selectors.", "translation": "组件样式中有一些从影子(Shadow) DOM 样式范围领域(记录在[W3C](https://www.w3.org)的[CSS Scoping Module Level 1](https://www.w3.org/TR/css-scoping-1)中) 引入的特殊*选择器*:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###:HOST", "original": "### :host", "translation": "### :host 选择器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "USETHE:HOSTPSEUDOCLASSSELECTORTOTARGETSTYLESINTHEELEMENTTHATHOSTSTHECOMPONENTASOPPOSEDTOTARGETINGELEMENTSINSIDETHECOMPONENTSTEMPLATE", "original": "Use the `:host` pseudo-class selector to target styles in the element that *hosts* the component (as opposed to\ntargeting elements *inside* the component's template).", "translation": "使用 `:host` 伪类选择器,用来选择组件*宿主*元素中的元素(相对于组件模板*内部*的元素)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THE:HOSTSELECTORISTHEONLYWAYTOTARGETTHEHOSTELEMENTYOUCANTREACHTHEHOSTELEMENTFROMINSIDETHECOMPONENTWITHOTHERSELECTORSBECAUSEITSNOTPARTOFTHECOMPONENTSOWNTEMPLATETHEHOSTELEMENTISINAPARENTCOMPONENTSTEMPLATE", "original": "The `:host` selector is the only way to target the host element. You can't reach\nthe host element from inside the component with other selectors because it's not part of the\ncomponent's own template. The host element is in a parent component's template.", "translation": "`:host` 选择是是把宿主元素作为目标的*唯一*方式。除此之外,你将没办法指定它,\n因为宿主不是组件自身模板的一部分,而是父组件模板的一部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "USETHEFUNCTIONFORMTOAPPLYHOSTSTYLESCONDITIONALLYBYINCLUDINGANOTHERSELECTORINSIDEPARENTHESESAFTER:HOST", "original": "Use the *function form* to apply host styles conditionally by\nincluding another selector inside parentheses after `:host`.", "translation": "要把宿主样式作为条件,就要像*函数*一样把其它选择器放在 `:host` 后面的括号中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THENEXTEXAMPLETARGETSTHEHOSTELEMENTAGAINBUTONLYWHENITALSOHASTHEACTIVECSSCLASS", "original": "The next example targets the host element again, but only when it also has the `active` CSS class.", "translation": "下一个例子再次把宿主元素作为目标,但是只有当它同时带有 `active` CSS 类的时候才会生效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###:HOSTCONTEXT", "original": "### :host-context", "translation": "### :host-context 选择器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "SOMETIMESITSUSEFULTOAPPLYSTYLESBASEDONSOMECONDITIONOUTSIDEOFACOMPONENTSVIEWFOREXAMPLEACSSTHEMECLASSCOULDBEAPPLIEDTOTHEDOCUMENTBODYELEMENTANDYOUWANTTOCHANGEHOWYOURCOMPONENTLOOKSBASEDONTHAT", "original": "Sometimes it's useful to apply styles based on some condition *outside* of a component's view.\nFor example, a CSS theme class could be applied to the document `<body>` element, and\nyou want to change how your component looks based on that.", "translation": "有时候,基于某些来自组件视图*外部*的条件应用样式是很有用的。\n例如,在文档的 `<body>` 元素上可能有一个用于表示样式主题 (theme) 的 CSS 类,你应当基于它来决定组件的样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "USETHE:HOSTCONTEXTPSEUDOCLASSSELECTORWHICHWORKSJUSTLIKETHEFUNCTIONFORMOF:HOSTTHE:HOSTCONTEXTSELECTORLOOKSFORACSSCLASSINANYANCESTOROFTHECOMPONENTHOSTELEMENTUPTOTHEDOCUMENTROOTTHE:HOSTCONTEXTSELECTORISUSEFULWHENCOMBINEDWITHANOTHERSELECTOR", "original": "Use the `:host-context()` pseudo-class selector, which works just like the function\nform of `:host()`. The `:host-context()` selector looks for a CSS class in any ancestor of the component host element,\nup to the document root. The `:host-context()` selector is useful when combined with another selector.", "translation": "这时可以使用 `:host-context()` 伪类选择器。它也以类似 `:host()` 形式使用。它在当前组件宿主元素的*祖先节点*中查找 CSS 类,\n直到文档的根节点为止。在与其它选择器组合使用时,它非常有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THEFOLLOWINGEXAMPLEAPPLIESABACKGROUNDCOLORSTYLETOALLH2ELEMENTSINSIDETHECOMPONENTONLYIFSOMEANCESTORELEMENTHASTHECSSCLASSTHEMELIGHT", "original": "The following example applies a `background-color` style to all `<h2>` elements *inside* the component, only\nif some ancestor element has the CSS class `theme-light`.", "translation": "在下面的例子中,只有当某个祖先元素有 CSS 类 `theme-light` 时,才会把 `background-color` 样式应用到组件*内部*的所有 `<h2>` 元素中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###DEPRECATEDDEEPAND::NGDEEP", "original": "### (deprecated) `/deep/`, `>>>`, and `::ng-deep`", "translation": "### 已废弃 `/deep/`、`>>>` 和 `::ng-deep`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "COMPONENTSTYLESNORMALLYAPPLYONLYTOTHEHTMLINTHECOMPONENTSOWNTEMPLATE", "original": "Component styles normally apply only to the HTML in the component's own template.", "translation": "组件样式通常只会作用于组件自身的 HTML 上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "USETHEDEEPSHADOWPIERCINGDESCENDANTCOMBINATORTOFORCEASTYLEDOWNTHROUGHTHECHILDCOMPONENTTREEINTOALLTHECHILDCOMPONENTVIEWSTHEDEEPCOMBINATORWORKSTOANYDEPTHOFNESTEDCOMPONENTSANDITAPPLIESTOBOTHTHEVIEWCHILDRENANDCONTENTCHILDRENOFTHECOMPONENT", "original": "Use the `/deep/` shadow-piercing descendant combinator to force a style down through the child\ncomponent tree into all the child component views.\nThe `/deep/` combinator works to any depth of nested components, and it applies to both the view\nchildren and content children of the component.", "translation": "可以使用 `/deep/` 选择器来强制一个样式对各级子组件的视图也生效,它*不但作用于组件的子视图,也会作用于组件的内容*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THEFOLLOWINGEXAMPLETARGETSALLH3ELEMENTSFROMTHEHOSTELEMENTDOWNTHROUGHTHISCOMPONENTTOALLOFITSCHILDELEMENTSINTHEDOM", "original": "The following example targets all `<h3>` elements, from the host element down\nthrough this component to all of its child elements in the DOM.", "translation": "这个例子以所有的 `<h3>` 元素为目标,从宿主元素到当前元素再到 DOM 中的所有子元素:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THEDEEPCOMBINATORALSOHASTHEALIASESAND::NGDEEP", "original": "The `/deep/` combinator also has the aliases `>>>`, and `::ng-deep`.", "translation": "`/deep/` 组合器还有两个别名:`>>>` 和 `::ng-deep`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "USEDEEPAND::NGDEEPONLYWITHEMULATEDVIEWENCAPSULATIONEMULATEDISTHEDEFAULTANDMOSTCOMMONLYUSEDVIEWENCAPSULATIONFORMOREINFORMATIONSEETHECONTROLLINGVIEWENCAPSULATIONGUIDECOMPONENTSTYLES#VIEWENCAPSULATIONSECTION", "original": "Use `/deep/`, `>>>` and `::ng-deep` only with *emulated* view encapsulation.\nEmulated is the default and most commonly used view encapsulation. For more information, see the\n[Controlling view encapsulation](guide/component-styles#view-encapsulation) section.", "translation": "`/deep/` 和 `>>>` 选择器只能被用在**仿真 (emulated) **模式下。\n这种方式是默认值,也是用得最多的方式。\n更多信息,见[控制视图封装模式](guide/component-styles#view-encapsulation)一节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THESHADOWPIERCINGDESCENDANTCOMBINATORISDEPRECATEDANDSUPPORTISBEINGREMOVEDFROMMAJORBROWSERSHTTPS:WWWCHROMESTATUSCOMFEATURES6750456638341120ANDTOOLSASSUCHWEPLANTODROPSUPPORTINANGULARFORALL3OFDEEPAND::NGDEEPUNTILTHEN::NGDEEPSHOULDBEPREFERREDFORABROADERCOMPATIBILITYWITHTHETOOLS", "original": "The shadow-piercing descendant combinator is deprecated and [support is being removed from major browsers](https://www.chromestatus.com/features/6750456638341120) and tools.\nAs such we plan to drop support in Angular (for all 3 of `/deep/`, `>>>` and `::ng-deep`).\nUntil then `::ng-deep` should be preferred for a broader compatibility with the tools.", "translation": "CSS 标准中用于 \"刺穿 Shadow DOM\" 的组合器已经被废弃,并将[这个特性从主流浏览器和工具中移除](https://www.chromestatus.com/features/6750456638341120)。\n因此,我们也将在 Angular 中移除对它们的支持(包括 `/deep/`、`>>>` 和 `::ng-deep`)。\n目前,建议先统一使用 `::ng-deep`,以便兼容将来的工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "##LOADINGCOMPONENTSTYLES", "original": "## Loading component styles", "translation": "## 把样式加载进组件中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THEREARESEVERALWAYSTOADDSTYLESTOACOMPONENT:", "original": "There are several ways to add styles to a component:", "translation": "有几种方式把样式加入组件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "BYSETTINGSTYLESORSTYLEURLSMETADATA", "original": "* By setting `styles` or `styleUrls` metadata.", "translation": "设置 `styles` 或 `styleUrls` 元数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "INLINEINTHETEMPLATEHTML", "original": "* Inline in the template HTML.", "translation": "内联在模板的 HTML 中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "WITHCSSIMPORTS", "original": "* With CSS imports.", "translation": "通过 CSS 文件导入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THESCOPINGRULESOUTLINEDEARLIERAPPLYTOEACHOFTHESELOADINGPATTERNS", "original": "The scoping rules outlined earlier apply to each of these loading patterns.", "translation": "上述作用域规则对所有这些加载模式都适用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###STYLESINCOMPONENTMETADATA", "original": "### Styles in component metadata", "translation": "### 元数据中的样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANADDASTYLESARRAYPROPERTYTOTHECOMPONENTDECORATOR", "original": "You can add a `styles` array property to the `@Component` decorator.", "translation": "你可以给 `@Component` 装饰器添加一个 `styles` 数组型属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "EACHSTRINGINTHEARRAYDEFINESSOMECSSFORTHISCOMPONENT", "original": "Each string in the array defines some CSS for this component.", "translation": "这个数组中的每一个字符串(通常也只有一个)定义一份 CSS。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "REMINDER:THESESTYLESAPPLYONLYTOTHISCOMPONENTTHEYARENOTINHERITEDBYANYCOMPONENTSNESTEDWITHINTHETEMPLATENORBYANYCONTENTPROJECTEDINTOTHECOMPONENT", "original": "Reminder: these styles apply _only to this component_.\nThey are _not inherited_ by any components nested within the template nor by any content projected into the component.", "translation": "注意:这些样式**只对当前组件生效**。\n它们**既不会作用于模板中嵌入的任何组件**,也不会作用于投影进来的组件(如 `ng-content` )。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THECLIDEFINESANEMPTYSTYLESARRAYWHENYOUCREATETHECOMPONENTWITHTHEINLINESTYLESFLAG", "original": "The CLI defines an empty `styles` array when you create the component with the `--inline-styles` flag.", "translation": "当使用 `--inline-styles` 标识创建组件时,CLI 就会定义一个空的 `styles` 数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###STYLEFILESINCOMPONENTMETADATA", "original": "### Style files in component metadata", "translation": "### 组件元数据中的样式文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANLOADSTYLESFROMEXTERNALCSSFILESBYADDINGASTYLEURLSPROPERTYTOACOMPONENTSCOMPONENTDECORATOR:", "original": "You can load styles from external CSS files by adding a `styleUrls` property\nto a component's `@Component` decorator:", "translation": "你可以通过把外部 CSS 文件添加到 `@Component` 的 `styleUrls` 属性中来加载外部样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "REMINDER:THESTYLESINTHESTYLEFILEAPPLYONLYTOTHISCOMPONENTTHEYARENOTINHERITEDBYANYCOMPONENTSNESTEDWITHINTHETEMPLATENORBYANYCONTENTPROJECTEDINTOTHECOMPONENT", "original": "Reminder: the styles in the style file apply _only to this component_.\nThey are _not inherited_ by any components nested within the template nor by any content projected into the component.", "translation": "注意:这些样式**只对当前组件生效**。\n它们**既不会作用于模板中嵌入的任何组件**,也不会作用于投影进来的组件(如 `ng-content` )。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANSPECIFYMORETHANONESTYLESFILEOREVENACOMBINATIONOFSTYLEANDSTYLEURLS", "original": "You can specify more than one styles file or even a combination of `style` and `styleUrls`.", "translation": "你可以指定多个样式文件,甚至可以组合使用 `style` 和 `styleUrls` 方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THECLICREATESANEMPTYSTYLESFILEFORYOUBYDEFAULTANDREFERENCESTHATFILEINTHECOMPONENTSGENERATEDSTYLEURLS", "original": "The CLI creates an empty styles file for you by default and references that file in the component's generated `styleUrls`.", "translation": "CLI 会默认为你创建一个空白的样式表文件,并且在所生成组件的 `styleUrls` 中引用该文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###TEMPLATEINLINESTYLES", "original": "### Template inline styles", "translation": "### 模板内联样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANEMBEDCSSSTYLESDIRECTLYINTOTHEHTMLTEMPLATEBYPUTTINGTHEMINSIDESTYLETAGS", "original": "You can embed CSS styles directly into the HTML template by putting them\ninside `<style>` tags.", "translation": "你也可以在组件的 HTML 模板中嵌入 `<style>` 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###TEMPLATELINKTAGS", "original": "### Template link tags", "translation": "### 模板中的 link 标签", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANALSOWRITELINKTAGSINTOTHECOMPONENTSHTMLTEMPLATE", "original": "You can also write `<link>` tags into the component's HTML template.", "translation": "你也可以在组件的 HTML 模板中写 `<link>` 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THELINKTAGSHREFURLMUSTBERELATIVETOTHEAPPLICATIONROOTNOTRELATIVETOTHECOMPONENTFILE", "original": "The link tag's `href` URL must be relative to the\n_**application root**_, not relative to the component file.", "translation": "link 标签的 `href` URL 必须是相对于***本应用的根路径***的,而不是相对于这个组件文件的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "WHENBUILDINGWITHTHECLIBESURETOINCLUDETHELINKEDSTYLEFILEAMONGTHEASSETSTOBECOPIEDTOTHESERVERASDESCRIBEDINTHECLIDOCUMENTATIONHTTPS:GITHUBCOMANGULARANGULARCLIWIKISTORIESASSETCONFIGURATION", "original": "When building with the CLI, be sure to include the linked style file among the assets to be copied to the server as described in the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-asset-configuration).", "translation": "当使用 CLI 进行构建时,要确保这个链接到的样式表文件被复制到了服务器上。参见 [CLI 官方文档](https://github.com/angular/angular-cli/wiki/stories-asset-configuration)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###CSSIMPORTS", "original": "### CSS @imports", "translation": "### CSS @imports 语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "YOUCANALSOIMPORTCSSFILESINTOTHECSSFILESUSINGTHESTANDARDCSSIMPORTRULEFORDETAILSSEEIMPORTHTTPS:DEVELOPERMOZILLAORGENDOCSWEBCSSIMPORTONTHEMDNHTTPS:DEVELOPERMOZILLAORGSITE", "original": "You can also import CSS files into the CSS files using the standard CSS `@import` rule.\nFor details, see [`@import`](https://developer.mozilla.org/en/docs/Web/CSS/@import)\non the [MDN](https://developer.mozilla.org) site.", "translation": "你还可以利用标准的 CSS [`@import` 规则](https://developer.mozilla.org/en/docs/Web/CSS/@import)来把其它\n CSS 文件导入到 CSS 文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "INTHISCASETHEURLISRELATIVETOTHECSSFILEINTOWHICHYOUREIMPORTING", "original": "In this case, the URL is relative to the CSS file into which you're importing.", "translation": "在*这种*情况下,URL 是相对于你正在导入的 CSS 文件的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###EXTERNALANDGLOBALSTYLEFILES", "original": "### External and global style files", "translation": "### 外部以及全局样式文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "WHENBUILDINGWITHTHECLIYOUMUSTCONFIGURETHEANGULARCLIJSONTOINCLUDEALLEXTERNALASSETSINCLUDINGEXTERNALSTYLEFILES", "original": "When building with the CLI, you must configure the `.angular-cli.json` to include _all external assets_, including external style files.", "translation": "当使用 CLI 进行构建时,你必须配置 `.angular-cli.json` 文件,使其包含*所有外部资源*(包括外部的样式表文件)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "REGISTERGLOBALSTYLEFILESINTHESTYLESSECTIONWHICHBYDEFAULTISPRECONFIGUREDWITHTHEGLOBALSTYLESCSSFILE", "original": "Register **global** style files in the `styles` section which, by default, is pre-configured with the global `styles.css` file.", "translation": "在它的 `styles` 区注册这些**全局**样式文件,默认情况下,它会有一个预先配置的全局 `styles.css` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "SEETHECLIDOCUMENTATIONHTTPS:GITHUBCOMANGULARANGULARCLIWIKISTORIESGLOBALSTYLESTOLEARNMORE", "original": "See the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-global-styles) to learn more.", "translation": "要了解更多,参见 [CLI 官方文档](https://github.com/angular/angular-cli/wiki/stories-global-styles)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "###NONCSSSTYLEFILES", "original": "### Non-CSS style files", "translation": "### 非 CSS 样式文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "IFYOUREBUILDINGWITHTHECLIYOUCANWRITESTYLEFILESINSASSHTTP:SASSLANGCOMLESSHTTP:LESSCSSORGORSTYLUSHTTP:STYLUSLANGCOMANDSPECIFYTHOSEFILESINTHECOMPONENTSTYLEURLSMETADATAWITHTHEAPPROPRIATEEXTENSIONSSCSSLESSSTYLASINTHEFOLLOWINGEXAMPLE:", "original": "If you're building with the CLI,\nyou can write style files in [sass](http://sass-lang.com/), [less](http://lesscss.org/), or [stylus](http://stylus-lang.com/) and specify those files in the `@Component.styleUrls` metadata with the appropriate extensions (`.scss`, `.less`, `.styl`) as in the following example:", "translation": "如果使用 CLI 进行构建,那么你可以用 [sass](http://sass-lang.com/)、[less](http://lesscss.org/) 或 [stylus](http://stylus-lang.com/) 来编写样式,并使用相应的扩展名(`.scss`、`.less`、`.styl`)把它们指定到 `@Component.styleUrls` 元数据中。例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THECLIBUILDPROCESSRUNSTHEPERTINENTCSSPREPROCESSOR", "original": "The CLI build process runs the pertinent CSS preprocessor.", "translation": "CLI 的构建过程会运行相关的预处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "WHENGENERATINGACOMPONENTFILEWITHNGGENERATECOMPONENTTHECLIEMITSANEMPTYCSSSTYLESFILECSSBYDEFAULTYOUCANCONFIGURETHECLITODEFAULTTOYOURPREFERREDCSSPREPROCESSORASEXPLAINEDINTHECLIDOCUMENTATIONHTTPS:GITHUBCOMANGULARANGULARCLIWIKISTORIESCSSPREPROCESSORSCSSPREPROCESSORINTEGRATION", "original": "When generating a component file with `ng generate component`, the CLI emits an empty CSS styles file (`.css`) by default.\nYou can configure the CLI to default to your preferred CSS preprocessor\nas explained in the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-css-preprocessors\n\"CSS Preprocessor integration\").", "translation": "当使用 `ng generate component` 命令生成组件文件时,CLI 会默认生成一个空白的 CSS 样式文件(`.css`)。\n你可以配置 CLI,让它默认使用你喜欢的 CSS 预处理器,参见 [CLI 官方文档](https://github.com/angular/angular-cli/wiki/stories-css-preprocessors\n \"CSS Preprocessor integration\") 中的解释。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "STYLESTRINGSADDEDTOTHECOMPONENTSTYLESARRAYMUSTBEWRITTENINCSSBECAUSETHECLICANNOTAPPLYAPREPROCESSORTOINLINESTYLES", "original": "Style strings added to the `@Component.styles` array _must be written in CSS_ because the CLI cannot apply a preprocessor to inline styles.", "translation": "添加到 `@Component.styles` 数组中的字符串*必须写成 CSS*,因为 CLI 没法对这些内联的样式使用任何 CSS 预处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "##VIEWENCAPSULATION", "original": "## View encapsulation", "translation": "## 控制视图的封装模式:原生 (Native)、仿真 (Emulated) 和无 (None)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "ASDISCUSSEDEARLIERCOMPONENTCSSSTYLESAREENCAPSULATEDINTOTHECOMPONENTSVIEWANDDONTAFFECTTHERESTOFTHEAPPLICATION", "original": "As discussed earlier, component CSS styles are encapsulated into the component's view and don't\naffect the rest of the application.", "translation": "像上面讨论过的一样,组件的 CSS 样式被封装进了自己的视图中,而不会影响到应用程序的其它部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "TOCONTROLHOWTHISENCAPSULATIONHAPPENSONAPERCOMPONENTBASISYOUCANSETTHEVIEWENCAPSULATIONMODEINTHECOMPONENTMETADATACHOOSEFROMTHEFOLLOWINGMODES:", "original": "To control how this encapsulation happens on a *per\ncomponent* basis, you can set the *view encapsulation mode* in the component metadata.\nChoose from the following modes:", "translation": "通过在组件的元数据上设置*视图封装模式*,你可以分别控制*每个组件*的封装模式。\n可选的封装模式一共有如下几种:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "NATIVEVIEWENCAPSULATIONUSESTHEBROWSERSNATIVESHADOWDOMIMPLEMENTATIONSEESHADOWDOMHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBWEBCOMPONENTSSHADOWDOMONTHEMDNHTTPS:DEVELOPERMOZILLAORGSITETOATTACHASHADOWDOMTOTHECOMPONENTSHOSTELEMENTANDTHENPUTSTHECOMPONENTVIEWINSIDETHATSHADOWDOMTHECOMPONENTSSTYLESAREINCLUDEDWITHINTHESHADOWDOM", "original": "* `Native` view encapsulation uses the browser's native shadow DOM implementation (see\n [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)\n on the [MDN](https://developer.mozilla.org) site)\n to attach a shadow DOM to the component's host element, and then puts the component\n view inside that shadow DOM. The component's styles are included within the shadow DOM.", "translation": "`Native` 模式使用浏览器原生的 [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)\n 实现来为组件的宿主元素附加一个 Shadow DOM。组件的样式被包裹在这个 Shadow DOM 中。(译注:不进不出,没有样式能进来,组件样式出不去。)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "EMULATEDVIEWENCAPSULATIONTHEDEFAULTEMULATESTHEBEHAVIOROFSHADOWDOMBYPREPROCESSINGANDRENAMINGTHECSSCODETOEFFECTIVELYSCOPETHECSSTOTHECOMPONENTSVIEWFORDETAILSSEEAPPENDIX1GUIDECOMPONENTSTYLES#INSPECTGENERATEDCSS", "original": "* `Emulated` view encapsulation (the default) emulates the behavior of shadow DOM by preprocessing\n (and renaming) the CSS code to effectively scope the CSS to the component's view.\n For details, see [Appendix 1](guide/component-styles#inspect-generated-css).", "translation": "`Emulated` 模式(**默认值**)通过预处理(并改名)CSS 代码来模拟 Shadow DOM 的行为,以达到把 CSS 样式局限在组件视图中的目的。\n 更多信息,见[附录 1](guide/component-styles#inspect-generated-css) 。(译注:只进不出,全局样式能进来,组件样式出不去)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "NONEMEANSTHATANGULARDOESNOVIEWENCAPSULATIONANGULARADDSTHECSSTOTHEGLOBALSTYLESTHESCOPINGRULESISOLATIONSANDPROTECTIONSDISCUSSEDEARLIERDONTAPPLYTHISISESSENTIALLYTHESAMEASPASTINGTHECOMPONENTSSTYLESINTOTHEHTML", "original": "* `None` means that Angular does no view encapsulation.\n Angular adds the CSS to the global styles.\n The scoping rules, isolations, and protections discussed earlier don't apply.\n This is essentially the same as pasting the component's styles into the HTML.", "translation": "`None` 意味着 Angular 不使用视图封装。\n Angular 会把 CSS 添加到全局样式中。而不会应用上前面讨论过的那些作用域规则、隔离和保护等。\n 从本质上来说,这跟把组件的样式直接放进 HTML 是一样的。(译注:能进能出。)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "TOSETTHECOMPONENTSENCAPSULATIONMODEUSETHEENCAPSULATIONPROPERTYINTHECOMPONENTMETADATA:", "original": "To set the components encapsulation mode, use the `encapsulation` property in the component metadata:", "translation": "通过组件元数据中的 `encapsulation` 属性来设置组件封装模式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "NATIVEVIEWENCAPSULATIONONLYWORKSONBROWSERSTHATHAVENATIVESUPPORTFORSHADOWDOMSEESHADOWDOMV0HTTP:CANIUSECOM#FEATSHADOWDOMONTHECANIUSEHTTP:CANIUSECOMSITETHESUPPORTISSTILLLIMITEDWHICHISWHYEMULATEDVIEWENCAPSULATIONISTHEDEFAULTMODEANDRECOMMENDEDINMOSTCASES", "original": "`Native` view encapsulation only works on browsers that have native support\nfor shadow DOM (see [Shadow DOM v0](http://caniuse.com/#feat=shadowdom) on the\n[Can I use](http://caniuse.com) site). The support is still limited,\nwhich is why `Emulated` view encapsulation is the default mode and recommended\nin most cases.", "translation": "原生(`Native`)模式只适用于[有原生 Shadow DOM 支持的浏览器](http://caniuse.com/#feat=shadowdom)。\n因此仍然受到很多限制,这就是为什么仿真 (`Emulated`) 模式是默认选项,并建议将其用于大多数情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "##INSPECTINGGENERATEDCSS", "original": "## Inspecting generated CSS", "translation": "## 查看仿真 (Emulated) 模式下生成的 CSS", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "WHENUSINGEMULATEDVIEWENCAPSULATIONANGULARPREPROCESSESALLCOMPONENTSTYLESSOTHATTHEYAPPROXIMATETHESTANDARDSHADOWCSSSCOPINGRULES", "original": "When using emulated view encapsulation, Angular preprocesses\nall component styles so that they approximate the standard shadow CSS scoping rules.", "translation": "当使用默认的仿真模式时,Angular 会对组件的所有样式进行预处理,让它们模仿出标准的 Shadow CSS 作用域规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "INTHEDOMOFARUNNINGANGULARAPPLICATIONWITHEMULATEDVIEWENCAPSULATIONENABLEDEACHDOMELEMENTHASSOMEEXTRAATTRIBUTESATTACHEDTOIT:", "original": "In the DOM of a running Angular application with emulated view\nencapsulation enabled, each DOM element has some extra attributes\nattached to it:", "translation": "在启用了仿真模式的 Angular 应用的 DOM 树中,每个 DOM 元素都被加上了一些额外的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THEREARETWOKINDSOFGENERATEDATTRIBUTES:", "original": "There are two kinds of generated attributes:", "translation": "生成出的属性分为两种:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "ANELEMENTTHATWOULDBEASHADOWDOMHOSTINNATIVEENCAPSULATIONHASAGENERATEDNGHOSTATTRIBUTETHISISTYPICALLYTHECASEFORCOMPONENTHOSTELEMENTS", "original": "* An element that would be a shadow DOM host in native encapsulation has a\n generated `_nghost` attribute. This is typically the case for component host elements.", "translation": "一个元素在原生封装方式下可能是 Shadow DOM 的宿主,在这里被自动添加上一个 `_nghost` 属性。\n 这是组件宿主元素的典型情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "ANELEMENTWITHINACOMPONENTSVIEWHASANGCONTENTATTRIBUTETHATIDENTIFIESTOWHICHHOSTSEMULATEDSHADOWDOMTHISELEMENTBELONGS", "original": "* An element within a component's view has a `_ngcontent` attribute\nthat identifies to which host's emulated shadow DOM this element belongs.", "translation": "组件视图中的每一个元素,都有一个 `_ngcontent` 属性,它会标记出该元素是哪个宿主的模拟 Shadow DOM。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THEEXACTVALUESOFTHESEATTRIBUTESARENTIMPORTANTTHEYAREAUTOMATICALLYGENERATEDANDYOUNEVERREFERTOTHEMINAPPLICATIONCODEBUTTHEYARETARGETEDBYTHEGENERATEDCOMPONENTSTYLESWHICHAREINTHEHEADSECTIONOFTHEDOM:", "original": "The exact values of these attributes aren't important. They are automatically\ngenerated and you never refer to them in application code. But they are targeted\nby the generated component styles, which are in the `<head>` section of the DOM:", "translation": "这些属性的具体值并不重要。它们是自动生成的,并且你永远不会在程序代码中直接引用到它们。\n但它们会作为生成的组件样式的目标,就像 DOM 的 `<head>` 中一样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "THESESTYLESAREPOSTPROCESSEDSOTHATEACHSELECTORISAUGMENTEDWITHNGHOSTORNGCONTENTATTRIBUTESELECTORSTHESEEXTRASELECTORSENABLETHESCOPINGRULESDESCRIBEDINTHISPAGE", "original": "These styles are post-processed so that each selector is augmented\nwith `_nghost` or `_ngcontent` attribute selectors.\nThese extra selectors enable the scoping rules described in this page.", "translation": "这些就是那些样式被处理后的结果,每个选择器都被增加了 `_nghost` 或 `_ngcontent` 属性选择器。\n这些额外的选择器实现了本文所描述的这些作用域规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/component-styles.md" }, { + "key": "##OVERVIEW", + "original": "## Overview", + "translation": "## 概览", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/custom-elements.md" + }, + { + "key": "#DEPENDENCYINJECTION", "original": "# Dependency Injection", "translation": "# 依赖注入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "DEPENDENCYINJECTIONISAPOWERFULPATTERNFORMANAGINGCODEDEPENDENCIESTHISCOOKBOOKEXPLORESMANYOFTHEFEATURESOFDEPENDENCYINJECTIONDIINANGULAR", "original": "Dependency Injection is a powerful pattern for managing code dependencies.\nThis cookbook explores many of the features of Dependency Injection (DI) in Angular.", "translation": "依赖注入是一个用来管理代码依赖的强大模式。本文会讨论 Angular 依赖注入的许多特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "SEETHELIVEEXAMPLENAMEDEPENDENCYINJECTIONINACTIONLIVEEXAMPLEOFTHECODEINTHISCOOKBOOK", "original": "See the <live-example name=\"dependency-injection-in-action\"></live-example>\nof the code in this cookbook.", "translation": "要获取本“烹饪宝典”的代码,**参见<live-example name=\"dependency-injection-in-action\"></live-example>**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##APPLICATIONWIDEDEPENDENCIES", "original": "## Application-wide dependencies", "translation": "## 应用程序全局依赖", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "REGISTERPROVIDERSFORDEPENDENCIESUSEDTHROUGHOUTTHEAPPLICATIONINTHEROOTAPPLICATIONCOMPONENTAPPCOMPONENT", "original": "Register providers for dependencies used throughout the application in the root application component, `AppComponent`.", "translation": "在应用程序根组件 `AppComponent` 中注册那些被应用程序全局使用的依赖提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEFOLLOWINGEXAMPLESHOWSIMPORTINGANDREGISTERINGTHELOGGERSERVICEUSERCONTEXTANDTHEUSERSERVICEINTHECOMPONENTMETADATAPROVIDERSARRAY", "original": "The following example shows importing and registering\nthe `LoggerService`, `UserContext`, and the `UserService`\nin the `@Component` metadata `providers` array.", "translation": "在下面的例子中,通过 `@Component` 元数据的 `providers` 数组导入和注册了几个服务(`LoggerService`, `UserContext` 和 `UserService`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ALLOFTHESESERVICESAREIMPLEMENTEDASCLASSESSERVICECLASSESCANACTASTHEIROWNPROVIDERSWHICHISWHYLISTINGTHEMINTHEPROVIDERSARRAYISALLTHEREGISTRATIONYOUNEED", "original": "All of these services are implemented as classes.\nService classes can act as their own providers which is why listing them in the `providers` array\nis all the registration you need.", "translation": "所有这些服务都是用类实现的。服务类能充当自己的提供商,这就是为什么只要把它们列在 `providers` 数组里就算注册成功了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "APROVIDERISSOMETHINGTHATCANCREATEORDELIVERASERVICEANGULARCREATESASERVICEINSTANCEFROMACLASSPROVIDERBYUSINGNEWREADMOREABOUTPROVIDERSINTHEDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTION#REGISTERPROVIDERSNGMODULEGUIDE", "original": "A *provider* is something that can create or deliver a service.\nAngular creates a service instance from a class provider by using `new`.\nRead more about providers in the [Dependency Injection](guide/dependency-injection#register-providers-ngmodule)\nguide.", "translation": "*提供商*是用来新建或者交付服务的。\nAngular 拿到“类提供商”之后,会通过 `new` 操作来新建服务实例。\n从[依赖注入](guide/dependency-injection#register-providers-ngmodule)一章可以学到关于提供商的更多知识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NOWTHATYOUVEREGISTEREDTHESESERVICESANGULARCANINJECTTHEMINTOTHECONSTRUCTOROFANYCOMPONENTORSERVICEANYWHEREINTHEAPPLICATION", "original": "Now that you've registered these services,\nAngular can inject them into the constructor of *any* component or service, *anywhere* in the application.", "translation": "现在你已经注册了这些服务,这样 Angular 就能在应用程序的*任何地方*,把它们注入到*任何*组件和服务的构造函数里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##EXTERNALMODULECONFIGURATION", "original": "## External module configuration", "translation": "## 外部模块配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "GENERALLYREGISTERPROVIDERSINTHENGMODULERATHERTHANINTHEROOTAPPLICATIONCOMPONENT", "original": "Generally, register providers in the `NgModule` rather than in the root application component.", "translation": "通常会在 `NgModule` 中注册提供商,而不是在应用程序根组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "DOTHISWHENYOUEXPECTTHESERVICETOBEINJECTABLEEVERYWHEREORYOUARECONFIGURINGANOTHERAPPLICATIONGLOBALSERVICEBEFORETHEAPPLICATIONSTARTS", "original": "Do this when you expect the service to be injectable everywhere,\nor you are configuring another application global service _before the application starts_.", "translation": "如果你希望这个服务在应用中到处都可以被注入,或者必须在应用**启动前**注册一个全局服务,那就这么做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "HEREISANEXAMPLEOFTHESECONDCASEWHERETHECOMPONENTROUTERCONFIGURATIONINCLUDESANONDEFAULTLOCATIONSTRATEGYGUIDEROUTER#LOCATIONSTRATEGYBYLISTINGITSPROVIDERINTHEPROVIDERSLISTOFTHEAPPMODULE", "original": "Here is an example of the second case, where the component router configuration includes a non-default\n[location strategy](guide/router#location-strategy) by listing its provider\nin the `providers` list of the `AppModule`.", "translation": "下面的例子是第二种情况,它为组件路由器配置了一个非默认的[地址策略(location strategy)](guide/router#location-strategy),并把它加入到 `AppModule` 的 `providers` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##INJECTABLEANDNESTEDSERVICEDEPENDENCIES", "original": "## _@Injectable()_ and nested service dependencies", "translation": "## *@Injectable*和嵌套服务依赖", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THECONSUMEROFANINJECTEDSERVICEDOESNOTKNOWHOWTOCREATETHATSERVICEITSHOULDNTCAREITSTHEDEPENDENCYINJECTIONSJOBTOCREATEANDCACHETHATSERVICE", "original": "The consumer of an injected service does not know how to create that service.\nIt shouldn't care.\nIt's the dependency injection's job to create and cache that service.", "translation": "这些被注入服务的消费者不需要知道如何创建这个服务,它也不应该在乎。新建和缓存这个服务是依赖注入器的工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "SOMETIMESASERVICEDEPENDSONOTHERSERVICESWHICHMAYDEPENDONYETOTHERSERVICESRESOLVINGTHESENESTEDDEPENDENCIESINTHECORRECTORDERISALSOTHEFRAMEWORKSJOBATEACHSTEPTHECONSUMEROFDEPENDENCIESSIMPLYDECLARESWHATITREQUIRESINITSCONSTRUCTORANDTHEFRAMEWORKTAKESOVER", "original": "Sometimes a service depends on other services, which may depend on yet other services.\nResolving these nested dependencies in the correct order is also the framework's job.\nAt each step, the consumer of dependencies simply declares what it requires in its\nconstructor and the framework takes over.", "translation": "有时候一个服务依赖其它服务...而其它服务可能依赖另外的更多服务。按正确的顺序解析这些嵌套依赖也是框架的工作。\n在每一步,依赖的使用者只要在它的构造函数里简单声明它需要什么,框架就会完成所有剩下的事情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEFOLLOWINGEXAMPLESHOWSINJECTINGBOTHTHELOGGERSERVICEANDTHEUSERCONTEXTINTHEAPPCOMPONENT", "original": "The following example shows injecting both the `LoggerService` and the `UserContext` in the `AppComponent`.", "translation": "下面的例子往 `AppComponent` 里注入的 `LoggerService` 和 `UserContext`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEUSERCONTEXTINTURNHASITSOWNDEPENDENCIESONBOTHTHELOGGERSERVICEANDAUSERSERVICETHATGATHERSINFORMATIONABOUTAPARTICULARUSER", "original": "The `UserContext` in turn has its own dependencies on both the `LoggerService` and\na `UserService` that gathers information about a particular user.", "translation": "`UserContext` 有两个依赖 `LoggerService`(再一次)和负责获取特定用户信息的 `UserService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "WHENANGULARCREATESTHEAPPCOMPONENTTHEDEPENDENCYINJECTIONFRAMEWORKCREATESANINSTANCEOFTHELOGGERSERVICEANDSTARTSTOCREATETHEUSERCONTEXTSERVICETHEUSERCONTEXTSERVICENEEDSTHELOGGERSERVICEWHICHTHEFRAMEWORKALREADYHASANDTHEUSERSERVICEWHICHITHASYETTOCREATETHEUSERSERVICEHASNODEPENDENCIESSOTHEDEPENDENCYINJECTIONFRAMEWORKCANJUSTUSENEWTOINSTANTIATEONE", "original": "When Angular creates the `AppComponent`, the dependency injection framework creates an instance of the `LoggerService` and\nstarts to create the `UserContextService`.\nThe `UserContextService` needs the `LoggerService`, which the framework already has, and the `UserService`, which it has yet to create.\nThe `UserService` has no dependencies so the dependency injection framework can just\nuse `new` to instantiate one.", "translation": "当 Angular 新建 `AppComponent` 时,依赖注入框架先创建一个 `LoggerService` 的实例,然后创建 `UserContextService` 实例。\n`UserContextService` 需要框架已经创建好的 `LoggerService` 实例和尚未创建的 `UserService` 实例。\n`UserService` 没有其它依赖,所以依赖注入框架可以直接 `new` 一个实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEBEAUTYOFDEPENDENCYINJECTIONISTHATAPPCOMPONENTDOESNTCAREABOUTANYOFTHISYOUSIMPLYDECLAREWHATISNEEDEDINTHECONSTRUCTORLOGGERSERVICEANDUSERCONTEXTSERVICEANDTHEFRAMEWORKDOESTHEREST", "original": "The beauty of dependency injection is that `AppComponent` doesn't care about any of this.\nYou simply declare what is needed in the constructor (`LoggerService` and `UserContextService`)\nand the framework does the rest.", "translation": "依赖注入最帅的地方在于,`AppComponent` 的作者不需要在乎这一切。作者只是在(`LoggerService` 和 `UserContextService` 的)构造函数里面简单的声明一下,框架就完成了剩下的工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ONCEALLTHEDEPENDENCIESAREINPLACETHEAPPCOMPONENTDISPLAYSTHEUSERINFORMATION:", "original": "Once all the dependencies are in place, the `AppComponent` displays the user information:", "translation": "一旦所有依赖都准备好了,`AppComponent` 就会显示用户信息:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###INJECTABLE", "original": "### *@Injectable()*", "translation": "### *@Injectable()* 注解", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NOTICETHEINJECTABLEDECORATORONTHEUSERCONTEXTSERVICECLASS", "original": "Notice the `@Injectable()`decorator on the `UserContextService` class.", "translation": "注意在 `UserContextService` 类里面的 `@Injectable()` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THATDECORATORMAKESITPOSSIBLEFORANGULARTOIDENTIFYTHETYPESOFITSTWODEPENDENCIESLOGGERSERVICEANDUSERSERVICE", "original": "That decorator makes it possible for Angular to identify the types of its two dependencies, `LoggerService` and `UserService`.", "translation": "该装饰器让 Angular 有能力识别这两个依赖 `LoggerService` 和 `UserService` 的类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "TECHNICALLYTHEINJECTABLEDECORATORISONLYREQUIREDFORASERVICECLASSTHATHASITSOWNDEPENDENCIESTHELOGGERSERVICEDOESNTDEPENDONANYTHINGTHELOGGERWOULDWORKIFYOUOMITTEDINJECTABLEANDTHEGENERATEDCODEWOULDBESLIGHTLYSMALLER", "original": "Technically, the `@Injectable()`decorator is only required for a service class that has _its own dependencies_.\nThe `LoggerService` doesn't depend on anything. The logger would work if you omitted `@Injectable()`\nand the generated code would be slightly smaller.", "translation": "严格来说,这个 `@Injectable()` 装饰器只在一个服务类有*自己的依赖*的时候,才是*不可缺少*的。\n`LoggerService` 不依赖任何东西,所以该日志服务在没有 `@Injectable()` 的时候应该也能工作,生成的代码也更少一些。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "BUTTHESERVICEWOULDBREAKTHEMOMENTYOUGAVEITADEPENDENCYANDYOUDHAVETOGOBACKANDADDINJECTABLETOFIXITADDINJECTABLEFROMTHESTARTFORTHESAKEOFCONSISTENCYANDTOAVOIDFUTUREPAIN", "original": "But the service would break the moment you gave it a dependency and you'd have to go back\nand add `@Injectable()` to fix it. Add `@Injectable()` from the start for the sake\nof consistency and to avoid future pain.", "translation": "但是在给它添加依赖的那一瞬间,该服务就会停止工作,要想修复它,就必须要添加 `@Injectable()`。\n为了保持一致性和防止将来的麻烦,推荐从一开始就加上 `@Injectable()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ALTHOUGHTHISSITERECOMMENDSAPPLYINGINJECTABLETOALLSERVICECLASSESDONTFEELBOUNDBYITSOMEDEVELOPERSPREFERTOADDITONLYWHERENEEDEDANDTHATSAREASONABLEPOLICYTOO", "original": "Although this site recommends applying `@Injectable()` to all service classes, don't feel bound by it.\nSome developers prefer to add it only where needed and that's a reasonable policy too.", "translation": "虽然推荐在所有服务中使用 `@Injectable()`,但你也不需要一定要这么做。一些开发者就更喜欢在真正需要的地方才添加,这也是一个合理的策略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEAPPCOMPONENTCLASSHADTWODEPENDENCIESASWELLBUTNOINJECTABLEITDIDNTNEEDINJECTABLEBECAUSETHATCOMPONENTCLASSHASTHECOMPONENTDECORATORINANGULARWITHTYPESCRIPTASINGLEDECORATORMDASHANYDECORATORMDASHISSUFFICIENTTOIDENTIFYDEPENDENCYTYPES", "original": "The `AppComponent` class had two dependencies as well but no `@Injectable()`.\nIt didn't need `@Injectable()` because that component class has the `@Component` decorator.\nIn Angular with TypeScript, a *single* decorator—*any* decorator—is sufficient to identify dependency types.", "translation": "`AppComponent` 类有两个依赖,但它没有 `@Injectable()`。\n它不需要 `@Injectable()`,这是因为组件类有 `@Component` 装饰器。\n在用 TypeScript 的 Angular 应用里,有一个*单独的*装饰器 — *任何*装饰器 — 来标识依赖的类型就够了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##LIMITSERVICESCOPETOACOMPONENTSUBTREE", "original": "## Limit service scope to a component subtree", "translation": "## 把服务作用域限制到一个组件支树", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ALLINJECTEDSERVICEDEPENDENCIESARESINGLETONSMEANINGTHATFORAGIVENDEPENDENCYINJECTORTHEREISONLYONEINSTANCEOFSERVICE", "original": "All injected service dependencies are singletons meaning that,\nfor a given dependency injector, there is only one instance of service.", "translation": "所有被注入的服务依赖都是单例的,也就是说,在任意一个依赖注入器(\"injector\")中,每个服务只有唯一的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "BUTANANGULARAPPLICATIONHASMULTIPLEDEPENDENCYINJECTORSARRANGEDINATREEHIERARCHYTHATPARALLELSTHECOMPONENTTREESOAPARTICULARSERVICECANBEPROVIDEDANDCREATEDATANYCOMPONENTLEVELANDMULTIPLETIMESIFPROVIDEDINMULTIPLECOMPONENTS", "original": "But an Angular application has multiple dependency injectors, arranged in a tree hierarchy that parallels the component tree.\nSo a particular service can be *provided* and created at any component level and multiple times\nif provided in multiple components.", "translation": "但是 Angular 应用程序有多个依赖注入器,组织成一个与组件树平行的树状结构。所以,可以在任何组件级别*提供*(和建立)特定的服务。如果在多个组件中注入,服务就会被新建出多个实例,分别提供给不同的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "BYDEFAULTASERVICEDEPENDENCYPROVIDEDINONECOMPONENTISVISIBLETOALLOFITSCHILDCOMPONENTSANDANGULARINJECTSTHESAMESERVICEINSTANCEINTOALLCHILDCOMPONENTSTHATASKFORTHATSERVICE", "original": "By default, a service dependency provided in one component is visible to all of its child components and\nAngular injects the same service instance into all child components that ask for that service.", "translation": "默认情况下,一个组件中注入的服务依赖,会在该组件的所有子组件中可见,而且 Angular 会把同样的服务实例注入到需要该服务的子组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ACCORDINGLYDEPENDENCIESPROVIDEDINTHEROOTAPPCOMPONENTCANBEINJECTEDINTOANYCOMPONENTANYWHEREINTHEAPPLICATION", "original": "Accordingly, dependencies provided in the root `AppComponent` can be injected into *any* component *anywhere* in the application.", "translation": "所以,在根部的 `AppComponent` 提供的依赖单例就能被注入到应用程序中*任何地方*的*任何*组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THATISNTALWAYSDESIRABLESOMETIMESYOUWANTTORESTRICTSERVICEAVAILABILITYTOAPARTICULARREGIONOFTHEAPPLICATION", "original": "That isn't always desirable.\nSometimes you want to restrict service availability to a particular region of the application.", "translation": "但这不一定总是想要的。有时候你想要把服务的有效性限制到应用程序的一个特定区域。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUCANLIMITTHESCOPEOFANINJECTEDSERVICETOABRANCHOFTHEAPPLICATIONHIERARCHYBYPROVIDINGTHATSERVICEATTHESUBROOTCOMPONENTFORTHATBRANCHTHISEXAMPLESHOWSHOWSIMILARPROVIDINGASERVICETOASUBROOTCOMPONENTISTOPROVIDINGASERVICEINTHEROOTAPPCOMPONENTTHESYNTAXISTHESAMEHERETHEHEROSERVICEISAVAILABLETOTHEHEROESBASECOMPONENTBECAUSEITISINTHEPROVIDERSARRAY:", "original": "You can limit the scope of an injected service to a *branch* of the application hierarchy\nby providing that service *at the sub-root component for that branch*.\nThis example shows how similar providing a service to a sub-root component is\nto providing a service in the root `AppComponent`. The syntax is the same.\nHere, the `HeroService` is available to the `HeroesBaseComponent` because it is in the `providers` array:", "translation": "通过*在组件树的子级根组件*中提供服务,可以把一个被注入服务的作用域局限在应用程序结构中的某个*分支*中。\n这个例子中展示了为子组件和根组件 `AppComponent` 提供服务的相似之处,它们的语法是相同的。\n这里通过列入 `providers` 数组,在 `HeroesBaseComponent` 中提供了 `HeroService`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "WHENANGULARCREATESTHEHEROESBASECOMPONENTITALSOCREATESANEWINSTANCEOFHEROSERVICETHATISVISIBLEONLYTOTHECOMPONENTANDITSCHILDRENIFANY", "original": "When Angular creates the `HeroesBaseComponent`, it also creates a new instance of `HeroService`\nthat is visible only to the component and its children, if any.", "translation": "当 Angular 新建 `HeroBaseComponent` 的时候,它会同时新建一个 `HeroService` 实例,该实例只在该组件及其子组件(如果有)中可见。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUCOULDALSOPROVIDETHEHEROSERVICETOADIFFERENTCOMPONENTELSEWHEREINTHEAPPLICATIONTHATWOULDRESULTINADIFFERENTINSTANCEOFTHESERVICELIVINGINADIFFERENTINJECTOR", "original": "You could also provide the `HeroService` to a *different* component elsewhere in the application.\nThat would result in a *different* instance of the service, living in a *different* injector.", "translation": "也可以在应用程序别处的*不同的*组件里提供 `HeroService`。这样就会导致在*不同*注入器中存在该服务的*不同*实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "EXAMPLESOFSUCHSCOPEDHEROSERVICESINGLETONSAPPEARTHROUGHOUTTHEACCOMPANYINGSAMPLECODEINCLUDINGTHEHEROBIOSCOMPONENTHEROOFTHEMONTHCOMPONENTANDHEROESBASECOMPONENTEACHOFTHESECOMPONENTSHASITSOWNHEROSERVICEINSTANCEMANAGINGITSOWNINDEPENDENTCOLLECTIONOFHEROES", "original": "Examples of such scoped `HeroService` singletons appear throughout the accompanying sample code,\nincluding the `HeroBiosComponent`, `HeroOfTheMonthComponent`, and `HeroesBaseComponent`.\nEach of these components has its own `HeroService` instance managing its own independent collection of heroes.", "translation": "这个例子中,局部化的 `HeroService` 单例,遍布整份范例代码,包括 `HeroBiosComponent`、`HeroOfTheMonthComponent` 和 `HeroBaseComponent`。\n这些组件每个都有自己的 `HeroService` 实例,用来管理独立的英雄库。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###TAKEABREAK", "original": "### Take a break!", "translation": "### 休息一下!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THISMUCHDEPENDENCYINJECTIONKNOWLEDGEMAYBEALLTHATMANYANGULARDEVELOPERSEVERNEEDTOBUILDTHEIRAPPLICATIONSITDOESNTALWAYSHAVETOBEMORECOMPLICATED", "original": "This much Dependency Injection knowledge may be all that many Angular developers\never need to build their applications. It doesn't always have to be more complicated.", "translation": "对一些 Angular 开发者来说,这么多依赖注入知识可能已经是它们需要知道的全部了。不是每个人都需要更复杂的用法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##MULTIPLESERVICEINSTANCESSANDBOXING", "original": "## Multiple service instances (sandboxing)", "translation": "## 多个服务实例(sandboxing)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "SOMETIMESYOUWANTMULTIPLEINSTANCESOFASERVICEATTHESAMELEVELOFTHECOMPONENTHIERARCHY", "original": "Sometimes you want multiple instances of a service at *the same level of the component hierarchy*.", "translation": "在*同一个级别的组件树*里,有时需要一个服务的多个实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "AGOODEXAMPLEISASERVICETHATHOLDSSTATEFORITSCOMPANIONCOMPONENTINSTANCEYOUNEEDASEPARATEINSTANCEOFTHESERVICEFOREACHCOMPONENTEACHSERVICEHASITSOWNWORKSTATEISOLATEDFROMTHESERVICEANDSTATEOFADIFFERENTCOMPONENTTHISISCALLEDSANDBOXINGBECAUSEEACHSERVICEANDCOMPONENTINSTANCEHASITSOWNSANDBOXTOPLAYIN", "original": "A good example is a service that holds state for its companion component instance.\nYou need a separate instance of the service for each component.\nEach service has its own work-state, isolated from the service-and-state of a different component.\nThis is called *sandboxing* because each service and component instance has its own sandbox to play in.", "translation": "一个用来保存其伴生组件的实例状态的服务就是个好例子。\n每个组件都需要该服务的单独实例。\n每个服务有自己的工作状态,与其它组件的服务和状态隔离。这叫做*沙箱化*,因为每个服务和组件实例都在自己的沙箱里运行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "IMAGINEAHEROBIOSCOMPONENTTHATPRESENTSTHREEINSTANCESOFTHEHEROBIOCOMPONENT", "original": "Imagine a `HeroBiosComponent` that presents three instances of the `HeroBioComponent`.", "translation": "想象一下,一个 `HeroBiosComponent` 组件显示三个 `HeroBioComponent` 的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "EACHHEROBIOCOMPONENTCANEDITASINGLEHEROSBIOGRAPHYAHEROBIOCOMPONENTRELIESONAHEROCACHESERVICETOFETCHCACHEANDPERFORMOTHERPERSISTENCEOPERATIONSONTHATHERO", "original": "Each `HeroBioComponent` can edit a single hero's biography.\nA `HeroBioComponent` relies on a `HeroCacheService` to fetch, cache, and perform other persistence operations on that hero.", "translation": "每个 `HeroBioComponent` 都能编辑一个英雄的生平。`HeroBioComponent` 依赖 `HeroCacheService` 服务来对该英雄进行读取、缓存和执行其它持久化操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "CLEARLYTHETHREEINSTANCESOFTHEHEROBIOCOMPONENTCANTSHARETHESAMEHEROCACHESERVICETHEYDBECOMPETINGWITHEACHOTHERTODETERMINEWHICHHEROTOCACHE", "original": "Clearly the three instances of the `HeroBioComponent` can't share the same `HeroCacheService`.\nThey'd be competing with each other to determine which hero to cache.", "translation": "很明显,这三个 `HeroBioComponent` 实例不能共享一样的 `HeroCacheService`。要不然它们会相互冲突,争相把自己的英雄放在缓存里面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "EACHHEROBIOCOMPONENTGETSITSOWNHEROCACHESERVICEINSTANCEBYLISTINGTHEHEROCACHESERVICEINITSMETADATAPROVIDERSARRAY", "original": "Each `HeroBioComponent` gets its *own* `HeroCacheService` instance\nby listing the `HeroCacheService` in its metadata `providers` array.", "translation": "通过在自己的元数据(metadata)`providers` 数组里面列出 `HeroCacheService`, 每个 `HeroBioComponent` 就能*拥有*自己独立的 `HeroCacheService` 实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEPARENTHEROBIOSCOMPONENTBINDSAVALUETOTHEHEROIDTHENGONINITPASSESTHATIDTOTHESERVICEWHICHFETCHESANDCACHESTHEHEROTHEGETTERFORTHEHEROPROPERTYPULLSTHECACHEDHEROFROMTHESERVICEANDTHETEMPLATEDISPLAYSTHISDATABOUNDPROPERTY", "original": "The parent `HeroBiosComponent` binds a value to the `heroId`.\nThe `ngOnInit` passes that `id` to the service, which fetches and caches the hero.\nThe getter for the `hero` property pulls the cached hero from the service.\nAnd the template displays this data-bound property.", "translation": "父组件 `HeroBiosComponent` 把一个值绑定到 `heroId`。`ngOnInit` 把该 `id` 传递到服务,然后服务获取和缓存英雄。`hero` 属性的 getter 从服务里面获取缓存的英雄,并在模板里显示它绑定到属性值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "FINDTHISEXAMPLEINLIVEEXAMPLENAMEDEPENDENCYINJECTIONINACTIONLIVECODELIVEEXAMPLEANDCONFIRMTHATTHETHREEHEROBIOCOMPONENTINSTANCESHAVETHEIROWNCACHEDHERODATA", "original": "Find this example in <live-example name=\"dependency-injection-in-action\">live code</live-example>\nand confirm that the three `HeroBioComponent` instances have their own cached hero data.", "translation": "到<live-example name=\"dependency-injection-in-action\">在线例子</live-example>中找到这个例子,确认三个 `HeroBioComponent` 实例拥有自己独立的英雄数据缓存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##QUALIFYDEPENDENCYLOOKUPWITHOPTIONALANDHOST", "original": "## Qualify dependency lookup with _@Optional()_ and `@Host()`", "translation": "## 使用*@Optional()*和 `@Host()` 装饰器来限定依赖查找方式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ASYOUNOWKNOWDEPENDENCIESCANBEREGISTEREDATANYLEVELINTHECOMPONENTHIERARCHY", "original": "As you now know, dependencies can be registered at any level in the component hierarchy.", "translation": "你知道,依赖可以被注入到任何组件级别。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "WHENACOMPONENTREQUESTSADEPENDENCYANGULARSTARTSWITHTHATCOMPONENTSINJECTORANDWALKSUPTHEINJECTORTREEUNTILITFINDSTHEFIRSTSUITABLEPROVIDERANGULARTHROWSANERRORIFITCANTFINDTHEDEPENDENCYDURINGTHATWALK", "original": "When a component requests a dependency, Angular starts with that component's injector and walks up the injector tree\nuntil it finds the first suitable provider. Angular throws an error if it can't find the dependency during that walk.", "translation": "当组件申请一个依赖时,Angular 从该组件本身的注入器开始,沿着依赖注入器的树往上找,直到找到第一个符合要求的提供商。如果 Angular 不能在这个过程中找到合适的依赖,它就会抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUWANTTHISBEHAVIORMOSTOFTHETIMEBUTSOMETIMESYOUNEEDTOLIMITTHESEARCHANDORACCOMMODATEAMISSINGDEPENDENCYYOUCANMODIFYANGULARSSEARCHBEHAVIORWITHTHEHOSTANDOPTIONALQUALIFYINGDECORATORSUSEDINDIVIDUALLYORTOGETHER", "original": "You *want* this behavior most of the time.\nBut sometimes you need to limit the search and/or accommodate a missing dependency.\nYou can modify Angular's search behavior with the `@Host` and `@Optional` qualifying decorators,\nused individually or together.", "translation": "大部分时候,你确实*想要*这个行为。\n但是有时候,需要限制这个(依赖)查找逻辑,且/或提供一个缺失的依赖。\n单独或联合使用 `@Host` 和 `@Optional` 限定型装饰器,就可以修改 Angular 的查找行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEOPTIONALDECORATORTELLSANGULARTOCONTINUEWHENITCANTFINDTHEDEPENDENCYANGULARSETSTHEINJECTIONPARAMETERTONULLINSTEAD", "original": "The `@Optional` decorator tells Angular to continue when it can't find the dependency.\nAngular sets the injection parameter to `null` instead.", "translation": "当 Angular 找不到依赖时,`@Optional` 装饰器会告诉 Angular 继续执行。Angular 把此注入参数设置为 `null`(而不用默认的抛出错误的行为)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHOSTDECORATORSTOPSTHEUPWARDSEARCHATTHEHOSTCOMPONENT", "original": "The `@Host` decorator stops the upward search at the *host component*.", "translation": "`@Host` 装饰器将把往上搜索的行为截止在*宿主组件*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHOSTCOMPONENTISTYPICALLYTHECOMPONENTREQUESTINGTHEDEPENDENCYBUTWHENTHISCOMPONENTISPROJECTEDINTOAPARENTCOMPONENTTHATPARENTCOMPONENTBECOMESTHEHOSTTHENEXTEXAMPLECOVERSTHISSECONDCASE", "original": "The host component is typically the component requesting the dependency.\nBut when this component is projected into a *parent* component, that parent component becomes the host.\nThe next example covers this second case.", "translation": "宿主组件通常是申请这个依赖的组件。但当这个组件被投影(projected)进一个*父组件*后,这个父组件就变成了宿主。\n下一个例子会演示第二种情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###DEMONSTRATION", "original": "### Demonstration", "translation": "### 示范", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHEROBIOSANDCONTACTSCOMPONENTISAREVISIONOFTHEHEROBIOSCOMPONENTTHATYOULOOKEDATABOVEGUIDEDEPENDENCYINJECTIONINACTION#HEROBIOSCOMPONENT", "original": "The `HeroBiosAndContactsComponent` is a revision of the `HeroBiosComponent` that you looked at [above](guide/dependency-injection-in-action#hero-bios-component).", "translation": "`HeroBiosAndContactsComponent` 是[前面](guide/dependency-injection-in-action#hero-bios-component)见过的 `HeroBiosComponent` 的修改版。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "FOCUSONTHETEMPLATE:", "original": "Focus on the template:", "translation": "注意看模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NOWTHEREISANEWHEROCONTACTELEMENTBETWEENTHEHEROBIOTAGSANGULARPROJECTSORTRANSCLUDESTHECORRESPONDINGHEROCONTACTCOMPONENTINTOTHEHEROBIOCOMPONENTVIEWPLACINGITINTHENGCONTENTSLOTOFTHEHEROBIOCOMPONENTTEMPLATE:", "original": "Now there is a new `<hero-contact>` element between the `<hero-bio>` tags.\nAngular *projects*, or *transcludes*, the corresponding `HeroContactComponent` into the `HeroBioComponent` view,\nplacing it in the `<ng-content>` slot of the `HeroBioComponent` template:", "translation": "在 `<hero-bio>` 标签中是一个新的 `<hero-contact>` 元素。Angular 就会把相应的 `HeroContactComponent`*投影*(*transclude*)进 `HeroBioComponent` 的视图里,\n将它放在 `HeroBioComponent` 模板的 `<ng-content>` 标签槽里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ITLOOKSLIKETHISWITHTHEHEROSTELEPHONENUMBERFROMHEROCONTACTCOMPONENTPROJECTEDABOVETHEHERODESCRIPTION:", "original": "It looks like this, with the hero's telephone number from `HeroContactComponent` projected above the hero description:", "translation": "从 `HeroContactComponent` 获得的英雄电话号码,被投影到上面的英雄描述里,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "HERESTHEHEROCONTACTCOMPONENTWHICHDEMONSTRATESTHEQUALIFYINGDECORATORS:", "original": "Here's the `HeroContactComponent` which demonstrates the qualifying decorators:", "translation": "下面的 `HeroContactComponent`,示范了限定型装饰器(@Optional 和@Host):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "FOCUSONTHECONSTRUCTORPARAMETERS:", "original": "Focus on the constructor parameters:", "translation": "注意看构造函数的参数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHOSTFUNCTIONDECORATINGTHEHEROCACHEPROPERTYENSURESTHATYOUGETAREFERENCETOTHECACHESERVICEFROMTHEPARENTHEROBIOCOMPONENTANGULARTHROWSANERRORIFTHEPARENTLACKSTHATSERVICEEVENIFACOMPONENTHIGHERINTHECOMPONENTTREEHAPPENSTOHAVEIT", "original": "The `@Host()` function decorating the `heroCache` property ensures that\nyou get a reference to the cache service from the parent `HeroBioComponent`.\nAngular throws an error if the parent lacks that service, even if a component higher\nin the component tree happens to have it.", "translation": "`@Host()` 函数是 `heroCache` 属性的装饰器,确保从其父组件 `HeroBioComponent` 得到一个缓存服务。如果该父组件不存在这个服务,Angular 就会抛出错误,即使组件树里的再上级有某个组件拥有这个服务,Angular 也会抛出错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ASECONDHOSTFUNCTIONDECORATESTHELOGGERSERVICEPROPERTYTHEONLYLOGGERSERVICEINSTANCEINTHEAPPISPROVIDEDATTHEAPPCOMPONENTLEVELTHEHOSTHEROBIOCOMPONENTDOESNTHAVEITSOWNLOGGERSERVICEPROVIDER", "original": "A second `@Host()` function decorates the `loggerService` property.\nThe only `LoggerService` instance in the app is provided at the `AppComponent` level.\nThe host `HeroBioComponent` doesn't have its own `LoggerService` provider.", "translation": "另一个 `@Host()` 函数是属性 `loggerService` 的装饰器。\n在本应用程序中只有一个在 `AppComponent` 级提供的 `LoggerService` 实例。\n该宿主 `HeroBioComponent` 没有自己的 `LoggerService` 提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ANGULARWOULDTHROWANERRORIFYOUHADNTALSODECORATEDTHEPROPERTYWITHTHEOPTIONALFUNCTIONTHANKSTOOPTIONALANGULARSETSTHELOGGERSERVICETONULLANDTHERESTOFTHECOMPONENTADAPTS", "original": "Angular would throw an error if you hadn't also decorated the property with the `@Optional()` function.\nThanks to `@Optional()`, Angular sets the `loggerService` to null and the rest of the component adapts.", "translation": "如果没有同时使用 `@Optional()` 装饰器的话,Angular 就会抛出错误。多亏了 `@Optional()`,Angular 把 `loggerService` 设置为 null,并继续执行组件而不会抛出错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "HERESTHEHEROBIOSANDCONTACTSCOMPONENTINACTION", "original": "Here's the `HeroBiosAndContactsComponent` in action.", "translation": "下面是 `HeroBiosAndContactsComponent` 的执行结果:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "IFYOUCOMMENTOUTTHEHOSTDECORATORANGULARNOWWALKSUPTHEINJECTORANCESTORTREEUNTILITFINDSTHELOGGERATTHEAPPCOMPONENTLEVELTHELOGGERLOGICKICKSINANDTHEHERODISPLAYUPDATESWITHTHEGRATUITOUSINDICATINGTHATTHELOGGERWASFOUND", "original": "If you comment out the `@Host()` decorator, Angular now walks up the injector ancestor tree\nuntil it finds the logger at the `AppComponent` level. The logger logic kicks in and the hero display updates\nwith the gratuitous \"!!!\", indicating that the logger was found.", "translation": "如果注释掉 `@Host()` 装饰器,Angular 就会沿着注入器树往上走,直到在 `AppComponent` 中找到该日志服务。日志服务的逻辑加入进来,更新了英雄的显示信息,这表明确实找到了日志服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ONTHEOTHERHANDIFYOURESTORETHEHOSTDECORATORANDCOMMENTOUTOPTIONALTHEAPPLICATIONFAILSFORLACKOFTHEREQUIREDLOGGERATTHEHOSTCOMPONENTLEVELBREXCEPTION:NOPROVIDERFORLOGGERSERVICEHEROCONTACTCOMPONENTLOGGERSERVICE", "original": "On the other hand, if you restore the `@Host()` decorator and comment out `@Optional`,\nthe application fails for lack of the required logger at the host component level.\n<br>\n`EXCEPTION: No provider for LoggerService! (HeroContactComponent -> LoggerService)`", "translation": "另一方面,如果恢复 `@Host()` 装饰器,注释掉 `@Optional`,应用程序就会运行失败,因为它在宿主组件级别找不到需要的日志服务。\n<br>\n`EXCEPTION: No provider for LoggerService! (HeroContactComponent -> LoggerService)`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##INJECTTHECOMPONENTSDOMELEMENT", "original": "## Inject the component's DOM element", "translation": "## 注入组件的 DOM 元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ONOCCASIONYOUMIGHTNEEDTOACCESSACOMPONENTSCORRESPONDINGDOMELEMENTALTHOUGHDEVELOPERSSTRIVETOAVOIDITMANYVISUALEFFECTSAND3RDPARTYTOOLSSUCHASJQUERYREQUIREDOMACCESS", "original": "On occasion you might need to access a component's corresponding DOM element.\nAlthough developers strive to avoid it, many visual effects and 3rd party tools, such as jQuery,\nrequire DOM access.", "translation": "偶尔,可能需要访问一个组件对应的 DOM 元素。尽量避免这样做,但还是有很多视觉效果和第三方工具(比如 jQuery)需要访问 DOM。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "TOILLUSTRATEHERESASIMPLIFIEDVERSIONOFTHEHIGHLIGHTDIRECTIVEFROMTHEATTRIBUTEDIRECTIVESGUIDEATTRIBUTEDIRECTIVESPAGE", "original": "To illustrate, here's a simplified version of the `HighlightDirective` from\nthe [Attribute Directives](guide/attribute-directives) page.", "translation": "要说明这一点,请在[属性型指令](guide/attribute-directives)`HighlightDirective` 的基础上,编写一个简化版。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEDIRECTIVESETSTHEBACKGROUNDTOAHIGHLIGHTCOLORWHENTHEUSERMOUSESOVERTHEDOMELEMENTTOWHICHITISAPPLIED", "original": "The directive sets the background to a highlight color when the user mouses over the\nDOM element to which it is applied.", "translation": "当用户把鼠标移到 DOM 元素上时,指令将该元素的背景设置为一个高亮颜色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ANGULARSETSTHECONSTRUCTORSELPARAMETERTOTHEINJECTEDELEMENTREFWHICHISAWRAPPERAROUNDTHATDOMELEMENTITSNATIVEELEMENTPROPERTYEXPOSESTHEDOMELEMENTFORTHEDIRECTIVETOMANIPULATE", "original": "Angular sets the constructor's `el` parameter to the injected `ElementRef`, which is\na wrapper around that DOM element.\nIts `nativeElement` property exposes the DOM element for the directive to manipulate.", "translation": "Angular 把构造函数参数 `el` 设置为注入的 `ElementRef`,该 `ElementRef` 代表了宿主的 DOM 元素, 它的 `nativeElement` 属性把该 DOM 元素暴露给了指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THESAMPLECODEAPPLIESTHEDIRECTIVESMYHIGHLIGHTATTRIBUTETOTWODIVTAGSFIRSTWITHOUTAVALUEYIELDINGTHEDEFAULTCOLORANDTHENWITHANASSIGNEDCOLORVALUE", "original": "The sample code applies the directive's `myHighlight` attribute to two `<div>` tags,\nfirst without a value (yielding the default color) and then with an assigned color value.", "translation": "下面的代码把指令的 `myHighlight` 属性(Attribute)填加到两个 `<div>` 标签里,一个没有赋值,一个赋值了颜色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEFOLLOWINGIMAGESHOWSTHEEFFECTOFMOUSINGOVERTHEHEROBIOSANDCONTACTSTAG", "original": "The following image shows the effect of mousing over the `<hero-bios-and-contacts>` tag.", "translation": "下图显示了鼠标移到 `<hero-bios-and-contacts>` 标签的效果:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##DEFINEDEPENDENCIESWITHPROVIDERS", "original": "## Define dependencies with providers", "translation": "## 使用提供商来定义依赖", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THISSECTIONDEMONSTRATESHOWTOWRITEPROVIDERSTHATDELIVERDEPENDENTSERVICES", "original": "This section demonstrates how to write providers that deliver dependent services.", "translation": "本节将演示如何编写提供商来提供被依赖的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "GETASERVICEFROMADEPENDENCYINJECTORBYGIVINGITATOKEN", "original": "Get a service from a dependency injector by giving it a ***token***.", "translation": "给依赖注入器提供***令牌***来获取服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUUSUALLYLETANGULARHANDLETHISTRANSACTIONBYSPECIFYINGACONSTRUCTORPARAMETERANDITSTYPETHEPARAMETERTYPESERVESASTHEINJECTORLOOKUPTOKENANGULARPASSESTHISTOKENTOTHEINJECTORANDASSIGNSTHERESULTTOTHEPARAMETERHERESATYPICALEXAMPLE:", "original": "You usually let Angular handle this transaction by specifying a constructor parameter and its type.\nThe parameter type serves as the injector lookup *token*.\nAngular passes this token to the injector and assigns the result to the parameter.\nHere's a typical example:", "translation": "你通常在构造函数里面,为参数指定类型,让 Angular 来处理依赖注入。该参数类型就是依赖注入器所需的*令牌*。\nAngular 把该令牌传给注入器,然后把得到的结果赋给参数。下面是一个典型的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ANGULARASKSTHEINJECTORFORTHESERVICEASSOCIATEDWITHTHELOGGERSERVICEANDASSIGNSTHERETURNEDVALUETOTHELOGGERPARAMETER", "original": "Angular asks the injector for the service associated with the `LoggerService`\nand assigns the returned value to the `logger` parameter.", "translation": "Angular 向注入器请求与 `LoggerService` 对应的服务,并将返回值赋给 `logger` 参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "WHEREDIDTHEINJECTORGETTHATVALUEITMAYALREADYHAVETHATVALUEINITSINTERNALCONTAINERIFITDOESNTITMAYBEABLETOMAKEONEWITHTHEHELPOFAPROVIDERAPROVIDERISARECIPEFORDELIVERINGASERVICEASSOCIATEDWITHATOKEN", "original": "Where did the injector get that value?\nIt may already have that value in its internal container.\nIf it doesn't, it may be able to make one with the help of a ***provider***.\nA *provider* is a recipe for delivering a service associated with a *token*.", "translation": "注入器从哪得到的依赖?\n它可能在自己内部容器里已经有该依赖了。\n如果它没有,也能在***提供商***的帮助下新建一个。\n*提供商*就是一个用于交付服务的配方,它被关联到一个令牌。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "IFTHEINJECTORDOESNTHAVEAPROVIDERFORTHEREQUESTEDTOKENITDELEGATESTHEREQUESTTOITSPARENTINJECTORWHERETHEPROCESSREPEATSUNTILTHEREARENOMOREINJECTORSIFTHESEARCHISFUTILETHEINJECTORTHROWSANERRORMDASHUNLESSTHEREQUESTWASOPTIONALGUIDEDEPENDENCYINJECTIONINACTION#OPTIONAL", "original": "If the injector doesn't have a provider for the requested *token*, it delegates the request\nto its parent injector, where the process repeats until there are no more injectors.\nIf the search is futile, the injector throws an error—unless the request was [optional](guide/dependency-injection-in-action#optional).", "translation": "如果注入器无法根据令牌在自己内部找到对应的提供商,它便将请求移交给它的父级注入器,这个过程不断重复,直到没有更多注入器为止。\n如果没找到,注入器就抛出一个错误...除非这个请求是[可选的](guide/dependency-injection-in-action#optional)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ANEWINJECTORHASNOPROVIDERSANGULARINITIALIZESTHEINJECTORSITCREATESWITHSOMEPROVIDERSITCARESABOUTYOUHAVETOREGISTERYOUROWNAPPLICATIONPROVIDERSMANUALLYUSUALLYINTHEPROVIDERSARRAYOFTHECOMPONENTORDIRECTIVEMETADATA:", "original": "A new injector has no providers.\nAngular initializes the injectors it creates with some providers it cares about.\nYou have to register your _own_ application providers manually,\nusually in the `providers` array of the `Component` or `Directive` metadata:", "translation": "新建的注入器中没有提供商。\nAngular 会使用一些自带的提供商来初始化这些注入器。你必须自行注册属于*自己*的提供商,通常用 ` 组件 ` 或者 ` 指令 ` 元数据中的 `providers` 数组进行注册。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###DEFININGPROVIDERS", "original": "### Defining providers", "translation": "### 定义提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THESIMPLECLASSPROVIDERISTHEMOSTTYPICALBYFARYOUMENTIONTHECLASSINTHEPROVIDERSARRAYANDYOUREDONE", "original": "The simple class provider is the most typical by far.\nYou mention the class in the `providers` array and you're done.", "translation": "简单的类提供商是最典型的例子。只要在 `providers` 数值里面提到该类就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ITSTHATSIMPLEBECAUSETHEMOSTCOMMONINJECTEDSERVICEISANINSTANCEOFACLASSBUTNOTEVERYDEPENDENCYCANBESATISFIEDBYCREATINGANEWINSTANCEOFACLASSYOUNEEDOTHERWAYSTODELIVERDEPENDENCYVALUESANDTHATMEANSYOUNEEDOTHERWAYSTOSPECIFYAPROVIDER", "original": "It's that simple because the most common injected service is an instance of a class.\nBut not every dependency can be satisfied by creating a new instance of a class.\nYou need other ways to deliver dependency values and that means you need other ways to specify a provider.", "translation": "注册类提供商之所以这么简单,是因为最常见的可注入服务就是一个类的实例。\n但是,并不是所有的依赖都只要创建一个类的新实例就可以交付了。你还需要其它的交付方式,这意味着你也要用其它方式来指定提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHEROOFTHEMONTHCOMPONENTEXAMPLEDEMONSTRATESMANYOFTHEALTERNATIVESANDWHYYOUNEEDTHEMITSVISUALLYSIMPLE:AFEWPROPERTIESANDTHELOGSPRODUCEDBYALOGGER", "original": "The `HeroOfTheMonthComponent` example demonstrates many of the alternatives and why you need them.\nIt's visually simple: a few properties and the logs produced by a logger.", "translation": "`HeroOfTheMonthComponent` 例子示范了一些替代方案,展示了为什么需要它们。\n它看起来很简单:一些属性和一个日志输出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THECODEBEHINDITGIVESYOUPLENTYTOTHINKABOUT", "original": "The code behind it gives you plenty to think about.", "translation": "这段代码的背后有很多值得深入思考的地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "####THEPROVIDEOBJECTLITERAL", "original": "#### The *provide* object literal", "translation": "#### *provide* 对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEPROVIDEOBJECTLITERALTAKESATOKENANDADEFINITIONOBJECTTHETOKENISUSUALLYACLASSBUTITDOESNTHAVETOBEGUIDEDEPENDENCYINJECTIONINACTION#TOKENS", "original": "The `provide` object literal takes a *token* and a *definition object*.\nThe *token* is usually a class but [it doesn't have to be](guide/dependency-injection-in-action#tokens).", "translation": "该 `provide` 对象需要一个*令牌*和一个*定义对象*。该*令牌*通常是一个类,但[并非一定是](guide/dependency-injection-in-action#tokens)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEDEFINITIONOBJECTHASAREQUIREDPROPERTYTHATSPECIFIESHOWTOCREATETHESINGLETONINSTANCEOFTHESERVICEINTHISCASETHEPROPERTY", "original": "The *definition* object has a required property that specifies how to create the singleton instance of the service. In this case, the property.", "translation": "该*定义*对象有一个必填属性(即 `useValue`),用来标识该提供商会如何新建和返回该服务的单例对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "####USEVALUEMDASHTHEVALUEPROVIDER", "original": "#### useValue—the *value provider*", "translation": "#### useValue - *值-提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "SETTHEUSEVALUEPROPERTYTOAFIXEDVALUETHATTHEPROVIDERCANRETURNASTHESERVICEINSTANCEAKATHEDEPENDENCYOBJECT", "original": "Set the `useValue` property to a ***fixed value*** that the provider can return as the service instance (AKA, the \"dependency object\").", "translation": "把一个***固定的值**,也就是该提供商可以将其作为依赖对象返回的值,赋给 `useValue` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "USETHISTECHNIQUETOPROVIDERUNTIMECONFIGURATIONCONSTANTSSUCHASWEBSITEBASEADDRESSESANDFEATUREFLAGSYOUCANUSEAVALUEPROVIDERINAUNITTESTTOREPLACEAPRODUCTIONSERVICEWITHAFAKEORMOCK", "original": "Use this technique to provide *runtime configuration constants* such as website base addresses and feature flags.\nYou can use a *value provider* in a unit test to replace a production service with a fake or mock.", "translation": "使用该技巧来进行*运行期常量设置*,比如网站的基础地址和功能标志等。\n你通常在单元测试中使用*值-提供商*,用一个假的或模仿的(服务)来取代一个生产环境的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHEROOFTHEMONTHCOMPONENTEXAMPLEHASTWOVALUEPROVIDERSTHEFIRSTPROVIDESANINSTANCEOFTHEHEROCLASSTHESECONDSPECIFIESALITERALSTRINGRESOURCE:", "original": "The `HeroOfTheMonthComponent` example has two *value providers*.\nThe first provides an instance of the `Hero` class;\nthe second specifies a literal string resource:", "translation": "`HeroOfTheMonthComponent` 例子有两个*值-提供商*。\n第一个提供了一个 `Hero` 类的实例;第二个指定了一个字符串资源:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHEROPROVIDERTOKENISACLASSWHICHMAKESSENSEBECAUSETHEVALUEISAHEROANDTHECONSUMEROFTHEINJECTEDHEROWOULDWANTTHETYPEINFORMATION", "original": "The `Hero` provider token is a class which makes sense because the value is a `Hero`\nand the consumer of the injected hero would want the type information.", "translation": "`Hero` 提供商的令牌是一个类,这很合理,因为它提供的结果是一个 `Hero` 实例,并且被注入该英雄的消费者也需要知道它类型信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THETITLEPROVIDERTOKENISNOTACLASSITSASPECIALKINDOFPROVIDERLOOKUPKEYCALLEDANINJECTIONTOKENGUIDEDEPENDENCYINJECTIONINACTION#INJECTIONTOKENYOUCANUSEANINJECTIONTOKENFORANYKINDOFPROVIDERBUTITSPARTICULARHELPFULWHENTHEDEPENDENCYISASIMPLEVALUELIKEASTRINGANUMBERORAFUNCTION", "original": "The `TITLE` provider token is *not a class*.\nIt's a special kind of provider lookup key called an [InjectionToken](guide/dependency-injection-in-action#injection-token).\nYou can use an `InjectionToken` for any kind of provider but it's particular\nhelpful when the dependency is a simple value like a string, a number, or a function.", "translation": "`TITLE` 提供商的令牌*不是一个类*。它是一个特别类型的提供商查询键,名叫[InjectionToken](guide/dependency-injection-in-action#injection-token).\n你可以把 `InjectionToken` 用作任何类型的提供商的令牌,但是它在依赖是简单类型(比如字符串、数字、函数)时会特别有帮助。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEVALUEOFAVALUEPROVIDERMUSTBEDEFINEDNOWYOUCANTCREATETHEVALUELATEROBVIOUSLYTHETITLESTRINGLITERALISIMMEDIATELYAVAILABLETHESOMEHEROVARIABLEINTHISEXAMPLEWASSETEARLIERINTHEFILE:", "original": "The value of a *value provider* must be defined *now*. You can't create the value later.\nObviously the title string literal is immediately available.\nThe `someHero` variable in this example was set earlier in the file:", "translation": "一个*值-提供商*的值必须要*立即*定义。不能事后再定义它的值。很显然,标题字符串是立刻可用的。\n该例中的 `someHero` 变量是以前在下面这个文件中定义的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEOTHERPROVIDERSCREATETHEIRVALUESLAZILYWHENTHEYRENEEDEDFORINJECTION", "original": "The other providers create their values *lazily* when they're needed for injection.", "translation": "其它提供商只在需要注入它们的时候才创建并*惰性加载*它们的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "####USECLASSMDASHTHECLASSPROVIDER", "original": "#### useClass—the *class provider*", "translation": "#### useClass - *类-提供商*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEUSECLASSPROVIDERCREATESANDRETURNSNEWINSTANCEOFTHESPECIFIEDCLASS", "original": "The `useClass` provider creates and returns new instance of the specified class.", "translation": "`userClass` 提供商创建并返回一个指定类的新实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "USETHISTECHNIQUETOSUBSTITUTEANALTERNATIVEIMPLEMENTATIONFORACOMMONORDEFAULTCLASSTHEALTERNATIVECOULDIMPLEMENTADIFFERENTSTRATEGYEXTENDTHEDEFAULTCLASSORFAKETHEBEHAVIOROFTHEREALCLASSINATESTCASE", "original": "Use this technique to ***substitute an alternative implementation*** for a common or default class.\nThe alternative could implement a different strategy, extend the default class,\nor fake the behavior of the real class in a test case.", "translation": "使用该技术来为公共或默认类***提供备选实现***。该替代品能实现一个不同的策略,比如拓展默认类或者在测试的时候假冒真实类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "HEREARETWOEXAMPLESINTHEHEROOFTHEMONTHCOMPONENT:", "original": "Here are two examples in the `HeroOfTheMonthComponent`:", "translation": "请看下面 `HeroOfTheMonthComponent` 里的两个例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEFIRSTPROVIDERISTHEDESUGAREDEXPANDEDFORMOFTHEMOSTTYPICALCASEINWHICHTHECLASSTOBECREATEDHEROSERVICEISALSOTHEPROVIDERSDEPENDENCYINJECTIONTOKENITSINTHISLONGFORMTODEMYSTIFYTHEPREFERREDSHORTFORM", "original": "The first provider is the *de-sugared*, expanded form of the most typical case in which the\nclass to be created (`HeroService`) is also the provider's dependency injection token.\nIt's in this long form to de-mystify the preferred short form.", "translation": "第一个提供商是*展开了语法糖的*,是一个典型情况的展开。一般来说,被新建的类(`HeroService`)同时也是该提供商的注入令牌。\n这里用完整形态来编写它,来反衬更受欢迎的缩写形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THESECONDPROVIDERSUBSTITUTESTHEDATELOGGERSERVICEFORTHELOGGERSERVICETHELOGGERSERVICEISALREADYREGISTEREDATTHEAPPCOMPONENTLEVELWHENTHISCOMPONENTREQUESTSTHELOGGERSERVICEITRECEIVESTHEDATELOGGERSERVICEINSTEAD", "original": "The second provider substitutes the `DateLoggerService` for the `LoggerService`.\nThe `LoggerService` is already registered at the `AppComponent` level.\nWhen _this component_ requests the `LoggerService`, it receives the `DateLoggerService` instead.", "translation": "第二个提供商使用 `DateLoggerService` 来满足 `LoggerService`。该 `LoggerService` 在 `AppComponent` 级别已经被注册。当*这个组件*要求 `LoggerService` 的时候,它得到的却是 `DateLoggerService` 服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THISCOMPONENTANDITSTREEOFCHILDCOMPONENTSRECEIVETHEDATELOGGERSERVICEINSTANCECOMPONENTSOUTSIDETHETREECONTINUETORECEIVETHEORIGINALLOGGERSERVICEINSTANCE", "original": "This component and its tree of child components receive the `DateLoggerService` instance.\nComponents outside the tree continue to receive the original `LoggerService` instance.", "translation": "这个组件及其子组件会得到 `DateLoggerService` 实例。这个组件树之外的组件得到的仍是 `LoggerService` 实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEDATELOGGERSERVICEINHERITSFROMLOGGERSERVICEITAPPENDSTHECURRENTDATETIMETOEACHMESSAGE:", "original": "The `DateLoggerService` inherits from `LoggerService`; it appends the current date/time to each message:", "translation": "`DateLoggerService` 从 `LoggerService` 继承;它把当前的日期/时间附加到每条信息上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "####USEEXISTINGMDASHTHEALIASPROVIDER", "original": "#### _useExisting_—the *alias provider*", "translation": "#### useExisting - *别名-提供商*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEUSEEXISTINGPROVIDERMAPSONETOKENTOANOTHERINEFFECTTHEFIRSTTOKENISANALIASFORTHESERVICEASSOCIATEDWITHTHESECONDTOKENCREATINGTWOWAYSTOACCESSTHESAMESERVICEOBJECT", "original": "The `useExisting` provider maps one token to another.\nIn effect, the first token is an ***alias*** for the service associated with the second token,\ncreating ***two ways to access the same service object***.", "translation": "使用 `useExisting`,提供商可以把一个令牌映射到另一个令牌上。实际上,第一个令牌是第二个令牌所对应的服务的一个***别名***,创造了***访问同一个服务对象的两种方法***。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NARROWINGANAPITHROUGHANALIASINGINTERFACEISONEIMPORTANTUSECASEFORTHISTECHNIQUETHEFOLLOWINGEXAMPLESHOWSALIASINGFORTHATPURPOSE", "original": "Narrowing an API through an aliasing interface is _one_ important use case for this technique.\nThe following example shows aliasing for that purpose.", "translation": "通过使用别名接口来把一个 API 变窄,是*一个*很重要的该技巧的使用例子。下面的例子中使用别名就是为了这个目的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "IMAGINETHATTHELOGGERSERVICEHADALARGEAPIMUCHLARGERTHANTHEACTUALTHREEMETHODSANDAPROPERTYYOUMIGHTWANTTOSHRINKTHATAPISURFACETOJUSTTHEMEMBERSYOUACTUALLYNEEDHERETHEMINIMALLOGGERCLASSINTERFACEGUIDEDEPENDENCYINJECTIONINACTION#CLASSINTERFACEREDUCESTHEAPITOTWOMEMBERS:", "original": "Imagine that the `LoggerService` had a large API, much larger than the actual three methods and a property.\nYou might want to shrink that API surface to just the members you actually need.\nHere the `MinimalLogger` [*class-interface*](guide/dependency-injection-in-action#class-interface) reduces the API to two members:", "translation": "想象一下如果 `LoggerService` 有个很大的 API 接口(虽然它其实只有三个方法,一个属性),通过使用 `MinimalLogger`[*类-接口*](guide/dependency-injection-in-action#class-interface)别名,就能成功的把这个 API 接口缩小到只暴露两个成员:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NOWPUTITTOUSEINASIMPLIFIEDVERSIONOFTHEHEROOFTHEMONTHCOMPONENT", "original": "Now put it to use in a simplified version of the `HeroOfTheMonthComponent`.", "translation": "现在,在一个简化版的 `HeroOfTheMonthComponent` 中使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHEROOFTHEMONTHCOMPONENTCONSTRUCTORSLOGGERPARAMETERISTYPEDASMINIMALLOGGERSOONLYTHELOGSANDLOGINFOMEMBERSAREVISIBLEINATYPESCRIPTAWAREEDITOR:", "original": "The `HeroOfTheMonthComponent` constructor's `logger` parameter is typed as `MinimalLogger` so only the `logs` and `logInfo` members are visible in a TypeScript-aware editor:", "translation": "`HeroOfTheMonthComponent` 构造函数的 `logger` 参数是一个 `MinimalLogger` 类型,支持 TypeScript 的编辑器里,只能看到它的两个成员 `logs` 和 `logInfo`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "BEHINDTHESCENESANGULARACTUALLYSETSTHELOGGERPARAMETERTOTHEFULLSERVICEREGISTEREDUNDERTHELOGGINGSERVICETOKENWHICHHAPPENSTOBETHEDATELOGGERSERVICETHATWASPROVIDEDABOVEGUIDEDEPENDENCYINJECTIONINACTION#USECLASS", "original": "Behind the scenes, Angular actually sets the `logger` parameter to the full service registered under the `LoggingService` token which happens to be the `DateLoggerService` that was [provided above](guide/dependency-injection-in-action#useclass).", "translation": "实际上,Angular 确实想把 `logger` 参数设置为注入器里 `LoggerService` 的完整版本。只是在之前的提供商注册里使用了 `useClass`,\n所以该完整版本被 `DateLoggerService` 取代了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEFOLLOWINGIMAGEWHICHDISPLAYSTHELOGGINGDATECONFIRMSTHEPOINT:", "original": "The following image, which displays the logging date, confirms the point:", "translation": "在下面的图片中,显示了日志日期,可以确认这一点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "####USEFACTORYMDASHTHEFACTORYPROVIDER", "original": "#### _useFactory_—the *factory provider*", "translation": "#### useFactory - *工厂-提供商*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEUSEFACTORYPROVIDERCREATESADEPENDENCYOBJECTBYCALLINGAFACTORYFUNCTIONASINTHISEXAMPLE", "original": "The `useFactory` provider creates a dependency object by calling a factory function\nas in this example.", "translation": "`useFactory` 提供商通过调用工厂函数来新建一个依赖对象,如下例所示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "USETHISTECHNIQUETOCREATEADEPENDENCYOBJECTWITHAFACTORYFUNCTIONWHOSEINPUTSARESOMECOMBINATIONOFINJECTEDSERVICESANDLOCALSTATE", "original": "Use this technique to ***create a dependency object***\nwith a factory function whose inputs are some ***combination of injected services and local state***.", "translation": "使用这项技术,可以用包含了一些***依赖服务和本地状态***输入的工厂函数来***建立一个依赖对象***。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEDEPENDENCYOBJECTDOESNTHAVETOBEACLASSINSTANCEITCOULDBEANYTHINGINTHISEXAMPLETHEDEPENDENCYOBJECTISASTRINGOFTHENAMESOFTHERUNNERSUPTOTHEHEROOFTHEMONTHCONTEST", "original": "The *dependency object* doesn't have to be a class instance. It could be anything.\nIn this example, the *dependency object* is a string of the names of the runners-up\nto the \"Hero of the Month\" contest.", "translation": "该*依赖对象*不一定是一个类实例。它可以是任何东西。在这个例子里,*依赖对象*是一个字符串,代表了**本月英雄**比赛的亚军的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THELOCALSTATEISTHENUMBER2THENUMBEROFRUNNERSUPTHISCOMPONENTSHOULDSHOWITEXECUTESRUNNERSUPFACTORYIMMEDIATELYWITH2", "original": "The local state is the number `2`, the number of runners-up this component should show.\nIt executes `runnersUpFactory` immediately with `2`.", "translation": "本地状态是数字 `2`,该组件应该显示的亚军的个数。它就会立刻用 `2` 来执行 `runnersUpFactory`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THERUNNERSUPFACTORYITSELFISNTTHEPROVIDERFACTORYFUNCTIONTHETRUEPROVIDERFACTORYFUNCTIONISTHEFUNCTIONTHATRUNNERSUPFACTORYRETURNS", "original": "The `runnersUpFactory` itself isn't the provider factory function.\nThe true provider factory function is the function that `runnersUpFactory` returns.", "translation": "`runnersUpFactory` 自身不是提供商工厂函数。真正的提供商工厂函数是 `runnersUpFactory` 返回的函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THATRETURNEDFUNCTIONTAKESAWINNINGHEROANDAHEROSERVICEASARGUMENTS", "original": "That returned function takes a winning `Hero` and a `HeroService` as arguments.", "translation": "这个返回的函数需要一个 `Hero` 和一个 `HeroService` 参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ANGULARSUPPLIESTHESEARGUMENTSFROMINJECTEDVALUESIDENTIFIEDBYTHETWOTOKENSINTHEDEPSARRAYTHETWODEPSVALUESARETOKENSTHATTHEINJECTORUSESTOPROVIDETHESEFACTORYFUNCTIONDEPENDENCIES", "original": "Angular supplies these arguments from injected values identified by\nthe two *tokens* in the `deps` array.\nThe two `deps` values are *tokens* that the injector uses\nto provide these factory function dependencies.", "translation": "Angular 通过使用 `deps` 数组中的两个*令牌*,来识别注入的值,用来提供这些参数。这两个 `deps` 值是供注入器使用的*令牌*,用来提供工厂函数的依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "AFTERSOMEUNDISCLOSEDWORKTHEFUNCTIONRETURNSTHESTRINGOFNAMESANDANGULARINJECTSITINTOTHERUNNERSUPPARAMETEROFTHEHEROOFTHEMONTHCOMPONENT", "original": "After some undisclosed work, the function returns the string of names\nand Angular injects it into the `runnersUp` parameter of the `HeroOfTheMonthComponent`.", "translation": "一些内部工作后,这个函数返回名字字符串,Angular 将其注入到 `HeroOfTheMonthComponent` 组件的 `runnersUp` 参数里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEFUNCTIONRETRIEVESCANDIDATEHEROESFROMTHEHEROSERVICETAKES2OFTHEMTOBETHERUNNERSUPANDRETURNSTHEIRCONCATENATEDNAMESLOOKATTHELIVEEXAMPLENAMEDEPENDENCYINJECTIONINACTIONLIVEEXAMPLEFORTHEFULLSOURCECODE", "original": "The function retrieves candidate heroes from the `HeroService`,\ntakes `2` of them to be the runners-up, and returns their concatenated names.\nLook at the <live-example name=\"dependency-injection-in-action\"></live-example>\nfor the full source code.", "translation": "该函数从 `HeroService` 获取英雄参赛者,从中取 `2` 个作为亚军,并把他们的名字拼接起来。请到<live-example name=\"dependency-injection-in-action\"></live-example>查看全部原代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##PROVIDERTOKENALTERNATIVES:THECLASSINTERFACEANDINJECTIONTOKEN", "original": "## Provider token alternatives: the *class-interface* and *InjectionToken*", "translation": "## 备选提供商令牌:*类-接口*和 *InjectionToken*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ANGULARDEPENDENCYINJECTIONISEASIESTWHENTHEPROVIDERTOKENISACLASSTHATISALSOTHETYPEOFTHERETURNEDDEPENDENCYOBJECTORWHATYOUUSUALLYCALLTHESERVICE", "original": "Angular dependency injection is easiest when the provider *token* is a class\nthat is also the type of the returned dependency object, or what you usually call the *service*.", "translation": "Angular 依赖注入当*令牌*是类的时候是最简单的,该类同时也是返回的依赖对象的类型(通常直接称之为*服务*)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "BUTTHETOKENDOESNTHAVETOBEACLASSANDEVENWHENITISACLASSITDOESNTHAVETOBETHESAMETYPEASTHERETURNEDOBJECTTHATSTHESUBJECTOFTHENEXTSECTION", "original": "But the token doesn't have to be a class and even when it is a class,\nit doesn't have to be the same type as the returned object.\nThat's the subject of the next section.", "translation": "但令牌不一定都是类,就算它是一个类,它也不一定都返回类型相同的对象。这是下一节的主题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###CLASSINTERFACE", "original": "### class-interface", "translation": "### 类-接口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEPREVIOUSHEROOFTHEMONTHEXAMPLEUSEDTHEMINIMALLOGGERCLASSASTHETOKENFORAPROVIDEROFALOGGERSERVICE", "original": "The previous *Hero of the Month* example used the `MinimalLogger` class\nas the token for a provider of a `LoggerService`.", "translation": "前面的*月度英雄*的例子使用了 `MinimalLogger` 类作为 `LoggerService` 提供商的令牌。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEMINIMALLOGGERISANABSTRACTCLASS", "original": "The `MinimalLogger` is an abstract class.", "translation": "该 `MinimalLogger` 是一个抽象类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUUSUALLYINHERITFROMANABSTRACTCLASSBUTNOCLASSINTHISAPPLICATIONINHERITSFROMMINIMALLOGGER", "original": "You usually inherit from an abstract class.\nBut *no class* in this application inherits from `MinimalLogger`.", "translation": "你通常从一个抽象类继承。但这个应用中*并没有*类会继承 `MinimalLogger`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THELOGGERSERVICEANDTHEDATELOGGERSERVICECOULDHAVEINHERITEDFROMMINIMALLOGGERTHEYCOULDHAVEIMPLEMENTEDITINSTEADINTHEMANNEROFANINTERFACEBUTTHEYDIDNEITHERTHEMINIMALLOGGERISUSEDEXCLUSIVELYASADEPENDENCYINJECTIONTOKEN", "original": "The `LoggerService` and the `DateLoggerService` _could_ have inherited from `MinimalLogger`.\nThey could have _implemented_ it instead in the manner of an interface.\nBut they did neither.\nThe `MinimalLogger` is used exclusively as a dependency injection token.", "translation": "`LoggerService` 和 `DateLoggerService`*本可以*从 `MinimalLogger` 中继承。\n它们也可以实现 `MinimalLogger`,而不用单独定义接口。\n但它们没有。\n`MinimalLogger` 在这里仅仅被用作一个 \"依赖注入令牌\"。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "WHENYOUUSEACLASSTHISWAYITSCALLEDACLASSINTERFACETHEKEYBENEFITOFACLASSINTERFACEISTHATYOUCANGETTHESTRONGTYPINGOFANINTERFACEANDYOUCANUSEITASAPROVIDERTOKENINTHEWAYYOUWOULDANORMALCLASS", "original": "When you use a class this way, it's called a ***class-interface***.\nThe key benefit of a *class-interface* is that you can get the strong-typing of an interface\nand you can ***use it as a provider token*** in the way you would a normal class.", "translation": "这种用法的类叫做*类-接口*。它关键的好处是:提供了接口的强类型,能像正常类一样***把它当做提供商令牌使用***。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ACLASSINTERFACESHOULDDEFINEONLYTHEMEMBERSTHATITSCONSUMERSAREALLOWEDTOCALLSUCHANARROWINGINTERFACEHELPSDECOUPLETHECONCRETECLASSFROMITSCONSUMERS", "original": "A ***class-interface*** should define *only* the members that its consumers are allowed to call.\nSuch a narrowing interface helps decouple the concrete class from its consumers.", "translation": "***类-接口***应该*只*定义允许它的消费者调用的成员。窄的接口有助于解耦该类的具体实现和它的消费者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "####WHYMINIMALLOGGERISACLASSANDNOTATYPESCRIPTINTERFACE", "original": "#### Why *MinimalLogger* is a class and not a TypeScript interface", "translation": "#### 为什么 *MinimalLogger* 是一个类而不是一个 TypeScript 接口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUCANTUSEANINTERFACEASAPROVIDERTOKENBECAUSEINTERFACESARENOTJAVASCRIPTOBJECTSTHEYEXISTONLYINTHETYPESCRIPTDESIGNSPACETHEYDISAPPEARAFTERTHECODEISTRANSPILEDTOJAVASCRIPT", "original": "You can't use an interface as a provider token because\ninterfaces are not JavaScript objects.\nThey exist only in the TypeScript design space.\nThey disappear after the code is transpiled to JavaScript.", "translation": "不能把接口当做提供商的令牌,因为接口不是有效的 JavaScript 对象。\n它们只存在在 TypeScript 的设计空间里。它们会在被编译为 JavaScript 之后消失。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "APROVIDERTOKENMUSTBEAREALJAVASCRIPTOBJECTOFSOMEKIND:SUCHASAFUNCTIONANOBJECTASTRINGORACLASS", "original": "A provider token must be a real JavaScript object of some kind:\nsuch as a function, an object, a string, or a class.", "translation": "一个提供商令牌必须是一个真实的 JavaScript 对象,比如:一个函数,一个对象,一个字符串,或一个类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "USINGACLASSASANINTERFACEGIVESYOUTHECHARACTERISTICSOFANINTERFACEINAREALJAVASCRIPTOBJECT", "original": "Using a class as an interface gives you the characteristics of an interface in a real JavaScript object.", "translation": "把类当做接口使用,可以为你在一个 JavaScript 对象上提供类似于接口的特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "OFCOURSEAREALOBJECTOCCUPIESMEMORYTOMINIMIZEMEMORYCOSTTHECLASSSHOULDHAVENOIMPLEMENTATIONTHEMINIMALLOGGERTRANSPILESTOTHISUNOPTIMIZEDPREMINIFIEDJAVASCRIPTFORACONSTRUCTORFUNCTION:", "original": "Of course a real object occupies memory. To minimize memory cost, the class should have *no implementation*.\nThe `MinimalLogger` transpiles to this unoptimized, pre-minified JavaScript for a constructor function:", "translation": "当然,一个真实的类会占用内存。为了节省内存占用,该类应该***没有具体的实现***。`MinimalLogger` 会被转译成下面这段没有优化过的,尚未最小化的 JavaScript:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NOTICETHATITDOESNTHAVEASINGLEMEMBERITNEVERGROWSNOMATTERHOWMANYMEMBERSYOUADDTOTHECLASSASLONGASTHOSEMEMBERSARETYPEDBUTNOTIMPLEMENTEDLOOKAGAINATTHETYPESCRIPTMINIMALLOGGERCLASSTOCONFIRMTHATITHASNOIMPLEMENTATION", "original": "Notice that it doesn't have a single member. It never grows no matter how many members you add to the class *as long as those members are typed but not implemented*. Look again at the TypeScript `MinimalLogger` class to confirm that it has no implementation.", "translation": "注意,***只要不实现它***,不管添加多少成员,它永远不会增长大小。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###INJECTIONTOKEN", "original": "### _InjectionToken_", "translation": "### _InjectionToken_ 值", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "DEPENDENCYOBJECTSCANBESIMPLEVALUESLIKEDATESNUMBERSANDSTRINGSORSHAPELESSOBJECTSLIKEARRAYSANDFUNCTIONS", "original": "Dependency objects can be simple values like dates, numbers and strings, or\nshapeless objects like arrays and functions.", "translation": "依赖对象可以是一个简单的值,比如日期,数字和字符串,或者一个无形的对象,比如数组和函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "SUCHOBJECTSDONTHAVEAPPLICATIONINTERFACESANDTHEREFOREARENTWELLREPRESENTEDBYACLASSTHEYREBETTERREPRESENTEDBYATOKENTHATISBOTHUNIQUEANDSYMBOLICAJAVASCRIPTOBJECTTHATHASAFRIENDLYNAMEBUTWONTCONFLICTWITHANOTHERTOKENTHATHAPPENSTOHAVETHESAMENAME", "original": "Such objects don't have application interfaces and therefore aren't well represented by a class.\nThey're better represented by a token that is both unique and symbolic,\na JavaScript object that has a friendly name but won't conflict with\nanother token that happens to have the same name.", "translation": "这样的对象没有应用程序接口,所以不能用一个类来表示。更适合表示它们的是:唯一的和符号性的令牌,一个 JavaScript 对象,拥有一个友好的名字,但不会与其它的同名令牌发生冲突。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEINJECTIONTOKENHASTHESECHARACTERISTICSYOUENCOUNTEREDTHEMTWICEINTHEHEROOFTHEMONTHEXAMPLEINTHETITLEVALUEPROVIDERANDINTHERUNNERSUPFACTORYPROVIDER", "original": "The `InjectionToken` has these characteristics.\nYou encountered them twice in the *Hero of the Month* example,\nin the *title* value provider and in the *runnersUp* factory provider.", "translation": "`InjectionToken` 具有这些特征。在*Hero of the Month*例子中遇见它们两次,一个是 *title* 的值,一个是 *runnersUp* 工厂提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUCREATEDTHETITLETOKENLIKETHIS:", "original": "You created the `TITLE` token like this:", "translation": "这样创建 `TITLE` 令牌:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THETYPEPARAMETERWHILEOPTIONALCONVEYSTHEDEPENDENCYSTYPETODEVELOPERSANDTOOLINGTHETOKENDESCRIPTIONISANOTHERDEVELOPERAID", "original": "The type parameter, while optional, conveys the dependency's type to developers and tooling.\nThe token description is another developer aid.", "translation": "类型参数,虽然是可选的,但可以向开发者和开发工具传达类型信息。\n而且这个令牌的描述信息也可以为开发者提供帮助。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##INJECTINTOADERIVEDCLASS", "original": "## Inject into a derived class", "translation": "## 注入到派生类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "TAKECAREWHENWRITINGACOMPONENTTHATINHERITSFROMANOTHERCOMPONENTIFTHEBASECOMPONENTHASINJECTEDDEPENDENCIESYOUMUSTREPROVIDEANDREINJECTTHEMINTHEDERIVEDCLASSANDTHENPASSTHEMDOWNTOTHEBASECLASSTHROUGHTHECONSTRUCTOR", "original": "Take care when writing a component that inherits from another component.\nIf the base component has injected dependencies,\nyou must re-provide and re-inject them in the derived class\nand then pass them down to the base class through the constructor.", "translation": "当编写一个继承自另一个组件的组件时,要格外小心。如果基础组件有依赖注入,必须要在派生类中重新提供和重新注入它们,并将它们通过构造函数传给基类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "INTHISCONTRIVEDEXAMPLESORTEDHEROESCOMPONENTINHERITSFROMHEROESBASECOMPONENTTODISPLAYASORTEDLISTOFHEROES", "original": "In this contrived example, `SortedHeroesComponent` inherits from `HeroesBaseComponent`\nto display a *sorted* list of heroes.", "translation": "在这个刻意生成的例子里,`SortedHeroesComponent` 继承自 `HeroesBaseComponent`,显示一个*被排序*的英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEHEROESBASECOMPONENTCOULDSTANDONITSOWNITDEMANDSITSOWNINSTANCEOFTHEHEROSERVICETOGETHEROESANDDISPLAYSTHEMINTHEORDERTHEYARRIVEFROMTHEDATABASE", "original": "The `HeroesBaseComponent` could stand on its own.\nIt demands its own instance of the `HeroService` to get heroes\nand displays them in the order they arrive from the database.", "translation": "`HeroesBaseComponent` 能自己独立运行。它在自己的实例里要求 `HeroService`,用来得到英雄,并将他们按照数据库返回的顺序显示出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "KEEPCONSTRUCTORSSIMPLETHEYSHOULDDOLITTLEMORETHANINITIALIZEVARIABLESTHISRULEMAKESTHECOMPONENTSAFETOCONSTRUCTUNDERTESTWITHOUTFEARTHATITWILLDOSOMETHINGDRAMATICLIKETALKTOTHESERVERTHATSWHYYOUCALLTHEHEROSERVICEFROMWITHINTHENGONINITRATHERTHANTHECONSTRUCTOR", "original": "***Keep constructors simple.*** They should do little more than initialize variables.\nThis rule makes the component safe to construct under test without fear that it will do something dramatic like talk to the server.\nThat's why you call the `HeroService` from within the `ngOnInit` rather than the constructor.", "translation": "***让构造函数保持简单。***它们只应该用来初始化变量。\n这条规则用于在测试环境中放心的构造组件,以免在构造它们时,无意做了一些非常戏剧化的动作(比如与服务器进行会话)。\n这就是为什么你要在 `ngOnInit` 里面调用 `HeroService`,而不是在构造函数中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "USERSWANTTOSEETHEHEROESINALPHABETICALORDERRATHERTHANMODIFYTHEORIGINALCOMPONENTSUBCLASSITANDCREATEASORTEDHEROESCOMPONENTTHATSORTSTHEHEROESBEFOREPRESENTINGTHEMTHESORTEDHEROESCOMPONENTLETSTHEBASECLASSFETCHTHEHEROES", "original": "Users want to see the heroes in alphabetical order.\nRather than modify the original component, sub-class it and create a\n`SortedHeroesComponent` that sorts the heroes before presenting them.\nThe `SortedHeroesComponent` lets the base class fetch the heroes.", "translation": "用户希望看到英雄按字母顺序排序。与其修改原始的组件,不如派生它,新建 `SortedHeroesComponent`,以便展示英雄之前进行排序。\n`SortedHeroesComponent` 让基类来获取英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "UNFORTUNATELYANGULARCANNOTINJECTTHEHEROSERVICEDIRECTLYINTOTHEBASECLASSYOUMUSTPROVIDETHEHEROSERVICEAGAINFORTHISCOMPONENTTHENPASSITDOWNTOTHEBASECLASSINSIDETHECONSTRUCTOR", "original": "Unfortunately, Angular cannot inject the `HeroService` directly into the base class.\nYou must provide the `HeroService` again for *this* component,\nthen pass it down to the base class inside the constructor.", "translation": "可惜,Angular 不能直接在基类里直接注入 `HeroService`。必须在*这个*组件里再次提供 `HeroService`,然后通过构造函数传给基类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NOWTAKENOTEOFTHEAFTERGETHEROESMETHODYOURFIRSTINSTINCTMIGHTHAVEBEENTOCREATEANNGONINITMETHODINSORTEDHEROESCOMPONENTANDDOTHESORTINGTHEREBUTANGULARCALLSTHEDERIVEDCLASSSNGONINITBEFORECALLINGTHEBASECLASSSNGONINITSOYOUDBESORTINGTHEHEROESARRAYBEFORETHEYARRIVEDTHATPRODUCESANASTYERROR", "original": "Now take note of the `afterGetHeroes()` method.\nYour first instinct might have been to create an `ngOnInit` method in `SortedHeroesComponent` and do the sorting there.\nBut Angular calls the *derived* class's `ngOnInit` *before* calling the base class's `ngOnInit`\nso you'd be sorting the heroes array *before they arrived*. That produces a nasty error.", "translation": "现在,请注意 `afterGetHeroes()` 方法。\n你的第一反应是在 `SortedHeroesComponent` 组件里面建一个 `ngOnInit` 方法来做排序。但是 Angular 会先调用*派生*类的 `ngOnInit`,后调用基类的 `ngOnInit`,\n所以可能在*英雄到达之前*就开始排序。这就产生了一个讨厌的错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "OVERRIDINGTHEBASECLASSSAFTERGETHEROESMETHODSOLVESTHEPROBLEM", "original": "Overriding the base class's `afterGetHeroes()` method solves the problem.", "translation": "覆盖基类的 `afterGetHeroes()` 方法可以解决这个问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THESECOMPLICATIONSARGUEFORAVOIDINGCOMPONENTINHERITANCE", "original": "These complications argue for *avoiding component inheritance*.", "translation": "分析上面的这些复杂性是为了强调*避免使用组件继承*这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##FINDAPARENTCOMPONENTBYINJECTION", "original": "## Find a parent component by injection", "translation": "## 通过注入来找到一个父组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "APPLICATIONCOMPONENTSOFTENNEEDTOSHAREINFORMATIONMORELOOSELYCOUPLEDTECHNIQUESSUCHASDATABINDINGANDSERVICESHARINGAREPREFERABLEBUTSOMETIMESITMAKESSENSEFORONECOMPONENTTOHAVEADIRECTREFERENCETOANOTHERCOMPONENTPERHAPSTOACCESSVALUESORCALLMETHODSONTHATCOMPONENT", "original": "Application components often need to share information.\nMore loosely coupled techniques such as data binding and service sharing\nare preferable. But sometimes it makes sense for one component\nto have a direct reference to another component\nperhaps to access values or call methods on that component.", "translation": "应用程序组件经常需要共享信息。使用松耦合的技术会更好一点,比如数据绑定和服务共享。\n但有时候组件确实需要拥有另一个组件的引用,用来访问该组件的属性值或者调用它的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "OBTAININGACOMPONENTREFERENCEISABITTRICKYINANGULARALTHOUGHANANGULARAPPLICATIONISATREEOFCOMPONENTSTHEREISNOPUBLICAPIFORINSPECTINGANDTRAVERSINGTHATTREE", "original": "Obtaining a component reference is a bit tricky in Angular.\nAlthough an Angular application is a tree of components,\nthere is no public API for inspecting and traversing that tree.", "translation": "在 Angular 里,获取一个组件的引用比较复杂。虽然 Angular 应用程序是一个组件树,但它没有公共 API 来在该树中巡查和穿梭。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEREISANAPIFORACQUIRINGACHILDREFERENCECHECKOUTQUERYQUERYLISTVIEWCHILDRENANDCONTENTCHILDRENINTHEAPIREFERENCEAPI", "original": "There is an API for acquiring a child reference.\nCheck out `Query`, `QueryList`, `ViewChildren`, and `ContentChildren`\nin the [API Reference](api/).", "translation": "有一个 API 可以获取子级的引用(请看[API 参考手册](api/)中的 `Query`, `QueryList`, `ViewChildren`,和 `ContentChildren`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEREISNOPUBLICAPIFORACQUIRINGAPARENTREFERENCEBUTBECAUSEEVERYCOMPONENTINSTANCEISADDEDTOANINJECTORSCONTAINERYOUCANUSEANGULARDEPENDENCYINJECTIONTOREACHAPARENTCOMPONENT", "original": "There is no public API for acquiring a parent reference.\nBut because every component instance is added to an injector's container,\nyou can use Angular dependency injection to reach a parent component.", "translation": "但没有公共 API 来获取父组件的引用。但是因为每个组件的实例都被加到了依赖注入器的容器中,可以使用 Angular 依赖注入来找到父组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THISSECTIONDESCRIBESSOMETECHNIQUESFORDOINGTHAT", "original": "This section describes some techniques for doing that.", "translation": "本章节描述了这项技术。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###FINDAPARENTCOMPONENTOFKNOWNTYPE", "original": "### Find a parent component of known type", "translation": "### 找到已知类型的父组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUUSESTANDARDCLASSINJECTIONTOACQUIREAPARENTCOMPONENTWHOSETYPEYOUKNOW", "original": "You use standard class injection to acquire a parent component whose type you know.", "translation": "你使用标准的类注入来获取已知类型的父组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "INTHEFOLLOWINGEXAMPLETHEPARENTALEXCOMPONENTHASSEVERALCHILDRENINCLUDINGACATHYCOMPONENT:", "original": "In the following example, the parent `AlexComponent` has several children including a `CathyComponent`:", "translation": "在下面的例子中,父组件 `AlexComponent` 有几个子组件,包括 `CathyComponent`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "CATHYREPORTSWHETHERORNOTSHEHASACCESSTOALEXAFTERINJECTINGANALEXCOMPONENTINTOHERCONSTRUCTOR:", "original": "*Cathy* reports whether or not she has access to *Alex*\nafter injecting an `AlexComponent` into her constructor:", "translation": "在注入*AlexComponent` 进来后,*Cathy* 报告它是否对 *Alex* 有访问权:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NOTICETHATEVENTHOUGHTHEOPTIONALGUIDEDEPENDENCYINJECTIONINACTION#OPTIONALQUALIFIERISTHEREFORSAFETYTHELIVEEXAMPLENAMEDEPENDENCYINJECTIONINACTIONLIVEEXAMPLECONFIRMSTHATTHEALEXPARAMETERISSET", "original": "Notice that even though the [@Optional](guide/dependency-injection-in-action#optional) qualifier\nis there for safety,\nthe <live-example name=\"dependency-injection-in-action\"></live-example>\nconfirms that the `alex` parameter is set.", "translation": "注意,这里为安全起见而添加了[@Optional](guide/dependency-injection-in-action#optional)装饰器,<live-example name=\"dependency-injection-in-action\"></live-example>显示 `alex` 参数确实被设置了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###CANNOTFINDAPARENTBYITSBASECLASS", "original": "### Cannot find a parent by its base class", "translation": "### 无法通过它的基类找到一个父级", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "WHATIFYOUDONTKNOWTHECONCRETEPARENTCOMPONENTCLASS", "original": "What if you *don't* know the concrete parent component class?", "translation": "如果*不*知道具体的父组件类名怎么办?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "AREUSABLECOMPONENTMIGHTBEACHILDOFMULTIPLECOMPONENTSIMAGINEACOMPONENTFORRENDERINGBREAKINGNEWSABOUTAFINANCIALINSTRUMENTFORBUSINESSREASONSTHISNEWSCOMPONENTMAKESFREQUENTCALLSDIRECTLYINTOITSPARENTINSTRUMENTASCHANGINGMARKETDATASTREAMSBY", "original": "A re-usable component might be a child of multiple components.\nImagine a component for rendering breaking news about a financial instrument.\nFor business reasons, this news component makes frequent calls\ndirectly into its parent instrument as changing market data streams by.", "translation": "一个可复用的组件可能是多个组件的子级。想象一个用来渲染金融工具头条新闻的组件。由于商业原因,该新闻组件在实时变化的市场数据流过时,要频繁的直接调用其父级工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEAPPPROBABLYDEFINESMORETHANADOZENFINANCIALINSTRUMENTCOMPONENTSIFYOURELUCKYTHEYALLIMPLEMENTTHESAMEBASECLASSWHOSEAPIYOURNEWSCOMPONENTUNDERSTANDS", "original": "The app probably defines more than a dozen financial instrument components.\nIf you're lucky, they all implement the same base class\nwhose API your `NewsComponent` understands.", "translation": "该应用程序可能有多于一打的金融工具组件。如果幸运,它们可能会从同一个基类派生,其 API 是 `NewsComponent` 组件所能理解的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "LOOKINGFORCOMPONENTSTHATIMPLEMENTANINTERFACEWOULDBEBETTERTHATSNOTPOSSIBLEBECAUSETYPESCRIPTINTERFACESDISAPPEARFROMTHETRANSPILEDJAVASCRIPTWHICHDOESNTSUPPORTINTERFACESTHERESNOARTIFACTTOLOOKFOR", "original": "Looking for components that implement an interface would be better.\nThat's not possible because TypeScript interfaces disappear\nfrom the transpiled JavaScript, which doesn't support interfaces.\nThere's no artifact to look for.", "translation": "更好的方式是通过接口来寻找实现了它的组件。但这是不可能的,因为 TypeScript 的接口在编译成 JavaScript 以后就消失了,JavaScript 不支持接口。没有东西可查。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THISISNTNECESSARILYGOODDESIGNTHISEXAMPLEISEXAMININGWHETHERACOMPONENTCANINJECTITSPARENTVIATHEPARENTSBASECLASS", "original": "This isn't necessarily good design.\nThis example is examining *whether a component can\ninject its parent via the parent's base class*.", "translation": "这并不是好的设计。问题是*一个组件是否能通过它父组件的基类来注入它的父组件呢*?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THESAMPLESCRAIGCOMPONENTEXPLORESTHISQUESTIONLOOKINGBACKGUIDEDEPENDENCYINJECTIONINACTION#ALEXYOUSEETHATTHEALEXCOMPONENTEXTENDSINHERITSFROMACLASSNAMEDBASE", "original": "The sample's `CraigComponent` explores this question. [Looking back](guide/dependency-injection-in-action#alex),\nyou see that the `Alex` component *extends* (*inherits*) from a class named `Base`.", "translation": "`CraigComponent` 例子探究了这个问题。[往回看 Alex]{guide/dependency-injection-in-action#alex},你看到 `Alex` 组件*扩展*(*派生*)自一个叫 `Base` 的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THECRAIGCOMPONENTTRIESTOINJECTBASEINTOITSALEXCONSTRUCTORPARAMETERANDREPORTSIFITSUCCEEDED", "original": "The `CraigComponent` tries to inject `Base` into its `alex` constructor parameter and reports if it succeeded.", "translation": "`CraigComponent` 试图把 `Base` 注入到到它的 `alex` 构造函数参数,来报告是否成功。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "UNFORTUNATELYTHISDOESNOTWORKTHELIVEEXAMPLENAMEDEPENDENCYINJECTIONINACTIONLIVEEXAMPLECONFIRMSTHATTHEALEXPARAMETERISNULLYOUCANNOTINJECTAPARENTBYITSBASECLASS", "original": "Unfortunately, this does not work.\nThe <live-example name=\"dependency-injection-in-action\"></live-example>\nconfirms that the `alex` parameter is null.\n*You cannot inject a parent by its base class.*", "translation": "可惜这样不行。<live-example name=\"dependency-injection-in-action\"></live-example>显示 `alex` 参数是 null。\n*不能通过基类注入父组件*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###FINDAPARENTBYITSCLASSINTERFACE", "original": "### Find a parent by its class-interface", "translation": "### 通过类-接口找到父组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUCANFINDAPARENTCOMPONENTWITHACLASSINTERFACEGUIDEDEPENDENCYINJECTIONINACTION#CLASSINTERFACE", "original": "You can find a parent component with a [class-interface](guide/dependency-injection-in-action#class-interface).", "translation": "可以通过[类-接口](guide/dependency-injection-in-action#class-interface)找到一个父组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEPARENTMUSTCOOPERATEBYPROVIDINGANALIASTOITSELFINTHENAMEOFACLASSINTERFACETOKEN", "original": "The parent must cooperate by providing an *alias* to itself in the name of a *class-interface* token.", "translation": "该父组件必须通过提供一个与*类-接口*令牌同名的*别名*来与之合作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "RECALLTHATANGULARALWAYSADDSACOMPONENTINSTANCETOITSOWNINJECTORTHATSWHYYOUCOULDINJECTALEXINTOCATHYEARLIERGUIDEDEPENDENCYINJECTIONINACTION#KNOWNPARENT", "original": "Recall that Angular always adds a component instance to its own injector;\nthat's why you could inject *Alex* into *Cathy* [earlier](guide/dependency-injection-in-action#known-parent).", "translation": "请记住 Angular 总是从它自己的注入器添加一个组件实例;这就是为什么在[之前](guide/dependency-injection-in-action#known-parent)可以 *Alex* 注入到 *Carol*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "WRITEANALIASPROVIDERGUIDEDEPENDENCYINJECTIONINACTION#USEEXISTINGMDASHAPROVIDEOBJECTLITERALWITHAUSEEXISTINGDEFINITIONMDASHTHATCREATESANALTERNATIVEWAYTOINJECTTHESAMECOMPONENTINSTANCEANDADDTHATPROVIDERTOTHEPROVIDERSARRAYOFTHECOMPONENTMETADATAFORTHEALEXCOMPONENT:", "original": "Write an [*alias provider*](guide/dependency-injection-in-action#useexisting)—a `provide` object literal with a `useExisting`\ndefinition—that creates an *alternative* way to inject the same component instance\nand add that provider to the `providers` array of the `@Component` metadata for the `AlexComponent`:", "translation": "编写一个[*别名提供商*](guide/dependency-injection-in-action#useexisting) &mdash;一个拥有 `useExisting` 定义的 `provide` 函数 —\n它新建一个*备选的*方式来注入同一个组件实例,并把这个提供商添加到 `AlexComponent` 的 `@Component` 元数据里的 `providers` 数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "PARENTGUIDEDEPENDENCYINJECTIONINACTION#PARENTTOKENISTHEPROVIDERSCLASSINTERFACETOKENTHEFORWARDREFGUIDEDEPENDENCYINJECTIONINACTION#FORWARDREFBREAKSTHECIRCULARREFERENCEYOUJUSTCREATEDBYHAVINGTHEALEXCOMPONENTREFERTOITSELF", "original": "[Parent](guide/dependency-injection-in-action#parent-token) is the provider's *class-interface* token.\nThe [*forwardRef*](guide/dependency-injection-in-action#forwardref) breaks the circular reference you just created by having the `AlexComponent` refer to itself.", "translation": "[Parent](guide/dependency-injection-in-action#parent-token)是该提供商的*类-接口*令牌。`AlexComponent` 引用了自身,造成循环引用,使用[*forwardRef*](guide/dependency-injection-in-action#forwardref)打破了该循环。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "CAROLTHETHIRDOFALEXSCHILDCOMPONENTSINJECTSTHEPARENTINTOITSPARENTPARAMETERTHESAMEWAYYOUVEDONEITBEFORE:", "original": "*Carol*, the third of *Alex*'s child components, injects the parent into its `parent` parameter,\nthe same way you've done it before:", "translation": "*Carol*,*Alex* 的第三个子组件,把父级注入到了自己的 `parent` 参数,和之前做的一样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "HERESALEXANDFAMILYINACTION:", "original": "Here's *Alex* and family in action:", "translation": "下面是 *Alex* 和其家庭的运行结果:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###FINDTHEPARENTINATREEOFPARENTSWITHSKIPSELF", "original": "### Find the parent in a tree of parents with _@SkipSelf()_", "translation": "### 通过父级树找到父组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "IMAGINEONEBRANCHOFACOMPONENTHIERARCHY:ALICEBARRYCAROLBOTHALICEANDBARRYIMPLEMENTTHEPARENTCLASSINTERFACE", "original": "Imagine one branch of a component hierarchy: *Alice* -> *Barry* -> *Carol*.\nBoth *Alice* and *Barry* implement the `Parent` *class-interface*.", "translation": "想象组件树中的一个分支为:*Alice* -> *Barry* -> *Carol*。*Alice* 和 *Barry* 都实现了这个 `Parent`*类-接口*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "BARRYISTHEPROBLEMHENEEDSTOREACHHISPARENTALICEANDALSOBEAPARENTTOCAROLTHATMEANSHEMUSTBOTHINJECTTHEPARENTCLASSINTERFACETOGETALICEANDPROVIDEAPARENTTOSATISFYCAROL", "original": "*Barry* is the problem. He needs to reach his parent, *Alice*, and also be a parent to *Carol*.\nThat means he must both *inject* the `Parent` *class-interface* to get *Alice* and\n*provide* a `Parent` to satisfy *Carol*.", "translation": "*Barry* 是个问题。它需要访问它的父组件 *Alice*,但同时它也是 *Carol* 的父组件。这个意味着它必须同时*注入*`Parent`*类-接口*来获取 *Alice*,和*提供*一个 `Parent` 来满足 *Carol*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "HERESBARRY:", "original": "Here's *Barry*:", "translation": "下面是 *Barry* 的代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "BARRYSPROVIDERSARRAYLOOKSJUSTLIKEALEXSGUIDEDEPENDENCYINJECTIONINACTION#ALEXPROVIDERSIFYOUREGOINGTOKEEPWRITINGALIASPROVIDERSGUIDEDEPENDENCYINJECTIONINACTION#USEEXISTINGLIKETHISYOUSHOULDCREATEAHELPERFUNCTIONGUIDEDEPENDENCYINJECTIONINACTION#PROVIDEPARENT", "original": "*Barry*'s `providers` array looks just like [*Alex*'s](guide/dependency-injection-in-action#alex-providers).\nIf you're going to keep writing [*alias providers*](guide/dependency-injection-in-action#useexisting) like this you should create a [helper function](guide/dependency-injection-in-action#provideparent).", "translation": "*Barry* 的 `providers` 数组看起来很像[*Alex* 的那个](guide/dependency-injection-in-action#alex-providers).\n如果准备一直像这样编写[*别名提供商*](guide/dependency-injection-in-action#useexisting)的话,你应该建立一个[辅助函数](guide/dependency-injection-in-action#provideparent)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "FORNOWFOCUSONBARRYSCONSTRUCTOR:", "original": "For now, focus on *Barry*'s constructor:", "translation": "眼下,请注意 *Barry* 的构造函数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ITSIDENTICALTOCAROLSCONSTRUCTOREXCEPTFORTHEADDITIONALSKIPSELFDECORATOR", "original": "It's identical to *Carol*'s constructor except for the additional `@SkipSelf` decorator.", "translation": "除额外添加了一个的 `@SkipSelf` 外,它和 *Carol* 的构造函数一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "SKIPSELFISESSENTIALFORTWOREASONS:", "original": "`@SkipSelf` is essential for two reasons:", "translation": "添加 `@SkipSelf` 主要是出于两个原因:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "1ITTELLSTHEINJECTORTOSTARTITSSEARCHFORAPARENTDEPENDENCYINACOMPONENTABOVEITSELFWHICHISWHATPARENTMEANS", "original": "1. It tells the injector to start its search for a `Parent` dependency in a component *above* itself,\nwhich *is* what parent means.", "translation": "它告诉注入器从一个在自己*上一级*的组件开始搜索一个 `Parent` 依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "2ANGULARTHROWSACYCLICDEPENDENCYERRORIFYOUOMITTHESKIPSELFDECORATOR", "original": "2. Angular throws a cyclic dependency error if you omit the `@SkipSelf` decorator.", "translation": "如果没写 `@SkipSelf` 装饰器的话,Angular 就会抛出一个循环依赖错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "CANNOTINSTANTIATECYCLICDEPENDENCYBETHCOMPONENTPARENTBETHCOMPONENT", "original": "`Cannot instantiate cyclic dependency! (BethComponent -> Parent -> BethComponent)`", "translation": "` 不能创建循环依赖实例!(BethComponent -> Parent -> BethComponent)`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "HERESALICEBARRYANDFAMILYINACTION:", "original": "Here's *Alice*, *Barry* and family in action:", "translation": "这里是 *Alice*,*Barry* 和该家庭的操作演示:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###THEPARENTCLASSINTERFACE", "original": "### The *Parent* class-interface", "translation": "### *Parent* 类-接口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOULEARNEDEARLIERGUIDEDEPENDENCYINJECTIONINACTION#CLASSINTERFACETHATACLASSINTERFACEISANABSTRACTCLASSUSEDASANINTERFACERATHERTHANASABASECLASS", "original": "You [learned earlier](guide/dependency-injection-in-action#class-interface) that a *class-interface* is an abstract class used as an interface rather than as a base class.", "translation": "你[以前学过](guide/dependency-injection-in-action#class-interface):*类-接口*是一个抽象类,被当成一个接口使用,而非基类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEEXAMPLEDEFINESAPARENTCLASSINTERFACE", "original": "The example defines a `Parent` *class-interface*.", "translation": "这个例子定义了一个 `Parent`*类-接口*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEPARENTCLASSINTERFACEDEFINESANAMEPROPERTYWITHATYPEDECLARATIONBUTNOIMPLEMENTATIONTHENAMEPROPERTYISTHEONLYMEMBEROFAPARENTCOMPONENTTHATACHILDCOMPONENTCANCALLSUCHANARROWINTERFACEHELPSDECOUPLETHECHILDCOMPONENTCLASSFROMITSPARENTCOMPONENTS", "original": "The `Parent` *class-interface* defines a `name` property with a type declaration but *no implementation*.\nThe `name` property is the only member of a parent component that a child component can call.\nSuch a narrow interface helps decouple the child component class from its parent components.", "translation": "该 `Parent`*类-接口*定义了 `Name` 属性,它有类型声明,但是*没有实现*,该 `name` 是该父级的所有子组件们唯一能调用的属性。\n这种“窄接口”有助于解耦子组件类和它的父组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ACOMPONENTTHATCOULDSERVEASAPARENTSHOULDIMPLEMENTTHECLASSINTERFACEASTHEALICECOMPONENTDOES:", "original": "A component that could serve as a parent *should* implement the *class-interface* as the `AliceComponent` does:", "translation": "一个能用做父级的组件*应该*实现*类-接口*,和下面的 `AliceComponent` 的做法一样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "DOINGSOADDSCLARITYTOTHECODEBUTITSNOTTECHNICALLYNECESSARYALTHOUGHTHEALEXCOMPONENTHASANAMEPROPERTYASREQUIREDBYITSBASECLASSITSCLASSSIGNATUREDOESNTMENTIONPARENT:", "original": "Doing so adds clarity to the code. But it's not technically necessary.\nAlthough the `AlexComponent` has a `name` property, as required by its `Base` class,\nits class signature doesn't mention `Parent`:", "translation": "这样做可以提升代码的清晰度,但严格来说并不是必须的。虽然 `AlexComponent` 有一个 `name` 属性(来自 `Base` 类的要求),但它的类签名并不需要提及 `Parent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEALEXCOMPONENTSHOULDIMPLEMENTPARENTASAMATTEROFPROPERSTYLEITDOESNTINTHISEXAMPLEONLYTODEMONSTRATETHATTHECODEWILLCOMPILEANDRUNWITHOUTTHEINTERFACE", "original": "The `AlexComponent` *should* implement `Parent` as a matter of proper style.\nIt doesn't in this example *only* to demonstrate that the code will compile and run without the interface", "translation": "为了正确的代码风格,该 `AlexComponent`*应该*实现 `Parent`。在这个例子里它没有这样,只是为了演示在没有该接口的情况下,该代码仍会被正确编译并运行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "###APROVIDEPARENTHELPERFUNCTION", "original": "### A _provideParent()_ helper function", "translation": "### *provideParent()*助手函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "WRITINGVARIATIONSOFTHESAMEPARENTALIASPROVIDERGETSOLDQUICKLYESPECIALLYTHISAWFULMOUTHFULWITHAFORWARDREFGUIDEDEPENDENCYINJECTIONINACTION#FORWARDREF:", "original": "Writing variations of the same parent *alias provider* gets old quickly,\nespecially this awful mouthful with a [*forwardRef*](guide/dependency-injection-in-action#forwardref):", "translation": "编写父组件相同的各种*别名提供商*很快就会变得啰嗦,在用[*forwardRef*](guide/dependency-injection-in-action#forwardref)的时候尤其绕口:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUCANEXTRACTTHATLOGICINTOAHELPERFUNCTIONLIKETHIS:", "original": "You can extract that logic into a helper function like this:", "translation": "可以像这样把该逻辑抽取到一个助手函数里:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "NOWYOUCANADDASIMPLERMOREMEANINGFULPARENTPROVIDERTOYOURCOMPONENTS:", "original": "Now you can add a simpler, more meaningful parent provider to your components:", "translation": "现在就可以为组件添加一个更简单、直观的父级提供商了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUCANDOBETTERTHECURRENTVERSIONOFTHEHELPERFUNCTIONCANONLYALIASTHEPARENTCLASSINTERFACETHEAPPLICATIONMIGHTHAVEAVARIETYOFPARENTTYPESEACHWITHITSOWNCLASSINTERFACETOKEN", "original": "You can do better. The current version of the helper function can only alias the `Parent` *class-interface*.\nThe application might have a variety of parent types, each with its own *class-interface* token.", "translation": "你可以做得更好。当前版本的助手函数只能为 `Parent`*类-接口*提供别名。应用程序可能有很多类型的父组件,每个父组件有自己的*类-接口*令牌。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "HERESAREVISEDVERSIONTHATDEFAULTSTOPARENTBUTALSOACCEPTSANOPTIONALSECONDPARAMETERFORADIFFERENTPARENTCLASSINTERFACE", "original": "Here's a revised version that defaults to `parent` but also accepts an optional second parameter for a different parent *class-interface*.", "translation": "下面是一个修改版本,默认接受一个 `Parent`,但同时接受一个可选的第二参数,可以用来指定一个不同的父级*类-接口*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "ANDHERESHOWYOUCOULDUSEITWITHADIFFERENTPARENTTYPE:", "original": "And here's how you could use it with a different parent type:", "translation": "下面的代码演示了如何使它添加一个不同类型的父级:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "##BREAKCIRCULARITIESWITHAFORWARDCLASSREFERENCEFORWARDREF", "original": "## Break circularities with a forward class reference (*forwardRef*)", "translation": "## 使用一个前向引用(*forwardRef*)来打破循环", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEORDEROFCLASSDECLARATIONMATTERSINTYPESCRIPTYOUCANTREFERDIRECTLYTOACLASSUNTILITSBEENDEFINED", "original": "The order of class declaration matters in TypeScript.\nYou can't refer directly to a class until it's been defined.", "translation": "在 TypeScript 里面,类声明的顺序是很重要的。如果一个类尚未定义,就不能引用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THISISNTUSUALLYAPROBLEMESPECIALLYIFYOUADHERETOTHERECOMMENDEDONECLASSPERFILERULEBUTSOMETIMESCIRCULARREFERENCESAREUNAVOIDABLEYOUREINABINDWHENCLASSAREFERSTOCLASSBANDBREFERSTOAONEOFTHEMHASTOBEDEFINEDFIRST", "original": "This isn't usually a problem, especially if you adhere to the recommended *one class per file* rule.\nBut sometimes circular references are unavoidable.\nYou're in a bind when class 'A' refers to class 'B' and 'B' refers to 'A'.\nOne of them has to be defined first.", "translation": "这通常不是一个问题,特别是当你遵循*一个文件一个类*规则的时候。\n但是有时候循环引用可能不能避免。当一个类*A 引用类 B*,同时'B'引用'A'的时候,你就陷入困境了:它们中间的某一个必须要先定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEANGULARFORWARDREFFUNCTIONCREATESANINDIRECTREFERENCETHATANGULARCANRESOLVELATER", "original": "The Angular `forwardRef()` function creates an *indirect* reference that Angular can resolve later.", "translation": "Angular 的 `forwardRef()` 函数建立一个*间接地*引用,Angular 可以随后解析。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "THEPARENTFINDERSAMPLEISFULLOFCIRCULARCLASSREFERENCESTHATAREIMPOSSIBLETOBREAK", "original": "The *Parent Finder* sample is full of circular class references that are impossible to break.", "translation": "*Parent Finder*是一个充满了无法解决的循环引用的例子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "YOUFACETHISDILEMMAWHENACLASSMAKESAREFERENCETOITSELFASDOESTHEALEXCOMPONENTINITSPROVIDERSARRAYTHEPROVIDERSARRAYISAPROPERTYOFTHECOMPONENTDECORATORFUNCTIONWHICHMUSTAPPEARABOVETHECLASSDEFINITION", "original": "You face this dilemma when a class makes *a reference to itself*\nas does the `AlexComponent` in its `providers` array.\nThe `providers` array is a property of the `@Component` decorator function which must\nappear *above* the class definition.", "translation": "当一个类*需要引用自身*的时候,你面临同样的困境,就像在 `AlexComponent` 的 `provdiers` 数组中遇到的困境一样。\n该 `providers` 数组是一个 `@Component` 装饰器函数的一个属性,它必须在类定义*之前*出现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "BREAKTHECIRCULARITYWITHFORWARDREF:", "original": "Break the circularity with `forwardRef`:", "translation": "使用 `forwardRef` 来打破这种循环:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-in-action.md" }, { + "key": "#THEDEPENDENCYINJECTIONPATTERN", "original": "# The Dependency Injection pattern", "translation": "# 依赖注入(Dependency injection)模式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "DEPENDENCYINJECTIONISANIMPORTANTAPPLICATIONDESIGNPATTERNITSUSEDSOWIDELYTHATALMOSTEVERYONEJUSTCALLSITDI", "original": "**Dependency injection** is an important application design pattern.\nIt's used so widely that almost everyone just calls it _DI_.", "translation": "**依赖注入**是一个很重要的设计模式。\n它使用得非常广泛,以至于几乎每个人都把它简称为 *DI* 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "ANGULARHASITSOWNDEPENDENCYINJECTIONFRAMEWORKANDYOUREALLYCANTBUILDANANGULARAPPLICATIONWITHOUTIT", "original": "Angular has its own dependency injection framework, and\nyou really can't build an Angular application without it.", "translation": "Angular 有自己的依赖注入框架,离开它,你几乎没办法构建出 Angular 应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THISPAGECOVERSWHATDIISANDWHYITSUSEFUL", "original": "This page covers what DI is and why it's useful.", "translation": "本页会告诉你 DI 是什么,以及为什么它很有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "WHENYOUVELEARNEDTHEGENERALPATTERNYOUREREADYTOTURNTOTHEANGULARDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONGUIDETOSEEHOWITWORKSINANANGULARAPP", "original": "When you've learned the general pattern, you're ready to turn to\nthe [Angular Dependency Injection](guide/dependency-injection) guide to see how it works in an Angular app.", "translation": "当你学会了这种通用的模式之后,就可以转到 [Angular 依赖注入](guide/dependency-injection) 中去看看它在 Angular 应用中的工作原理了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "##WHYDEPENDENCYINJECTION", "original": "## Why dependency injection?", "translation": "## 为什么需要依赖注入?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "TOUNDERSTANDWHYDEPENDENCYINJECTIONISSOIMPORTANTCONSIDERANEXAMPLEWITHOUTITIMAGINEWRITINGTHEFOLLOWINGCODE:", "original": "To understand why dependency injection is so important, consider an example without it.\nImagine writing the following code:", "translation": "要理解为什么依赖注入这么重要,不妨先考虑不使用它的一个例子。想象下列代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THECARCLASSCREATESEVERYTHINGITNEEDSINSIDEITSCONSTRUCTORWHATSTHEPROBLEMTHEPROBLEMISTHATTHECARCLASSISBRITTLEINFLEXIBLEANDHARDTOTEST", "original": "The `Car` class creates everything it needs inside its constructor.\nWhat's the problem?\nThe problem is that the `Car` class is brittle, inflexible, and hard to test.", "translation": "`Car` 类在自己的构造函数中创建了它所需的一切。\n这样做有什么问题?\n问题在于 `Car` 类是脆弱、不灵活以及难于测试的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THISCARNEEDSANENGINEANDTIRESINSTEADOFASKINGFORTHEMTHECARCONSTRUCTORINSTANTIATESITSOWNCOPIESFROMTHEVERYSPECIFICCLASSESENGINEANDTIRES", "original": "This `Car` needs an engine and tires. Instead of asking for them,\nthe `Car` constructor instantiates its own copies from\nthe very specific classes `Engine` and `Tires`.", "translation": "`Car` 类需要一个引擎 (engine) 和一些轮胎 (tire),它没有去请求现成的实例,\n而是在构造函数中用具体的 `Engine` 和 `Tires` 类实例化出自己的副本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "WHATIFTHEENGINECLASSEVOLVESANDITSCONSTRUCTORREQUIRESAPARAMETERTHATWOULDBREAKTHECARCLASSANDITWOULDSTAYBROKENUNTILYOUREWROTEITALONGTHELINESOFTHISENGINENEWENGINETHENEWPARAMETERTHEENGINECONSTRUCTORPARAMETERSWERENTEVENACONSIDERATIONWHENYOUFIRSTWROTECARYOUMAYNOTANTICIPATETHEMEVENNOWBUTYOULLHAVETOSTARTCARINGBECAUSEWHENTHEDEFINITIONOFENGINECHANGESTHECARCLASSMUSTCHANGETHATMAKESCARBRITTLE", "original": "What if the `Engine` class evolves and its constructor requires a parameter?\nThat would break the `Car` class and it would stay broken until you rewrote it along the lines of\n`this.engine = new Engine(theNewParameter)`.\nThe `Engine` constructor parameters weren't even a consideration when you first wrote `Car`.\nYou may not anticipate them even now.\nBut you'll *have* to start caring because\nwhen the definition of `Engine` changes, the `Car` class must change.\nThat makes `Car` brittle.", "translation": "如果 `Engine` 类升级了,它的构造函数要求传入一个参数,这该怎么办?\n这个 `Car` 类就被破坏了,在把创建引擎的代码重写为 `this.engine = new Engine(theNewParameter)` 之前,它都是坏的。\n当第一次写 `Car` 类时,你不关心 `Engine` 构造函数的参数,现在也不想关心。\n但是,当 `Engine` 类的定义发生变化时,就不得不在乎了,`Car` 类也不得不跟着改变。\n这就会让 `Car` 类过于脆弱。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "WHATIFYOUWANTTOPUTADIFFERENTBRANDOFTIRESONYOURCARTOOBADYOURELOCKEDINTOWHATEVERBRANDTHETIRESCLASSCREATESTHATMAKESTHECARCLASSINFLEXIBLE", "original": "What if you want to put a different brand of tires on your `Car`? Too bad.\nYou're locked into whatever brand the `Tires` class creates. That makes the\n`Car` class inflexible.", "translation": "如果想在 `Car` 上使用不同品牌的轮胎会怎样?太糟了。\n你被锁定在 `Tires` 类创建时使用的那个品牌上。这让 `Car` 类缺乏弹性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "RIGHTNOWEACHNEWCARGETSITSOWNENGINEITCANTSHAREANENGINEWITHOTHERCARSWHILETHATMAKESSENSEFORANAUTOMOBILEENGINESURELYYOUCANTHINKOFOTHERDEPENDENCIESTHATSHOULDBESHAREDSUCHASTHEONBOARDWIRELESSCONNECTIONTOTHEMANUFACTURERSSERVICECENTERTHISCARLACKSTHEFLEXIBILITYTOSHARESERVICESTHATHAVEBEENCREATEDPREVIOUSLYFOROTHERCONSUMERS", "original": "Right now each new car gets its own `engine`. It can't share an `engine` with other cars.\nWhile that makes sense for an automobile engine,\nsurely you can think of other dependencies that should be shared, such as the onboard\nwireless connection to the manufacturer's service center. This `Car` lacks the flexibility\nto share services that have been created previously for other consumers.", "translation": "现在,每辆车都有它自己的引擎。它不能和其它车辆共享引擎。\n虽然这对于汽车来说还算可以理解,但是设想一下那些应该被共享的依赖,比如用来联系厂家服务中心的车载无线电。\n这种车缺乏必要的弹性,无法共享当初给其它消费者创建的车载无线电。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "WHENYOUWRITETESTSFORCARYOUREATTHEMERCYOFITSHIDDENDEPENDENCIESISITEVENPOSSIBLETOCREATEANEWENGINEINATESTENVIRONMENTWHATDOESENGINEDEPENDUPONWHATDOESTHATDEPENDENCYDEPENDONWILLANEWINSTANCEOFENGINEMAKEANASYNCHRONOUSCALLTOTHESERVERYOUCERTAINLYDONTWANTTHATGOINGONDURINGTESTS", "original": "When you write tests for `Car` you're at the mercy of its hidden dependencies.\nIs it even possible to create a new `Engine` in a test environment?\nWhat does `Engine` depend upon? What does that dependency depend on?\nWill a new instance of `Engine` make an asynchronous call to the server?\nYou certainly don't want that going on during tests.", "translation": "当给 `Car` 类写测试的时候,你就会受制于它背后的那些依赖。\n能在测试环境中成功创建新的 `Engine` 吗?\n`Engine` 自己又依赖什么?那些依赖本身又依赖什么?\n`Engine` 的新实例会发起到服务器的异步调用吗?\n你当然不想在测试期间这么一层层追下去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "WHATIFTHECARSHOULDFLASHAWARNINGSIGNALWHENTIREPRESSUREISLOWHOWDOYOUCONFIRMTHATITACTUALLYDOESFLASHAWARNINGIFYOUCANTSWAPINLOWPRESSURETIRESDURINGTHETEST", "original": "What if the `Car` should flash a warning signal when tire pressure is low?\nHow do you confirm that it actually does flash a warning\nif you can't swap in low-pressure tires during the test?", "translation": "如果 `Car` 应该在轮胎气压低的时候闪动警示灯该怎么办?\n如果没法在测试期间换上一个低气压的轮胎,那该如何确认它能正确的闪警示灯?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "YOUHAVENOCONTROLOVERTHECARSHIDDENDEPENDENCIESWHENYOUCANTCONTROLTHEDEPENDENCIESACLASSBECOMESDIFFICULTTOTEST", "original": "You have no control over the car's hidden dependencies.\nWhen you can't control the dependencies, a class becomes difficult to test.", "translation": "你没法控制这辆车背后隐藏的依赖。\n当不能控制依赖时,类就会变得难以测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "HOWCANYOUMAKECARMOREROBUSTFLEXIBLEANDTESTABLE", "original": "How can you make `Car` more robust, flexible, and testable?", "translation": "该如何让 `Car` 更强壮、有弹性以及可测试?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THATSSUPEREASYCHANGETHECARCONSTRUCTORTOAVERSIONWITHDI:", "original": "That's super easy. Change the `Car` constructor to a version with DI:", "translation": "答案非常简单。把 `Car` 的构造函数改造成使用 DI 的版本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "SEEWHATHAPPENEDTHEDEFINITIONOFTHEDEPENDENCIESARENOWINTHECONSTRUCTORTHECARCLASSNOLONGERCREATESANENGINEORTIRESITJUSTCONSUMESTHEM", "original": "See what happened? The definition of the dependencies are\nnow in the constructor.\nThe `Car` class no longer creates an `engine` or `tires`.\nIt just consumes them.", "translation": "发生了什么?现在依赖的定义移到了构造函数中。\n `Car` 类不再创建引擎 `engine` 或者轮胎 `tires`。\n 它仅仅“消费”它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THISEXAMPLELEVERAGESTYPESCRIPTSCONSTRUCTORSYNTAXFORDECLARINGPARAMETERSANDPROPERTIESSIMULTANEOUSLY", "original": "This example leverages TypeScript's constructor syntax for declaring\nparameters and properties simultaneously.", "translation": "这个例子又一次借助 TypeScript 的构造器语法来同时定义参数和属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "NOWYOUCANCREATEACARBYPASSINGTHEENGINEANDTIRESTOTHECONSTRUCTOR", "original": "Now you can create a car by passing the engine and tires to the constructor.", "translation": "现在,通过往构造函数中传入引擎和轮胎来创建一辆车。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "HOWCOOLISTHATTHEDEFINITIONOFTHEENGINEANDTIREDEPENDENCIESAREDECOUPLEDFROMTHECARCLASSYOUCANPASSINANYKINDOFENGINEORTIRESYOULIKEASLONGASTHEYCONFORMTOTHEGENERALAPIREQUIREMENTSOFANENGINEORTIRES", "original": "How cool is that?\nThe definition of the `engine` and `tire` dependencies are\ndecoupled from the `Car` class.\nYou can pass in any kind of `engine` or `tires` you like, as long as they\nconform to the general API requirements of an `engine` or `tires`.", "translation": "酷!引擎和轮胎这两个依赖的定义与 `Car` 类本身解耦了。\n只要喜欢,可以传入任何类型的引擎或轮胎,只要它们能满足引擎或轮胎的通用 API 需求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "NOWIFSOMEONEEXTENDSTHEENGINECLASSTHATISNOTCARSPROBLEM", "original": "Now, if someone extends the `Engine` class, that is not `Car`'s problem.", "translation": "这样一来,如果有人扩展了 `Engine` 类,那就不再是 `Car` 类的烦恼了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THECONSUMEROFCARHASTHEPROBLEMTHECONSUMERMUSTUPDATETHECARCREATIONCODETOSOMETHINGLIKETHIS:", "original": "The _consumer_ of `Car` has the problem. The consumer must update the car creation code to\nsomething like this:", "translation": "`Car` 的*消费者*也有这个问题。消费者必须修改创建这辆车的代码,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THECRITICALPOINTISTHIS:THECARCLASSDIDNOTHAVETOCHANGEYOULLTAKECAREOFTHECONSUMERSPROBLEMSHORTLY", "original": "The critical point is this: the `Car` class did not have to change.\nYou'll take care of the consumer's problem shortly.", "translation": "这里的要点是:`Car` 本身不必变化。下面就来解决消费者的问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THECARCLASSISMUCHEASIERTOTESTNOWBECAUSEYOUAREINCOMPLETECONTROLOFITSDEPENDENCIESYOUCANPASSMOCKSTOTHECONSTRUCTORTHATDOEXACTLYWHATYOUWANTTHEMTODODURINGEACHTEST:", "original": "The `Car` class is much easier to test now because you are in complete control\nof its dependencies.\nYou can pass mocks to the constructor that do exactly what you want them to do\nduring each test:", "translation": "`Car` 类非常容易测试,因为现在你对它的依赖有了完全的控制权。\n 在每个测试期间,你可以往构造函数中传入 mock 对象,做想让它们做的事:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "YOUJUSTLEARNEDWHATDEPENDENCYINJECTIONIS", "original": "**You just learned what dependency injection is**.", "translation": "**刚刚学习了什么是依赖注入**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "ITSACODINGPATTERNINWHICHACLASSRECEIVESITSDEPENDENCIESFROMEXTERNALSOURCESRATHERTHANCREATINGTHEMITSELF", "original": "It's a coding pattern in which a class receives its dependencies from external\nsources rather than creating them itself.", "translation": "它是一种编程模式,可以让类从外部源中获得它的依赖,而不必亲自创建它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "COOLBUTWHATABOUTTHATPOORCONSUMERANYONEWHOWANTSACARMUSTNOWCREATEALLTHREEPARTS:THECARENGINEANDTIRESTHECARCLASSSHEDITSPROBLEMSATTHECONSUMERSEXPENSEYOUNEEDSOMETHINGTHATTAKESCAREOFASSEMBLINGTHESEPARTS", "original": "Cool! But what about that poor consumer?\nAnyone who wants a `Car` must now\ncreate all three parts: the `Car`, `Engine`, and `Tires`.\nThe `Car` class shed its problems at the consumer's expense.\nYou need something that takes care of assembling these parts.", "translation": "酷!但是,可怜的消费者怎么办?\n 那些希望得到一个 `Car` 的人们现在必须创建所有这三部分了:`Car`、`Engine` 和 `Tires`。\n `Car` 类把它的快乐建立在了消费者的痛苦之上。\n 需要某种机制为你把这三个部分装配好。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "YOUCOULDWRITEAGIANTCLASSTODOTHAT:", "original": "You _could_ write a giant class to do that:", "translation": "可以写一个巨型类来做这件事:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "ITSNOTSOBADNOWWITHONLYTHREECREATIONMETHODSBUTMAINTAININGITWILLBEHAIRYASTHEAPPLICATIONGROWSTHISFACTORYISGOINGTOBECOMEAHUGESPIDERWEBOFINTERDEPENDENTFACTORYMETHODS", "original": "It's not so bad now with only three creation methods.\nBut maintaining it will be hairy as the application grows.\nThis factory is going to become a huge spiderweb of\ninterdependent factory methods!", "translation": "现在只需要三个创建方法,这还不算太坏。\n但是当应用规模变大之后,维护它将变得惊险重重。\n这个工厂类将变成由相互依赖的工厂方法构成的巨型蜘蛛网。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "WOULDNTITBENICEIFYOUCOULDSIMPLYLISTTHETHINGSYOUWANTTOBUILDWITHOUTHAVINGTODEFINEWHICHDEPENDENCYGETSINJECTEDINTOWHAT", "original": "Wouldn't it be nice if you could simply list the things you want to build without\nhaving to define which dependency gets injected into what?", "translation": "如果能简单的列出想建造的东西,而不用定义该把哪些依赖注入到哪些对象中,那该多好!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THISISWHERETHEDEPENDENCYINJECTIONFRAMEWORKCOMESINTOPLAYIMAGINETHEFRAMEWORKHADSOMETHINGCALLEDANINJECTORYOUREGISTERSOMECLASSESWITHTHISINJECTORANDITFIGURESOUTHOWTOCREATETHEM", "original": "This is where the dependency injection framework comes into play.\nImagine the framework had something called an _injector_.\nYou register some classes with this injector, and it figures out how to create them.", "translation": "到了依赖注入框架一展身手的时候了!\n想象框架中有一个叫做*注入器 (injector)* 的东西。\n用这个注入器注册一些类,它会弄明白如何创建它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "WHENYOUNEEDACARYOUSIMPLYASKTHEINJECTORTOGETITFORYOUANDYOUREGOODTOGO", "original": "When you need a `Car`, you simply ask the injector to get it for you and you're good to go.", "translation": "当需要一个 `Car` 时,就简单的找注入器取车就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "EVERYONEWINSTHECARKNOWSNOTHINGABOUTCREATINGANENGINEORTIRESTHECONSUMERKNOWSNOTHINGABOUTCREATINGACARYOUDONTHAVEAGIGANTICFACTORYCLASSTOMAINTAINBOTHCARANDCONSUMERSIMPLYASKFORWHATTHEYNEEDANDTHEINJECTORDELIVERS", "original": "Everyone wins. The `Car` knows nothing about creating an `Engine` or `Tires`.\nThe consumer knows nothing about creating a `Car`.\nYou don't have a gigantic factory class to maintain.\nBoth `Car` and consumer simply ask for what they need and the injector delivers.", "translation": "皆大欢喜。`Car` 不需要知道如何创建 `Engine` 和 `Tires`。\n消费者不需要知道如何创建 `Car`。\n开发人员不需要维护巨大的工厂类。\n`Car` 和消费者只要简单地请求想要什么,注入器就会交付它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "THISISWHATADEPENDENCYINJECTIONFRAMEWORKISALLABOUT", "original": "This is what a **dependency injection framework** is all about.", "translation": "这就是“**依赖注入框架**”存在的原因。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "NOWTHATYOUKNOWWHATDEPENDENCYINJECTIONISANDAPPRECIATEITSBENEFITSTURNTOTHEANGULARDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONGUIDETOSEEHOWITISIMPLEMENTEDINANGULAR", "original": "Now that you know what dependency injection is and appreciate its benefits,\nturn to the [Angular Dependency Injection](guide/dependency-injection) guide to see how it is implemented in Angular.", "translation": "现在,你知道什么是依赖注入以及它有什么优点了吧?那就请到 [Angular 依赖注入](guide/dependency-injection) 中去看看它在 Angular 中是如何实现的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection-pattern.md" }, { + "key": "#ANGULARDEPENDENCYINJECTION", "original": "# Angular Dependency Injection", "translation": "# Angular 依赖注入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "DEPENDENCYINJECTIONDIISAWAYTOCREATEOBJECTSTHATDEPENDUPONOTHEROBJECTSADEPENDENCYINJECTIONSYSTEMSUPPLIESTHEDEPENDENTOBJECTSCALLEDTHEDEPENDENCIESWHENITCREATESANINSTANCEOFANOBJECT", "original": "**Dependency Injection (DI)** is a way to create objects that depend upon other objects.\nA Dependency Injection system supplies the dependent objects (called the _dependencies_)\nwhen it creates an instance of an object.", "translation": "**依赖注入(DI)**是用来创建对象及其依赖的其它对象的一种方式。\n当依赖注入系统创建某个对象实例时,会负责提供该对象所依赖的对象(称为该对象的*依赖*)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEDEPENDENCYINJECTIONPATTERNGUIDEDEPENDENCYINJECTIONPATTERNPAGEDESCRIBESTHISGENERALAPPROACHTHEGUIDEYOUREREADINGNOWEXPLAINSHOWANGULARSOWNDEPENDENCYINJECTIONSYSTEMWORKS", "original": "The [Dependency Injection pattern](guide/dependency-injection-pattern) page describes this general approach.\n_The guide you're reading now_ explains how Angular's own Dependency Injection system works.", "translation": "[依赖注入模式](guide/dependency-injection-pattern)中讲解了这种通用的方法。\n*在这里*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##DIBYEXAMPLE", "original": "## DI by example", "translation": "## DI 的例子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOULLLEARNANGULARDEPENDENCYINJECTIONTHROUGHADISCUSSIONOFTHESAMPLEAPPTHATACCOMPANIESTHISGUIDERUNTHELIVEEXAMPLELIVEEXAMPLEANYTIME", "original": "You'll learn Angular Dependency Injection through a discussion of the sample app that accompanies this guide.\nRun the <live-example></live-example> anytime.", "translation": "在这篇指南中,你将会通过对一个范例应用的讨论来学习 Angular 的依赖注入技术。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "STARTBYREVIEWINGTHISSIMPLIFIEDVERSIONOFTHEHEROESFEATUREFROMTHETHETOUROFHEROESTUTORIAL", "original": "Start by reviewing this simplified version of the _heroes_ feature\nfrom the [The Tour of Heroes](tutorial/).", "translation": "先从[《英雄指南》](tutorial/)中*英雄*特性区的一个简化版本开始。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEHEROESCOMPONENTISTHETOPLEVELHEROESCOMPONENTITSONLYPURPOSEISTODISPLAYTHEHEROLISTCOMPONENTWHICHDISPLAYSALISTOFHERONAMES", "original": "The `HeroesComponent` is the top-level heroes component.\nIt's only purpose is to display the `HeroListComponent`\nwhich displays a list of hero names.", "translation": "`HeroesComponent` 是位于顶级的组件。\n它唯一的用途是显示 `HeroListComponent`,它显示一个英雄名字的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THISVERSIONOFTHEHEROLISTCOMPONENTGETSITSHEROESFROMTHEHEROESARRAYANINMEMORYCOLLECTIONDEFINEDINASEPARATEMOCKHEROESFILE", "original": "This version of the `HeroListComponent` gets its `heroes` from the `HEROES` array, an in-memory collection\ndefined in a separate `mock-heroes` file.", "translation": "这个版本的 `HeroListComponent` 从 `HEROES` 数组(定义在 `mock-heroes` 文件中的内存数组)中获取 `heroes`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THATMAYSUFFICEINTHEEARLYSTAGESOFDEVELOPMENTBUTITSFARFROMIDEALASSOONASYOUTRYTOTESTTHISCOMPONENTORGETHEROESFROMAREMOTESERVERYOULLHAVETOCHANGETHEIMPLEMENTATIONOFHEROSLISTCOMPONENTANDREPLACEEVERYOTHERUSEOFTHEHEROESMOCKDATA", "original": "That may suffice in the early stages of development, but it's far from ideal.\nAs soon as you try to test this component or get heroes from a remote server,\nyou'll have to change the implementation of `HerosListComponent` and\nreplace every other use of the `HEROES` mock data.", "translation": "在开发的早期阶段,这就够用了,不过还很不理想。\n当要测试这个组件或者要从远端服务器获取英雄数据时,你就不得不去修改 `HeroesListComponent` 的实现,并要替换所有使用了 `HEROES` 模拟数据的地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ITSBETTERTOHIDETHESEDETAILSINSIDEASERVICECLASSDEFINEDINITSOWNFILE#ONECLASSPERFILE", "original": "It's better to hide these details inside a _service_ class, \n[defined in its own file](#one-class-per-file).", "translation": "最好隐藏服务类的这些内部实现细节,那就先[把它定义在自己的文件中](#one-class-per-file)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##CREATEANINJECTABLEHEROSERVICE", "original": "## Create an injectable _HeroService_", "translation": "## 创建一个可注入的 `HeroService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEANGULARCLIHTTPS:CLIANGULARIOCANGENERATEANEWHEROSERVICECLASSINTHESRCAPPHEROESFOLDERWITHTHISCOMMAND", "original": "The [**Angular CLI**](https://cli.angular.io/) can generate a new `HeroService` class in the `src/app/heroes` folder with this command.", "translation": "[**Angular CLI**](https://cli.angular.io/) 可以使用下列命令在 `src/app/heroes` 目录下新建一个 `HeroService` 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THATCOMMANDCREATESTHEFOLLOWINGHEROSERVICESKELETON", "original": "That command creates the following `HeroService` skeleton.", "translation": "这条命令会创建如下的 `HeroService` 骨架代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ASSUMEFORNOWTHATTHEINJECTABLEDECORATOR#INJECTABLEISANESSENTIALINGREDIENTINEVERYANGULARSERVICEDEFINITIONTHERESTOFTHECLASSHASBEENREWRITTENTOEXPOSEAGETHEROESMETHODTHATRETURNSTHESAMEMOCKDATAASBEFORE", "original": "Assume for now that the [`@Injectable` decorator](#injectable) is an essential ingredient in every Angular service definition.\nThe rest of the class has been rewritten to expose a `getHeroes` method \nthat returns the same mock data as before.", "translation": "目前先把 [`@Injectable` 装饰器](#injectable)当做定义每个 Angular 服务时的必备部分。\n把该类的其它部分改写为暴露一个返回和以前一样的 mock 数据的 `getHeroes` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "OFCOURSETHISISNTAREALDATASERVICEIFTHEAPPWEREACTUALLYGETTINGDATAFROMAREMOTESERVERTHEGETHEROESMETHODSIGNATUREWOULDHAVETOBEASYNCHRONOUS", "original": "Of course, this isn't a real data service.\nIf the app were actually getting data from a remote server, \nthe `getHeroes` method signature would have to be asynchronous.", "translation": "当然,这还不是真正的数据服务。\n如果该应用真的从远端服务器获取数据,那么 `getHeroes` 的方法签名就应该是异步形式的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THATSADEFECTWECANSAFELYIGNOREINTHISGUIDEWHEREOURFOCUSISONINJECTINGTHESERVICEINTOTHEHEROLISTCOMPONENT", "original": "That's a defect we can safely ignore in this guide where our focus is on\n_injecting the service_ into the `HeroList` component.", "translation": "我们可以放心地忽略这个问题,因为这里的焦点在于*把服务注入*到 `HeroListComponent` 组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##REGISTERASERVICEPROVIDER", "original": "## Register a service provider", "translation": "## 注册服务提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ASERVICEISJUSTACLASSINANGULARUNTILYOUREGISTERITWITHANANGULARDEPENDENCYINJECTOR", "original": "A _service_ is just a class in Angular until you register it with an Angular dependency injector.", "translation": "在你把 Angular 中的*服务*注册进依赖注入器(injector)之前,它只是一个普通的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ANANGULARINJECTORISRESPONSIBLEFORCREATINGSERVICEINSTANCESANDINJECTINGTHEMINTOCLASSESLIKETHEHEROLISTCOMPONENT", "original": "An Angular injector is responsible for creating service instances and injecting them into classes like the `HeroListComponent`.", "translation": "Angular 的依赖注入器负责创建服务的实例,并把它们注入到像 `HeroListComponent` 这样的类中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOURARELYCREATEANANGULARINJECTORYOURSELFANGULARCREATESINJECTORSFORYOUASITEXECUTESTHEAPPSTARTINGWITHTHEROOTINJECTORTHATITCREATESDURINGTHEBOOTSTRAPPROCESSGUIDEBOOTSTRAPPING", "original": "You rarely create an Angular injector yourself.\nAngular creates injectors for you as it executes the app,\nstarting with the _root injector_ that it creates during the [bootstrap process](guide/bootstrapping).", "translation": "你很少需要自己创建 Angular 的依赖注入器。\n当 Angular 运行本应用时,它会为你创建这些注入器,首先会在[引导过程](guide/bootstrapping)中创建一个*根注入器*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUDOHAVETOREGISTERPROVIDERSWITHANINJECTORBEFORETHEINJECTORCANCREATETHATSERVICE", "original": "You do have to register _providers_ with an injector \nbefore the injector can create that service.", "translation": "但在注入器能创建服务之前,你得先往注入器中注入这个服务的*提供商*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "PROVIDERSTELLTHEINJECTORHOWTOCREATETHESERVICEWITHOUTAPROVIDERTHEINJECTORWOULDNOTKNOWTHATITISRESPONSIBLEFORINJECTINGTHESERVICENORBEABLETOCREATETHESERVICE", "original": "**Providers** tell the injector _how to create the service_.\nWithout a provider, the injector would not know\nthat it is responsible for injecting the service\nnor be able to create the service.", "translation": "**提供商**会告诉注入器*如何创建该服务*。\n如果没有提供商,注入器既不知道它该负责创建该服务,也不知道如何创建该服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOULLLEARNMUCHMOREABOUTPROVIDERSBELOW#PROVIDERSFORNOWITISSUFFICIENTTOKNOWTHATTHEYCREATESERVICESANDMUSTBEREGISTEREDWITHANINJECTOR", "original": "You'll learn much more about _providers_ [below](#providers).\nFor now it is sufficient to know that they create services\nand must be registered with an injector.", "translation": "你可以在[稍后的部分](#providers)学到更多关于*提供商*的知识。\n不过目前,只要知道它们用于创建服务,以及它们必须用注入器进行注册就行了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUCANREGISTERAPROVIDERWITHANYANGULARDECORATORTHATSUPPORTSTHEPROVIDERSARRAYPROPERTY", "original": "You can register a provider with any Angular decorator that supports the **`providers` array property**.", "translation": "你可以使用 Angular 中那些支持 `providers` 数组属性的装饰器来注册提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "MANYANGULARDECORATORSACCEPTMETADATAWITHAPROVIDERSPROPERTYTHETWOMOSTIMPORTANTEXAMPLESARECOMPONENTANDNGMODULE", "original": "Many Angular decorators accept metadata with a `providers` property.\nThe two most important examples are `@Component` and `@NgModule`.", "translation": "很多 Angular 的装饰器都支持带有 `providers` 属性的元数据。\n最重要的两个例子是 `@Component` 和 `@NgModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###COMPONENTPROVIDERS", "original": "### _@Component_ providers", "translation": "### 在组件中注册提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "HERESAREVISEDHEROESCOMPONENTTHATREGISTERSTHEHEROSERVICEINITSPROVIDERSARRAY", "original": "Here's a revised `HeroesComponent` that registers the `HeroService` in its `providers` array.", "translation": "下面是修改过的 `HerosComponent`,把 `HeroService` 注册到了它的 `providers` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###NGMODULEPROVIDERS", "original": "### _@NgModule_ providers", "translation": "### `@NgModule` 中的 `providers`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "INTHEFOLLOWINGEXCERPTTHEROOTAPPMODULEREGISTERSTWOPROVIDERSINITSPROVIDERSARRAY", "original": "In the following excerpt, the root `AppModule` registers two providers in its `providers` array.", "translation": "在下面的代码片段中,根模块 `AppModule` 在自己的 `providers` 数组中注册了两个提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEFIRSTENTRYREGISTERSTHEUSERSERVICECLASSNOTSHOWNUNDERTHEUSERSERVICEINJECTIONTOKENTHESECONDREGISTERSAVALUEHERODICONFIGUNDERTHEAPPCONFIGINJECTIONTOKEN", "original": "The first entry registers the `UserService` class (_not shown_) under the `UserService` _injection token_.\nThe second registers a value (`HERO_DI_CONFIG`) under the `APP_CONFIG` _injection token_.", "translation": "第一条使用 `UserService` 这个*注入令牌(injection token)*注册了 `UserService` 类(代码中未显示)。\n第二条使用 `APP_CONFIG` 这个注入令牌注册了一个值(`HERO_DI_CONFIG`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THANKSTOTHESEREGISTRATIONSANGULARCANINJECTTHEUSERSERVICEORTHEHERODICONFIGVALUEINTOANYCLASSTHATITCREATES", "original": "Thanks to these registrations, Angular can inject the `UserService` or the `HERO_DI_CONFIG` value\ninto any class that it creates.", "translation": "得益于这些注册语句,Angular 现在可以向它创建的任何类中注册 `UserService` 或 `HERO_DI_CONFIG` 值了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOULLLEARNABOUTINJECTIONTOKENSANDPROVIDERSYNTAXBELOW#PROVIDERS", "original": "You'll learn about _injection tokens_ and _provider_ syntax [below](#providers).", "translation": "[稍后](#providers)你就会学到关于*注入令牌*和服务提供商语法的知识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###NGMODULEORCOMPONENT", "original": "### _@NgModule_ or _@Component_?", "translation": "### _@NgModule_ 还是 _@Component_?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "SHOULDYOUREGISTERASERVICEWITHANANGULARMODULEORWITHACOMPONENTTHETWOCHOICESLEADTODIFFERENCESINSERVICESCOPEANDSERVICELIFETIME", "original": "Should you register a service with an Angular module or with a component?\nThe two choices lead to differences in service _scope_ and service _lifetime_.", "translation": "你该使用 Angular 的模块还是组件来注册服务呢?\n这两个选择的差别在于服务的*范围*和*生命周期*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ANGULARMODULEPROVIDERSNGMODULEPROVIDERSAREREGISTEREDWITHTHEAPPLICATIONSROOTINJECTORANGULARCANINJECTTHECORRESPONDINGSERVICESINANYCLASSITCREATESONCECREATEDASERVICEINSTANCELIVESFORTHELIFEOFTHEAPPANDANGULARINJECTSTHISONESERVICEINSTANCEINEVERYCLASSTHATNEEDSIT", "original": "**Angular module providers** (`@NgModule.providers`) are registered with the application's root injector.\nAngular can inject the corresponding services in any class it creates.\nOnce created, a service instance lives for the life of the app and Angular injects this one service instance in every class that needs it.", "translation": "**Angular 模块中的 `providers`**(`@NgModule.providers`)是注册在应用的根注入器下的。\n因此,Angular 可以往它所创建的任何类中注入相应的服务。 \n一旦创建,服务的实例就会存在于该应用的全部生存期中,Angular 会把这一个服务实例注入到需求它的每个类中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOURELIKELYTOINJECTTHEUSERSERVICEINMANYPLACESTHROUGHOUTTHEAPPANDWILLWANTTOINJECTTHESAMESERVICEINSTANCEEVERYTIMEPROVIDINGTHEUSERSERVICEWITHANANGULARMODULEISAGOODCHOICE", "original": "You're likely to inject the `UserService` in many places throughout the app\nand will want to inject the same service instance every time.\nProviding the `UserService` with an Angular module is a good choice.", "translation": "如果你想要把这个 `UserService` 注入到应用中的很多地方,并且期望每次注入的都是同一个服务实例,那么在 Angular 的模块中提供 `UserService` 就是不错的选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "TOBEPRECISEANGULARMODULEPROVIDERSAREREGISTEREDWITHTHEROOTINJECTORUNLESSTHEMODULEISLAZYLOADEDGUIDELAZYLOADINGNGMODULESINTHISSAMPLEALLMODULESAREEAGERLYLOADEDWHENTHEAPPLICATIONSTARTSSOALLMODULEPROVIDERSAREREGISTEREDWITHTHEAPPSROOTINJECTOR", "original": "To be precise, Angular module providers are registered with the root injector\n_unless the module is_ [lazy loaded](guide/lazy-loading-ngmodules).\nIn this sample, all modules are _eagerly loaded_ when the application starts,\nso all module providers are registered with the app's root injector.", "translation": "严格来说,Angular 模块中的服务提供商会注册到根注入器上,但是,[惰性加载](guide/lazy-loading-ngmodules)的模块是例外。\n在这个例子中,所有模块都是在应用启动时*立即加载*的,因此模块上的所有服务提供商都注册到了应用的根注入器上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ACOMPONENTSPROVIDERSCOMPONENTPROVIDERSAREREGISTEREDWITHEACHCOMPONENTINSTANCESOWNINJECTOR", "original": "**A component's providers** (`@Component.providers`) are registered with each component instance's own injector.", "translation": "**组件的提供商**(`@Component.providers`)会注册到每个组件实例自己的注入器上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ANGULARCANONLYINJECTTHECORRESPONDINGSERVICESINTHATCOMPONENTINSTANCEORONEOFITSDESCENDANTCOMPONENTINSTANCESANGULARCANNOTINJECTTHESAMESERVICEINSTANCEANYWHEREELSE", "original": "Angular can only inject the corresponding services in that component instance or one of its descendant component instances.\nAngular cannot inject the same service instance anywhere else.", "translation": "因此 Angular 只能在该组件及其各级子组件的实例上注入这个服务实例,而不能在其它地方注入这个服务实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "NOTETHATACOMPONENTPROVIDEDSERVICEMAYHAVEALIMITEDLIFETIMEEACHNEWINSTANCEOFTHECOMPONENTGETSITSOWNINSTANCEOFTHESERVICEANDWHENTHECOMPONENTINSTANCEISDESTROYEDSOISTHATSERVICEINSTANCE", "original": "Note that a component-provided service may have a limited lifetime. Each new instance of the component gets its own instance of the service\nand, when the component instance is destroyed, so is that service instance.", "translation": "注意,由组件提供的服务,也同样具有有限的生命周期。组件的每个实例都会有它自己的服务实例,并且,当组件实例被销毁的时候,服务的实例也同样会被销毁。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "INTHISSAMPLEAPPTHEHEROCOMPONENTISCREATEDWHENTHEAPPLICATIONSTARTSANDISNEVERDESTROYEDSOTHEHEROSERVICECREATEDFORTHEHEROCOMPONENTALSOLIVEFORTHELIFEOFTHEAPP", "original": "In this sample app, the `HeroComponent` is created when the application starts\nand is never destroyed so the `HeroService` created for the `HeroComponent` also live for the life of the app.", "translation": "在这个范例应用中,`HeroComponent` 会在应用启动时创建,并且它从未销毁,因此,由 `HeroComponent` 创建的 `HeroService` 也同样会活在应用的整个生命周期中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { - "original": "If you want to restrict `HeroService` access to the `HeroesComponent` and its nested `HeroListComponent`,\nproviding the `HeroService` in the `HeroComponent` may be a good choice.", + "key": "IFYOUWANTTORESTRICTHEROSERVICEACCESSTOTHEHEROCOMPONENTANDITSNESTEDHEROLISTCOMPONENTPROVIDINGTHEHEROSERVICEINTHEHEROCOMPONENTMAYBEAGOODCHOICE", + "original": "If you want to restrict `HeroService` access to the `HeroComponent` and its nested `HeroListComponent`,\nproviding the `HeroService` in the `HeroComponent` may be a good choice.", "translation": "如果你要把 `HeroService` 的访问权限定在 `HeroesComponent` 及其嵌套的 `HeroListComponent` 中,那么在 `HeroesComponent` 中提供这个 `HeroService` 就是一个好选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THESCOPEANDLIFETIMEOFCOMPONENTPROVIDEDSERVICESISACONSEQUENCEOFTHEWAYANGULARCREATESCOMPONENTINSTANCES#COMPONENTCHILDINJECTORS", "original": "The scope and lifetime of component-provided services is a consequence of [the way Angular creates component instances](#component-child-injectors).", "translation": "由组件提供的服务,其范围和生命周期是 [Angular 如何创建组件实例](#component-child-injectors) 的必然结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##INJECTASERVICE", "original": "## Inject a service", "translation": "## 注入某个服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEHEROLISTCOMPONENTSHOULDGETHEROESFROMTHEHEROSERVICE", "original": "The `HeroListComponent` should get heroes from the `HeroService`.", "translation": "`HeroListComponent` 应该从 `HeroService` 中获取这些英雄数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THECOMPONENTSHOULDNTCREATETHEHEROSERVICEWITHNEWITSHOULDASKFORTHEHEROSERVICETOBEINJECTED", "original": "The component shouldn't create the `HeroService` with `new`.\nIt should ask for the `HeroService` to be injected.", "translation": "该组件不应该使用 `new` 来创建 `HeroService`。\n它应该要求注入 `HeroService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUCANTELLANGULARTOINJECTADEPENDENCYINTHECOMPONENTSCONSTRUCTORBYSPECIFYINGACONSTRUCTORPARAMETERWITHTHEDEPENDENCYTYPEHERESTHEHEROLISTCOMPONENTCONSTRUCTORASKINGFORTHEHEROSERVICETOBEINJECTED", "original": "You can tell Angular to inject a dependency in the component's constructor by specifying a **constructor parameter with the dependency type**.\nHere's the `HeroListComponent` constructor, asking for the `HeroService` to be injected.", "translation": "你可以通过**在构造函数中添加一个带有该依赖类型的参数**来要求 Angular 把这个依赖注入到组件的构造函数中。\n下面是 `HeroListComponent` 的构造函数,它要求注入 `HeroService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "OFCOURSETHEHEROLISTCOMPONENTSHOULDDOSOMETHINGWITHTHEINJECTEDHEROSERVICEHERESTHEREVISEDCOMPONENTMAKINGUSEOFTHEINJECTEDSERVICESIDEBYSIDEWITHTHEPREVIOUSVERSIONFORCOMPARISON", "original": "Of course, the `HeroListComponent` should do something with the injected `HeroService`.\nHere's the revised component, making use of the injected service, side-by-side with the previous version for comparison.", "translation": "当然,`HeroListComponent` 还应该使用注入的这个 `HeroService` 做点什么。\n下面输出修改过的组件,改用注入的服务,与前一个版本对比一下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "NOTICETHATTHEHEROLISTCOMPONENTDOESNTKNOWWHERETHEHEROSERVICECOMESFROMYOUKNOWTHATITCOMESFROMTHEPARENTHEROESCOMPONENTBUTIFYOUDECIDEDINSTEADTOPROVIDETHEHEROSERVICEINTHEAPPMODULETHEHEROLISTCOMPONENTWOULDNTCHANGEATALLTHEONLYTHINGTHATMATTERSISTHATTHEHEROSERVICEISPROVIDEDINSOMEPARENTINJECTOR", "original": "Notice that the `HeroListComponent` doesn't know where the `HeroService` comes from.\n_You_ know that it comes from the parent `HeroesComponent`.\nBut if you decided instead to provide the `HeroService` in the `AppModule`,\nthe `HeroListComponent` wouldn't change at all.\nThe _only thing that matters_ is that the `HeroService` is provided in some parent injector.", "translation": "注意,`HeroListComponent` 并不知道 `HeroService` 来自哪里。\n当然*你自己*知道它来自父组件 `HeroesComponent`。\n但是如果你决定改在 `AppModule` 中提供 `HeroService`,`HeroListComponent` 不用做任何修改。\n它*唯一需要关心的事情*是 `HeroService` 是由某个父注入器提供的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##SINGLETONSERVICES", "original": "## Singleton services", "translation": "## 单例服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "SERVICESARESINGLETONSWITHINTHESCOPEOFANINJECTORTHEREISATMOSTONEINSTANCEOFASERVICEINAGIVENINJECTOR", "original": "Services are singletons _within the scope of an injector_.\nThere is at most one instance of a service in a given injector.", "translation": "服务*在每个注入器的范围内*是单例的。\n在任何一个注入器中,最多只会有同一个服务的一个实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEREISONLYONEROOTINJECTORANDTHEUSERSERVICEISREGISTEREDWITHTHATINJECTORTHEREFORETHERECANBEJUSTONEUSERSERVICEINSTANCEINTHEENTIREAPPANDEVERYCLASSTHATINJECTSUSERSERVICEGETTHISSERVICEINSTANCE", "original": "There is only one root injector and the `UserService` is registered with that injector.\nTherefore, there can be just one `UserService` instance in the entire app\nand every class that injects `UserService` get this service instance.", "translation": "这里只有一个根注入器,而 `UserService` 就是在该注入器中注册的。\n所以,在整个应用中只能有一个 `UserService` 实例,每个要求注入 `UserService` 的类都会得到这个服务实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "HOWEVERANGULARDIISAHIERARCHICALINJECTIONSYSTEMGUIDEHIERARCHICALDEPENDENCYINJECTIONWHICHMEANSTHATNESTEDINJECTORSCANCREATETHEIROWNSERVICEINSTANCESANGULARCREATESNESTEDINJECTORSALLTHETIME", "original": "However, Angular DI is a \n[hierarchical injection system](guide/hierarchical-dependency-injection), \nwhich means that nested injectors can create their own service instances.\nAngular creates nested injectors all the time.", "translation": "不过,Angular DI 是一个 [多级注入系统](guide/hierarchical-dependency-injection),这意味着各级注入器都可以创建它们自己的服务实例。\nAngular 总会创建多级注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##COMPONENTCHILDINJECTORS", "original": "## Component child injectors", "translation": "## 组件的子注入器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "FOREXAMPLEWHENANGULARCREATESANEWINSTANCEOFACOMPONENTTHATHASCOMPONENTPROVIDERSITALSOCREATESANEWCHILDINJECTORFORTHATINSTANCE", "original": "For example, when Angular creates a new instance of a component that has `@Component.providers`,\nit also creates a new _child injector_ for that instance.", "translation": "例如,当 Angular 创建一个带有 `@Component.providers` 的组件实例时,也会同时为这个实例创建一个新的*子注入器*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "COMPONENTINJECTORSAREINDEPENDENTOFEACHOTHERANDEACHOFTHEMCREATESITSOWNINSTANCESOFTHECOMPONENTPROVIDEDSERVICES", "original": "Component injectors are independent of each other and\neach of them creates its own instances of the component-provided services.", "translation": "组件注入器是彼此独立的,每一个都会为这些组件提供的服务创建单独的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHENANGULARDESTROYSONEOFTHESECOMPONENTINSTANCEITALSODESTROYSTHECOMPONENTSINJECTORANDTHATINJECTORSSERVICEINSTANCES", "original": "When Angular destroys one of these component instance, it also destroys the\ncomponent's injector and that injector's service instances.", "translation": "当 Angular 销毁任何一个组件实例时,也会同时销毁组件的注入器以及该注入器中的那些服务实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THANKSTOINJECTORINHERITANCEGUIDEHIERARCHICALDEPENDENCYINJECTIONYOUCANSTILLINJECTAPPLICATIONWIDESERVICESINTOTHESECOMPONENTSACOMPONENTSINJECTORISACHILDOFITSPARENTCOMPONENTSINJECTORANDADESCENDENTOFITSPARENTSPARENTSINJECTORANDSOONALLTHEWAYBACKTOTHEAPPLICATIONSROOTINJECTORANGULARCANINJECTASERVICEPROVIDEDBYANYINJECTORINTHATLINEAGE", "original": "Thanks to [injector inheritance](guide/hierarchical-dependency-injection),\nyou can still inject application-wide services into these components.\nA component's injector is a child of its parent component's injector,\nand a descendent of its parent's parent's injector, and so on all the way back to the application's _root_ injector.\nAngular can inject a service provided by any injector in that lineage.", "translation": "在[注入器继承机制](guide/hierarchical-dependency-injection)的帮助下,你仍然可以把全应用级的服务注入到这些组件中。\n组件的注入器也是其父组件的注入器的子注入器,这同样适用于其父组件的父组件的注入器,以此类推,最终会回到应用的*根*注入器。\nAngular 可以注入由这个注入器谱系提供的任何一个注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "FOREXAMPLEANGULARCOULDINJECTAHEROLISTCOMPONENTWITHBOTHTHEHEROSERVICEPROVIDEDINHEROCOMPONENTANDTHEUSERSERVICEPROVIDEDINAPPMODULE", "original": "For example, Angular could inject a `HeroListComponent`\nwith both the `HeroService` provided in `HeroComponent`\nand the `UserService` provided in `AppModule`.", "translation": "比如,Angular 可以把由 `HeroComponent` 提供的 `HeroService` 和由 `AppModule` 提供的 `UserService` 注入到 `HeroService` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##TESTINGTHECOMPONENT", "original": "## Testing the component", "translation": "## 测试组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "EARLIERYOUSAWTHATDESIGNINGACLASSFORDEPENDENCYINJECTIONMAKESTHECLASSEASIERTOTESTLISTINGDEPENDENCIESASCONSTRUCTORPARAMETERSMAYBEALLYOUNEEDTOTESTAPPLICATIONPARTSEFFECTIVELY", "original": "Earlier you saw that designing a class for dependency injection makes the class easier to test.\nListing dependencies as constructor parameters may be all you need to test application parts effectively.", "translation": "前面强调过,设计一个适合依赖注入的类,可以让这个类更容易测试。\n要有效的测试应用中的一部分,只需要在构造函数的参数中列出依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "FOREXAMPLEYOUCANCREATEANEWHEROLISTCOMPONENTWITHAMOCKSERVICETHATYOUCANMANIPULATEUNDERTEST:", "original": "For example, you can create a new `HeroListComponent` with a mock service that you can manipulate\nunder test:", "translation": "例如,新建的 `HeroListComponent` 实例使用一个模拟 (mock) 服务,以便可以在测试中操纵它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "LEARNMOREINTHETESTINGGUIDETESTINGGUIDE", "original": "Learn more in the [Testing](guide/testing) guide.", "translation": "要学习更多知识,参见[测试](guide/testing)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##WHENTHESERVICENEEDSASERVICE", "original": "## When the service needs a service", "translation": "## 当服务需要别的服务时", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEHEROSERVICEISVERYSIMPLEITDOESNTHAVEANYDEPENDENCIESOFITSOWN", "original": "The `HeroService` is very simple. It doesn't have any dependencies of its own.", "translation": "这个 `HeroService` 非常简单。它本身不需要任何依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHATIFITHADADEPENDENCYWHATIFITREPORTEDITSACTIVITIESTHROUGHALOGGINGSERVICEYOUDAPPLYTHESAMECONSTRUCTORINJECTIONPATTERNADDINGACONSTRUCTORTHATTAKESALOGGERPARAMETER", "original": "What if it had a dependency? What if it reported its activities through a logging service?\nYou'd apply the same *constructor injection* pattern,\nadding a constructor that takes a `Logger` parameter.", "translation": "如果它也有依赖,该怎么办呢?例如,它需要通过日志服务来汇报自己的活动。\n你同样用*构造函数注入*模式,来添加一个带有 `Logger` 参数的构造函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "HEREISTHEREVISEDHEROSERVICETHATINJECTSTHELOGGERSIDEBYSIDEWITHTHEPREVIOUSSERVICEFORCOMPARISON", "original": "Here is the revised `HeroService` that injects the `Logger`, side-by-side with the previous service for comparison.", "translation": "下面是修改后的 `HeroService`,它注入了 `Logger`,对比前后这两个版本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THECONSTRUCTORASKSFORANINJECTEDINSTANCEOFALOGGERANDSTORESITINAPRIVATEFIELDCALLEDLOGGERTHEGETHEROESMETHODLOGSAMESSAGEWHENASKEDTOFETCHHEROES", "original": "The constructor asks for an injected instance of a `Logger` and stores it in a private field called `logger`.\nThe `getHeroes()` method logs a message when asked to fetch heroes.", "translation": "这个构造函数要求注入一个 `Logger` 类的实例,并把它存到名为 `logger` 的私有字段中。\n 当请求英雄数据时,`getHeroes()` 中就会记录一个消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "####THEDEPENDENTLOGGERSERVICE", "original": "#### The dependent _Logger_ service", "translation": "#### 被依赖的 `Logger` 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THESAMPLEAPPSLOGGERSERVICEISQUITESIMPLE:", "original": "The sample app's `Logger` service is quite simple:", "translation": "这个范例应用的 `Logger` 服务非常简单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "IFTHEAPPDIDNTPROVIDETHISLOGGERANGULARWOULDTHROWANEXCEPTIONWHENITLOOKEDFORALOGGERTOINJECTINTOTHEHEROSERVICE", "original": "If the app didn't provide this `Logger`,\nAngular would throw an exception when it looked for a `Logger` to inject\ninto the `HeroService`.", "translation": "如果该应用没有提供这个 `Logger` 服务,当 Angular 试图把 `Logger` 注入到 `HeroService` 中时,就会抛出一个异常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "BECAUSEASINGLETONLOGGERSERVICEISUSEFULEVERYWHEREITSPROVIDEDINTHEROOTAPPMODULE", "original": "Because a singleton logger service is useful everywhere,\nit's provided in the root `AppModule`.", "translation": "因为 `Logger` 服务的单例应该随处可用,所以要在根模块 `AppModule` 中提供它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEINJECTABLEAPICOREINJECTABLEDECORATORIDENTIFIESASERVICECLASSTHATMIGHTREQUIREINJECTEDDEPENDENCIES", "original": "The **[@Injectable()](api/core/Injectable)** decorator identifies a service class \nthat _might_ require injected dependencies.", "translation": "**[@Injectable()](api/core/Injectable)** 装饰器表示*可能*需要往这个服务类中注入其它依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEHEROSERVICEMUSTBEANNOTATEDWITHINJECTABLEBECAUSEITREQUIRESANINJECTEDLOGGER", "original": "The `HeroService` must be annotated with `@Injectable()` because it requires an injected `Logger`.", "translation": "`HeroService` 必须带有 `@Injectable()` 装饰器,因为它需要把 `Logger` 注入进来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ALWAYSWRITEINJECTABLEWITHPARENTHESESNOTJUSTINJECTABLE", "original": "Always write `@Injectable()` with parentheses, not just `@Injectable`.", "translation": "写 `@Injectable()` 时必须带括号,不能只写 `@Injectable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHENANGULARCREATESACLASSWHOSECONSTRUCTORHASPARAMETERSITLOOKSFORTYPEANDINJECTIONMETADATAABOUTTHOSEPARAMETERSSOTHATITCANINJECTTHERIGHTSERVICE", "original": "When Angular creates a class whose constructor has parameters,\nit looks for type and injection metadata about those parameters\nso that it can inject the right service.", "translation": "当 Angular 要创建一个构造函数中带参数的类时,会先查找这些参数的类型,以便根据这些参数的元数据注入正确的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "IFANGULARCANTFINDTHATPARAMETERINFORMATIONITTHROWSANERROR", "original": "If Angular can't find that parameter information, it throws an error.", "translation": "如果不能找到该参数的信息,Angular 就会报错。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ANGULARCANONLYFINDTHEPARAMETERINFORMATIONIFTHECLASSHASADECORATOROFSOMEKINDWHILEANYDECORATORWILLDOTHEINJECTABLEDECORATORISTHESTANDARDDECORATORFORSERVICECLASSES", "original": "Angular can only find the parameter information _if the class has a decorator of some kind_.\nWhile _any_ decorator will do,\nthe `@Injectable()` decorator is the standard decorator for service classes.", "translation": "Angular 只能在*带有某种装饰器的类*上查找参数信息。*任何*装饰器都可以,而 `@Injectable()` 装饰器是各种服务类的标准装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEDECORATORREQUIREMENTISIMPOSEDBYTYPESCRIPT", "original": "The decorator requirement is imposed by TypeScript.", "translation": "之所以必须有装饰器,是因为 TypeScript 强制要求的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "TYPESCRIPTNORMALLYDISCARDSPARAMETERTYPEINFORMATIONWHENITTRANSPILESTHECODETOJAVASCRIPTITPRESERVESTHISINFORMATIONIFTHECLASSHASADECORATORANDTHEEMITDECORATORMETADATACOMPILEROPTIONISSETTRUEINTYPESCRIPTSTSCONFIGJSONCONFIGURATIONFILE", "original": "TypeScript normally discards parameter type information when it _transpiles_ the code to JavaScript.\nIt preserves this information if the class has a decorator\nand the `emitDecoratorMetadata` compiler option is set `true` \nin TypeScript's `tsconfig.json` configuration file, .", "translation": "当把 TypeScript 转译成 JavaScript 时,通常会丢弃参数的类型信息。\n但当该类带有装饰器并且当 `tsconfig.json` 配置文件中的 `emitDecoratorMetadata` 编译选项为 `true` 时,它就会保留这些信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THECLICONFIGURESTSCONFIGJSONWITHEMITDECORATORMETADATA:TRUEITSYOURJOBTOPUTINJECTABLEONYOURSERVICECLASSES", "original": "The CLI configures `tsconfig.json` with `emitDecoratorMetadata: true`\nIt's your job to put `@Injectable()` on your service classes.", "translation": "CLI 生成的 `tsconfig.json` 中已经有 `emitDecoratorMetadata: true` 选项了,你只要把 `@Injectable()` 加到你的服务类上就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THELOGGERSERVICEISANNOTATEDWITHINJECTABLEDECORATORTOOALTHOUGHITHASNOCONSTRUCTORANDNODEPENDENCIES", "original": "The `Logger` service is annotated with `@Injectable()` decorator too, \nalthough it has no constructor and no dependencies.", "translation": "`Logger` 服务也带有 `@Injectable()` 装饰器,不过它没有构造器,也没有依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "INFACTEVERYANGULARSERVICECLASSINTHISAPPISANNOTATEDWITHTHEINJECTABLEDECORATORWHETHERORNOTITHASACONSTRUCTORANDDEPENDENCIESINJECTABLEISAREQUIREDCODINGSTYLEFORSERVICES", "original": "In fact, _every_ Angular service class in this app is annotated with the `@Injectable()` decorator, whether or not it has a constructor and dependencies.\n`@Injectable()` is a required coding style for services.", "translation": "该应用中的*每个* Angular 服务类不管有没有构造器和依赖,都带有 `@Injectable()` 装饰器。\n事实上,`@Injectable()` 是风格指南中对服务类的要求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##PROVIDERS", "original": "## Providers", "translation": "## 服务提供商们", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ASERVICEPROVIDERPROVIDESTHECONCRETERUNTIMEVERSIONOFADEPENDENCYVALUETHEINJECTORRELIESONPROVIDERSTOCREATEINSTANCESOFTHESERVICESTHATTHEINJECTORINJECTSINTOCOMPONENTSDIRECTIVESPIPESANDOTHERSERVICES", "original": "A service provider *provides* the concrete, runtime version of a dependency value.\nThe injector relies on **providers** to create instances of the services\nthat the injector injects into components, directives, pipes, and other services.", "translation": "服务提供商*提供*依赖值的一个具体的、运行时的版本。\n注入器依靠**提供商**来创建服务的实例,注入器再将服务的实例注入组件、管道或其它服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUMUSTREGISTERASERVICEPROVIDERWITHANINJECTORORITWONTKNOWHOWTOCREATETHESERVICE", "original": "You must register a service *provider* with an injector, or it won't know how to create the service.", "translation": "必须为注入器注册一个服务的*提供商*,否则它就不知道该如何创建该服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THENEXTFEWSECTIONSEXPLAINTHEMANYWAYSYOUCANSPECIFYAPROVIDER", "original": "The next few sections explain the many ways you can specify a provider.", "translation": "在下面的几节中会解释指定提供商的多种方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ALMOSTALLOFTHEACCOMPANYINGCODESNIPPETSAREEXTRACTSFROMTHESAMPLEAPPSPROVIDERSCOMPONENTTSFILE", "original": "Almost all of the accompanying code snippets are extracts from the sample app's `providers.component.ts` file.", "translation": "几乎所有的代码片段都是从范例应用的 `providers.component.ts` 文件中提取出来的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###THECLASSASITSOWNPROVIDER", "original": "### The class as its own provider", "translation": "### 把类作为它自己的提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEREAREMANYWAYSTOPROVIDESOMETHINGTHATLOOKSANDBEHAVESLIKEALOGGERTHELOGGERCLASSITSELFISANOBVIOUSANDNATURALPROVIDER", "original": "There are many ways to *provide* something that looks and behaves like a `Logger`.\nThe `Logger` class itself is an obvious and natural provider.", "translation": "有很多方式可以*提供*一些实现 `Logger` 类的东西。\n `Logger` 类本身是一个显而易见而且自然而然的提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "BUTITSNOTTHEONLYWAY", "original": "But it's not the only way.", "translation": "但它不是唯一的途径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUCANCONFIGURETHEINJECTORWITHALTERNATIVEPROVIDERSTHATCANDELIVERANOBJECTTHATBEHAVESLIKEALOGGERYOUCOULDPROVIDEASUBSTITUTECLASSYOUCOULDPROVIDEALOGGERLIKEOBJECTYOUCOULDGIVEITAPROVIDERTHATCALLSALOGGERFACTORYFUNCTIONANYOFTHESEAPPROACHESMIGHTBEAGOODCHOICEUNDERTHERIGHTCIRCUMSTANCES", "original": "You can configure the injector with alternative providers that can deliver an object that behaves like a `Logger`.\nYou could provide a substitute class. You could provide a logger-like object.\nYou could give it a provider that calls a logger factory function.\nAny of these approaches might be a good choice under the right circumstances.", "translation": "可以用其它备选提供商来配置注入器,只要它们能交付一个行为类似于 `Logger` 的对象就可以了。\n可以提供一个替代类。你可以提供一个类似日志的对象。\n可以给它一个提供商,让它调用可以创建日志服务的工厂函数。\n所有这些方法,只要用在正确的场合,都可能是一个好的选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHATMATTERSISTHATTHEINJECTORHASAPROVIDERTOGOTOWHENITNEEDSALOGGER", "original": "What matters is that the injector has a provider to go to when it needs a `Logger`.", "translation": "重点是,当注入器需要一个 `Logger` 时,它得先有一个提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###THEPROVIDEOBJECTLITERAL", "original": "### The _provide_ object literal", "translation": "### *provide* 对象字面量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "HERESTHECLASSPROVIDERSYNTAXAGAIN", "original": "Here's the class-provider syntax again.", "translation": "下面是类提供商的另一种语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THISISACTUALLYASHORTHANDEXPRESSIONFORAPROVIDERREGISTRATIONUSINGAPROVIDEROBJECTLITERALWITHTWOPROPERTIES:", "original": "This is actually a shorthand expression for a provider registration\nusing a _provider_ object literal with two properties:", "translation": "这其实是用于注册提供商的简写表达式。\n 使用的是一个带有两个属性的*提供商*对象字面量:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEPROVIDEPROPERTYHOLDSTHETOKENGUIDEDEPENDENCYINJECTION#TOKENTHATSERVESASTHEKEYFORBOTHLOCATINGADEPENDENCYVALUEANDREGISTERINGTHEPROVIDER", "original": "The `provide` property holds the [token](guide/dependency-injection#token) that serves as the key for both locating a dependency value\nand registering the provider.", "translation": "`provide` 属性保存的是[令牌 (token)](guide/dependency-injection#token),它作为键值 (key) 使用,用于定位依赖值和注册提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THESECONDPROPERTYISALWAYSAPROVIDERDEFINITIONOBJECTWHICHYOUCANTHINKOFASARECIPEFORCREATINGTHEDEPENDENCYVALUETHEREAREMANYWAYSTOCREATEDEPENDENCYVALUESJUSTASTHEREAREMANYWAYSTOWRITEARECIPE", "original": "The second property is always a provider definition object,\nwhich you can think of as a *recipe* for creating the dependency value.\nThere are many ways to create dependency values just as there are many ways to write a recipe.", "translation": "第二个是一个提供商定义对象。\n可以把它看做是指导如何创建依赖值的*配方*。\n有很多方式创建依赖值…… 也有很多方式可以写配方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###ALTERNATIVECLASSPROVIDERS", "original": "### Alternative class providers", "translation": "### 备选的类提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "OCCASIONALLYYOULLASKADIFFERENTCLASSTOPROVIDETHESERVICETHEFOLLOWINGCODETELLSTHEINJECTORTORETURNABETTERLOGGERWHENSOMETHINGASKSFORTHELOGGER", "original": "Occasionally you'll ask a different class to provide the service.\nThe following code tells the injector\nto return a `BetterLogger` when something asks for the `Logger`.", "translation": "某些时候,你会请求一个不同的类来提供服务。\n下列代码告诉注入器,当有人请求 `Logger` 时,返回 `BetterLogger`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###CLASSPROVIDERWITHDEPENDENCIES", "original": "### Class provider with dependencies", "translation": "### 带依赖的类提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "MAYBEANEVENBETTERLOGGERCOULDDISPLAYTHEUSERNAMEINTHELOGMESSAGETHISLOGGERGETSTHEUSERFROMTHEINJECTEDUSERSERVICEWHICHISALSOINJECTEDATTHEAPPLICATIONLEVEL", "original": "Maybe an `EvenBetterLogger` could display the user name in the log message.\nThis logger gets the user from the injected `UserService`,\nwhich is also injected at the application level.", "translation": "假设 `EvenBetterLogger` 可以在日志消息中显示用户名。\n这个日志服务从注入的 `UserService` 中取得用户,\n`UserService` 通常也会在应用级注入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "CONFIGUREITLIKEBETTERLOGGER", "original": "Configure it like `BetterLogger`.", "translation": "就像之前在 `BetterLogger` 中那样配置它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###ALIASEDCLASSPROVIDERS", "original": "### Aliased class providers", "translation": "### 别名类提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "SUPPOSEANOLDCOMPONENTDEPENDSUPONANOLDLOGGERCLASSOLDLOGGERHASTHESAMEINTERFACEASTHENEWLOGGERBUTFORSOMEREASONYOUCANTUPDATETHEOLDCOMPONENTTOUSEIT", "original": "Suppose an old component depends upon an `OldLogger` class.\n`OldLogger` has the same interface as the `NewLogger`, but for some reason\nyou can't update the old component to use it.", "translation": "假设某个旧组件依赖一个 `OldLogger` 类。\n`OldLogger` 和 `NewLogger` 具有相同的接口,但是由于某些原因,\n你不能升级这个旧组件并使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHENTHEOLDCOMPONENTLOGSAMESSAGEWITHOLDLOGGERYOUDLIKETHESINGLETONINSTANCEOFNEWLOGGERTOHANDLEITINSTEAD", "original": "When the *old* component logs a message with `OldLogger`,\nyou'd like the singleton instance of `NewLogger` to handle it instead.", "translation": "当*旧*组件想使用 `OldLogger` 记录消息时,你希望改用 `NewLogger` 的单例对象来记录。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEDEPENDENCYINJECTORSHOULDINJECTTHATSINGLETONINSTANCEWHENACOMPONENTASKSFOREITHERTHENEWORTHEOLDLOGGERTHEOLDLOGGERSHOULDBEANALIASFORNEWLOGGER", "original": "The dependency injector should inject that singleton instance\nwhen a component asks for either the new or the old logger.\nThe `OldLogger` should be an alias for `NewLogger`.", "translation": "不管组件请求的是新的还是旧的日志服务,依赖注入器注入的都应该是同一个单例对象。\n 也就是说,`OldLogger` 应该是 `NewLogger` 的别名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUCERTAINLYDONOTWANTTWODIFFERENTNEWLOGGERINSTANCESINYOURAPPUNFORTUNATELYTHATSWHATYOUGETIFYOUTRYTOALIASOLDLOGGERTONEWLOGGERWITHUSECLASS", "original": "You certainly do not want two different `NewLogger` instances in your app.\nUnfortunately, that's what you get if you try to alias `OldLogger` to `NewLogger` with `useClass`.", "translation": "你当然不会希望应用中有两个不同的 `NewLogger` 实例。\n不幸的是,如果尝试通过 `useClass` 来把 `OldLogger` 作为 `NewLogger` 的别名,就会导致这样的后果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THESOLUTION:ALIASWITHTHEUSEEXISTINGOPTION", "original": "The solution: alias with the `useExisting` option.", "translation": "解决方案:使用 `useExisting` 选项指定别名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###VALUEPROVIDERS", "original": "### Value providers", "translation": "### 值提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "SOMETIMESITSEASIERTOPROVIDEAREADYMADEOBJECTRATHERTHANASKTHEINJECTORTOCREATEITFROMACLASS", "original": "Sometimes it's easier to provide a ready-made object rather than ask the injector to create it from a class.", "translation": "有时,提供一个预先做好的对象会比请求注入器从类中创建它更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THENYOUREGISTERAPROVIDERWITHTHEUSEVALUEOPTIONWHICHMAKESTHISOBJECTPLAYTHELOGGERROLE", "original": "Then you register a provider with the `useValue` option,\nwhich makes this object play the logger role.", "translation": "于是可以通过 `useValue` 选项来注册提供商,它会让这个对象直接扮演 logger 的角色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "SEEMOREUSEVALUEEXAMPLESINTHENONCLASSDEPENDENCIESGUIDEDEPENDENCYINJECTION#NONCLASSDEPENDENCIESANDINJECTIONTOKENGUIDEDEPENDENCYINJECTION#INJECTIONTOKENSECTIONS", "original": "See more `useValue` examples in the\n[Non-class dependencies](guide/dependency-injection#non-class-dependencies) and\n[InjectionToken](guide/dependency-injection#injection-token) sections.", "translation": "查看更多 `useValue` 的例子,见[非类依赖](guide/dependency-injection#non-class-dependencies)和 [InjectionToken](guide/dependency-injection#injection-token)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###FACTORYPROVIDERS", "original": "### Factory providers", "translation": "### 工厂提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "SOMETIMESYOUNEEDTOCREATETHEDEPENDENTVALUEDYNAMICALLYBASEDONINFORMATIONYOUWONTHAVEUNTILTHELASTPOSSIBLEMOMENTMAYBETHEINFORMATIONCHANGESREPEATEDLYINTHECOURSEOFTHEBROWSERSESSION", "original": "Sometimes you need to create the dependent value dynamically,\nbased on information you won't have until the last possible moment.\nMaybe the information changes repeatedly in the course of the browser session.", "translation": "有时,你需要动态创建这个依赖值,因为它所需要的信息直到最后一刻才能确定。\n也许这个信息会在浏览器的会话中不停地变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "SUPPOSEALSOTHATTHEINJECTABLESERVICEHASNOINDEPENDENTACCESSTOTHESOURCEOFTHISINFORMATION", "original": "Suppose also that the injectable service has no independent access to the source of this information.", "translation": "还假设这个可注入的服务没法通过独立的源访问此信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THISSITUATIONCALLSFORAFACTORYPROVIDER", "original": "This situation calls for a **factory provider**.", "translation": "这种情况下,请调用**工厂提供商**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "TOILLUSTRATETHEPOINTADDANEWBUSINESSREQUIREMENT:THEHEROSERVICEMUSTHIDESECRETHEROESFROMNORMALUSERSONLYAUTHORIZEDUSERSSHOULDSEESECRETHEROES", "original": "To illustrate the point, add a new business requirement:\nthe `HeroService` must hide *secret* heroes from normal users.\nOnly authorized users should see secret heroes.", "translation": "下面通过添加新的业务需求来说明这一点:\n`HeroService` 必须对普通用户隐藏掉*秘密*英雄。\n只有授权用户才能看到秘密英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "LIKETHEEVENBETTERLOGGERTHEHEROSERVICENEEDSAFACTABOUTTHEUSERITNEEDSTOKNOWIFTHEUSERISAUTHORIZEDTOSEESECRETHEROESTHATAUTHORIZATIONCANCHANGEDURINGTHECOURSEOFASINGLEAPPLICATIONSESSIONASWHENYOULOGINADIFFERENTUSER", "original": "Like the `EvenBetterLogger`, the `HeroService` needs a fact about the user.\nIt needs to know if the user is authorized to see secret heroes.\nThat authorization can change during the course of a single application session,\nas when you log in a different user.", "translation": "就像 `EvenBetterLogger` 那样,`HeroService` 需要了解此用户的身份。\n它需要知道,这个用户是否有权看到隐藏英雄。\n这个授权可能在单一的应用会话中被改变,例如,改用另一个用户的身份登录时。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "UNLIKEEVENBETTERLOGGERYOUCANTINJECTTHEUSERSERVICEINTOTHEHEROSERVICETHEHEROSERVICEWONTHAVEDIRECTACCESSTOTHEUSERINFORMATIONTODECIDEWHOISAUTHORIZEDANDWHOISNOT", "original": "Unlike `EvenBetterLogger`, you can't inject the `UserService` into the `HeroService`.\nThe `HeroService` won't have direct access to the user information to decide\nwho is authorized and who is not.", "translation": "与 `EvenBetterLogger` 不同,不能把 `UserService` 注入到 `HeroService` 中。\n `HeroService` 无权访问用户信息,来决定谁有授权谁没有授权。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "INSTEADTHEHEROSERVICECONSTRUCTORTAKESABOOLEANFLAGTOCONTROLDISPLAYOFSECRETHEROES", "original": "Instead, the `HeroService` constructor takes a boolean flag to control display of secret heroes.", "translation": "让 `HeroService` 的构造函数带上一个布尔型的标志,来控制是否显示隐藏的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUCANINJECTTHELOGGERBUTYOUCANTINJECTTHEBOOLEANISAUTHORIZEDYOULLHAVETOTAKEOVERTHECREATIONOFNEWINSTANCESOFTHISHEROSERVICEWITHAFACTORYPROVIDER", "original": "You can inject the `Logger`, but you can't inject the boolean `isAuthorized`.\nYou'll have to take over the creation of new instances of this `HeroService` with a factory provider.", "translation": "你可以注入 `Logger`,但是不能注入逻辑型的 `isAuthorized`。\n你不得不通过通过工厂提供商创建这个 `HeroService` 的新实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "AFACTORYPROVIDERNEEDSAFACTORYFUNCTION:", "original": "A factory provider needs a factory function:", "translation": "工厂提供商需要一个工厂方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ALTHOUGHTHEHEROSERVICEHASNOACCESSTOTHEUSERSERVICETHEFACTORYFUNCTIONDOES", "original": "Although the `HeroService` has no access to the `UserService`, the factory function does.", "translation": "虽然 `HeroService` 不能访问 `UserService`,但是工厂方法可以。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUINJECTBOTHTHELOGGERANDTHEUSERSERVICEINTOTHEFACTORYPROVIDERANDLETTHEINJECTORPASSTHEMALONGTOTHEFACTORYFUNCTION:", "original": "You inject both the `Logger` and the `UserService` into the factory provider\nand let the injector pass them along to the factory function:", "translation": "同时把 `Logger` 和 `UserService` 注入到工厂提供商中,并且让注入器把它们传给工厂方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEUSEFACTORYFIELDTELLSANGULARTHATTHEPROVIDERISAFACTORYFUNCTIONWHOSEIMPLEMENTATIONISTHEHEROSERVICEFACTORY", "original": "The `useFactory` field tells Angular that the provider is a factory function\nwhose implementation is the `heroServiceFactory`.", "translation": "`useFactory` 字段告诉 Angular:这个提供商是一个工厂方法,它的实现是 `heroServiceFactory`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEDEPSPROPERTYISANARRAYOFPROVIDERTOKENSGUIDEDEPENDENCYINJECTION#TOKENTHELOGGERANDUSERSERVICECLASSESSERVEASTOKENSFORTHEIROWNCLASSPROVIDERSTHEINJECTORRESOLVESTHESETOKENSANDINJECTSTHECORRESPONDINGSERVICESINTOTHEMATCHINGFACTORYFUNCTIONPARAMETERS", "original": "The `deps` property is an array of [provider tokens](guide/dependency-injection#token).\nThe `Logger` and `UserService` classes serve as tokens for their own class providers.\nThe injector resolves these tokens and injects the corresponding services into the matching factory function parameters.", "translation": "`deps` 属性是[提供商令牌](guide/dependency-injection#token)数组。\n `Logger` 和 `UserService` 类作为它们自身类提供商的令牌。\n 注入器解析这些令牌,把相应的服务注入到工厂函数中相应的参数中去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "NOTICETHATYOUCAPTUREDTHEFACTORYPROVIDERINANEXPORTEDVARIABLEHEROSERVICEPROVIDERTHISEXTRASTEPMAKESTHEFACTORYPROVIDERREUSABLEYOUCANREGISTERTHEHEROSERVICEWITHTHISVARIABLEWHEREVERYOUNEEDIT", "original": "Notice that you captured the factory provider in an exported variable, `heroServiceProvider`.\nThis extra step makes the factory provider reusable.\nYou can register the `HeroService` with this variable wherever you need it.", "translation": "注意,你在一个导出的变量中捕获了这个工厂提供商:`heroServiceProvider`。\n这个额外的步骤让工厂提供商可被复用。\n无论哪里需要,都可以使用这个变量注册 `HeroService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "INTHISSAMPLEYOUNEEDITONLYINTHEHEROESCOMPONENTWHEREITREPLACESTHEPREVIOUSHEROSERVICEREGISTRATIONINTHEMETADATAPROVIDERSARRAYHEREYOUSEETHENEWANDTHEOLDIMPLEMENTATIONSIDEBYSIDE:", "original": "In this sample, you need it only in the `HeroesComponent`,\nwhere it replaces the previous `HeroService` registration in the metadata `providers` array.\nHere you see the new and the old implementation side-by-side:", "translation": "在这个例子中,只在 `HeroesComponent` 中需要它,\n 这里,它代替了元数据 `providers` 数组中原来的 `HeroService` 注册。\n 对比一下新的和旧的实现:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##DEPENDENCYINJECTIONTOKENS", "original": "## Dependency injection tokens", "translation": "## 依赖注入令牌", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHENYOUREGISTERAPROVIDERWITHANINJECTORYOUASSOCIATETHATPROVIDERWITHADEPENDENCYINJECTIONTOKENTHEINJECTORMAINTAINSANINTERNALTOKENPROVIDERMAPTHATITREFERENCESWHENASKEDFORADEPENDENCYTHETOKENISTHEKEYTOTHEMAP", "original": "When you register a provider with an injector, you associate that provider with a dependency injection token.\nThe injector maintains an internal *token-provider* map that it references when\nasked for a dependency. The token is the key to the map.", "translation": "当向注入器注册提供商时,实际上是把这个提供商和一个 DI 令牌关联起来了。\n注入器维护一个内部的*令牌-提供商*映射表,这个映射表会在请求依赖时被引用到。\n令牌就是这个映射表中的键值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "INALLPREVIOUSEXAMPLESTHEDEPENDENCYVALUEHASBEENACLASSINSTANCEANDTHECLASSTYPESERVEDASITSOWNLOOKUPKEYHEREYOUGETAHEROSERVICEDIRECTLYFROMTHEINJECTORBYSUPPLYINGTHEHEROSERVICETYPEASTHETOKEN:", "original": "In all previous examples, the dependency value has been a class *instance*, and\nthe class *type* served as its own lookup key.\nHere you get a `HeroService` directly from the injector by supplying the `HeroService` type as the token:", "translation": "在前面的所有例子中,依赖值都是一个类*实例*,并且类的*类型*作为它自己的查找键值。\n在下面的代码中,`HeroService` 类型作为令牌,直接从注入器中获取 `HeroService` 实例:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUHAVESIMILARGOODFORTUNEWHENYOUWRITEACONSTRUCTORTHATREQUIRESANINJECTEDCLASSBASEDDEPENDENCYWHENYOUDEFINEACONSTRUCTORPARAMETERWITHTHEHEROSERVICECLASSTYPEANGULARKNOWSTOINJECTTHESERVICEASSOCIATEDWITHTHATHEROSERVICECLASSTOKEN:", "original": "You have similar good fortune when you write a constructor that requires an injected class-based dependency.\nWhen you define a constructor parameter with the `HeroService` class type,\nAngular knows to inject the\nservice associated with that `HeroService` class token:", "translation": "编写需要基于类的依赖注入的构造函数对你来说是很幸运的。\n只要定义一个 `HeroService` 类型的构造函数参数,\nAngular 就会知道把跟 `HeroService` 类令牌关联的服务注入进来:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THISISESPECIALLYCONVENIENTWHENYOUCONSIDERTHATMOSTDEPENDENCYVALUESAREPROVIDEDBYCLASSES", "original": "This is especially convenient when you consider that most dependency values are provided by classes.", "translation": "这是一个特殊的规约,因为大多数依赖值都是以类的形式提供的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###NONCLASSDEPENDENCIES", "original": "### Non-class dependencies", "translation": "### 非类依赖", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHATIFTHEDEPENDENCYVALUEISNTACLASSSOMETIMESTHETHINGYOUWANTTOINJECTISASTRINGFUNCTIONOROBJECT", "original": "What if the dependency value isn't a class? Sometimes the thing you want to inject is a\nstring, function, or object.", "translation": "如果依赖值不是一个类呢?有时候想要注入的东西是一个字符串,函数或者对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "APPLICATIONSOFTENDEFINECONFIGURATIONOBJECTSWITHLOTSOFSMALLFACTSLIKETHETITLEOFTHEAPPLICATIONORTHEADDRESSOFAWEBAPIENDPOINTBUTTHESECONFIGURATIONOBJECTSARENTALWAYSINSTANCESOFACLASSTHEYCANBEOBJECTLITERALSSUCHASTHISONE:", "original": "Applications often define configuration objects with lots of small facts\n(like the title of the application or the address of a web API endpoint)\nbut these configuration objects aren't always instances of a class.\nThey can be object literals such as this one:", "translation": "应用程序经常为很多很小的因素定义配置对象(例如应用程序的标题或网络 API 终点的地址)。\n 但是这些配置对象不总是类的实例,它们可能是对象,如下面这个:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHATIFYOUDLIKETOMAKETHISCONFIGURATIONOBJECTAVAILABLEFORINJECTIONYOUKNOWYOUCANREGISTERANOBJECTWITHAVALUEPROVIDERGUIDEDEPENDENCYINJECTION#VALUEPROVIDER", "original": "What if you'd like to make this configuration object available for injection?\nYou know you can register an object with a [value provider](guide/dependency-injection#value-provider).", "translation": "如果想让这个配置对象在注入时可用该怎么办?你知道你可以用[值提供商](guide/dependency-injection#value-provider)来注册一个对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "BUTWHATSHOULDYOUUSEASTHETOKENYOUDONTHAVEACLASSTOSERVEASATOKENTHEREISNOAPPCONFIGCLASS", "original": "But what should you use as the token?\nYou don't have a class to serve as a token.\nThere is no `AppConfig` class.", "translation": "但是,这种情况下用什么作令牌呢?\n你没办法找一个类来当作令牌,因为没有 `Config` 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###TYPESCRIPTINTERFACESARENTVALIDTOKENS", "original": "### TypeScript interfaces aren't valid tokens", "translation": "### TypeScript 接口不是一个有效的令牌", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEHERODICONFIGCONSTANTCONFORMSTOTHEAPPCONFIGINTERFACEUNFORTUNATELYYOUCANNOTUSEATYPESCRIPTINTERFACEASATOKEN:", "original": "The `HERO_DI_CONFIG` constant conforms to the `AppConfig` interface. \nUnfortunately, you cannot use a TypeScript interface as a token:", "translation": "`HERO_DI_CONFIG` 常量有一个接口:`AppConfig`。不幸的是,不能把 TypeScript 接口用作令牌:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THATSEEMSSTRANGEIFYOUREUSEDTODEPENDENCYINJECTIONINSTRONGLYTYPEDLANGUAGESWHEREANINTERFACEISTHEPREFERREDDEPENDENCYLOOKUPKEY", "original": "That seems strange if you're used to dependency injection in strongly typed languages, where\nan interface is the preferred dependency lookup key.", "translation": "对于习惯于在强类型的语言中使用依赖注入的开发人员,这会看起来很奇怪,\n因为在强类型语言中,接口是首选的用于查找依赖的主键。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ITSNOTANGULARSDOINGANINTERFACEISATYPESCRIPTDESIGNTIMEARTIFACTJAVASCRIPTDOESNTHAVEINTERFACESTHETYPESCRIPTINTERFACEDISAPPEARSFROMTHEGENERATEDJAVASCRIPTTHEREISNOINTERFACETYPEINFORMATIONLEFTFORANGULARTOFINDATRUNTIME", "original": "It's not Angular's doing. An interface is a TypeScript design-time artifact. JavaScript doesn't have interfaces.\nThe TypeScript interface disappears from the generated JavaScript.\nThere is no interface type information left for Angular to find at runtime.", "translation": "这不是 Angular 的错。接口只是 TypeScript 设计时 (design-time) 的概念。JavaScript 没有接口。\nTypeScript 接口不会出现在生成的 JavaScript 代码中。\n在运行期,没有接口类型信息可供 Angular 查找。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "###INJECTIONTOKEN", "original": "### _InjectionToken_", "translation": "### _InjectionToken_ 值", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ONESOLUTIONTOCHOOSINGAPROVIDERTOKENFORNONCLASSDEPENDENCIESISTODEFINEANDUSEANINJECTIONTOKENAPICOREINJECTIONTOKENTHEDEFINITIONOFSUCHATOKENLOOKSLIKETHIS:", "original": "One solution to choosing a provider token for non-class dependencies is\nto define and use an [*InjectionToken*](api/core/InjectionToken).\nThe definition of such a token looks like this:", "translation": "解决方案是为非类依赖定义和使用<a href=\"../api/core/InjectionToken\"><b>InjectionToken</b></a>作为提供商令牌。\n定义方式是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THETYPEPARAMETERWHILEOPTIONALCONVEYSTHEDEPENDENCYSTYPETODEVELOPERSANDTOOLINGTHETOKENDESCRIPTIONISANOTHERDEVELOPERAID", "original": "The type parameter, while optional, conveys the dependency's type to developers and tooling.\nThe token description is another developer aid.", "translation": "类型参数,虽然是可选的,但可以向开发者和开发工具传达类型信息。\n而且这个令牌的描述信息也可以为开发者提供帮助。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "REGISTERTHEDEPENDENCYPROVIDERUSINGTHEINJECTIONTOKENOBJECT:", "original": "Register the dependency provider using the `InjectionToken` object:", "translation": "使用这个 `InjectionToken` 对象注册依赖的提供商:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "NOWYOUCANINJECTTHECONFIGURATIONOBJECTINTOANYCONSTRUCTORTHATNEEDSITWITHTHEHELPOFANINJECTDECORATOR:", "original": "Now you can inject the configuration object into any constructor that needs it, with\nthe help of an `@Inject` decorator:", "translation": "现在,在 `@Inject` 装饰器的帮助下,这个配置对象可以注入到任何需要它的构造函数中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ALTHOUGHTHEAPPCONFIGINTERFACEPLAYSNOROLEINDEPENDENCYINJECTIONITSUPPORTSTYPINGOFTHECONFIGURATIONOBJECTWITHINTHECLASS", "original": "Although the `AppConfig` interface plays no role in dependency injection,\nit supports typing of the configuration object within the class.", "translation": "虽然 `AppConfig` 接口在依赖注入过程中没有任何作用,但它为该类中的配置对象提供了强类型信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ALTERNATIVELYYOUCANPROVIDEANDINJECTTHECONFIGURATIONOBJECTINANNGMODULELIKEAPPMODULE", "original": "Alternatively, you can provide and inject the configuration object in an ngModule like `AppModule`.", "translation": "或者在 ngModule 中提供并注入这个配置对象,如 `AppModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##OPTIONALDEPENDENCIES", "original": "## Optional dependencies", "translation": "## 可选依赖", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEHEROSERVICEREQUIRESALOGGERBUTWHATIFITCOULDGETBYWITHOUTALOGGERYOUCANTELLANGULARTHATTHEDEPENDENCYISOPTIONALBYANNOTATINGTHECONSTRUCTORARGUMENTWITHOPTIONAL:", "original": "The `HeroService` *requires* a `Logger`, but what if it could get by without\na `logger`?\nYou can tell Angular that the dependency is optional by annotating the\nconstructor argument with `@Optional()`:", "translation": "`HeroService`*需要*一个 `Logger`,但是如果想不提供 Logger 也能得到它,该怎么办呢?\n可以把构造函数的参数标记为 `@Optional()`,告诉 Angular 该依赖是可选的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "WHENUSINGOPTIONALYOURCODEMUSTBEPREPAREDFORANULLVALUEIFYOUDONTREGISTERALOGGERSOMEWHEREUPTHELINETHEINJECTORWILLSETTHEVALUEOFLOGGERTONULL", "original": "When using `@Optional()`, your code must be prepared for a null value. If you\ndon't register a `logger` somewhere up the line, the injector will set the\nvalue of `logger` to null.", "translation": "当使用 `@Optional()` 时,代码必须准备好如何处理空值。\n如果其它的代码没有注册一个 `logger`,注入器会设置该 `logger` 的值为空 null。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOULEARNEDTHEBASICSOFANGULARDEPENDENCYINJECTIONINTHISPAGEYOUCANREGISTERVARIOUSKINDSOFPROVIDERSANDYOUKNOWHOWTOASKFORANINJECTEDOBJECTSUCHASASERVICEBYADDINGAPARAMETERTOACONSTRUCTOR", "original": "You learned the basics of Angular dependency injection in this page.\nYou can register various kinds of providers,\nand you know how to ask for an injected object (such as a service) by\nadding a parameter to a constructor.", "translation": "本章,你学习了 Angular 依赖注入的基础知识。\n你可以注册很多种类的提供商,知道如何通过添加构造函数的参数来请求一个注入对象(例如一个服务)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ANGULARDEPENDENCYINJECTIONISMORECAPABLETHANTHISGUIDEHASDESCRIBEDYOUCANLEARNMOREABOUTITSADVANCEDFEATURESBEGINNINGWITHITSSUPPORTFORNESTEDINJECTORSINHIERARCHICALDEPENDENCYINJECTIONGUIDEHIERARCHICALDEPENDENCYINJECTION", "original": "Angular dependency injection is more capable than this guide has described.\nYou can learn more about its advanced features, beginning with its support for\nnested injectors, in\n[Hierarchical Dependency Injection](guide/hierarchical-dependency-injection).", "translation": "Angular 依赖注入比前面描述的更能干。\n学习更多高级特性,如对嵌套注入器的支持,见[多级依赖注入](guide/hierarchical-dependency-injection)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##APPENDIX:WORKINGWITHINJECTORSDIRECTLY", "original": "## Appendix: Working with injectors directly", "translation": "## 附录:直接使用注入器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "DEVELOPERSRARELYWORKDIRECTLYWITHANINJECTORBUTHERESANINJECTORCOMPONENTTHATDOES", "original": "Developers rarely work directly with an injector, but\nhere's an `InjectorComponent` that does.", "translation": "这里的 `InjectorComponent` 直接使用了注入器,\n但开发者很少直接使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "ANINJECTORISITSELFANINJECTABLESERVICE", "original": "An `Injector` is itself an injectable service.", "translation": "`Injector` 本身是可注入的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "INTHISEXAMPLEANGULARINJECTSTHECOMPONENTSOWNINJECTORINTOTHECOMPONENTSCONSTRUCTORTHECOMPONENTTHENASKSTHEINJECTEDINJECTORFORTHESERVICESITWANTSINNGONINIT", "original": "In this example, Angular injects the component's own `Injector` into the component's constructor.\nThe component then asks the injected injector for the services it wants in `ngOnInit()`.", "translation": "在这个例子中,Angular 把组件自身的 `Injector` 注入到了组件的构造函数中。\n然后,组件在 `ngOnInit()` 中向注入的注入器请求它所需的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "NOTETHATTHESERVICESTHEMSELVESARENOTINJECTEDINTOTHECOMPONENTTHEYARERETRIEVEDBYCALLINGINJECTORGET", "original": "Note that the services themselves are not injected into the component.\nThey are retrieved by calling `injector.get()`.", "translation": "注意,这些服务本身没有注入到组件,它们是通过调用 `injector.get()` 获得的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THEGETMETHODTHROWSANERRORIFITCANTRESOLVETHEREQUESTEDSERVICEYOUCANCALLGETWITHASECONDPARAMETERWHICHISTHEVALUETORETURNIFTHESERVICEISNOTFOUNDANGULARCANTFINDTHESERVICEIFITSNOTREGISTEREDWITHTHISORANYANCESTORINJECTOR", "original": "The `get()` method throws an error if it can't resolve the requested service.\nYou can call `get()` with a second parameter, which is the value to return if the service\nis not found. Angular can't find the service if it's not registered with this or any ancestor injector.", "translation": "`get()` 方法如果不能解析所请求的服务,会抛出异常。\n调用 `get()` 时,还可以使用第二个参数,一旦获取的服务没有在当前或任何祖先注入器中注册过,\n就把它作为返回值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "THETECHNIQUEISANEXAMPLEOFTHESERVICELOCATORPATTERNHTTPS:ENWIKIPEDIAORGWIKISERVICELOCATORPATTERN", "original": "The technique is an example of the\n[service locator pattern](https://en.wikipedia.org/wiki/Service_locator_pattern).", "translation": "刚描述的这项技术是[服务定位器模式](https://en.wikipedia.org/wiki/Service_locator_pattern)的一个范例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "AVOIDTHISTECHNIQUEUNLESSYOUGENUINELYNEEDITITENCOURAGESACARELESSGRABBAGAPPROACHSUCHASYOUSEEHEREITSDIFFICULTTOEXPLAINUNDERSTANDANDTESTYOUCANTKNOWBYINSPECTINGTHECONSTRUCTORWHATTHISCLASSREQUIRESORWHATITWILLDOITCOULDACQUIRESERVICESFROMANYANCESTORCOMPONENTNOTJUSTITSOWNYOUREFORCEDTOSPELUNKTHEIMPLEMENTATIONTODISCOVERWHATITDOES", "original": "**Avoid** this technique unless you genuinely need it.\nIt encourages a careless grab-bag approach such as you see here.\nIt's difficult to explain, understand, and test.\nYou can't know by inspecting the constructor what this class requires or what it will do.\nIt could acquire services from any ancestor component, not just its own.\nYou're forced to spelunk the implementation to discover what it does.", "translation": "要**避免使用**此技术,除非确实需要它。\n它会鼓励鲁莽的方式,就像在这里看到的。\n它难以解释、理解和测试。\n仅通过阅读构造函数,没法知道这个类需要什么或者它将做什么。\n它可以从任何祖先组件中获得服务,而不仅仅是它自己。\n会迫使你深入它的实现,才可能明白它都做了啥。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "FRAMEWORKDEVELOPERSMAYTAKETHISAPPROACHWHENTHEYMUSTACQUIRESERVICESGENERICALLYANDDYNAMICALLY", "original": "Framework developers may take this approach when they\nmust acquire services generically and dynamically.", "translation": "框架开发人员必须采用通用的或者动态的方式获取服务时,可能采用这个方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "##APPENDIX:ONECLASSPERFILE", "original": "## Appendix: one class per file", "translation": "## 附录:为什么建议每个文件只放一个类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "HAVINGMULTIPLECLASSESINTHESAMEFILEISCONFUSINGANDBESTAVOIDEDDEVELOPERSEXPECTONECLASSPERFILEKEEPTHEMHAPPY", "original": "Having multiple classes in the same file is confusing and best avoided.\nDevelopers expect one class per file. Keep them happy.", "translation": "在同一个文件中有多个类容易造成混淆,最好避免。\n开发人员期望每个文件只放一个类。这会让它们开心点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "IFYOUCOMBINETHEHEROSERVICECLASSWITHTHEHEROESCOMPONENTINTHESAMEFILEDEFINETHECOMPONENTLASTIFYOUDEFINETHECOMPONENTBEFORETHESERVICEYOULLGETARUNTIMENULLREFERENCEERROR", "original": "If you combine the `HeroService` class with\nthe `HeroesComponent` in the same file,\n**define the component last**.\nIf you define the component before the service,\nyou'll get a runtime null reference error.", "translation": "如果你把 `HeroService` 和 `HeroesComponent` 组合在同一个文件里,\n **就得把组件定义放在最后面!**\n 如果把组件定义在了服务的前面,\n 在运行时抛出空指针错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "YOUACTUALLYCANDEFINETHECOMPONENTFIRSTWITHTHEHELPOFTHEFORWARDREFMETHODASEXPLAINEDINTHISBLOGPOSTHTTP:BLOGTHOUGHTRAMIOANGULAR20150903FORWARDREFERENCESINANGULAR2HTML", "original": "You actually can define the component first with the help of the `forwardRef()` method as explained\nin this [blog post](http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html).", "translation": "在 `forwardRef()` 方法的帮助下,实际上也可以先定义组件,\n具体说明见这篇[博客](http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "BUTITSBESTTOAVOIDTHEPROBLEMALTOGETHERBYDEFININGCOMPONENTSANDSERVICESINSEPARATEFILES", "original": "But it's best to avoid the problem altogether by defining components and services in separate files.", "translation": "但是为什么要先给自己找麻烦呢?\n还是通过在独立的文件中定义组件和服务,完全避免此问题吧。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dependency-injection.md" }, { + "key": "#DEPLOYMENT", "original": "# Deployment", "translation": "# 部署", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THISPAGEDESCRIBESTECHNIQUESFORDEPLOYINGYOURANGULARAPPLICATIONTOAREMOTESERVER", "original": "This page describes techniques for deploying your Angular application to a remote server.", "translation": "本章会描述在远程服务器上部署 Angular 应用的工具与技术。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "##SIMPLESTDEPLOYMENTPOSSIBLE", "original": "## Simplest deployment possible", "translation": "## 最简化的部署方式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "FORTHESIMPLESTDEPLOYMENTBUILDFORDEVELOPMENTANDCOPYTHEOUTPUTDIRECTORYTOAWEBSERVER", "original": "For the simplest deployment, build for development and copy the output directory to a web server.", "translation": "最简化的部署方式就是为开发环境构建,并把其输出复制到 Web 服务器上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "1STARTWITHTHEDEVELOPMENTBUILD", "original": "1. Start with the development build", "translation": "使用开发环境进行构建", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "2COPYEVERYTHINGWITHINTHEOUTPUTFOLDERDISTBYDEFAULTTOAFOLDERONTHESERVER", "original": "2. Copy _everything_ within the output folder (`dist/` by default) to a folder on the server.", "translation": "把输出目录(默认为 `dist/`)下的*每个文件*都复制到到服务器上的某个目录下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "3IFYOUCOPYTHEFILESINTOASERVERSUBFOLDERAPPENDTHEBUILDFLAGBASEHREFANDSETTHEBASEHREFAPPROPRIATELYBRBR", "original": "3. If you copy the files into a server _sub-folder_, append the build flag, `--base-href` and set the `<base href>` appropriately.<br><br>", "translation": "如果要把文件部署到服务器上的*某个子路径*下,构建时还要添加 `--base-href`(基地址)标识,并设置合适的 `<base href>`。<br><br>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "FOREXAMPLEIFTHEINDEXHTMLISONTHESERVERATMYAPPINDEXHTMLSETTHEBASEHREFTOBASEHREFMYAPPLIKETHIS", "original": "For example, if the `index.html` is on the server at `/my/app/index.html`, set the _base href_ to\n `<base href=\"/my/app/\">` like this.", "translation": "比如,如果 `index.html` 位于服务器上的 `/my/app/index.html` 路径下,就要把 *base href* 设置为 `<base href=\"/my/app/\">`,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "YOULLSEETHATTHEBASEHREFISSETPROPERLYINTHEGENERATEDDISTINDEXHTMLBRBRIFYOUCOPYTOTHESERVERSROOTDIRECTORYOMITTHISSTEPANDLEAVETHEBASEHREFALONEBRBRLEARNMOREABOUTTHEROLEOFBASEHREFBELOWGUIDEDEPLOYMENT#BASETAG", "original": "You'll see that the `<base href>` is set properly in the generated `dist/index.html`.<br><br>\n If you copy to the server's root directory, omit this step and leave the `<base href>` alone.<br><br>\n Learn more about the role of `<base href>` [below](guide/deployment#base-tag).", "translation": "你会看到在生成的 `dist/index.html` 中 `<base href>` 已经被设置好了。<br><br>\n 如果复制到服务器的根目录下,就省略这个步骤,并且让 `<base href>` 保持原样。<br><br> \n 要了解 `<base href>` 的作用,参见 [下面](guide/deployment#base-tag) 的内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "4CONFIGURETHESERVERTOREDIRECTREQUESTSFORMISSINGFILESTOINDEXHTMLLEARNMOREABOUTSERVERSIDEREDIRECTSBELOWGUIDEDEPLOYMENT#FALLBACK", "original": "4. Configure the server to redirect requests for missing files to `index.html`.\nLearn more about server-side redirects [below](guide/deployment#fallback).", "translation": "配置服务器,使其在找不到文件时把请求重定向到 `index.html`。要了解服务端重定向的更多知识,参见 [下面](guide/deployment#fallback) 的内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THISISNOTAPRODUCTIONDEPLOYMENTITSNOTOPTIMIZEDANDITWONTBEFASTFORUSERSITMIGHTBEGOODENOUGHFORSHARINGYOURPROGRESSANDIDEASINTERNALLYWITHMANAGERSTEAMMATESANDOTHERSTAKEHOLDERS", "original": "This is _not_ a production deployment. It's not optimized and it won't be fast for users.\nIt might be good enough for sharing your progress and ideas internally with managers, teammates, and other stakeholders.", "translation": "这不是生产级部署。它没有优化过,并且对用户来说也不够快。\n但是当你向经理、团队成员或其它利益相关者内部分享你的进度和想法时它是足够的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "##OPTIMIZEFORPRODUCTION", "original": "## Optimize for production", "translation": "## 为生产环境优化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "ALTHOUGHDEPLOYINGDIRECTLYFROMTHEDEVELOPMENTENVIRONMENTWORKSYOUCANGENERATEANOPTIMIZEDBUILDWITHADDITIONALCLICOMMANDLINEFLAGSSTARTINGWITHPROD", "original": "Although deploying directly from the development environment works, \nyou can generate an optimized build with additional CLI command line flags,\nstarting with `--prod`.", "translation": "虽然也可以直接用开发环境的设置进行部署,不过你也可以使用 CLI 命令的其它标志生成一个优化过的构建成果。\n先来看 `--prod`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "###BUILDWITHPROD", "original": "### Build with _--prod_", "translation": "### 使用 `--prod` 构建。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEPRODMETAFLAGENGAGESTHEFOLLOWINGOPTIMIZATIONFEATURES", "original": "The `--prod` _meta-flag_ engages the following optimization features.", "translation": "`--prod` *元标志*包括下列优化特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "AHEADOFTIMEAOTCOMPILATIONGUIDEAOTCOMPILER:PRECOMPILESANGULARCOMPONENTTEMPLATES", "original": "* [Ahead-of-Time (AOT) Compilation](guide/aot-compiler): pre-compiles Angular component templates.", "translation": "[预(AOT)编译](guide/aot-compiler):预编译 Angular 组件的模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "PRODUCTIONMODE#ENABLEPRODMODE:DEPLOYSTHEPRODUCTIONENVIRONMENTWHICHENABLESPRODUCTIONMODE", "original": "* [Production mode](#enable-prod-mode): deploys the production environment which enables _production mode_.", "translation": "[生产模式](#enable-prod-mode):启用生产模式部署到生产环境。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "BUNDLING:CONCATENATESYOURMANYAPPLICATIONANDLIBRARYFILESINTOAFEWBUNDLES", "original": "* Bundling: concatenates your many application and library files into a few bundles.", "translation": "打捆(Bundle):把这些模块串接成一个单独的捆文件(bundle)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "MINIFICATION:REMOVESEXCESSWHITESPACECOMMENTSANDOPTIONALTOKENS", "original": "* Minification: removes excess whitespace, comments, and optional tokens.", "translation": "最小化:移除不必要的空格、注释和可选令牌(Token)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "UGLIFICATION:REWRITESCODETOUSESHORTCRYPTICVARIABLEANDFUNCTIONNAMES", "original": "* Uglification: rewrites code to use short, cryptic variable and function names.", "translation": "混淆:使用短的、无意义的变量名和函数名来重写代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "DEADCODEELIMINATION:REMOVESUNREFERENCEDMODULESANDMUCHUNUSEDCODE", "original": "* Dead code elimination: removes unreferenced modules and much unused code.", "translation": "消除死代码:移除未引用过的模块和未使用过的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEREMAININGCOPYDEPLOYMENTSTEPS#COPYFILESARETHESAMEASBEFORE", "original": "The remaining [copy deployment steps](#copy-files) are the same as before.", "translation": "剩下的 [拷贝部署步骤](#copy-files) 和以前的方式是一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "YOUMAYFURTHERREDUCEBUNDLESIZESBYADDINGTHEBUILDOPTIMIZERFLAG", "original": "You may further reduce bundle sizes by adding the `build-optimizer` flag.", "translation": "你还可以添加 `build-optimizer` 标志来进一步缩减打包体积。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "SEETHECLIDOCUMENTATIONHTTPS:GITHUBCOMANGULARANGULARCLIWIKIBUILDFORDETAILSABOUTAVAILABLEBUILDOPTIONSANDWHATTHEYDO", "original": "See the [CLI Documentation](https://github.com/angular/angular-cli/wiki/build) \nfor details about available build options and what they do.", "translation": "参见 [CLI 文档](https://github.com/angular/angular-cli/wiki/build),来了解可用的构建选项及其用途的详细信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "###ENABLEPRODUCTIONMODE", "original": "### Enable production mode", "translation": "### 启用生产模式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "ANGULARAPPSRUNINDEVELOPMENTMODEBYDEFAULTASYOUCANSEEBYTHEFOLLOWINGMESSAGEONTHEBROWSERCONSOLE:", "original": "Angular apps run in development mode by default, as you can see by the following message on the browser\nconsole:", "translation": "Angular 应用默认运行在开发模式下,正如在浏览器控制台中看到的如下信息:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "SWITCHINGTOPRODUCTIONMODECANMAKEITRUNFASTERBYDISABLINGDEVELOPMENTSPECIFICCHECKSSUCHASTHEDUALCHANGEDETECTIONCYCLES", "original": "Switching to _production mode_ can make it run faster by disabling development specific checks such as the dual change detection cycles.", "translation": "切换到生产模式可以通过禁用开发环境下特有的检查(比如双重变更检测周期)来让应用运行得更快。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "BUILDINGFORPRODUCTIONORAPPENDINGTHEENVIRONMENTPRODFLAGENABLESPRODUCTIONMODELOOKATTHECLIGENERATEDMAINTSTOSEEHOWTHISWORKS", "original": "Building for production (or appending the `--environment=prod` flag) enables _production mode_\nLook at the CLI-generated `main.ts` to see how this works.", "translation": "为生产环境构建(或添加 `--environment=prod` 标志)可以启用*生产模式*。\n查看 CLI 自动生成的 `main.ts` 文件来了解它的工作原理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "###LAZYLOADING", "original": "### Lazy loading", "translation": "### 惰性加载", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "YOUCANDRAMATICALLYREDUCELAUNCHTIMEBYONLYLOADINGTHEAPPLICATIONMODULESTHATABSOLUTELYMUSTBEPRESENTWHENTHEAPPSTARTS", "original": "You can dramatically reduce launch time by only loading the application modules that\nabsolutely must be present when the app starts.", "translation": "通过只加载应用启动时必须展示的那些应用模块,你可以显著缩减启动时间。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "CONFIGURETHEANGULARROUTERTODEFERLOADINGOFALLOTHERMODULESANDTHEIRASSOCIATEDCODEEITHERBYWAITINGUNTILTHEAPPHASLAUNCHEDGUIDEROUTER#PRELOADINGPRELOADINGORBYLAZYLOADINGGUIDEROUTER#ASYNCHRONOUSROUTINGLAZYLOADINGTHEMONDEMAND", "original": "Configure the Angular Router to defer loading of all other modules (and their associated code), either by\n[waiting until the app has launched](guide/router#preloading \"Preloading\")\nor by [_lazy loading_](guide/router#asynchronous-routing \"Lazy loading\")\nthem on demand.", "translation": "配置 Angular 路由器可以延迟加载所有其它模块(以及与它们相关的代码),无论是[等应用启动](guide/router#preloading \"Preloading\"),\n还是在需要时才[惰性加载](guide/router#asynchronous-routing \"Lazy loading\")。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "####DONTEAGERLYIMPORTSOMETHINGFROMALAZYLOADEDMODULE", "original": "#### Don't eagerly import something from a lazy loaded module", "translation": "#### 不要立即导入惰性加载模块中的任何东西", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "ITSACOMMONMISTAKEYOUVEARRANGEDTOLAZYLOADAMODULEBUTYOUUNINTENTIONALLYIMPORTITWITHAJAVASCRIPTIMPORTSTATEMENTINAFILETHATSEAGERLYLOADEDWHENTHEAPPSTARTSAFILESUCHASTHEROOTAPPMODULEIFYOUDOTHATTHEMODULEWILLBELOADEDIMMEDIATELY", "original": "It's a common mistake.\nYou've arranged to lazy load a module.\nBut you unintentionally import it, with a JavaScript `import` statement,\nin a file that's eagerly loaded when the app starts, a file such as the root `AppModule`.\nIf you do that, the module will be loaded immediately.", "translation": "这是一种常犯的错误。\n你本打算惰性加载一个模块,但可能无意中在根模块 `AppModule` 文件中使用一个 JavaScript 的 `import` 语句导入了它。\n这样一来,该模块就被立即加载了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEBUNDLINGCONFIGURATIONMUSTTAKELAZYLOADINGINTOCONSIDERATIONBECAUSELAZYLOADEDMODULESARENTIMPORTEDINJAVASCRIPTASJUSTNOTEDBUNDLERSEXCLUDETHEMBYDEFAULTBUNDLERSDONTKNOWABOUTTHEROUTERCONFIGURATIONANDWONTCREATESEPARATEBUNDLESFORLAZYLOADEDMODULESYOUHAVETOCREATETHESEBUNDLESMANUALLY", "original": "The bundling configuration must take lazy loading into consideration.\nBecause lazy loaded modules aren't imported in JavaScript (as just noted), bundlers exclude them by default.\nBundlers don't know about the router configuration and won't create separate bundles for lazy loaded modules.\nYou have to create these bundles manually.", "translation": "关于打包(bundle)方式的配置必须考虑到惰性加载问题。\n因为惰性加载模块不能在 JavaScript 中导入(就像刚才说明的),打包器应该默认排除它们。\n打包器不知道路由器的配置,并且不会为延迟加载模块创建单独的包。\n你不得不手动创建这些包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THECLIRUNSTHEANGULARAHEADOFTIMEWEBPACKPLUGINHTTPS:GITHUBCOMANGULARANGULARCLITREEMASTERPACKAGES40NGTOOLSWEBPACKWHICHAUTOMATICALLYRECOGNIZESLAZYLOADEDNGMODULESANDCREATESSEPARATEBUNDLESFORTHEM", "original": "The CLI runs the\n[Angular Ahead-of-Time Webpack Plugin](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack)\nwhich automatically recognizes lazy loaded `NgModules` and creates separate bundles for them.", "translation": "CLI 会运行 [Angular AOT 编译 Webpack 插件](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack),它会自动识别出那些需要惰性加载的 `NgModule`,并为它们创建单独的文件包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "###MEASUREPERFORMANCE", "original": "### Measure performance", "translation": "### 性能测量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "YOUCANMAKEBETTERDECISIONSABOUTWHATTOOPTIMIZEANDHOWWHENYOUHAVEACLEARANDACCURATEUNDERSTANDINGOFWHATSMAKINGTHEAPPLICATIONSLOWTHECAUSEMAYNOTBEWHATYOUTHINKITISYOUCANWASTEALOTOFTIMEANDMONEYOPTIMIZINGSOMETHINGTHATHASNOTANGIBLEBENEFITOREVENMAKESTHEAPPSLOWERYOUSHOULDMEASURETHEAPPSACTUALBEHAVIORWHENRUNNINGINTHEENVIRONMENTSTHATAREIMPORTANTTOYOU", "original": "You can make better decisions about what to optimize and how when you have a clear and accurate understanding of\nwhat's making the application slow.\nThe cause may not be what you think it is.\nYou can waste a lot of time and money optimizing something that has no tangible benefit or even makes the app slower.\nYou should measure the app's actual behavior when running in the environments that are important to you.", "translation": "如果你能对“是什么导致了应用变慢”的问题有一个清晰、准确的理解,那就可以对优化什么、如何优化做出更好地决策了。\n真正的原因可能并不是你所想的那样。\n你可能花费大量的时间和金钱去优化一些东西,但它却无法产生可感知的效果甚至让应用变得更慢。\n你应该在那些最重要的环境中实际运行,来度量应用的实际行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEAHREFHTTPS:DEVELOPERSGOOGLECOMWEBTOOLSCHROMEDEVTOOLSNETWORKPERFORMANCEUNDERSTANDINGRESOURCETIMINGTITLECHROMEDEVTOOLSNETWORKPERFORMANCECHROMEDEVTOOLSNETWORKPERFORMANCEPAGEAISAGOODPLACETOSTARTLEARNINGABOUTMEASURINGPERFORMANCE", "original": "The\n<a href=\"https://developers.google.com/web/tools/chrome-devtools/network-performance/understanding-resource-timing\" title=\"Chrome DevTools Network Performance\">\nChrome DevTools Network Performance page</a> is a good place to start learning about measuring performance.", "translation": "<p><a href=\"https://developers.google.com/web/tools/chrome-devtools/network-performance/understanding-resource-timing\" target=\"_blank\" title=\"Chrome DevTools Network Performance\">\n Chrome 开发工具的网络性能页</a>是开始学习度量性能的好地方。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEWEBPAGETESTHTTPS:WWWWEBPAGETESTORGTOOLISANOTHERGOODCHOICETHATCANALSOHELPVERIFYTHATYOURDEPLOYMENTWASSUCCESSFUL", "original": "The [WebPageTest](https://www.webpagetest.org/) tool is another good choice\nthat can also help verify that your deployment was successful.", "translation": "[WebPageTest](https://www.webpagetest.org/)工具是另一个不错的选择,它能帮你验证你的部署是否成功了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "###INSPECTTHEBUNDLES", "original": "### Inspect the bundles", "translation": "### 深入探查文件包(bundle)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEAHREFHTTPS:GITHUBCOMDANVKSOURCEMAPEXPLORERBLOBMASTERREADMEMDSOURCEMAPEXPLORERATOOLISAGREATWAYTOINSPECTTHEGENERATEDJAVASCRIPTBUNDLESAFTERAPRODUCTIONBUILD", "original": "The <a href=\"https://github.com/danvk/source-map-explorer/blob/master/README.md\">source-map-explorer</a>\ntool is a great way to inspect the generated JavaScript bundles after a production build.", "translation": "<a href=\"https://github.com/danvk/source-map-explorer/blob/master/README.md\">source-map-explorer</a> 是在生产环境构建中深入探查所生成的文件包的好工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "INSTALLSOURCEMAPEXPLORER:", "original": "Install `source-map-explorer`:", "translation": "安装 `source-map-explorer`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "BUILDYOURAPPFORPRODUCTIONINCLUDINGTHESOURCEMAPS", "original": "Build your app for production _including the source maps_", "translation": "构建*带源码映射*的生产版本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "LISTTHEGENERATEDBUNDLESINTHEDISTFOLDER", "original": "List the generated bundles in the `dist/` folder.", "translation": "列出 `dist/` 文件夹中生成的文件包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "RUNTHEEXPLORERTOGENERATEAGRAPHICALREPRESENTATIONOFONEOFTHEBUNDLESTHEFOLLOWINGEXAMPLEDISPLAYSTHEGRAPHFORTHEMAINBUNDLE", "original": "Run the explorer to generate a graphical representation of one of the bundles.\nThe following example displays the graph for the _main_ bundle.", "translation": "运行这个源码映射浏览器,以生成文件包之一的图形化表示。\n下面的例子中就是 `main` 这个文件包的图形。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THESOURCEMAPEXPLORERANALYZESTHESOURCEMAPGENERATEDWITHTHEBUNDLEANDDRAWSAMAPOFALLDEPENDENCIESSHOWINGEXACTLYWHICHCLASSESAREINCLUDEDINTHEBUNDLE", "original": "The `source-map-explorer` analyzes the source map generated with the bundle and draws a map of all dependencies,\nshowing exactly which classes are included in the bundle.", "translation": "`source-map-explorer` 分析了文件包生成的源码映射信息,并画出了所有这些依赖的地图,准确的展示了这个包中包含了哪些类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "HERESTHEOUTPUTFORTHEMAINBUNDLEOFTHEQUICKSTART", "original": "Here's the output for the _main_ bundle of the QuickStart.", "translation": "下面是《快速起步》一章生成的 `main` 文件包的输出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "##THEBASETAG", "original": "## The `base` tag", "translation": "## `base` 标签", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEHTMLLTBASEHREFGTGUIDEROUTERSPECIFIESABASEPATHFORRESOLVINGRELATIVEURLSTOASSETSSUCHASIMAGESSCRIPTSANDSTYLESHEETSFOREXAMPLEGIVENTHEBASEHREFMYAPPTHEBROWSERRESOLVESAURLSUCHASSOMEPLACEFOOJPGINTOASERVERREQUESTFORMYAPPSOMEPLACEFOOJPGDURINGNAVIGATIONTHEANGULARROUTERUSESTHEBASEHREFASTHEBASEPATHTOCOMPONENTTEMPLATEANDMODULEFILES", "original": "The HTML [_<base href=\"...\"/>_](/guide/router)\nspecifies a base path for resolving relative URLs to assets such as images, scripts, and style sheets.\nFor example, given the `<base href=\"/my/app/\">`, the browser resolves a URL such as `some/place/foo.jpg`\ninto a server request for `my/app/some/place/foo.jpg`.\nDuring navigation, the Angular router uses the _base href_ as the base path to component, template, and module files.", "translation": "HTML 中的[_<base href=\"...\"/>_](https://angular.io/docs/ts/latest/guide/router.html#!)用于指定一个解析相对路径的基地址,如图片、脚本和样式表。\n比如,指定 `<base href=\"/my/app/\">` 时,浏览器就会把 `some/place/foo.jpg` 这样的 URL 解析成到 `my/app/some/place/foo.jpg` 的服务端请求。\n在浏览期间,Angular 路由器会使用*base href*作为组件、模板和模块文件的基地址。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "SEEALSOTHEAPPBASEHREFAPICOMMONAPPBASEHREFAPI:APPBASEHREFALTERNATIVE", "original": "See also the [*APP_BASE_HREF*](api/common/APP_BASE_HREF \"API: APP_BASE_HREF\") alternative.", "translation": "参见另一种备选方案[*APP_BASE_HREF*](api/common/APP_BASE_HREF \"API: APP_BASE_HREF\")。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "INDEVELOPMENTYOUTYPICALLYSTARTTHESERVERINTHEFOLDERTHATHOLDSINDEXHTMLTHATSTHEROOTFOLDERANDYOUDADDBASEHREFNEARTHETOPOFINDEXHTMLBECAUSEISTHEROOTOFTHEAPP", "original": "In development, you typically start the server in the folder that holds `index.html`.\nThat's the root folder and you'd add `<base href=\"/\">` near the top of `index.html` because `/` is the root of the app.", "translation": "在开发期间,你通常会在 `index.html` 所在的目录中启动服务器。这个目录就是根目录,因为 `/` 就是本应用的根,所以你要在 `index.html` 的顶部添加 `<base href=\"/\">`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "BUTONTHESHAREDORPRODUCTIONSERVERYOUMIGHTSERVETHEAPPFROMASUBFOLDERFOREXAMPLEWHENTHEURLTOLOADTHEAPPISSOMETHINGLIKEHTTP:WWWMYSITECOMMYAPPTHESUBFOLDERISMYAPPANDYOUSHOULDADDBASEHREFMYAPPTOTHESERVERVERSIONOFTHEINDEXHTML", "original": "But on the shared or production server, you might serve the app from a subfolder.\nFor example, when the URL to load the app is something like `http://www.mysite.com/my/app/`,\nthe subfolder is `my/app/` and you should add `<base href=\"/my/app/\">` to the server version of the `index.html`.", "translation": "但是在共享服务器或生产服务器上,你可能得从子目录下启动服务器。\n比如,当加载本应用的 URL 是 `http://www.mysite.com/my/app/` 时,子目录就是 `my/app/`,而你就要在服务器版的 `index.html` 中添加 `<base href=\"/my/app/\">`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "WHENTHEBASETAGISMISCONFIGUREDTHEAPPFAILSTOLOADANDTHEBROWSERCONSOLEDISPLAYS404NOTFOUNDERRORSFORTHEMISSINGFILESLOOKATWHEREITTRIEDTOFINDTHOSEFILESANDADJUSTTHEBASETAGAPPROPRIATELY", "original": "When the `base` tag is mis-configured, the app fails to load and the browser console displays `404 - Not Found` errors\nfor the missing files. Look at where it _tried_ to find those files and adjust the base tag appropriately.", "translation": "当没有配置 `base` 标签时,加载应用就会失败,浏览器的控制台中会为这些缺失的文件显示一些 `404 - Not Found` 错误。\n看看浏览器*试图*从哪里找这些文件,然后调整出合适的 base 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "##BUILDVSSERVE", "original": "## _build_ vs. _serve_", "translation": "## *构建*与*服务*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "YOULLPROBABLYPREFERNGBUILDFORDEPLOYMENTS", "original": "You'll probably prefer `ng build` for deployments.", "translation": "你会更喜欢用 `ng build` 进行部署。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THENGBUILDCOMMANDISINTENDEDFORBUILDINGTHEAPPANDDEPLOYINGTHEBUILDARTIFACTSELSEWHERETHENGSERVECOMMANDISINTENDEDFORFASTLOCALITERATIVEDEVELOPMENT", "original": "The **ng build** command is intended for building the app and deploying the build artifacts elsewhere.\nThe **ng serve** command is intended for fast, local, iterative development.", "translation": "**ng build** 命令的设计意图是构建该应用,并且把构建成果部署到别处。\n而**ng serve** 命令的设计意图是快速进行本地的迭代式开发。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "BOTHNGBUILDANDNGSERVECLEARTHEOUTPUTFOLDERBEFORETHEYBUILDTHEPROJECTTHENGBUILDCOMMANDWRITESGENERATEDBUILDARTIFACTSTOTHEOUTPUTFOLDERTHENGSERVECOMMANDDOESNOTITSERVESBUILDARTIFACTSFROMMEMORYINSTEADFORAFASTERDEVELOPMENTEXPERIENCE", "original": "Both `ng build` and `ng serve` **clear the output folder** before they build the project.\nThe `ng build` command writes generated build artifacts to the output folder.\nThe `ng serve` command does not.\nIt serves build artifacts from memory instead for a faster development experience.", "translation": "在开始构建项目之前,`ng build` 和 `ng serve` **都会清空输出文件夹**。\n`ng build` 命令会把生成的构建成果写入输出文件夹中,但 `ng serve` 命令并不会如此。\n它会用内存中的构建成果提供服务,以获得更快速的开发体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEOUTPUTFOLDERISDISTBYDEFAULTTOOUTPUTTOADIFFERENTFOLDERCHANGETHEOUTDIRINANGULARCLIJSON", "original": "The output folder is `dist/` by default.\nTo output to a different folder, change the `outDir` in `.angular-cli.json`.", "translation": "默认的输出文件夹是 `dist/`。\n要输出到其它文件夹中,请修改 `.angular-cli.json` 中的 `outDir`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THENGSERVECOMMANDBUILDSWATCHESANDSERVESTHEAPPLICATIONFROMALOCALCLIDEVELOPMENTSERVER", "original": "The `ng serve` command builds, watches, and serves the application from a local CLI development server.", "translation": "`ng serve` 命令会构建、监听并使用本地的 CLI 开发服务器作为服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THENGBUILDCOMMANDGENERATESOUTPUTFILESJUSTONCEANDDOESNOTSERVETHEMTHENGBUILDWATCHCOMMANDWILLREGENERATEOUTPUTFILESWHENSOURCEFILESCHANGETHISWATCHFLAGISUSEFULIFYOUREBUILDINGDURINGDEVELOPMENTANDAREAUTOMATICALLYREDEPLOYINGCHANGESTOANOTHERSERVER", "original": "The `ng build` command generates output files just once and does not serve them.\nThe `ng build --watch` command will regenerate output files when source files change.\nThis `--watch` flag is useful if you're building during development and \nare automatically re-deploying changes to another server.", "translation": "`ng build` 命令只会生成一次这些输出文件,而不会用它们提供服务。\n`ng build --watch` 命令会在源码变化的时候重新生成输出文件。\n当你在开发期间需要不断构建并自动把修改后的版本发布到另一台服务器的时候,这个 `--watch` 标志会很有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "SEETHECLIBUILDTOPICHTTPS:GITHUBCOMANGULARANGULARCLIWIKIBUILDFORMOREDETAILSANDOPTIONS", "original": "See the [CLI `build` topic](https://github.com/angular/angular-cli/wiki/build) for more details and options.", "translation": "参见 [CLI 中的 `build` 主题](https://github.com/angular/angular-cli/wiki/build)以了解详情以及其它选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "##SERVERCONFIGURATION", "original": "## Server configuration", "translation": "## 服务端配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THISSECTIONCOVERSCHANGESYOUMAYHAVEMAKETOTHESERVERORTOFILESDEPLOYEDTOTHESERVER", "original": "This section covers changes you may have make to the server or to files deployed to the server.", "translation": "这一节涵盖了你可能对服务器或准备部署到服务器的文件要做的那些修改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "###ROUTEDAPPSMUSTFALLBACKTOINDEXHTML", "original": "### Routed apps must fallback to `index.html`", "translation": "### 带路由的应用必须以 `index.html` 作为后备页面", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "ANGULARAPPSAREPERFECTCANDIDATESFORSERVINGWITHASIMPLESTATICHTMLSERVERYOUDONTNEEDASERVERSIDEENGINETODYNAMICALLYCOMPOSEAPPLICATIONPAGESBECAUSEANGULARDOESTHATONTHECLIENTSIDE", "original": "Angular apps are perfect candidates for serving with a simple static HTML server.\nYou don't need a server-side engine to dynamically compose application pages because\nAngular does that on the client-side.", "translation": "Angular 应用很适合用简单的静态 HTML 服务器提供服务。\n你不需要服务端引擎来动态合成应用页面,因为 Angular 会在客户端完成这件事。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "IFTHEAPPUSESTHEANGULARROUTERYOUMUSTCONFIGURETHESERVERTORETURNTHEAPPLICATIONSHOSTPAGEINDEXHTMLWHENASKEDFORAFILETHATITDOESNOTHAVE", "original": "If the app uses the Angular router, you must configure the server\nto return the application's host page (`index.html`) when asked for a file that it does not have.", "translation": "如果该应用使用 Angular 路由器,你就必须配置服务器,让它对不存在的文件返回应用的宿主页(`index.html`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "AROUTEDAPPLICATIONSHOULDSUPPORTDEEPLINKSADEEPLINKISAURLTHATSPECIFIESAPATHTOACOMPONENTINSIDETHEAPPFOREXAMPLEHTTP:WWWMYSITECOMHEROES42ISADEEPLINKTOTHEHERODETAILPAGETHATDISPLAYSTHEHEROWITHID:42", "original": "A routed application should support \"deep links\".\nA _deep link_ is a URL that specifies a path to a component inside the app.\nFor example, `http://www.mysite.com/heroes/42` is a _deep link_ to the hero detail page\nthat displays the hero with `id: 42`.", "translation": "带路由的应用应该支持“深链接”。\n所谓*深链接*就是指一个 URL,它用于指定到应用内某个组件的路径。\n比如,`http://www.mysite.com/heroes/42` 就是一个到英雄详情页面的*深链接*,用于显示 `id: 42` 的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEREISNOISSUEWHENTHEUSERNAVIGATESTOTHATURLFROMWITHINARUNNINGCLIENTTHEANGULARROUTERINTERPRETSTHEURLANDROUTESTOTHATPAGEANDHERO", "original": "There is no issue when the user navigates to that URL from within a running client.\nThe Angular router interprets the URL and routes to that page and hero.", "translation": "当用户从运行中的客户端应用导航到这个 URL 时,这没问题。\nAngular 路由器会拦截这个 URL,并且把它路由到正确的页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "BUTCLICKINGALINKINANEMAILENTERINGITINTHEBROWSERADDRESSBARORMERELYREFRESHINGTHEBROWSERWHILEONTHEHERODETAILPAGEMDASHALLOFTHESEACTIONSAREHANDLEDBYTHEBROWSERITSELFOUTSIDETHERUNNINGAPPLICATIONTHEBROWSERMAKESADIRECTREQUESTTOTHESERVERFORTHATURLBYPASSINGTHEROUTER", "original": "But clicking a link in an email, entering it in the browser address bar,\nor merely refreshing the browser while on the hero detail page —\nall of these actions are handled by the browser itself, _outside_ the running application.\nThe browser makes a direct request to the server for that URL, bypassing the router.", "translation": "但是,当从邮件中点击链接或在浏览器地址栏中输入它或仅仅在英雄详情页刷新下浏览器时,所有这些操作都是由浏览器本身处理的,在应用的控制范围之外。\n浏览器会直接向服务器请求那个 URL,路由器没机会插手。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "ASTATICSERVERROUTINELYRETURNSINDEXHTMLWHENITRECEIVESAREQUESTFORHTTP:WWWMYSITECOMBUTITREJECTSHTTP:WWWMYSITECOMHEROES42ANDRETURNSA404NOTFOUNDERRORUNLESSITISCONFIGUREDTORETURNINDEXHTMLINSTEAD", "original": "A static server routinely returns `index.html` when it receives a request for `http://www.mysite.com/`.\nBut it rejects `http://www.mysite.com/heroes/42` and returns a `404 - Not Found` error *unless* it is\nconfigured to return `index.html` instead.", "translation": "静态服务器会在收到对 `http://www.mysite.com/` 的请求时返回 `index.html`,但是会拒绝对 `http://www.mysite.com/heroes/42` 的请求,\n并返回一个 `404 - Not Found` 错误,除非,它被配置成了返回 `index.html`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "####FALLBACKCONFIGURATIONEXAMPLES", "original": "#### Fallback configuration examples", "translation": "#### 后备页面配置范例", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEREISNOSINGLECONFIGURATIONTHATWORKSFOREVERYSERVERTHEFOLLOWINGSECTIONSDESCRIBECONFIGURATIONSFORSOMEOFTHEMOSTPOPULARSERVERSTHELISTISBYNOMEANSEXHAUSTIVEBUTSHOULDPROVIDEYOUWITHAGOODSTARTINGPOINT", "original": "There is no single configuration that works for every server.\nThe following sections describe configurations for some of the most popular servers.\nThe list is by no means exhaustive, but should provide you with a good starting point.", "translation": "没有一种配置可以适用于所有服务器。\n后面这些部分会描述对常见服务器的配置方式。\n这个列表虽然不够详尽,但可以为你提供一个良好的起点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "####DEVELOPMENTSERVERS", "original": "#### Development servers", "translation": "#### 开发服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "LITESERVERHTTPS:GITHUBCOMJOHNPAPALITESERVER:THEDEFAULTDEVSERVERINSTALLEDWITHTHEQUICKSTARTREPOHTTPS:GITHUBCOMANGULARQUICKSTARTISPRECONFIGUREDTOFALLBACKTOINDEXHTML", "original": "* [Lite-Server](https://github.com/johnpapa/lite-server): the default dev server installed with the\n[Quickstart repo](https://github.com/angular/quickstart) is pre-configured to fallback to `index.html`.", "translation": "[Lite-Server](https://github.com/johnpapa/lite-server)是[\"快速上手\"仓库](https://github.com/angular/quickstart)中安装的默认开发服务器,它被预先配置为回退到 `index.html`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "WEBPACKDEVSERVERHTTPS:GITHUBCOMWEBPACKWEBPACKDEVSERVER:SETUPTHEHISTORYAPIFALLBACKENTRYINTHEDEVSERVEROPTIONSASFOLLOWS:", "original": "* [Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server): setup the\n`historyApiFallback` entry in the dev server options as follows:", "translation": "[Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server)在开发服务器的配置中设置了 `historyApiFallback`,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "####PRODUCTIONSERVERS", "original": "#### Production servers", "translation": "#### 生产服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "APACHEHTTPS:HTTPDAPACHEORG:ADDAREWRITERULEHTTP:HTTPDAPACHEORGDOCSCURRENTMODMODREWRITEHTMLTOTHEHTACCESSFILEASSHOWNHTTPS:NGMILKROCKS20150309ANGULARJSHTML5MODEORPRETTYURLSONAPACHEUSINGHTACCESS:", "original": "* [Apache](https://httpd.apache.org/): add a\n[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown\n (https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):", "translation": "[Apache](https://httpd.apache.org/):在 `.htaccess` 文件中添加一个[重写规则](http://httpd.apache.org/docs/current/mod/mod_rewrite.html),\n代码如下([出处](https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/)):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "NGINXHTTP:NGINXORG:USETRYFILESASDESCRIBEDINFRONTCONTROLLERPATTERNWEBAPPSHTTPS:WWWNGINXCOMRESOURCESWIKISTARTTOPICSTUTORIALSCONFIGPITFALLS#FRONTCONTROLLERPATTERNWEBAPPSMODIFIEDTOSERVEINDEXHTML:", "original": "* [NGinx](http://nginx.org/): use `try_files`, as described in\n[Front Controller Pattern Web Apps](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#front-controller-pattern-web-apps),\nmodified to serve `index.html`:", "translation": "[NGinx](http://nginx.org/):使用 `try_files` 指向 `index.html`,详细描述见[Web 应用的前端控制器模式](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#front-controller-pattern-web-apps)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "IISHTTPS:WWWIISNET:ADDAREWRITERULETOWEBCONFIGSIMILARTOTHEONESHOWNHEREHTTP:STACKOVERFLOWCOMA261520112116927:", "original": "* [IIS](https://www.iis.net/): add a rewrite rule to `web.config`, similar to the one shown\n[here](http://stackoverflow.com/a/26152011/2116927):", "translation": "[IIS](https://www.iis.net/):往 `web.config` 中添加一条重写规则,类似于[这里](http://stackoverflow.com/a/26152011/2116927):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "GITHUBPAGESHTTPS:PAGESGITHUBCOM:YOUCANTDIRECTLYCONFIGUREHTTPS:GITHUBCOMISAACSGITHUBISSUES408THEGITHUBPAGESSERVERBUTYOUCANADDA404PAGECOPYINDEXHTMLINTO404HTMLITWILLSTILLBESERVEDASTHE404RESPONSEBUTTHEBROWSERWILLPROCESSTHATPAGEANDLOADTHEAPPPROPERLYITSALSOAGOODIDEATOSERVEFROMDOCSONMASTERHTTPS:HELPGITHUBCOMARTICLESCONFIGURINGAPUBLISHINGSOURCEFORGITHUBPAGES#PUBLISHINGYOURGITHUBPAGESSITEFROMADOCSFOLDERONYOURMASTERBRANCHANDTOCREATEANOJEKYLLFILEHTTPS:WWWBENNADELCOMBLOG3181INCLUDINGNODEMODULESANDVENDORSFOLDERSINYOURGITHUBPAGESSITEHTM", "original": "* [GitHub Pages](https://pages.github.com/): you can't\n[directly configure](https://github.com/isaacs/github/issues/408)\nthe GitHub Pages server, but you can add a 404 page.\nCopy `index.html` into `404.html`.\nIt will still be served as the 404 response, but the browser will process that page and load the app properly.\nIt's also a good idea to\n[serve from `docs/` on master](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch)\nand to\n[create a `.nojekyll` file](https://www.bennadel.com/blog/3181-including-node-modules-and-vendors-folders-in-your-github-pages-site.htm)", "translation": "[GitHub 页面服务](https://pages.github.com/):你没办法[直接配置](https://github.com/isaacs/github/issues/408) Github 的页面服务,但可以添加一个 404 页,只要把 `index.html` 复制到 `404.html` 就可以了。\n 它仍然会给出一个 404 响应,但是浏览器将会正确处理该页,并正常加载该应用。\n 使用[在主分支的 `docs/` 下启动服务](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch)\n 并[创建一个 `.nojekyll` 文件](https://www.bennadel.com/blog/3181-including-node-modules-and-vendors-folders-in-your-github-pages-site.htm)也是一个好办法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "FIREBASEHOSTINGHTTPS:FIREBASEGOOGLECOMDOCSHOSTING:ADDAREWRITERULEHTTPS:FIREBASEGOOGLECOMDOCSHOSTINGURLREDIRECTSREWRITES#SECTIONREWRITES", "original": "* [Firebase hosting](https://firebase.google.com/docs/hosting/): add a\n[rewrite rule](https://firebase.google.com/docs/hosting/url-redirects-rewrites#section-rewrites).", "translation": "[Firebase 主机服务](https://firebase.google.com/docs/hosting/):添加一条[重写规则](https://firebase.google.com/docs/hosting/url-redirects-rewrites#section-rewrites)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "###REQUESTINGSERVICESFROMADIFFERENTSERVERCORS", "original": "### Requesting services from a different server (CORS)", "translation": "### 请求来自另一个服务器的服务(CORS)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "ANGULARDEVELOPERSMAYENCOUNTERAAHREFHTTPS:ENWIKIPEDIAORGWIKICROSSORIGINRESOURCESHARINGTITLECROSSORIGINRESOURCESHARINGICROSSORIGINRESOURCESHARINGIAERRORWHENMAKINGASERVICEREQUESTTYPICALLYADATASERVICEREQUESTTOASERVEROTHERTHANTHEAPPLICATIONSOWNHOSTSERVERBROWSERSFORBIDSUCHREQUESTSUNLESSTHESERVERPERMITSTHEMEXPLICITLY", "original": "Angular developers may encounter a\n<a href=\"https://en.wikipedia.org/wiki/Cross-origin_resource_sharing\" title=\"Cross-origin resource sharing\">\n<i>cross-origin resource sharing</i></a> error when making a service request (typically a data service request)\nto a server other than the application's own host server.\nBrowsers forbid such requests unless the server permits them explicitly.", "translation": "Angular 开发者在向与该应用的宿主服务器不同域的服务器发起请求时,可能会遇到一种<a href=\"https://en.wikipedia.org/wiki/Cross-origin_resource_sharing\" target=\"_blank\" title=\"Cross-origin resource sharing\"><i>跨域资源共享(CORS)</i></a>错误。\n浏览器会阻止该请求,除非得到那台服务器的明确许可。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "THEREISNTANYTHINGTHECLIENTAPPLICATIONCANDOABOUTTHESEERRORSTHESERVERMUSTBECONFIGUREDTOACCEPTTHEAPPLICATIONSREQUESTSREADABOUTHOWTOENABLECORSFORSPECIFICSERVERSATAHREFHTTP:ENABLECORSORGSERVERHTMLTITLEENABLINGCORSSERVERENABLECORSORGA", "original": "There isn't anything the client application can do about these errors.\nThe server must be configured to accept the application's requests.\nRead about how to enable CORS for specific servers at\n<a href=\"http://enable-cors.org/server.html\" title=\"Enabling CORS server\">enable-cors.org</a>.", "translation": "客户端应用对这种错误无能为力。\n服务器必须配置成可以接受来自该应用的请求。\n要了解如何对特定的服务器开启 CORS,参见<a href=\"http://enable-cors.org/server.html\" target=\"_blank\" title=\"Enabling CORS server\">enable-cors.org</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/deployment.md" }, { + "key": "#DISPLAYINGDATA", "original": "# Displaying Data", "translation": "# 显示数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "YOUCANDISPLAYDATABYBINDINGCONTROLSINANHTMLTEMPLATETOPROPERTIESOFANANGULARCOMPONENT", "original": "You can display data by binding controls in an HTML template to properties of an Angular component.", "translation": "在 Angular 中最典型的数据显示方式,就是把 HTML 模板中的控件绑定到 Angular 组件的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "INTHISPAGEYOULLCREATEACOMPONENTWITHALISTOFHEROESYOULLDISPLAYTHELISTOFHERONAMESANDCONDITIONALLYSHOWAMESSAGEBELOWTHELIST", "original": "In this page, you'll create a component with a list of heroes.\nYou'll display the list of hero names and\nconditionally show a message below the list.", "translation": "本章中,你将创建一个英雄列表组件。\n你将显示英雄名字的列表,并根据条件在列表下方显示一条消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THEFINALUILOOKSLIKETHIS:", "original": "The final UI looks like this:", "translation": "最终的用户界面是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THELIVEEXAMPLELIVEEXAMPLEDEMONSTRATESALLOFTHESYNTAXANDCODESNIPPETSDESCRIBEDINTHISPAGE", "original": "The <live-example></live-example> demonstrates all of the syntax and code\nsnippets described in this page.", "translation": "这个<live-example></live-example>演示了本章中描述的所有语法和代码片段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "##SHOWINGCOMPONENTPROPERTIESWITHINTERPOLATION", "original": "## Showing component properties with interpolation", "translation": "## 使用插值表达式显示组件属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THEEASIESTWAYTODISPLAYACOMPONENTPROPERTYISTOBINDTHEPROPERTYNAMETHROUGHINTERPOLATIONWITHINTERPOLATIONYOUPUTTHEPROPERTYNAMEINTHEVIEWTEMPLATEENCLOSEDINDOUBLECURLYBRACES:MYHERO", "original": "The easiest way to display a component property\nis to bind the property name through interpolation.\nWith interpolation, you put the property name in the view template, enclosed in double curly braces: `{{myHero}}`.", "translation": "要显示组件的属性,最简单的方式就是通过插值表达式 (interpolation) 来绑定属性名。\n要使用插值表达式,就把属性名包裹在双花括号里放进视图模板,如 `{{myHero}}`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "FOLLOWTHEQUICKSTARTGUIDEQUICKSTARTINSTRUCTIONSFORCREATINGANEWPROJECTNAMEDCODEDISPLAYINGDATACODE", "original": "Follow the [quickstart](guide/quickstart) instructions for creating a new project\nnamed <code>displaying-data</code>.", "translation": "按照[快速起步](guide/quickstart)的说明,创建一个新项目,名为<code>displaying-data</code>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "DELETETHECODEAPPCOMPONENTHTMLCODEFILEITISNOTNEEDEDFORTHISEXAMPLE", "original": "Delete the <code>app.component.html</code> file. It is not needed for this example.", "translation": "删除 <code>app.component.html</code> 文件,这个范例中不再需要它了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THENMODIFYTHECODEAPPCOMPONENTTSCODEFILEBYCHANGINGTHETEMPLATEANDTHEBODYOFTHECOMPONENT", "original": "Then modify the <code>app.component.ts</code> file by\nchanging the template and the body of the component.", "translation": "然后,到 `app.component.ts` 文件中修改组件的模板和代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "WHENYOUREDONEITSHOULDLOOKLIKETHIS:", "original": "When you're done, it should look like this:", "translation": "修改完之后,它应该是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "YOUADDEDTWOPROPERTIESTOTHEFORMERLYEMPTYCOMPONENT:TITLEANDMYHERO", "original": "You added two properties to the formerly empty component: `title` and `myHero`.", "translation": "再把两个属性 `title` 和 `myHero` 添加到之前空白的组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THETEMPLATEDISPLAYSTHETWOCOMPONENTPROPERTIESUSINGDOUBLECURLYBRACEINTERPOLATION:", "original": "The template displays the two component properties using double curly brace\ninterpolation:", "translation": "修改完的模板会使用双花括号形式的插值表达式来显示这两个模板属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THETEMPLATEISAMULTILINESTRINGWITHINECMASCRIPT2015BACKTICKSCODECODETHEBACKTICKCODECODEMDASHWHICHISNOTTHESAMECHARACTERASASINGLEQUOTEMDASHALLOWSYOUTOCOMPOSEASTRINGOVERSEVERALLINESWHICHMAKESTHEHTMLMOREREADABLE", "original": "The template is a multi-line string within ECMAScript 2015 backticks (<code>\\`</code>).\nThe backtick (<code>\\`</code>)—which is *not* the same character as a single\nquote (`'`)—allows you to compose a string over several lines, which makes the\nHTML more readable.", "translation": "模板是包在 ECMAScript 2015 反引号 (<code>\\`</code>) 中的一个多行字符串。\n反引号 (<code>\\`</code>) — 注意,不是单引号 (') — 允许把一个字符串写在多行上,\n使 HTML 模板更容易阅读。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "ANGULARAUTOMATICALLYPULLSTHEVALUEOFTHETITLEANDMYHEROPROPERTIESFROMTHECOMPONENTANDINSERTSTHOSEVALUESINTOTHEBROWSERANGULARUPDATESTHEDISPLAYWHENTHESEPROPERTIESCHANGE", "original": "Angular automatically pulls the value of the `title` and `myHero` properties from the component and\ninserts those values into the browser. Angular updates the display\nwhen these properties change.", "translation": "Angular 自动从组件中提取 `title` 和 `myHero` 属性的值,并且把这些值插入浏览器中。当这些属性发生变化时,Angular 就会自动刷新显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "MOREPRECISELYTHEREDISPLAYOCCURSAFTERSOMEKINDOFASYNCHRONOUSEVENTRELATEDTOTHEVIEWSUCHASAKEYSTROKEATIMERCOMPLETIONORARESPONSETOANHTTPREQUEST", "original": "More precisely, the redisplay occurs after some kind of asynchronous event related to\nthe view, such as a keystroke, a timer completion, or a response to an HTTP request.", "translation": "严格来说,“重新显示”是在某些与视图有关的异步事件之后发生的,例如,按键、定时器完成或对 HTTP 请求的响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NOTICETHATYOUDONTCALLNEWTOCREATEANINSTANCEOFTHEAPPCOMPONENTCLASSANGULARISCREATINGANINSTANCEFORYOUHOW", "original": "Notice that you don't call **new** to create an instance of the `AppComponent` class.\nAngular is creating an instance for you. How?", "translation": "注意,你没有调用 **new** 来创建 `AppComponent` 类的实例,是 Angular 替你创建了它。那么它是如何创建的呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THECSSSELECTORINTHECOMPONENTDECORATORSPECIFIESANELEMENTNAMEDAPPROOTTHATELEMENTISAPLACEHOLDERINTHEBODYOFYOURINDEXHTMLFILE:", "original": "The CSS `selector` in the `@Component` decorator specifies an element named `<app-root>`.\nThat element is a placeholder in the body of your `index.html` file:", "translation": "注意 `@Component` 装饰器中指定的 CSS 选择器 `selector`,它指定了一个叫 `my-app` 的元素。\n该元素是 `index.html` 的 `body` 里的占位符。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "WHENYOUBOOTSTRAPWITHTHEAPPCOMPONENTCLASSINCODEMAINTSCODEANGULARLOOKSFORAAPPROOTINTHEINDEXHTMLFINDSITINSTANTIATESANINSTANCEOFAPPCOMPONENTANDRENDERSITINSIDETHEAPPROOTTAG", "original": "When you bootstrap with the `AppComponent` class (in <code>main.ts</code>), Angular looks for a `<app-root>`\nin the `index.html`, finds it, instantiates an instance of `AppComponent`, and renders it\ninside the `<app-root>` tag.", "translation": "当你通过 `main.ts` 中的 `AppComponent` 类启动时,Angular 在 `index.html` 中查找一个 `<app-root>` 元素,\n然后实例化一个 `AppComponent`,并将其渲染到 `<app-root>` 标签中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NOWRUNTHEAPPITSHOULDDISPLAYTHETITLEANDHERONAME:", "original": "Now run the app. It should display the title and hero name:", "translation": "运行应用。它应该显示出标题和英雄名:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THENEXTFEWSECTIONSREVIEWSOMEOFTHECODINGCHOICESINTHEAPP", "original": "The next few sections review some of the coding choices in the app.", "translation": "回顾一下前面所做的决定,看看还有哪些其它选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "##TEMPLATEINLINEORTEMPLATEFILE", "original": "## Template inline or template file?", "translation": "## 内联 (inline) 模板还是模板文件?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "YOUCANSTOREYOURCOMPONENTSTEMPLATEINONEOFTWOPLACESYOUCANDEFINEITINLINEUSINGTHETEMPLATEPROPERTYORYOUCANDEFINETHETEMPLATEINASEPARATEHTMLFILEANDLINKTOITINTHECOMPONENTMETADATAUSINGTHECOMPONENTDECORATORSTEMPLATEURLPROPERTY", "original": "You can store your component's template in one of two places.\nYou can define it *inline* using the `template` property, or you can define\nthe template in a separate HTML file and link to it in\nthe component metadata using the `@Component` decorator's `templateUrl` property.", "translation": "你可以在两种地方存放组件模板。\n你可以使用 `template` 属性把它定义为*内联*的,或者把模板定义在一个独立的 HTML 文件中,\n再通过 `@Component` 装饰器中的 `templateUrl` 属性,\n在组件元数据中把它链接到组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THECHOICEBETWEENINLINEANDSEPARATEHTMLISAMATTEROFTASTECIRCUMSTANCESANDORGANIZATIONPOLICYHERETHEAPPUSESINLINEHTMLBECAUSETHETEMPLATEISSMALLANDTHEDEMOISSIMPLERWITHOUTTHEADDITIONALHTMLFILE", "original": "The choice between inline and separate HTML is a matter of taste,\ncircumstances, and organization policy.\nHere the app uses inline HTML because the template is small and the demo\nis simpler without the additional HTML file.", "translation": "到底选择内联 HTML 还是独立 HTML 取决于个人喜好、具体状况和组织级策略。\n上面的应用选择内联 HTML ,是因为模板很小,而且没有额外的 HTML 文件显得这个演示简单些。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "INEITHERSTYLETHETEMPLATEDATABINDINGSHAVETHESAMEACCESSTOTHECOMPONENTSPROPERTIES", "original": "In either style, the template data bindings have the same access to the component's properties.", "translation": "无论用哪种风格,模板数据绑定在访问组件属性方面都是完全一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "BYDEFAULTTHEANGULARCLIGENERATESCOMPONENTSWITHATEMPLATEFILEYOUCANOVERRIDETHATWITH:", "original": "By default, the Angular CLI generates components with a template file. You can override that with:", "translation": "默认情况下,Angular CLI 生成组件时会带有模板文件,你可以通过参数覆盖它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "##CONSTRUCTORORVARIABLEINITIALIZATION", "original": "## Constructor or variable initialization?", "translation": "## 使用构造函数还是变量初始化?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "ALTHOUGHTHISEXAMPLEUSESVARIABLEASSIGNMENTTOINITIALIZETHECOMPONENTSYOUCOULDINSTEADDECLAREANDINITIALIZETHEPROPERTIESUSINGACONSTRUCTOR:", "original": "Although this example uses variable assignment to initialize the components, you could instead declare and initialize the properties using a constructor:", "translation": "虽然这个例子使用了变量赋值的方式初始化组件,你还可以使用构造函数来声明和初始化属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THISAPPUSESMORETERSEVARIABLEASSIGNMENTSTYLESIMPLYFORBREVITY", "original": "This app uses more terse \"variable assignment\" style simply for brevity.", "translation": "为了让本应用更加简短,它采用了更简单的“变量赋值”风格。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "##SHOWINGANARRAYPROPERTYWITHNGFOR", "original": "## Showing an array property with ***ngFor**", "translation": "## 使用 ***ngFor*** 显示数组属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "TODISPLAYALISTOFHEROESBEGINBYADDINGANARRAYOFHERONAMESTOTHECOMPONENTANDREDEFINEMYHEROTOBETHEFIRSTNAMEINTHEARRAY", "original": "To display a list of heroes, begin by adding an array of hero names to the component and redefine `myHero` to be the first name in the array.", "translation": "要显示一个英雄列表,先向组件中添加一个英雄名字数组,然后把 `myHero` 重定义为数组中的第一个名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NOWUSETHEANGULARNGFORDIRECTIVEINTHETEMPLATETODISPLAYEACHITEMINTHEHEROESLIST", "original": "Now use the Angular `ngFor` directive in the template to display\neach item in the `heroes` list.", "translation": "接着,在模板中使用 Angular 的 `ngFor` 指令来显示 `heroes` 列表中的每一项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THISUIUSESTHEHTMLUNORDEREDLISTWITHULANDLITAGSTHENGFORINTHELIELEMENTISTHEANGULARREPEATERDIRECTIVEITMARKSTHATLIELEMENTANDITSCHILDRENASTHEREPEATERTEMPLATE:", "original": "This UI uses the HTML unordered list with `<ul>` and `<li>` tags. The `*ngFor`\nin the `<li>` element is the Angular \"repeater\" directive.\nIt marks that `<li>` element (and its children) as the \"repeater template\":", "translation": "这个界面使用了由 `<ul>` 和 `<li>` 标签组成的无序列表。`<li>` 元素里的 `*ngFor` 是 Angular 的“迭代”指令。\n它将 `<li>` 元素及其子级标记为“迭代模板”:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "DONTFORGETTHELEADINGASTERISKINNGFORITISANESSENTIALPARTOFTHESYNTAXFORMOREINFORMATIONSEETHETEMPLATESYNTAXGUIDETEMPLATESYNTAX#NGFORPAGE", "original": "Don't forget the leading asterisk (\\*) in `*ngFor`. It is an essential part of the syntax.\nFor more information, see the [Template Syntax](guide/template-syntax#ngFor) page.", "translation": "不要忘记 `*ngFor` 中的前导星号 (\\*)。它是语法中不可或缺的一部分。\n更多信息,见[模板语法](guide/template-syntax#ngFor)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NOTICETHEHEROINTHENGFORDOUBLEQUOTEDINSTRUCTIONITISANEXAMPLEOFATEMPLATEINPUTVARIABLEREADMOREABOUTTEMPLATEINPUTVARIABLESINTHEMICROSYNTAXGUIDETEMPLATESYNTAX#MICROSYNTAXSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "Notice the `hero` in the `ngFor` double-quoted instruction;\nit is an example of a template input variable. Read\nmore about template input variables in the [microsyntax](guide/template-syntax#microsyntax) section of\nthe [Template Syntax](guide/template-syntax) page.", "translation": "注意看 `ngFor` 双引号表达式中的 `hero`,它是一个模板输入变量。\n更多模板输入变量的信息,见[模板语法](guide/template-syntax)中的\n[微语法 (microsyntax)](guide/template-syntax#microsyntax)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "ANGULARDUPLICATESTHELIFOREACHITEMINTHELISTSETTINGTHEHEROVARIABLETOTHEITEMTHEHEROINTHECURRENTITERATIONANGULARUSESTHATVARIABLEASTHECONTEXTFORTHEINTERPOLATIONINTHEDOUBLECURLYBRACES", "original": "Angular duplicates the `<li>` for each item in the list, setting the `hero` variable\nto the item (the hero) in the current iteration. Angular uses that variable as the\ncontext for the interpolation in the double curly braces.", "translation": "Angular 为列表中的每个条目复制一个 `<li>` 元素,在每个迭代中,把 `hero` 变量设置为当前条目(英雄)。\nAngular 把 `hero` 变量作为双花括号插值表达式的上下文。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "INTHISCASENGFORISDISPLAYINGANARRAYBUTNGFORCANREPEATITEMSFORANYITERABLEHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCEITERATIONPROTOCOLSOBJECT", "original": "In this case, `ngFor` is displaying an array, but `ngFor` can\nrepeat items for any [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) object.", "translation": "本例中,`ngFor` 用于显示一个“数组”,\n但 `ngFor` 可以为任何[可迭代的 (iterable) ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)对象重复渲染条目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NOWTHEHEROESAPPEARINANUNORDEREDLIST", "original": "Now the heroes appear in an unordered list.", "translation": "现在,英雄们出现在了一个无序列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "##CREATINGACLASSFORTHEDATA", "original": "## Creating a class for the data", "translation": "## 为数据创建一个类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THEAPPSCODEDEFINESTHEDATADIRECTLYINSIDETHECOMPONENTWHICHISNTBESTPRACTICEINASIMPLEDEMOHOWEVERITSFINE", "original": "The app's code defines the data directly inside the component, which isn't best practice.\nIn a simple demo, however, it's fine.", "translation": "应用代码直接在组件内部直接定义了数据。\n作为演示还可以,但它显然不是最佳实践。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "ATTHEMOMENTTHEBINDINGISTOANARRAYOFSTRINGSINREALAPPLICATIONSMOSTBINDINGSARETOMORESPECIALIZEDOBJECTS", "original": "At the moment, the binding is to an array of strings.\nIn real applications, most bindings are to more specialized objects.", "translation": "现在使用的是到了一个字符串数组的绑定。在真实的应用中,大多是到一个对象数组的绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "TOCONVERTTHISBINDINGTOUSESPECIALIZEDOBJECTSTURNTHEARRAYOFHERONAMESINTOANARRAYOFHEROOBJECTSFORTHATYOULLNEEDAHEROCLASS:", "original": "To convert this binding to use specialized objects, turn the array\nof hero names into an array of `Hero` objects. For that you'll need a `Hero` class:", "translation": "要将此绑定转换成使用对象,需要把这个英雄名字数组变成 `Hero` 对象数组。但首先得有一个 `Hero` 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "WITHTHEFOLLOWINGCODE:", "original": "With the following code:", "translation": "代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "YOUVEDEFINEDACLASSWITHACONSTRUCTORANDTWOPROPERTIES:IDANDNAME", "original": "You've defined a class with a constructor and two properties: `id` and `name`.", "translation": "你定义了一个类,具有一个构造函数和两个属性:`id` 和 `name`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "ITMIGHTNOTLOOKLIKETHECLASSHASPROPERTIESBUTITDOESTHEDECLARATIONOFTHECONSTRUCTORPARAMETERSTAKESADVANTAGEOFATYPESCRIPTSHORTCUT", "original": "It might not look like the class has properties, but it does.\nThe declaration of the constructor parameters takes advantage of a TypeScript shortcut.", "translation": "它可能看上去不像是有属性的类,但它确实有,利用的是 TypeScript 提供的简写形式 —— 用构造函数的参数直接定义属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "CONSIDERTHEFIRSTPARAMETER:", "original": "Consider the first parameter:", "translation": "来看第一个参数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THATBRIEFSYNTAXDOESALOT:", "original": "That brief syntax does a lot:", "translation": "这个简写语法做了很多:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "DECLARESACONSTRUCTORPARAMETERANDITSTYPE", "original": "* Declares a constructor parameter and its type.", "translation": "声明了一个构造函数参数及其类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "DECLARESAPUBLICPROPERTYOFTHESAMENAME", "original": "* Declares a public property of the same name.", "translation": "声明了一个同名的公共属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "INITIALIZESTHATPROPERTYWITHTHECORRESPONDINGARGUMENTWHENCREATINGANINSTANCEOFTHECLASS", "original": "* Initializes that property with the corresponding argument when creating an instance of the class.", "translation": "当创建该类的一个实例时,把该属性初始化为相应的参数值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "###USINGTHEHEROCLASS", "original": "### Using the Hero class", "translation": "### 使用 Hero 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "AFTERIMPORTINGTHEHEROCLASSTHEAPPCOMPONENTHEROESPROPERTYCANRETURNATYPEDARRAYOFHEROOBJECTS:", "original": "After importing the `Hero` class, the `AppComponent.heroes` property can return a _typed_ array\nof `Hero` objects:", "translation": "导入了 `Hero` 类之后,组件的 `heroes` 属性就可以返回一个*类型化的*`Hero` 对象数组了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NEXTUPDATETHETEMPLATEATTHEMOMENTITDISPLAYSTHEHEROSIDANDNAMEFIXTHATTODISPLAYONLYTHEHEROSNAMEPROPERTY", "original": "Next, update the template.\nAt the moment it displays the hero's `id` and `name`.\nFix that to display only the hero's `name` property.", "translation": "接着,修改模板。\n现在它显示的是英雄的 `id` 和 `name`。\n要修复它,只显示英雄的 `name` 属性就行了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THEDISPLAYLOOKSTHESAMEBUTTHECODEISCLEARER", "original": "The display looks the same, but the code is clearer.", "translation": "显示上还和以前一样,不过代码更清晰了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "##CONDITIONALDISPLAYWITHNGIF", "original": "## Conditional display with NgIf", "translation": "## 通过 NgIf 进行条件显示", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "SOMETIMESANAPPNEEDSTODISPLAYAVIEWORAPORTIONOFAVIEWONLYUNDERSPECIFICCIRCUMSTANCES", "original": "Sometimes an app needs to display a view or a portion of a view only under specific circumstances.", "translation": "有时,应用需要只在特定情况下显示视图或视图的一部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "LETSCHANGETHEEXAMPLETODISPLAYAMESSAGEIFTHEREAREMORETHANTHREEHEROES", "original": "Let's change the example to display a message if there are more than three heroes.", "translation": "来改一下这个例子,如果多于三位英雄,显示一条消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THEANGULARNGIFDIRECTIVEINSERTSORREMOVESANELEMENTBASEDONATRUTHYFALSYCONDITIONTOSEEITINACTIONADDTHEFOLLOWINGPARAGRAPHATTHEBOTTOMOFTHETEMPLATE:", "original": "The Angular `ngIf` directive inserts or removes an element based on a _truthy/falsy_ condition.\nTo see it in action, add the following paragraph at the bottom of the template:", "translation": "Angular 的 `ngIf` 指令会根据一个布尔条件来显示或移除一个元素。\n来看看实际效果,把下列语句加到模板的底部:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "DONTFORGETTHELEADINGASTERISKINNGIFITISANESSENTIALPARTOFTHESYNTAXREADMOREABOUTNGIFANDINTHENGIFSECTIONGUIDETEMPLATESYNTAX#NGIFOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "Don't forget the leading asterisk (\\*) in `*ngIf`. It is an essential part of the syntax.\nRead more about `ngIf` and `*` in the [ngIf section](guide/template-syntax#ngIf) of the [Template Syntax](guide/template-syntax) page.", "translation": "不要忘了 `*ngIf` 中的前导星号 (\\*)。它是本语法中不可或缺的一部分。\n更多 `ngIf` 和 `* ` 的内容,见[模板语法](guide/template-syntax)中的[ngIf](guide/template-syntax#ngIf)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "THETEMPLATEEXPRESSIONINSIDETHEDOUBLEQUOTESNGIFHEROESLENGTH3LOOKSANDBEHAVESMUCHLIKETYPESCRIPTWHENTHECOMPONENTSLISTOFHEROESHASMORETHANTHREEITEMSANGULARADDSTHEPARAGRAPHTOTHEDOMANDTHEMESSAGEAPPEARSIFTHEREARETHREEORFEWERITEMSANGULAROMITSTHEPARAGRAPHSONOMESSAGEAPPEARSFORMOREINFORMATIONSEETHETEMPLATEEXPRESSIONSGUIDETEMPLATESYNTAX#TEMPLATEEXPRESSIONSSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "The template expression inside the double quotes,\n`*ngIf=\"heroes.length > 3\"`, looks and behaves much like TypeScript.\nWhen the component's list of heroes has more than three items, Angular adds the paragraph\nto the DOM and the message appears. If there are three or fewer items, Angular omits the\nparagraph, so no message appears. For more information,\nsee the [template expressions](guide/template-syntax#template-expressions) section of the\n[Template Syntax](guide/template-syntax) page.", "translation": "双引号中的模板表达式 `*ngIf=\"heros.length > 3\"`,外观和行为很象 TypeScript 。\n当组件中的英雄列表有三个以上的条目时,Angular 把这个段落添加到 DOM 中,于是消息显示了出来。\n更多信息,见[模板语法](guide/template-syntax)中的[模板表达式](guide/template-syntax#template-expressions)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "ANGULARISNTSHOWINGANDHIDINGTHEMESSAGEITISADDINGANDREMOVINGTHEPARAGRAPHELEMENTFROMTHEDOMTHATIMPROVESPERFORMANCEESPECIALLYINLARGERPROJECTSWHENCONDITIONALLYINCLUDINGOREXCLUDINGBIGCHUNKSOFHTMLWITHMANYDATABINDINGS", "original": "Angular isn't showing and hiding the message. It is adding and removing the paragraph element from the DOM. That improves performance, especially in larger projects when conditionally including or excluding\nbig chunks of HTML with many data bindings.", "translation": "Angular 并不是在显示和隐藏这条消息,它是在从 DOM 中添加和移除这个段落元素。\n这会提高性能,特别是在一些大的项目中有条件地包含或排除一大堆带着很多数据绑定的 HTML 时。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "TRYITOUTBECAUSETHEARRAYHASFOURITEMSTHEMESSAGESHOULDAPPEARGOBACKINTOCODEAPPCOMPONENTTSCODEANDDELETEORCOMMENTOUTONEOFTHEELEMENTSFROMTHEHEROARRAYTHEBROWSERSHOULDREFRESHAUTOMATICALLYANDTHEMESSAGESHOULDDISAPPEAR", "original": "Try it out. Because the array has four items, the message should appear.\nGo back into <code>app.component.ts\"</code> and delete or comment out one of the elements from the hero array.\nThe browser should refresh automatically and the message should disappear.", "translation": "试一下。因为这个数组中有四个条目,所以消息应该显示出来。\n回到 `app.component.ts`,从英雄数组中删除或注释掉一个元素。\n浏览器应该自动刷新,消息应该会消失。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NOWYOUKNOWHOWTOUSE:", "original": "Now you know how to use:", "translation": "现在你知道了如何使用:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "INTERPOLATIONWITHDOUBLECURLYBRACESTODISPLAYACOMPONENTPROPERTY", "original": "* **Interpolation** with double curly braces to display a component property.", "translation": "带有双花括号的**插值表达式 (interpolation) **来显示一个组件属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NGFORTODISPLAYANARRAYOFITEMS", "original": "* **ngFor** to display an array of items.", "translation": "用 **ngFor** 显示数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "ATYPESCRIPTCLASSTOSHAPETHEMODELDATAFORYOURCOMPONENTANDDISPLAYPROPERTIESOFTHATMODEL", "original": "* A TypeScript class to shape the **model data** for your component and display properties of that model.", "translation": "用一个 TypeScript 类来为你的组件描述**模型数据**并显示模型的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "NGIFTOCONDITIONALLYDISPLAYACHUNKOFHTMLBASEDONABOOLEANEXPRESSION", "original": "* **ngIf** to conditionally display a chunk of HTML based on a boolean expression.", "translation": "用 **ngIf** 根据一个布尔表达式有条件地显示一段 HTML。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "HERESTHEFINALCODE:", "original": "Here's the final code:", "translation": "下面是最终的代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/displaying-data.md" }, { + "key": "##NAVIGATION", "original": "## Navigation", "translation": "## 导航", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/docs-style-guide.md" }, { + "key": "##LIVEEXAMPLES", "original": "## Live examples", "translation": "## 在线例子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/docs-style-guide.md" }, { + "key": "ROUTING", "original": "Routing", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/docs-style-guide.md" }, { + "key": "ROUTING", "original": "Routing", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/docs-style-guide.md" }, { + "key": "ROUTING", "original": "Routing", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/docs-style-guide.md" }, { + "key": "ROUTING", "original": "Routing", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/docs-style-guide.md" }, { + "key": "ROUTING", "original": "Routing", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/docs-style-guide.md" }, { + "key": "ROUTING", "original": "Routing", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/docs-style-guide.md" }, { + "key": "#DYNAMICCOMPONENTLOADER", "original": "# Dynamic Component Loader", "translation": "# 动态组件加载器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "COMPONENTTEMPLATESARENOTALWAYSFIXEDANAPPLICATIONMAYNEEDTOLOADNEWCOMPONENTSATRUNTIME", "original": "Component templates are not always fixed. An application may need to load new components at runtime.", "translation": "组件的模板不会永远是固定的。应用可能会需要在运行期间加载一些新的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THISCOOKBOOKSHOWSYOUHOWTOUSECOMPONENTFACTORYRESOLVERTOADDCOMPONENTSDYNAMICALLY", "original": "This cookbook shows you how to use `ComponentFactoryResolver` to add components dynamically.", "translation": "这本烹饪书为你展示如何使用 `ComponentFactoryResolver` 来动态添加组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "SEETHELIVEEXAMPLENAMEDYNAMICCOMPONENTLOADERLIVEEXAMPLEOFTHECODEINTHISCOOKBOOK", "original": "See the <live-example name=\"dynamic-component-loader\"></live-example>\nof the code in this cookbook.", "translation": "到<live-example name=\"dynamic-component-loader\"></live-example>查看本烹饪书的源码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "##DYNAMICCOMPONENTLOADING", "original": "## Dynamic component loading", "translation": "## 动态组件加载", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THEFOLLOWINGEXAMPLESHOWSHOWTOBUILDADYNAMICADBANNER", "original": "The following example shows how to build a dynamic ad banner.", "translation": "下面的例子展示了如何构建动态广告条。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THEHEROAGENCYISPLANNINGANADCAMPAIGNWITHSEVERALDIFFERENTADSCYCLINGTHROUGHTHEBANNERNEWADCOMPONENTSAREADDEDFREQUENTLYBYSEVERALDIFFERENTTEAMSTHISMAKESITIMPRACTICALTOUSEATEMPLATEWITHASTATICCOMPONENTSTRUCTURE", "original": "The hero agency is planning an ad campaign with several different\nads cycling through the banner. New ad components are added\nfrequently by several different teams. This makes it impractical\nto use a template with a static component structure.", "translation": "英雄管理局正在计划一个广告活动,要在广告条中显示一系列不同的广告。几个不同的小组可能会频繁加入新的广告组件。\n再用只支持静态组件结构的模板显然是不现实的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "INSTEADYOUNEEDAWAYTOLOADANEWCOMPONENTWITHOUTAFIXEDREFERENCETOTHECOMPONENTINTHEADBANNERSTEMPLATE", "original": "Instead, you need a way to load a new component without a fixed\nreference to the component in the ad banner's template.", "translation": "你需要一种新的组件加载方式,它不需要在广告条组件的模板中引用固定的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "ANGULARCOMESWITHITSOWNAPIFORLOADINGCOMPONENTSDYNAMICALLY", "original": "Angular comes with its own API for loading components dynamically.", "translation": "Angular 自带的 API 就能支持动态加载组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "##THEANCHORDIRECTIVE", "original": "## The anchor directive", "translation": "## 指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "BEFOREYOUCANADDCOMPONENTSYOUHAVETODEFINEANANCHORPOINTTOTELLANGULARWHERETOINSERTCOMPONENTS", "original": "Before you can add components you have to define an anchor point\nto tell Angular where to insert components.", "translation": "在添加组件之前,先要定义一个锚点来告诉 Angular 要把组件插入到什么地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THEADBANNERUSESAHELPERDIRECTIVECALLEDADDIRECTIVETOMARKVALIDINSERTIONPOINTSINTHETEMPLATE", "original": "The ad banner uses a helper directive called `AdDirective` to\nmark valid insertion points in the template.", "translation": "广告条使用一个名叫 `AdDirective` 的辅助指令来在模板中标记出有效的插入点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "ADDIRECTIVEINJECTSVIEWCONTAINERREFTOGAINACCESSTOTHEVIEWCONTAINEROFTHEELEMENTTHATWILLHOSTTHEDYNAMICALLYADDEDCOMPONENT", "original": "`AdDirective` injects `ViewContainerRef` to gain access to the view\ncontainer of the element that will host the dynamically added component.", "translation": "`AdDirective` 注入了 `ViewContainerRef` 来获取对容器视图的访问权,这个容器就是那些动态加入的组件的宿主。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "INTHEDIRECTIVEDECORATORNOTICETHESELECTORNAMEADHOSTTHATSWHATYOUUSETOAPPLYTHEDIRECTIVETOTHEELEMENTTHENEXTSECTIONSHOWSYOUHOW", "original": "In the `@Directive` decorator, notice the selector name, `ad-host`;\nthat's what you use to apply the directive to the element.\nThe next section shows you how.", "translation": "在 `@Directive` 装饰器中,要注意选择器的名称:`ad-host`,它就是你将应用到元素上的指令。下一节会展示该如何做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "##LOADINGCOMPONENTS", "original": "## Loading components", "translation": "## 加载组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "MOSTOFTHEADBANNERIMPLEMENTATIONISINADBANNERCOMPONENTTSTOKEEPTHINGSSIMPLEINTHISEXAMPLETHEHTMLISINTHECOMPONENTDECORATORSTEMPLATEPROPERTYASATEMPLATESTRING", "original": "Most of the ad banner implementation is in `ad-banner.component.ts`.\nTo keep things simple in this example, the HTML is in the `@Component`\ndecorator's `template` property as a template string.", "translation": "广告条的大部分实现代码都在 `ad-banner.component.ts` 中。\n为了让这个例子简单点,HTML 被直接放在了 `@Component` 装饰器的 `template` 属性中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THENGTEMPLATEELEMENTISWHEREYOUAPPLYTHEDIRECTIVEYOUJUSTMADETOAPPLYTHEADDIRECTIVERECALLTHESELECTORFROMADDIRECTIVETSADHOSTAPPLYTHATTONGTEMPLATEWITHOUTTHESQUAREBRACKETSNOWANGULARKNOWSWHERETODYNAMICALLYLOADCOMPONENTS", "original": "The `<ng-template>` element is where you apply the directive you just made.\nTo apply the `AdDirective`, recall the selector from `ad.directive.ts`,\n`ad-host`. Apply that to `<ng-template>` without the square brackets. Now Angular knows\nwhere to dynamically load components.", "translation": "`<ng-template>` 元素就是刚才制作的指令将应用到的地方。\n要应用 `AdDirective`,回忆一下来自 `ad.directive.ts` 的选择器 `ad-host`。把它应用到 `<ng-template>`(不用带方括号)。\n这下,Angular 就知道该把组件动态加载到哪里了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THENGTEMPLATEELEMENTISAGOODCHOICEFORDYNAMICCOMPONENTSBECAUSEITDOESNTRENDERANYADDITIONALOUTPUT", "original": "The `<ng-template>` element is a good choice for dynamic components\nbecause it doesn't render any additional output.", "translation": "`<ng-template>` 元素是动态加载组件的最佳选择,因为它不会渲染任何额外的输出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "##RESOLVINGCOMPONENTS", "original": "## Resolving components", "translation": "## 解析组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "TAKEACLOSERLOOKATTHEMETHODSINADBANNERCOMPONENTTS", "original": "Take a closer look at the methods in `ad-banner.component.ts`.", "translation": "深入看看 `ad-banner.component.ts` 中的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "ADBANNERCOMPONENTTAKESANARRAYOFADITEMOBJECTSASINPUTWHICHULTIMATELYCOMESFROMADSERVICEADITEMOBJECTSSPECIFYTHETYPEOFCOMPONENTTOLOADANDANYDATATOBINDTOTHECOMPONENTADSERVICERETURNSTHEACTUALADSMAKINGUPTHEADCAMPAIGN", "original": "`AdBannerComponent` takes an array of `AdItem` objects as input,\nwhich ultimately comes from `AdService`. `AdItem` objects specify\nthe type of component to load and any data to bind to the\ncomponent.`AdService` returns the actual ads making up the ad campaign.", "translation": "`AdBannerComponent` 接收一个 `AdItem` 对象的数组作为输入,它最终来自 `AdService`。\n`AdItem` 对象指定要加载的组件类,以及绑定到该组件上的任意数据。\n`AdService` 可以返回广告活动中的那些广告。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "PASSINGANARRAYOFCOMPONENTSTOADBANNERCOMPONENTALLOWSFORADYNAMICLISTOFADSWITHOUTSTATICELEMENTSINTHETEMPLATE", "original": "Passing an array of components to `AdBannerComponent` allows for a\ndynamic list of ads without static elements in the template.", "translation": "给 `AdBannerComponent` 传入一个组件数组可以在模板中放入一个广告的动态列表,而不用写死在模板中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "WITHITSGETADSMETHODADBANNERCOMPONENTCYCLESTHROUGHTHEARRAYOFADITEMSANDLOADSANEWCOMPONENTEVERY3SECONDSBYCALLINGLOADCOMPONENT", "original": "With its `getAds()` method, `AdBannerComponent` cycles through the array of `AdItems`\nand loads a new component every 3 seconds by calling `loadComponent()`.", "translation": "通过 `getAds()` 方法,`AdBannerComponent` 可以循环遍历 `AdItems` 的数组,并且每三秒调用一次 `loadComponent()` 来加载新组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THELOADCOMPONENTMETHODISDOINGALOTOFTHEHEAVYLIFTINGHERETAKEITSTEPBYSTEPFIRSTITPICKSANAD", "original": "The `loadComponent()` method is doing a lot of the heavy lifting here.\nTake it step by step. First, it picks an ad.", "translation": "这里的 `loadComponent()` 方法很重要。\n来一步步看看。首先,它选取了一个广告。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "HOWLOADCOMPONENTCHOOSESANAD", "original": "**How _loadComponent()_ chooses an ad**", "translation": "**`loadComponent()` 如何选择广告**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THELOADCOMPONENTMETHODCHOOSESANADUSINGSOMEMATH", "original": "The `loadComponent()` method chooses an ad using some math.", "translation": "`loadComponent()` 方法使用某种算法选择了一个广告。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { - "original": "First, it sets the `currentAddIndex` by taking whatever it\ncurrently is plus one, dividing that by the length of the `AdItem` array, and\nusing the _remainder_ as the new `currentAddIndex` value. Then, it uses that\nvalue to select an `adItem` from the array.", - "translation": "(译注:循环选取算法)首先,它把 `currentAddIndex` 递增一,然后用它除以 `AdItem` 数组长度的*余数*作为新的 `currentAddIndex` 的值,\n最后用这个值来从数组中选取一个 `adItem`。", + "key": "FIRSTITSETSTHECURRENTADINDEXBYTAKINGWHATEVERITCURRENTLYISPLUSONEDIVIDINGTHATBYTHELENGTHOFTHEADITEMARRAYANDUSINGTHEREMAINDERASTHENEWCURRENTADINDEXVALUETHENITUSESTHATVALUETOSELECTANADITEMFROMTHEARRAY", + "original": "First, it sets the `currentAdIndex` by taking whatever it\ncurrently is plus one, dividing that by the length of the `AdItem` array, and\nusing the _remainder_ as the new `currentAdIndex` value. Then, it uses that\nvalue to select an `adItem` from the array.", + "translation": "(译注:循环选取算法)首先,它把 `currentAdIndex` 递增一,然后用它除以 `AdItem` 数组长度的*余数*作为新的 `currentAdIndex` 的值,\n最后用这个值来从数组中选取一个 `adItem`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "AFTERLOADCOMPONENTSELECTSANADITUSESCOMPONENTFACTORYRESOLVERTORESOLVEACOMPONENTFACTORYFOREACHSPECIFICCOMPONENTTHECOMPONENTFACTORYTHENCREATESANINSTANCEOFEACHCOMPONENT", "original": "After `loadComponent()` selects an ad, it uses `ComponentFactoryResolver`\nto resolve a `ComponentFactory` for each specific component.\nThe `ComponentFactory` then creates an instance of each component.", "translation": "在 `loadComponent()` 选取了一个广告之后,它使用 `ComponentFactoryResolver` 来为每个具体的组件解析出一个 `ComponentFactory`。\n然后 `ComponentFactory` 会为每一个组件创建一个实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "NEXTYOURETARGETINGTHEVIEWCONTAINERREFTHATEXISTSONTHISSPECIFICINSTANCEOFTHECOMPONENTHOWDOYOUKNOWITSTHISSPECIFICINSTANCEBECAUSEITSREFERRINGTOADHOSTANDADHOSTISTHEDIRECTIVEYOUSETUPEARLIERTOTELLANGULARWHERETOINSERTDYNAMICCOMPONENTS", "original": "Next, you're targeting the `viewContainerRef` that\nexists on this specific instance of the component. How do you know it's\nthis specific instance? Because it's referring to `adHost` and `adHost` is the\ndirective you set up earlier to tell Angular where to insert dynamic components.", "translation": "接下来,你要把 `viewContainerRef` 指向这个组件的现有实例。但你怎么才能找到这个实例呢?\n很简单,因为它指向了 `adHost`,而这个 `adHost` 就是你以前设置过的指令,用来告诉 Angular 该把动态组件插入到什么位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "ASYOUMAYRECALLADDIRECTIVEINJECTSVIEWCONTAINERREFINTOITSCONSTRUCTORTHISISHOWTHEDIRECTIVEACCESSESTHEELEMENTTHATYOUWANTTOUSETOHOSTTHEDYNAMICCOMPONENT", "original": "As you may recall, `AdDirective` injects `ViewContainerRef` into its constructor.\nThis is how the directive accesses the element that you want to use to host the dynamic component.", "translation": "回忆一下,`AdDirective` 曾在它的构造函数中注入了一个 `ViewContainerRef`。\n因此这个指令可以访问到这个你打算用作动态组件宿主的元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "TOADDTHECOMPONENTTOTHETEMPLATEYOUCALLCREATECOMPONENTONVIEWCONTAINERREF", "original": "To add the component to the template, you call `createComponent()` on `ViewContainerRef`.", "translation": "要把这个组件添加到模板中,你可以调用 `ViewContainerRef` 的 `createComponent()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THECREATECOMPONENTMETHODRETURNSAREFERENCETOTHELOADEDCOMPONENTUSETHATREFERENCETOINTERACTWITHTHECOMPONENTBYASSIGNINGTOITSPROPERTIESORCALLINGITSMETHODS", "original": "The `createComponent()` method returns a reference to the loaded component.\nUse that reference to interact with the component by assigning to its properties or calling its methods.", "translation": "`createComponent()` 方法返回一个引用,指向这个刚刚加载的组件。\n使用这个引用就可以与该组件进行交互,比如设置它的属性或调用它的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "####SELECTORREFERENCES", "original": "#### Selector references", "translation": "#### 对选择器的引用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "GENERALLYTHEANGULARCOMPILERGENERATESACOMPONENTFACTORYFORANYCOMPONENTREFERENCEDINATEMPLATEHOWEVERTHEREARENOSELECTORREFERENCESINTHETEMPLATESFORDYNAMICALLYLOADEDCOMPONENTSSINCETHEYLOADATRUNTIME", "original": "Generally, the Angular compiler generates a `ComponentFactory`\nfor any component referenced in a template. However, there are\nno selector references in the templates for\ndynamically loaded components since they load at runtime.", "translation": "通常,Angular 编译器会为模板中所引用的每个组件都生成一个 `ComponentFactory` 类。\n但是,对于动态加载的组件,模板中不会出现对它们的选择器的引用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "TOENSURETHATTHECOMPILERSTILLGENERATESAFACTORYADDDYNAMICALLYLOADEDCOMPONENTSTOTHENGMODULESENTRYCOMPONENTSARRAY:", "original": "To ensure that the compiler still generates a factory,\nadd dynamically loaded components to the `NgModule`'s `entryComponents` array:", "translation": "要想确保编译器照常生成工厂类,就要把这些动态加载的组件添加到 `NgModule` 的 `entryComponents` 数组中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "##THEADCOMPONENTINTERFACE", "original": "## The _AdComponent_ interface", "translation": "## 公共的 `AdComponent` 接口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "INTHEADBANNERALLCOMPONENTSIMPLEMENTACOMMONADCOMPONENTINTERFACETOSTANDARDIZETHEAPIFORPASSINGDATATOTHECOMPONENTS", "original": "In the ad banner, all components implement a common `AdComponent` interface to\nstandardize the API for passing data to the components.", "translation": "在广告条中,所有组件都实现了一个公共接口 `AdComponent`,它定义了一个标准化的 API,来把数据传给组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "HEREARETWOSAMPLECOMPONENTSANDTHEADCOMPONENTINTERFACEFORREFERENCE:", "original": "Here are two sample components and the `AdComponent` interface for reference:", "translation": "下面就是两个范例组件及其 `AdComponent` 接口:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "##FINALADBANNER", "original": "## Final ad banner", "translation": "## 最终的广告栏", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "THEFINALADBANNERLOOKSLIKETHIS:", "original": "The final ad banner looks like this:", "translation": "最终的广告栏是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "SEETHELIVEEXAMPLENAMEDYNAMICCOMPONENTLOADERLIVEEXAMPLE", "original": "See the <live-example name=\"dynamic-component-loader\"></live-example>.", "translation": "参见<live-example name=\"dynamic-component-loader\"></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-component-loader.md" }, { + "key": "#DYNAMICFORMS", "original": "# Dynamic Forms", "translation": "# 动态表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "BUILDINGHANDCRAFTEDFORMSCANBECOSTLYANDTIMECONSUMINGESPECIALLYIFYOUNEEDAGREATNUMBEROFTHEMTHEYRESIMILARTOEACHOTHERANDTHEYCHANGEFREQUENTLYTOMEETRAPIDLYCHANGINGBUSINESSANDREGULATORYREQUIREMENTS", "original": "Building handcrafted forms can be costly and time-consuming,\nespecially if you need a great number of them, they're similar to each other, and they change frequently\nto meet rapidly changing business and regulatory requirements.", "translation": "有时候手动编写和维护表单所需工作量和时间会过大。特别是在需要编写大量表单时。表单都很相似,而且随着业务和监管需求的迅速变化,表单也要随之变化,这样维护的成本过高。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "ITMAYBEMOREECONOMICALTOCREATETHEFORMSDYNAMICALLYBASEDONMETADATATHATDESCRIBESTHEBUSINESSOBJECTMODEL", "original": "It may be more economical to create the forms dynamically, based on\nmetadata that describes the business object model.", "translation": "基于业务对象模型的元数据,动态创建表单可能会更划算。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THISCOOKBOOKSHOWSYOUHOWTOUSEFORMGROUPTODYNAMICALLYRENDERASIMPLEFORMWITHDIFFERENTCONTROLTYPESANDVALIDATIONITSAPRIMITIVESTARTITMIGHTEVOLVETOSUPPORTAMUCHRICHERVARIETYOFQUESTIONSMOREGRACEFULRENDERINGANDSUPERIORUSEREXPERIENCEALLSUCHGREATNESSHASHUMBLEBEGINNINGS", "original": "This cookbook shows you how to use `formGroup` to dynamically\nrender a simple form with different control types and validation.\nIt's a primitive start.\nIt might evolve to support a much richer variety of questions, more graceful rendering, and superior user experience.\nAll such greatness has humble beginnings.", "translation": "本文会展示如何利用 `formGroup` 来动态渲染一个简单的表单,包括各种控件类型和验证规则。\n这个起点很简陋,但可以在这个基础上添加丰富多彩的问卷问题、更优美的渲染以及更卓越的用户体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THEEXAMPLEINTHISCOOKBOOKISADYNAMICFORMTOBUILDANONLINEAPPLICATIONEXPERIENCEFORHEROESSEEKINGEMPLOYMENTTHEAGENCYISCONSTANTLYTINKERINGWITHTHEAPPLICATIONPROCESSYOUCANCREATETHEFORMSONTHEFLYWITHOUTCHANGINGTHEAPPLICATIONCODE", "original": "The example in this cookbook is a dynamic form to build an\nonline application experience for heroes seeking employment.\nThe agency is constantly tinkering with the application process.\nYou can create the forms on the fly *without changing the application code*.", "translation": "这个例子要为正在找工作的英雄们创建一个在线申请表的动态表单。英雄管理局会不断修改申请流程,你要在*不修改应用代码*的情况下,动态创建这些表单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "SEETHELIVEEXAMPLENAMEDYNAMICFORMLIVEEXAMPLE", "original": "See the <live-example name=\"dynamic-form\"></live-example>.", "translation": "参见<live-example name=\"dynamic-form\"></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "##BOOTSTRAP", "original": "## Bootstrap", "translation": "## 启动/引导 (bootstrap)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "STARTBYCREATINGANNGMODULECALLEDAPPMODULE", "original": "Start by creating an `NgModule` called `AppModule`.", "translation": "从创建一个名叫 `AppModule` 的 `NgModule` 开始。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THISCOOKBOOKUSESREACTIVEFORMSGUIDEREACTIVEFORMS", "original": "This cookbook uses [reactive forms](guide/reactive-forms).", "translation": "这个烹饪书使用[响应式表单](guide/reactive-forms)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "REACTIVEFORMSBELONGSTOADIFFERENTNGMODULECALLEDREACTIVEFORMSMODULESOINORDERTOACCESSANYREACTIVEFORMSDIRECTIVESYOUHAVETOIMPORTREACTIVEFORMSMODULEFROMTHEANGULARFORMSLIBRARY", "original": "Reactive forms belongs to a different `NgModule` called `ReactiveFormsModule`,\nso in order to access any reactive forms directives, you have to import\n`ReactiveFormsModule` from the `@angular/forms` library.", "translation": "响应式表单属于另外一个叫做 `ReactiveFormsModule` 的 `NgModule`,所以,为了使用响应式表单类的指令,你得从 `@angular/forms` 库中引入 `ReactiveFormsModule` 模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "BOOTSTRAPTHEAPPMODULEINMAINTS", "original": "Bootstrap the `AppModule` in `main.ts`.", "translation": "在 `main.ts` 中启动 `AppModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "##QUESTIONMODEL", "original": "## Question model", "translation": "## 问卷问题模型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THENEXTSTEPISTODEFINEANOBJECTMODELTHATCANDESCRIBEALLSCENARIOSNEEDEDBYTHEFORMFUNCTIONALITYTHEHEROAPPLICATIONPROCESSINVOLVESAFORMWITHALOTOFQUESTIONSTHEQUESTIONISTHEMOSTFUNDAMENTALOBJECTINTHEMODEL", "original": "The next step is to define an object model that can describe all scenarios needed by the form functionality.\nThe hero application process involves a form with a lot of questions.\nThe _question_ is the most fundamental object in the model.", "translation": "第一步是定义一个对象模型,用来描述所有表单功能需要的场景。英雄的申请流程涉及到一个包含很多问卷问题的表单。问卷问题是最基础的对象模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THEFOLLOWINGQUESTIONBASEISAFUNDAMENTALQUESTIONCLASS", "original": "The following `QuestionBase` is a fundamental question class.", "translation": "下面的 `QuestionBase` 是最基础的问卷问题基类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "FROMTHISBASEYOUCANDERIVETWONEWCLASSESINTEXTBOXQUESTIONANDDROPDOWNQUESTIONTHATREPRESENTTEXTBOXANDDROPDOWNQUESTIONSTHEIDEAISTHATTHEFORMWILLBEBOUNDTOSPECIFICQUESTIONTYPESANDRENDERTHEAPPROPRIATECONTROLSDYNAMICALLY", "original": "From this base you can derive two new classes in `TextboxQuestion` and `DropdownQuestion`\nthat represent textbox and dropdown questions.\nThe idea is that the form will be bound to specific question types and render the\nappropriate controls dynamically.", "translation": "在这个基础上,你派生出两个新类 `TextboxQuestion` 和 `DropdownQuestion`,分别代表文本框和下拉框。这么做的初衷是,表单能动态绑定到特定的问卷问题类型,并动态渲染出合适的控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "TEXTBOXQUESTIONSUPPORTSMULTIPLEHTML5TYPESSUCHASTEXTEMAILANDURLVIATHETYPEPROPERTY", "original": "`TextboxQuestion` supports multiple HTML5 types such as text, email, and url\nvia the `type` property.", "translation": "`TextboxQuestion` 可以通过 `type` 属性来支持多种 HTML5 元素类型,比如文本、邮件、网址等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "DROPDOWNQUESTIONPRESENTSALISTOFCHOICESINASELECTBOX", "original": "`DropdownQuestion` presents a list of choices in a select box.", "translation": "`DropdownQuestion` 表示一个带可选项列表的选择框。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "NEXTISQUESTIONCONTROLSERVICEASIMPLESERVICEFORTRANSFORMINGTHEQUESTIONSTOAFORMGROUPINANUTSHELLTHEFORMGROUPCONSUMESTHEMETADATAFROMTHEQUESTIONMODELANDALLOWSYOUTOSPECIFYDEFAULTVALUESANDVALIDATIONRULES", "original": "Next is `QuestionControlService`, a simple service for transforming the questions to a `FormGroup`.\nIn a nutshell, the form group consumes the metadata from the question model and\nallows you to specify default values and validation rules.", "translation": "接下来定义了 `QuestionControlService`,一个可以把问卷问题转换为 `FormGroup` 的服务。\n简而言之,这个 `FormGroup` 使用问卷模型的元数据,并允许你指定默认值和验证规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "##QUESTIONFORMCOMPONENTS", "original": "## Question form components", "translation": "## 问卷表单组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "NOWTHATYOUHAVEDEFINEDTHECOMPLETEMODELYOUAREREADYTOCREATECOMPONENTSTOREPRESENTTHEDYNAMICFORM", "original": "Now that you have defined the complete model you are ready\nto create components to represent the dynamic form.", "translation": "现在你已经有一个定义好的完整模型了,接着就可以开始创建一个展现动态表单的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "DYNAMICFORMCOMPONENTISTHEENTRYPOINTANDTHEMAINCONTAINERFORTHEFORM", "original": "`DynamicFormComponent` is the entry point and the main container for the form.", "translation": "`DynamicFormComponent` 是表单的主要容器和入口点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "ITPRESENTSALISTOFQUESTIONSEACHBOUNDTOAAPPQUESTIONCOMPONENTELEMENTTHEAPPQUESTIONTAGMATCHESTHEDYNAMICFORMQUESTIONCOMPONENTTHECOMPONENTRESPONSIBLEFORRENDERINGTHEDETAILSOFEACHINDIVIDUALQUESTIONBASEDONVALUESINTHEDATABOUNDQUESTIONOBJECT", "original": "It presents a list of questions, each bound to a `<app-question>` component element.\nThe `<app-question>` tag matches the `DynamicFormQuestionComponent`,\nthe component responsible for rendering the details of each _individual_\nquestion based on values in the data-bound question object.", "translation": "它代表了问卷问题列表,每个问题都被绑定到一个 `<app-question>` 组件元素。\n`<app-question>` 标签匹配到的是组件 `DynamicFormQuestionComponent`,该组件的职责是根据各个问卷问题对象的值来动态渲染表单控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "NOTICETHISCOMPONENTCANPRESENTANYTYPEOFQUESTIONINYOURMODELYOUONLYHAVETWOTYPESOFQUESTIONSATTHISPOINTBUTYOUCANIMAGINEMANYMORETHENGSWITCHDETERMINESWHICHTYPEOFQUESTIONTODISPLAY", "original": "Notice this component can present any type of question in your model.\nYou only have two types of questions at this point but you can imagine many more.\nThe `ngSwitch` determines which type of question to display.", "translation": "请注意,这个组件能代表模型里的任何问题类型。目前,还只有两种问题类型,但可以添加更多类型。可以用 `ngSwitch` 决定显示哪种类型的问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "INBOTHCOMPONENTSYOURERELYINGONANGULARSFORMGROUPTOCONNECTTHETEMPLATEHTMLTOTHEUNDERLYINGCONTROLOBJECTSPOPULATEDFROMTHEQUESTIONMODELWITHDISPLAYANDVALIDATIONRULES", "original": "In both components you're relying on Angular's **formGroup** to connect the template HTML to the\nunderlying control objects, populated from the question model with display and validation rules.", "translation": "在这两个组件中,你依赖 Angular 的 **formGroup** 来把模板 HTML 和底层控件对象连接起来,该对象从问卷问题模型里获取渲染和验证规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "FORMCONTROLNAMEANDFORMGROUPAREDIRECTIVESDEFINEDINREACTIVEFORMSMODULETHETEMPLATESCANACCESSTHESEDIRECTIVESDIRECTLYSINCEYOUIMPORTEDREACTIVEFORMSMODULEFROMAPPMODULE", "original": "`formControlName` and `formGroup` are directives defined in\n`ReactiveFormsModule`. The templates can access these directives\ndirectly since you imported `ReactiveFormsModule` from `AppModule`.", "translation": "`formControlName` 和 `formGroup` 是在 `ReactiveFormsModule` 中定义的指令。这个模板之所以能使用它们,是因为你曾从 `AppModule` 中导入了 `ReactiveFormsModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "##QUESTIONNAIREDATA", "original": "## Questionnaire data", "translation": "## 问卷数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "DYNAMICFORMCOMPONENTEXPECTSTHELISTOFQUESTIONSINTHEFORMOFANARRAYBOUNDTOINPUTQUESTIONS", "original": "`DynamicFormComponent` expects the list of questions in the form of an array bound to `@Input() questions`.", "translation": "`DynamicForm` 期望得到一个问题列表,该列表被绑定到 `@Input() questions` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THESETOFQUESTIONSYOUVEDEFINEDFORTHEJOBAPPLICATIONISRETURNEDFROMTHEQUESTIONSERVICEINAREALAPPYOUDRETRIEVETHESEQUESTIONSFROMSTORAGE", "original": "The set of questions you've defined for the job application is returned from the `QuestionService`.\n In a real app you'd retrieve these questions from storage.", "translation": "`QuestionService` 会返回为工作申请表定义的那组问题列表。在真实的应用程序环境中,你会从数据库里获得这些问题列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THEKEYPOINTISTHATYOUCONTROLTHEHEROJOBAPPLICATIONQUESTIONSENTIRELYTHROUGHTHEOBJECTSRETURNEDFROMQUESTIONSERVICEQUESTIONNAIREMAINTENANCEISASIMPLEMATTEROFADDINGUPDATINGANDREMOVINGOBJECTSFROMTHEQUESTIONSARRAY", "original": "The key point is that you control the hero job application questions\n entirely through the objects returned from `QuestionService`.\n Questionnaire maintenance is a simple matter of adding, updating,\n and removing objects from the `questions` array.", "translation": "关键是,你完全根据 `QuestionService` 返回的对象来控制英雄的工作申请表。\n 要维护这份问卷,只要非常简单的添加、修改和删除 `questions` 数组中的对象就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "FINALLYDISPLAYANINSTANCEOFTHEFORMINTHEAPPCOMPONENTSHELL", "original": "Finally, display an instance of the form in the `AppComponent` shell.", "translation": "最后,在 `AppComponent` 里显示出表单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "##DYNAMICTEMPLATE", "original": "## Dynamic Template", "translation": "## 动态模板", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "ALTHOUGHINTHISEXAMPLEYOUREMODELLINGAJOBAPPLICATIONFORHEROESTHEREARENOREFERENCESTOANYSPECIFICHEROQUESTIONOUTSIDETHEOBJECTSRETURNEDBYQUESTIONSERVICE", "original": "Although in this example you're modelling a job application for heroes, there are\nno references to any specific hero question\noutside the objects returned by `QuestionService`.", "translation": "在这个例子中,虽然你是在为英雄的工作申请表建模,但是除了 `QuestionService` 返回的那些对象外,没有其它任何地方是与英雄有关的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THISISVERYIMPORTANTSINCEITALLOWSYOUTOREPURPOSETHECOMPONENTSFORANYTYPEOFSURVEYASLONGASITSCOMPATIBLEWITHTHEQUESTIONOBJECTMODELTHEKEYISTHEDYNAMICDATABINDINGOFMETADATAUSEDTORENDERTHEFORMWITHOUTMAKINGANYHARDCODEDASSUMPTIONSABOUTSPECIFICQUESTIONSINADDITIONTOCONTROLMETADATAYOUAREALSOADDINGVALIDATIONDYNAMICALLY", "original": "This is very important since it allows you to repurpose the components for any type of survey\nas long as it's compatible with the *question* object model.\nThe key is the dynamic data binding of metadata used to render the form\nwithout making any hardcoded assumptions about specific questions.\nIn addition to control metadata, you are also adding validation dynamically.", "translation": "这点非常重要,因为只要与*问卷*对象模型兼容,就可以在任何类型的调查问卷中复用这些组件。\n这里的关键是用到元数据的动态数据绑定来渲染表单,对问卷问题没有任何硬性的假设。除控件的元数据外,还可以动态添加验证规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THESAVEBUTTONISDISABLEDUNTILTHEFORMISINAVALIDSTATEWHENTHEFORMISVALIDYOUCANCLICKSAVEANDTHEAPPRENDERSTHECURRENTFORMVALUESASJSONTHISPROVESTHATANYUSERINPUTISBOUNDBACKTOTHEDATAMODELSAVINGANDRETRIEVINGTHEDATAISANEXERCISEFORANOTHERTIME", "original": "The *Save* button is disabled until the form is in a valid state.\nWhen the form is valid, you can click *Save* and the app renders the current form values as JSON.\nThis proves that any user input is bound back to the data model.\nSaving and retrieving the data is an exercise for another time.", "translation": "表单验证通过之前,*保存*按钮是禁用的。验证通过后,就可以点击*保存*按钮,程序会把当前值渲染成 JSON 显示出来。\n这表明任何用户输入都被传到了数据模型里。至于如何储存和提取数据则是另一话题了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "THEFINALFORMLOOKSLIKETHIS:", "original": "The final form looks like this:", "translation": "完整的表单是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "BACKTOTOPGUIDEDYNAMICFORM#TOP", "original": "[Back to top](guide/dynamic-form#top)", "translation": "[回到顶部](guide/dynamic-form#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/dynamic-form.md" }, { + "key": "#ENTRYCOMPONENTS", "original": "# Entry Components", "translation": "# 入口组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "####PREREQUISITES:", "original": "#### Prerequisites:", "translation": "#### 前提条件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWINGCONCEPTS:", "original": "A basic understanding of the following concepts:", "translation": "对下列概念有基本的理解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "BOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "* [Bootstrapping](guide/bootstrapping).", - "translation": "[引导](guide/bootstrapping)。", + "translation": "[引导启动](guide/bootstrapping)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "ANENTRYCOMPONENTISANYCOMPONENTTHATANGULARLOADSIMPERATIVELYWHICHMEANSYOURENOTREFERENCINGITINTHETEMPLATEBYTYPEYOUSPECIFYANENTRYCOMPONENTBYBOOTSTRAPPINGITINANNGMODULEORINCLUDINGITINAROUTINGDEFINITION", "original": "An entry component is any component that Angular loads imperatively, (which means you’re not referencing it in the template), by type. You specify an entry component by bootstrapping it in an NgModule, or including it in a routing definition.", "translation": "从分类上说,入口组件是 Angular 命令式加载的(也就是说你没有在模板中引用过它)任意组件,\n你可以通过在 NgModule 中引导它,或者把它包含在路由定义中来指定入口组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "TOCONTRASTTHETWOTYPESOFCOMPONENTSTHEREARECOMPONENTSWHICHAREINCLUDEDINTHETEMPLATEWHICHAREDECLARATIVEADDITIONALLYTHEREARECOMPONENTSWHICHYOULOADIMPERATIVELYTHATISENTRYCOMPONENTS", "original": "To contrast the two types of components, there are components which are included in the template, which are declarative. Additionally, there are components which you load imperatively; that is, entry components.", "translation": "对比一下这两种组件类型:有一类组件被包含在模板中,它们是声明式加载的;另一类组件你会命令式加载它,这就是入口组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "THEREARETWOMAINKINDSOFENTRYCOMPONENTS:", "original": "There are two main kinds of entry components:", "translation": "入口组件有两种主要的类型:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "THEBOOTSTRAPPEDROOTCOMPONENT", "original": "* The bootstrapped root component.", "translation": "引导用的根组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "ACOMPONENTYOUSPECIFYINAROUTEDEFINITION", "original": "* A component you specify in a route definition.", "translation": "在路由定义中指定的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "##ABOOTSTRAPPEDENTRYCOMPONENT", "original": "## A bootstrapped entry component", "translation": "## 引导用的入口组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "THEFOLLOWINGISANEXAMPLEOFSPECIFYINGABOOTSTRAPPEDCOMPONENTAPPCOMPONENTINABASICAPPMODULETS:", "original": "The following is an example of specifying a bootstrapped component,\n`AppComponent`, in a basic `app.module.ts`:", "translation": "下面这个例子中指定了一个引导用组件 `AppComponent`,位于基本的 `app.module.ts` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "ABOOTSTRAPPEDCOMPONENTISANENTRYCOMPONENTTHATANGULARLOADSINTOTHEDOMDURINGTHEBOOTSTRAPPROCESSAPPLICATIONLAUNCHOTHERENTRYCOMPONENTSARELOADEDDYNAMICALLYBYOTHERMEANSSUCHASWITHTHEROUTER", "original": "A bootstrapped component is an entry component\nthat Angular loads into the DOM during the bootstrap process (application launch).\nOther entry components are loaded dynamically by other means, such as with the router.", "translation": "可引导组件是一个入口组件,Angular 会在引导过程中把它加载到 DOM 中。\n其它入口组件是在其它时机动态加载的,比如用路由器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "ANGULARLOADSAROOTAPPCOMPONENTDYNAMICALLYBECAUSEITSLISTEDBYTYPEINNGMODULEBOOTSTRAP", "original": "Angular loads a root `AppComponent` dynamically because it's listed by type in `@NgModule.bootstrap`.", "translation": "Angular 会动态加载根组件 `AppComponent`,是因为它的类型作为参数传给了 `@NgModule.bootstrap` 函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "ACOMPONENTCANALSOBEBOOTSTRAPPEDIMPERATIVELYINTHEMODULESNGDOBOOTSTRAPMETHODTHENGMODULEBOOTSTRAPPROPERTYTELLSTHECOMPILERTHATTHISISANENTRYCOMPONENTANDITSHOULDGENERATECODETOBOOTSTRAPTHEAPPLICATIONWITHTHISCOMPONENT", "original": "A component can also be bootstrapped imperatively in the module's `ngDoBootstrap()` method.\nThe `@NgModule.bootstrap` property tells the compiler that this is an entry component and\nit should generate code to bootstrap the application with this component.", "translation": "组件也可以在该模块的 `ngDoBootstrap()` 方法中进行命令式引导。\n`@NgModule.bootstrap` 属性告诉编译器,这里是一个入口组件,它应该生成代码,来使用这个组件引导该应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "ABOOTSTRAPPEDCOMPONENTISNECESSARILYANENTRYCOMPONENTBECAUSEBOOTSTRAPPINGISANIMPERATIVEPROCESSTHUSITNEEDSTOHAVEANENTRYCOMPONENT", "original": "A bootstrapped component is necessarily an entry component because bootstrapping is an imperative process, thus it needs to have an entry component.", "translation": "引导用的组件必须是入口组件,因为引导过程是命令式的,所以它需要一个入口组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "##AROUTEDENTRYCOMPONENT", "original": "## A routed entry component", "translation": "## 路由到的入口组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "THESECONDKINDOFENTRYCOMPONENTOCCURSINAROUTEDEFINITIONLIKETHIS:", "original": "The second kind of entry component occurs in a route definition like\nthis:", "translation": "入口组件的第二种类型出现在路由定义中,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "AROUTEDEFINITIONREFERSTOACOMPONENTBYITSTYPEWITHCOMPONENT:CUSTOMERLISTCOMPONENT", "original": "A route definition refers to a component by its type with `component: CustomerListComponent`.", "translation": "路由定义使用组件类型引用了一个组件:`component: CustomerListComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "ALLROUTERCOMPONENTSMUSTBEENTRYCOMPONENTSBECAUSETHISWOULDREQUIREYOUTOADDTHECOMPONENTINTWOPLACESROUTERANDENTRYCOMPONENTSTHECOMPILERISSMARTENOUGHTORECOGNIZETHATTHISISAROUTERDEFINITIONANDAUTOMATICALLYADDTHEROUTERCOMPONENTINTOENTRYCOMPONENTS", "original": "All router components must be entry components. Because this would require you to add the component in two places (router and `entryComponents`) the Compiler is smart enough to recognize that this is a router definition and automatically add the router component into `entryComponents`.", "translation": "所有路由组件都必须是入口组件。这需要你把同一个组件添加到两个地方(路由中和 `entryComponents` 中),但编译器足够聪明,可以识别出这里是一个路由定义,因此它会自动把这些路由组件添加到 `entryComponents` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "##THEENTRYCOMPONENTSARRAY", "original": "## The `entryComponents` array", "translation": "## `entryComponents` 数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "THOUGHTHENGMODULEDECORATORHASANENTRYCOMPONENTSARRAYMOSTOFTHETIMEYOUWONTHAVETOEXPLICITLYSETANYENTRYCOMPONENTSBECAUSEANGULARADDSCOMPONENTSLISTEDINNGMODULEBOOTSTRAPANDTHOSEINROUTEDEFINITIONSTOENTRYCOMPONENTSAUTOMATICALLYTHOUGHTHESETWOMECHANISMSACCOUNTFORMOSTENTRYCOMPONENTSIFYOURAPPHAPPENSTOBOOTSTRAPORDYNAMICALLYLOADACOMPONENTBYTYPEIMPERATIVELYYOUMUSTADDITTOENTRYCOMPONENTSEXPLICITLY", "original": "Though the `@NgModule` decorator has an `entryComponents` array, most of the time\nyou won't have to explicitly set any entry components because Angular adds components listed in `@NgModule.bootstrap` and those in route definitions to entry components automatically. Though these two mechanisms account for most entry components, if your app happens to bootstrap or dynamically load a component by type imperatively,\nyou must add it to `entryComponents` explicitly.", "translation": "虽然 `@NgModule` 装饰器具有一个 `entryComponents` 数组,但大多数情况下你不用显式设置入口组件,因为 Angular 会自动把 `@NgModule.bootstrap` 中的组件以及路由定义中的组件添加到入口组件中。\n虽然这两种机制足够自动添加大多数入口组件,但如果你要用其它方式根据类型来命令式的引导或动态加载某个组件,你就必须把它们显式添加到 `entryComponents` 中了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "###ENTRYCOMPONENTSANDTHECOMPILER", "original": "### `entryComponents` and the compiler", "translation": "### `entryComponents` 和编译器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "FORPRODUCTIONAPPSYOUWANTTOLOADTHESMALLESTCODEPOSSIBLETHECODESHOULDCONTAINONLYTHECLASSESTHATYOUACTUALLYNEEDANDEXCLUDECOMPONENTSTHATARENEVERUSEDFORTHISREASONTHEANGULARCOMPILERONLYGENERATESCODEFORCOMPONENTSWHICHAREREACHABLEFROMTHEENTRYCOMPONENTSTHISMEANSTHATADDINGMOREREFERENCESTONGMODULEDECLARATIONSDOESNOTIMPLYTHATTHEYWILLNECESSARILYBEINCLUDEDINTHEFINALBUNDLE", "original": "For production apps you want to load the smallest code possible.\nThe code should contain only the classes that you actually need and\nexclude components that are never used. For this reason, the Angular compiler only generates code for components which are reachable from the `entryComponents`; This means that adding more references to `@NgModule.declarations` does not imply that they will necessarily be included in the final bundle.", "translation": "对于生产环境的应用,你总是希望加载尽可能小的代码。\n这些代码应该只包含你实际使用到的类,并且排除那些从未用到的组件。因此,Angular 编译器只会为那些可以从 `entryComponents` 中直接或间接访问到的组件生成代码。\n这意味着,仅仅往 `@NgModule.declarations` 中添加更多引用,并不能表达出它们在最终的代码包中是必要的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "INFACTMANYLIBRARIESDECLAREANDEXPORTCOMPONENTSYOULLNEVERUSEFOREXAMPLEAMATERIALDESIGNLIBRARYWILLEXPORTALLCOMPONENTSBECAUSEITDOESNTKNOWWHICHONESYOUWILLUSEHOWEVERITISUNLIKELYTHATYOUWILLUSETHEMALLFORTHEONESYOUDONTREFERENCETHETREESHAKERDROPSTHESECOMPONENTSFROMTHEFINALCODEPACKAGE", "original": "In fact, many libraries declare and export components you'll never use.\nFor example, a material design library will export all components because it doesn’t know which ones you will use. However, it is unlikely that you will use them all.\nFor the ones you don't reference, the tree shaker drops these components from the final code package.", "translation": "实际上,很多库声明和导出的组件都是你从未用过的。\n比如,Material Design 库会导出其中的所有组件,因为它不知道你会用哪一个。然而,显然你也不打算全都用上。\n对于那些你没有引用过的,摇树优化工具就会把这些组件从最终的代码包中摘出去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "IFACOMPONENTISNTANENTRYCOMPONENTANDISNTFOUNDINATEMPLATETHETREESHAKERWILLTHROWITAWAYSOITSBESTTOADDONLYTHECOMPONENTSTHATARETRULYENTRYCOMPONENTSTOHELPKEEPYOURAPPASTRIMASPOSSIBLE", "original": "If a component isn't an _entry component_ and isn't found in a template,\nthe tree shaker will throw it away. So, it's best to add only the components that are truly entry components to help keep your app\nas trim as possible.", "translation": "如果一个组件既不是*入口组件*也不没有在模板中使用过,摇树优化工具就会把它扔出去。\n所以,最好只添加那些真正的入口组件,以便让应用尽可能保持精简。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "##MOREONANGULARMODULES", "original": "## More on Angular modules", "translation": "## 关于 Angular 模块的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "TYPESOFNGMODULESGUIDEMODULETYPES", "original": "* [Types of NgModules](guide/module-types)", - "translation": "[Angular 模块的分类](guide/module-types)", + "translation": "[NgModule 的分类](guide/module-types).", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "LAZYLOADINGMODULESWITHTHEANGULARROUTERGUIDELAZYLOADINGNGMODULES", "original": "* [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules).", - "translation": "[使用 Angular 路由器实现惰性加载模块](guide/lazy-loading-ngmodules).", + "translation": "[使用 Angular 路由器惰性加载模块](guide/lazy-loading-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "PROVIDERSGUIDEPROVIDERS", "original": "* [Providers](guide/providers).", - "translation": "[服务提供商](guide/providers).", + "translation": "[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "NGMODULESFAQGUIDENGMODULEFAQ", "original": "* [NgModules FAQ](guide/ngmodule-faq).", "translation": "[NgModule 常见问题](guide/ngmodule-faq).", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/entry-components.md" }, { + "key": "#FEATUREMODULES", "original": "# Feature Modules", "translation": "# 特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "FEATUREMODULESARENGMODULESFORTHEPURPOSEOFORGANIZINGCODE", "original": "Feature modules are NgModules for the purpose of organizing code.", "translation": "特性模块是用来对代码进行组织的模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWING:", "original": "A basic understanding of the following:", "translation": "对下列知识有基本的了解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "BOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "* [Bootstrapping](guide/bootstrapping).", - "translation": "[引导](guide/bootstrapping)。", + "translation": "[引导启动](guide/bootstrapping)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "JAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "FREQUENTLYUSEDMODULESGUIDEFREQUENTNGMODULES", "original": "* [Frequently Used Modules](guide/frequent-ngmodules).", - "translation": "[常用模块](guide/frequent-ngmodules).", + "translation": "[常用模块](guide/frequent-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "FORTHEFINALSAMPLEAPPWITHAFEATUREMODULETHATTHISPAGEDESCRIBESSEETHELIVEEXAMPLELIVEEXAMPLE", "original": "For the final sample app with a feature module that this page describes,\nsee the <live-example></live-example>.", "translation": "要想查看本页提到的这个带有特性模块的范例应用,参见 <live-example></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "ASYOURAPPGROWSYOUCANORGANIZECODERELEVANTFORASPECIFICFEATURETHISHELPSAPPLYCLEARBOUNDARIESFORFEATURESWITHFEATUREMODULESYOUCANKEEPCODERELATEDTOASPECIFICFUNCTIONALITYORFEATURESEPARATEFROMOTHERCODEDELINEATINGAREASOFYOURAPPHELPSWITHCOLLABORATIONBETWEENDEVELOPERSANDTEAMSSEPARATINGDIRECTIVESANDMANAGINGTHESIZEOFTHEROOTMODULE", "original": "As your app grows, you can organize code relevant for a specific feature.\nThis helps apply clear boundaries for features. With feature modules,\nyou can keep code related to a specific functionality or feature\nseparate from other code. Delineating areas of your\napp helps with collaboration between developers and teams, separating\ndirectives, and managing the size of the root module.", "translation": "随着应用的增长,你可能需要组织与特定应用有关的代码。\n这将帮你把特性划出清晰的边界。使用特性模块,你可以把与特定的功能或特性有关的代码从其它代码中分离出来。\n为应用勾勒出清晰的边界,有助于开发人员之间、小组之间的协作,有助于分离各个指令,并帮助管理根模块的大小。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "##FEATUREMODULESVSROOTMODULES", "original": "## Feature modules vs. root modules", "translation": "## 特性模块 vs. 根模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "AFEATUREMODULEISANORGANIZATIONALBESTPRACTICEASOPPOSEDTOACONCEPTOFTHECOREANGULARAPIAFEATUREMODULEDELIVERSACOHESIVESETOFFUNCTIONALITYFOCUSEDONASPECIFICAPPLICATIONNEEDSUCHASAUSERWORKFLOWROUTINGORFORMSWHILEYOUCANDOEVERYTHINGWITHINTHEROOTMODULEFEATUREMODULESHELPYOUPARTITIONTHEAPPINTOFOCUSEDAREASAFEATUREMODULECOLLABORATESWITHTHEROOTMODULEANDWITHOTHERMODULESTHROUGHTHESERVICESITPROVIDESANDTHECOMPONENTSDIRECTIVESANDPIPESTHATITSHARES", "original": "A feature module is an organizational best practice, as opposed to a concept of the core Angular API. A feature module delivers a cohesive set of functionality focused on a\nspecific application need such as a user workflow, routing, or forms.\nWhile you can do everything within the root module, feature modules\nhelp you partition the app into focused areas. A feature module\ncollaborates with the root module and with other modules through\nthe services it provides and the components, directives, and\npipes that it shares.", "translation": "与核心的 Angular API 的概念相反,特性模块是最佳的组织方式。特性模块提供了聚焦于特定应用需求的一组功能,比如用户工作流、路由或表单。\n虽然你也可以用根模块做完所有事情,不过特性模块可以帮助你把应用划分成一些聚焦的功能区。特性模块通过它提供的服务以及共享出的组件、指令和管道来与根模块和其它模块合作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "##HOWTOMAKEAFEATUREMODULE", "original": "## How to make a feature module", "translation": "## 如何制作特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "ASSUMINGYOUALREADYHAVEACLIGENERATEDAPPCREATEAFEATUREMODULEUSINGTHECLIBYENTERINGTHEFOLLOWINGCOMMANDINTHEROOTPROJECTDIRECTORYREPLACECUSTOMERDASHBOARDWITHTHENAMEOFYOURMODULEYOUCANOMITTHEMODULESUFFIXFROMTHENAMEBECAUSETHECLIAPPENDSIT:", "original": "Assuming you already have a CLI generated app, create a feature\nmodule using the CLI by entering the following command in the\nroot project directory. Replace `CustomerDashboard` with the\nname of your module. You can omit the \"Module\" suffix from the name because the CLI appends it:", "translation": "如果你已经有了 CLI 生成的应用,可以在项目的根目录下输入下面的命令来创建特性模块。把这里的 `CustomerDashboard` 替换成你的模块名。你可以从名字中省略掉“Module”后缀,因为 CLI 会自动追加上它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "THISCAUSESTHECLITOCREATEAFOLDERCALLEDCUSTOMERDASHBOARDWITHAFILEINSIDECALLEDCUSTOMERDASHBOARDMODULETSWITHTHEFOLLOWINGCONTENTS:", "original": "This causes the CLI to create a folder called `customer-dashboard` with a file inside called `customer-dashboard.module.ts` with the following contents:", "translation": "这会让 CLI 创建一个名叫 `customer-dashboard` 的文件夹,其中有一个名叫 `customer-dashboard.module.ts`,内容如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "THESTRUCTUREOFANNGMODULEISTHESAMEWHETHERITISAROOTMODULEORAFEATUREMODULEINTHECLIGENERATEDFEATUREMODULETHEREARETWOJAVASCRIPTIMPORTSTATEMENTSATTHETOPOFTHEFILE:THEFIRSTIMPORTSNGMODULEWHICHLIKETHEROOTMODULELETSYOUUSETHENGMODULEDECORATORTHESECONDIMPORTSCOMMONMODULEWHICHCONTRIBUTESMANYCOMMONDIRECTIVESSUCHASNGIFANDNGFORFEATUREMODULESIMPORTCOMMONMODULEINSTEADOFBROWSERMODULEWHICHISONLYIMPORTEDONCEINTHEROOTMODULECOMMONMODULEONLYCONTAINSINFORMATIONFORCOMMONDIRECTIVESSUCHASNGIFANDNGFORWHICHARENEEDEDINMOSTTEMPLATESWHEREASBROWSERMODULECONFIGURESTHEANGULARAPPFORTHEBROWSERWHICHNEEDSTOBEDONEONLYONCE", "original": "The structure of an NgModule is the same whether it is a root module or a feature module. In the CLI generated feature module, there are two JavaScript import statements at the top of the file: the first imports `NgModule`, which, like the root module, lets you use the `@NgModule` decorator; the second imports `CommonModule`, which contributes many common directives such as `ngIf` and `ngFor`. Feature modules import `CommonModule` instead of `BrowserModule`, which is only imported once in the root module. `CommonModule` only contains information for common directives such as `ngIf` and `ngFor` which are needed in most templates, whereas `BrowserModule` configures the Angular app for the browser which needs to be done only once.", "translation": "无论根模块还是特性模块,其 NgModule 结构都是一样的。在 CLI 生成的特性模块中,在文件顶部有两个 JavaScript 的导入语句:第一个导入了 `NgModule`,它像根模块中一样让你能使用 `@NgModule` 装饰器;第二个导入了 `CommonModule`,它提供了很多像 `ngIf` 和 `ngFor` 这样的常用指令。\n特性模块导入 `CommonModule`,而不是 `BrowserModule`,后者只应该在根模块中导入一次。\n`CommonModule` 只包含常用指令的信息,比如 `ngIf` 和 `ngFor`,它们在大多数模板中都要用到,而 `BrowserModule` 为浏览器所做的应用配置只会使用一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "THEDECLARATIONSARRAYISAVAILABLEFORYOUTOADDDECLARABLESWHICHARECOMPONENTSDIRECTIVESANDPIPESTHATBELONGEXCLUSIVELYTOTHISPARTICULARMODULETOADDACOMPONENTENTERTHEFOLLOWINGCOMMANDATTHECOMMANDLINEWHERECUSTOMERDASHBOARDISTHEDIRECTORYWHERETHECLIGENERATEDTHEFEATUREMODULEANDCUSTOMERDASHBOARDISTHENAMEOFTHECOMPONENT:", "original": "The `declarations` array is available for you to add declarables, which\nare components, directives, and pipes that belong exclusively to this particular module. To add a component, enter the following command at the command line where `customer-dashboard` is the directory where the CLI generated the feature module and `CustomerDashboard` is the name of the component:", "translation": "`declarations` 数组让你能添加专属于这个模块的可声明对象(组件、指令和管道)。\n要添加组件,就在命令行中输入如下命令,这里的 `customer-dashboard` 是一个目录,CLI 会把特性模块生成在这里,而 `CustomerDashboard` 就是该组件的名字:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "THISGENERATESAFOLDERFORTHENEWCOMPONENTWITHINTHECUSTOMERDASHBOARDFOLDERANDUPDATESTHEFEATUREMODULEWITHTHECUSTOMERDASHBOARDCOMPONENTINFO:", "original": "This generates a folder for the new component within the customer-dashboard folder and updates the feature module with the `CustomerDashboardComponent` info:", "translation": "这会在 `customer-dashboard` 中为新组件生成一个目录,并使用 `CustomerDashboardComponent` 的信息修改这个特性模块:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "THECUSTOMERDASHBOARDCOMPONENTISNOWINTHEJAVASCRIPTIMPORTLISTATTHETOPANDADDEDTOTHEDECLARATIONSARRAYWHICHLETSANGULARKNOWTOASSOCIATETHISNEWCOMPONENTWITHTHISFEATUREMODULE", "original": "The `CustomerDashboardComponent` is now in the JavaScript import list at the top and added to the `declarations` array, which lets Angular know to associate this new component with this feature module.", "translation": "`CustomerDashboardComponent` 出现在了顶部的 JavaScript 导入列表里,并且被添加到了 `declarations` 数组中,它会让 Angular 把新组件和这个特性模块联系起来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "##IMPORTINGAFEATUREMODULE", "original": "## Importing a feature module", "translation": "## 导入特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "TOINCORPORATETHEFEATUREMODULEINTOYOURAPPYOUHAVETOLETTHEROOTMODULEAPPMODULETSKNOWABOUTITNOTICETHECUSTOMERDASHBOARDMODULEEXPORTATTHEBOTTOMOFCUSTOMERDASHBOARDMODULETSTHISEXPOSESITSOTHATOTHERMODULESCANGETTOITTOIMPORTITINTOTHEAPPMODULEADDITTOTHEIMPORTSINAPPMODULETSANDTOTHEIMPORTSARRAY:", "original": "To incorporate the feature module into your app, you have to let the root module, `app.module.ts`, know about it. Notice the `CustomerDashboardModule` export at the bottom of `customer-dashboard.module.ts`. This exposes it so that other modules can get to it. To import it into the `AppModule`, add it to the imports in `app.module.ts` and to the `imports` array:", "translation": "要想把这个特性模块包含进应用中,你还得让根模块 `app.module.ts` 知道它。注意,在 `customer-dashboard.module.ts` 的底部导出了 `CustomerDashboardModule`。这样就把它暴露出来,以便其它模块可以拿到它。要想把它导入到 `AppModule` 中,就把它加入 `app.module.ts` 的导入表中,并将其加入 `imports` 数组:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "NOWTHEAPPMODULEKNOWSABOUTTHEFEATUREMODULEIFYOUWERETOADDANYSERVICEPROVIDERSTOTHEFEATUREMODULEAPPMODULEWOULDKNOWABOUTTHOSETOOASWOULDANYOTHERFEATUREMODULESHOWEVERNGMODULESDONTEXPOSETHEIRCOMPONENTS", "original": "Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules don’t expose their components.", "translation": "现在 `AppModule` 知道这个特性模块了。如果你往该特性模块中加入过任何服务提供商,`AppModule` 也同样会知道它,其它模块中也一样。不过,NgModule 并不会暴露出它们的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "##RENDERINGAFEATUREMODULESCOMPONENTTEMPLATE", "original": "## Rendering a feature module’s component template", "translation": "## 渲染特性模块的组件模板", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "WHENTHECLIGENERATEDTHECUSTOMERDASHBOARDCOMPONENTFORTHEFEATUREMODULEITINCLUDEDATEMPLATECUSTOMERDASHBOARDCOMPONENTHTMLWITHTHEFOLLOWINGMARKUP:", "original": "When the CLI generated the `CustomerDashboardComponent` for the feature module, it included a template, `customer-dashboard.component.html`, with the following markup:", "translation": "当 CLI 为这个特性模块生成 `CustomerDashboardComponent` 时,还包含一个模板 `customer-dashboard.component.html`,它带有如下页面脚本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "TOSEETHISHTMLINTHEAPPCOMPONENTYOUFIRSTHAVETOEXPORTTHECUSTOMERDASHBOARDCOMPONENTINTHECUSTOMERDASHBOARDMODULEINCUSTOMERDASHBOARDMODULETSJUSTBENEATHTHEDECLARATIONSARRAYADDANEXPORTSARRAYCONTAININGCUSTOMERDASHBOARDMODULE:", "original": "To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardModule`:", "translation": "要想在 `AppComponent` 中查看这些 HTML,你首先要在 `CustomerDashboardModule` 中导出 `CustomerDashboardComponent`。\n在 `customer-dashboard.module.ts` 中,`declarations` 数组的紧下方,加入一个包含 `CustomerDashboardModule` 的 `exports` 数组:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "NEXTINTHEAPPCOMPONENTAPPCOMPONENTHTMLADDTHETAGAPPCUSTOMERDASHBOARD:", "original": "Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-dashboard>`:", "translation": "然后,在 `AppComponent` 的 `app.component.html` 中,加入标签 `<app-customer-dashboard>`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "NOWINADDITIONTOTHETITLETHATRENDERSBYDEFAULTTHECUSTOMERDASHBOARDCOMPONENTTEMPLATERENDERSTOO:", "original": "Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:", "translation": "现在,除了默认渲染出的标题外,还渲染出了 `CustomerDashboardComponent` 的模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "LAZYLOADINGMODULESWITHTHEANGULARROUTERGUIDELAZYLOADINGNGMODULES", "original": "* [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules).", - "translation": "[使用 Angular 路由器实现惰性加载模块](guide/lazy-loading-ngmodules).", + "translation": "[使用 Angular 路由器惰性加载模块](guide/lazy-loading-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "PROVIDERSGUIDEPROVIDERS", "original": "* [Providers](guide/providers).", - "translation": "[服务提供商](guide/providers).", + "translation": "[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "TYPESOFFEATUREMODULESGUIDEMODULETYPES", "original": "* [Types of Feature Modules](guide/module-types).", - "translation": "[Angular 模块的分类](guide/module-types)", + "translation": "[特性模块的分类](guide/module-types)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/feature-modules.md" }, { + "key": "#FORMVALIDATION", "original": "# Form Validation", "translation": "# 表单验证", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "IMPROVEOVERALLDATAQUALITYBYVALIDATINGUSERINPUTFORACCURACYANDCOMPLETENESS", "original": "Improve overall data quality by validating user input for accuracy and completeness.", "translation": "通过验证用户输入的准确性和完整性,来增强整体数据质量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THISPAGESHOWSHOWTOVALIDATEUSERINPUTINTHEUIANDDISPLAYUSEFULVALIDATIONMESSAGESUSINGBOTHREACTIVEANDTEMPLATEDRIVENFORMSITASSUMESSOMEBASICKNOWLEDGEOFTHETWOFORMSMODULES", "original": "This page shows how to validate user input in the UI and display useful validation messages\nusing both reactive and template-driven forms. It assumes some basic knowledge of the two \nforms modules.", "translation": "本文展示了如何在界面中如何验证用户输入,并显示有用的验证信息,先使用模板驱动表单方式,再使用响应式表单方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "IFYOURENEWTOFORMSSTARTBYREVIEWINGTHEFORMSGUIDEFORMSANDREACTIVEFORMSGUIDEREACTIVEFORMSGUIDES", "original": "If you're new to forms, start by reviewing the [Forms](guide/forms) and \n[Reactive Forms](guide/reactive-forms) guides.", "translation": "参见[表单](guide/forms)和[响应式表单](guide/reactive-forms)了解关于这些选择的更多知识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "##TEMPLATEDRIVENVALIDATION", "original": "## Template-driven validation", "translation": "## 模板驱动验证", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "TOADDVALIDATIONTOATEMPLATEDRIVENFORMYOUADDTHESAMEVALIDATIONATTRIBUTESASYOUWOULDWITHNATIVEHTMLFORMVALIDATIONHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBGUIDEHTMLHTML5CONSTRAINTVALIDATIONANGULARUSESDIRECTIVESTOMATCHTHESEATTRIBUTESWITHVALIDATORFUNCTIONSINTHEFRAMEWORK", "original": "To add validation to a template-driven form, you add the same validation attributes as you \nwould with [native HTML form validation](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation). \nAngular uses directives to match these attributes with validator functions in the framework.", "translation": "为了往模板驱动表单中添加验证机制,你要添加一些验证属性,就像[原生的 HTML 表单验证器](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation)。\nAngular 会用指令来匹配这些具有验证功能的指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "EVERYTIMETHEVALUEOFAFORMCONTROLCHANGESANGULARRUNSVALIDATIONANDGENERATESEITHERALISTOFVALIDATIONERRORSWHICHRESULTSINANINVALIDSTATUSORNULLWHICHRESULTSINAVALIDSTATUS", "original": "Every time the value of a form control changes, Angular runs validation and generates \neither a list of validation errors, which results in an INVALID status, or null, which results in a VALID status.", "translation": "每当表单控件中的值发生变化时,Angular 就会进行验证,并生成一个验证错误的列表(对应着 INVALID 状态)或者 null(对应着 VALID 状态)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "YOUCANTHENINSPECTTHECONTROLSSTATEBYEXPORTINGNGMODELTOALOCALTEMPLATEVARIABLETHEFOLLOWINGEXAMPLEEXPORTSNGMODELINTOAVARIABLECALLEDNAME:", "original": "You can then inspect the control's state by exporting `ngModel` to a local template variable.\nThe following example exports `NgModel` into a variable called `name`:", "translation": "你可以通过把 `ngModel` 导出成局部模板变量来查看该控件的状态。\n比如下面这个例子就把 `NgModel` 导出成了一个名叫 `name` 的变量:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "NOTETHEFOLLOWING:", "original": "Note the following:", "translation": "请注意以下几点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THEINPUTELEMENTCARRIESTHEHTMLVALIDATIONATTRIBUTES:REQUIREDANDMINLENGTHITALSOCARRIESACUSTOMVALIDATORDIRECTIVEFORBIDDENNAMEFORMOREINFORMATIONSEECUSTOMVALIDATORSGUIDEFORMVALIDATION#CUSTOMVALIDATORSSECTION", "original": "* The `<input>` element carries the HTML validation attributes: `required` and `minlength`. It \nalso carries a custom validator directive, `forbiddenName`. For more \ninformation, see [Custom validators](guide/form-validation#custom-validators) section.", "translation": "`<input>` 元素带有一些 HTML 验证属性:`required` 和 `minlength`。它还带有一个自定义的验证器指令 `forbiddenName`。要了解更多信息,参见[自定义验证器](guide/form-validation#custom-validators)一节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "#NAMENGMODELEXPORTSNGMODELINTOALOCALVARIABLECALLEDNAMENGMODELMIRRORSMANYOFTHEPROPERTIESOFITSUNDERLYINGFORMCONTROLINSTANCESOYOUCANUSETHISINTHETEMPLATETOCHECKFORCONTROLSTATESSUCHASVALIDANDDIRTYFORAFULLLISTOFCONTROLPROPERTIESSEETHEABSTRACTCONTROLAPIFORMSABSTRACTCONTROLAPIREFERENCE", "original": "* `#name=\"ngModel\"` exports `NgModel` into a local variable called `name`. `NgModel` mirrors many of the properties of its underlying \n`FormControl` instance, so you can use this in the template to check for control states such as `valid` and `dirty`. For a full list of control properties, see the [AbstractControl](api/forms/AbstractControl) \nAPI reference.", "translation": "`#name=\"ngModel\"` 把 `NgModel` 导出成了一个名叫 `name` 的局部变量。`NgModel` 把自己控制的 `FormControl` 实例的属性映射出去,让你能在模板中检查控件的状态,比如 `valid` 和 `dirty`。要了解完整的控件属性,参见 API 参考手册中的[AbstractControl](api/forms/AbstractControl)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THENGIFONTHEDIVELEMENTREVEALSASETOFNESTEDMESSAGEDIVSBUTONLYIFTHENAMEISINVALIDANDTHECONTROLISEITHERDIRTYORTOUCHED", "original": "* The `*ngIf` on the `<div>` element reveals a set of nested message `divs`\nbut only if the `name` is invalid and the control is either `dirty` or `touched`.", "translation": "`<div>` 元素的 `*ngIf` 揭露了一套嵌套消息 `divs`,但是只在有“name”错误和控制器为 `dirty` 或者 `touched`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "EACHNESTEDDIVCANPRESENTACUSTOMMESSAGEFORONEOFTHEPOSSIBLEVALIDATIONERRORSTHEREAREMESSAGESFORREQUIREDMINLENGTHANDFORBIDDENNAME", "original": "* Each nested `<div>` can present a custom message for one of the possible validation errors.\nThere are messages for `required`, `minlength`, and `forbiddenName`.", "translation": "每个嵌套的 `<div>` 为其中一个可能出现的验证错误显示一条自定义消息。比如 `required`、`minlength` 和 `forbiddenName`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "####WHYCHECKDIRTYANDTOUCHED", "original": "#### Why check _dirty_ and _touched_?", "translation": "#### 为何检查 **dirty** 和 **touched**?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "YOUMAYNOTWANTYOURAPPLICATIONTODISPLAYERRORSBEFORETHEUSERHASACHANCETOEDITTHEFORMTHECHECKSFORDIRTYANDTOUCHEDPREVENTERRORSFROMSHOWINGUNTILTHEUSERDOESONEOFTWOTHINGS:CHANGESTHEVALUETURNINGTHECONTROLDIRTYORBLURSTHEFORMCONTROLELEMENTSETTINGTHECONTROLTOTOUCHED", "original": "You may not want your application to display errors before the user has a chance to edit the form.\nThe checks for `dirty` and `touched` prevent errors from showing until the user \ndoes one of two things: changes the value, \nturning the control dirty; or blurs the form control element, setting the control to touched.", "translation": "你肯定不希望应用在用户还没有编辑过表单的时候就给他们显示错误提示。\n对 `dirty` 和 `touched` 的检查可以避免这种问题。改变控件的值会改变控件的 `dirty`(脏)状态,而当控件失去焦点时,就会改变控件的 `touched`(碰过)状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "##REACTIVEFORMVALIDATION", "original": "## Reactive form validation", "translation": "## 响应式表单的验证", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "INAREACTIVEFORMTHESOURCEOFTRUTHISTHECOMPONENTCLASSINSTEADOFADDINGVALIDATORSTHROUGHATTRIBUTESINTHETEMPLATEYOUADDVALIDATORFUNCTIONSDIRECTLYTOTHEFORMCONTROLMODELINTHECOMPONENTCLASSANGULARTHENCALLSTHESEFUNCTIONSWHENEVERTHEVALUEOFTHECONTROLCHANGES", "original": "In a reactive form, the source of truth is the component class. Instead of adding validators through attributes in the template, you add validator functions directly to the form control model in the component class. Angular then calls these functions whenever the value of the control changes.", "translation": "在响应式表单中,真正的源码都在组件类中。不应该通过模板上的属性来添加验证器,而应该在组件类中直接把验证器函数添加到表单控件模型上(`FormControl`)。然后,一旦控件发生了变化,Angular 就会调用这些函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "###VALIDATORFUNCTIONS", "original": "### Validator functions", "translation": "### 验证器函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THEREARETWOTYPESOFVALIDATORFUNCTIONS:SYNCVALIDATORSANDASYNCVALIDATORS", "original": "There are two types of validator functions: sync validators and async validators.", "translation": "有两种验证器函数:同步验证器和异步验证器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "SYNCVALIDATORS:FUNCTIONSTHATTAKEACONTROLINSTANCEANDIMMEDIATELYRETURNEITHERASETOFVALIDATIONERRORSORNULLYOUCANPASSTHESEINASTHESECONDARGUMENTWHENYOUINSTANTIATEAFORMCONTROL", "original": "* **Sync validators**: functions that take a control instance and immediately return either a set of validation errors or `null`. You can pass these in as the second argument when you instantiate a `FormControl`.", "translation": "**同步验证器**函数接受一个控件实例,然后返回一组验证错误或 `null`。你可以在实例化一个 `FormControl` 时把它作为构造函数的第二个参数传进去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "ASYNCVALIDATORS:FUNCTIONSTHATTAKEACONTROLINSTANCEANDRETURNAPROMISEOROBSERVABLETHATLATEREMITSASETOFVALIDATIONERRORSORNULLYOUCANPASSTHESEINASTHETHIRDARGUMENTWHENYOUINSTANTIATEAFORMCONTROL", "original": "* **Async validators**: functions that take a control instance and return a Promise \nor Observable that later emits a set of validation errors or `null`. You can \npass these in as the third argument when you instantiate a `FormControl`.", "translation": "**异步验证器**函数接受一个控件实例,并返回一个承诺(Promise)或可观察对象(Observable),它们稍后会发出一组验证错误或者 `null`。你可以在实例化一个 `FormControl` 时把它作为构造函数的第三个参数传进去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "NOTE:FORPERFORMANCEREASONSANGULARONLYRUNSASYNCVALIDATORSIFALLSYNCVALIDATORSPASSEACHMUSTCOMPLETEBEFOREERRORSARESET", "original": "Note: for performance reasons, Angular only runs async validators if all sync validators pass. Each must complete before errors are set.", "translation": "注意:出于性能方面的考虑,只有在所有同步验证器都通过之后,Angular 才会运行异步验证器。当每一个异步验证器都执行完之后,才会设置这些验证错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "###BUILTINVALIDATORS", "original": "### Built-in validators", "translation": "### 内置验证器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "YOUCANCHOOSETOWRITEYOUROWNVALIDATORFUNCTIONSGUIDEFORMVALIDATION#CUSTOMVALIDATORSORYOUCANUSESOMEOFANGULARSBUILTINVALIDATORS", "original": "You can choose to [write your own validator functions](guide/form-validation#custom-validators), or you can use some of \nAngular's built-in validators.", "translation": "你可以[写自己的验证器](guide/form-validation#custom-validators),也可以使用一些 Angular 内置的验证器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THESAMEBUILTINVALIDATORSTHATAREAVAILABLEASATTRIBUTESINTEMPLATEDRIVENFORMSSUCHASREQUIREDANDMINLENGTHAREALLAVAILABLETOUSEASFUNCTIONSFROMTHEVALIDATORSCLASSFORAFULLLISTOFBUILTINVALIDATORSSEETHEVALIDATORSAPIFORMSVALIDATORSAPIREFERENCE", "original": "The same built-in validators that are available as attributes in template-driven forms, such as `required` and `minlength`, are all available to use as functions from the `Validators` class. For a full list of built-in validators, see the [Validators](api/forms/Validators) API reference.", "translation": "模板驱动表单中可用的那些属性型验证器(如 `required`、`minlength` 等)对应于 `Validators` 类中的同名函数。要想查看内置验证器的全列表,参见 API 参考手册中的[验证器](api/forms/Validators)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "TOUPDATETHEHEROFORMTOBEAREACTIVEFORMYOUCANUSESOMEOFTHESAMEBUILTINVALIDATORSMDASHTHISTIMEINFUNCTIONFORMSEEBELOW:", "original": "To update the hero form to be a reactive form, you can use some of the same \nbuilt-in validators—this time, in function form. See below:", "translation": "要想把这个英雄表单改造成一个响应式表单,你还是用那些内置验证器,但这次改为用它们的函数形态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "NOTETHAT:", "original": "Note that:", "translation": "注意", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THENAMECONTROLSETSUPTWOBUILTINVALIDATORSMDASHVALIDATORSREQUIREDANDVALIDATORSMINLENGTH4MDASHANDONECUSTOMVALIDATORFORBIDDENNAMEVALIDATORFORMOREDETAILSSEETHECUSTOMVALIDATORSGUIDEFORMVALIDATION#CUSTOMVALIDATORSSECTIONINTHISGUIDE", "original": "* The name control sets up two built-in validators—`Validators.required` and `Validators.minLength(4)`—and one custom validator, `forbiddenNameValidator`. For more details see the [Custom validators](guide/form-validation#custom-validators) section in this guide.", "translation": "`name` 控件设置了两个内置验证器:`Validators.required` 和 `Validators.minLength(4)`。要了解更多信息,参见本章的[自定义验证器](guide/form-validation#custom-validators)一节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "ASTHESEVALIDATORSAREALLSYNCVALIDATORSYOUPASSTHEMINASTHESECONDARGUMENT", "original": "* As these validators are all sync validators, you pass them in as the second argument.", "translation": "由于这些验证器都是同步验证器,因此你要把它们作为第二个参数传进去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "SUPPORTMULTIPLEVALIDATORSBYPASSINGTHEFUNCTIONSINASANARRAY", "original": "* Support multiple validators by passing the functions in as an array.", "translation": "可以通过把这些函数放进一个数组后传进去,可以支持多重验证器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THISEXAMPLEADDSAFEWGETTERMETHODSINAREACTIVEFORMYOUCANALWAYSACCESSANYFORMCONTROLTHROUGHTHEGETMETHODONITSPARENTGROUPBUTSOMETIMESITSUSEFULTODEFINEGETTERSASSHORTHANDSFORTHETEMPLATE", "original": "* This example adds a few getter methods. In a reactive form, you can always access any form control through the `get` method on its parent group, but sometimes it's useful to define getters as shorthands \nfor the template.", "translation": "这个例子添加了一些 getter 方法。在响应式表单中,你通常会通过它所属的控件组(FormGroup)的 `get` 方法来访问表单控件,但有时候为模板定义一些 getter 作为简短形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "IFYOULOOKATTHETEMPLATEFORTHENAMEINPUTAGAINITISFAIRLYSIMILARTOTHETEMPLATEDRIVENEXAMPLE", "original": "If you look at the template for the name input again, it is fairly similar to the template-driven example.", "translation": "如果你到模板中找到 name 输入框,就会发现它和模板驱动的例子很相似。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "KEYTAKEAWAYS:", "original": "Key takeaways:", "translation": "关键改动是:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THEFORMNOLONGEREXPORTSANYDIRECTIVESANDINSTEADUSESTHENAMEGETTERDEFINEDINTHECOMPONENTCLASS", "original": "* The form no longer exports any directives, and instead uses the `name` getter defined in \n the component class.", "translation": "该表单不再导出任何指令,而是使用组件类中定义的 `name` 读取器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THEREQUIREDATTRIBUTEISSTILLPRESENTWHILEITSNOTNECESSARYFORVALIDATIONPURPOSESYOUMAYWANTTOKEEPITINYOURTEMPLATEFORCSSSTYLINGORACCESSIBILITYREASONS", "original": "* The `required` attribute is still present. While it's not necessary for validation purposes, \n you may want to keep it in your template for CSS styling or accessibility reasons.", "translation": "`required` 属性仍然存在,虽然验证不再需要它,但你仍然要在模板中保留它,以支持 CSS 样式或可访问性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "##CUSTOMVALIDATORS", "original": "## Custom validators", "translation": "## 自定义验证器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "SINCETHEBUILTINVALIDATORSWONTALWAYSMATCHTHEEXACTUSECASEOFYOURAPPLICATIONSOMETIMESYOULLWANTTOCREATEACUSTOMVALIDATOR", "original": "Since the built-in validators won't always match the exact use case of your application, sometimes you'll want to create a custom validator.", "translation": "由于内置验证器无法适用于所有应用场景,有时候你还是得创建自定义验证器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "CONSIDERTHEFORBIDDENNAMEVALIDATORFUNCTIONFROMPREVIOUSEXAMPLESGUIDEFORMVALIDATION#REACTIVECOMPONENTCLASSINTHISGUIDEHERESWHATTHEDEFINITIONOFTHATFUNCTIONLOOKSLIKE:", "original": "Consider the `forbiddenNameValidator` function from previous\n[examples](guide/form-validation#reactive-component-class) in \nthis guide. Here's what the definition of that function looks like:", "translation": "考虑前面的[例子](guide/form-validation#reactive-component-class)中的 `forbiddenNameValidator` 函数。该函数的定义看起来是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THEFUNCTIONISACTUALLYAFACTORYTHATTAKESAREGULAREXPRESSIONTODETECTASPECIFICFORBIDDENNAMEANDRETURNSAVALIDATORFUNCTION", "original": "The function is actually a factory that takes a regular expression to detect a _specific_ forbidden name and returns a validator function.", "translation": "这个函数实际上是一个工厂,它接受一个用来检测指定名字是否已被禁用的正则表达式,并返回一个验证器函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "INTHISSAMPLETHEFORBIDDENNAMEISBOBSOTHEVALIDATORWILLREJECTANYHERONAMECONTAININGBOBELSEWHEREITCOULDREJECTALICEORANYNAMETHATTHECONFIGURINGREGULAREXPRESSIONMATCHES", "original": "In this sample, the forbidden name is \"bob\", so the validator will reject any hero name containing \"bob\".\nElsewhere it could reject \"alice\" or any name that the configuring regular expression matches.", "translation": "在本例中,禁止的名字是“bob”;\n验证器会拒绝任何带有“bob”的英雄名字。\n在其他地方,只要配置的正则表达式可以匹配上,它可能拒绝“alice”或者任何其他名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THEFORBIDDENNAMEVALIDATORFACTORYRETURNSTHECONFIGUREDVALIDATORFUNCTIONTHATFUNCTIONTAKESANANGULARCONTROLOBJECTANDRETURNSEITHERNULLIFTHECONTROLVALUEISVALIDORAVALIDATIONERROROBJECTTHEVALIDATIONERROROBJECTTYPICALLYHASAPROPERTYWHOSENAMEISTHEVALIDATIONKEYFORBIDDENNAMEANDWHOSEVALUEISANARBITRARYDICTIONARYOFVALUESTHATYOUCOULDINSERTINTOANERRORMESSAGENAME", "original": "The `forbiddenNameValidator` factory returns the configured validator function.\nThat function takes an Angular control object and returns _either_\nnull if the control value is valid _or_ a validation error object.\nThe validation error object typically has a property whose name is the validation key, `'forbiddenName'`,\nand whose value is an arbitrary dictionary of values that you could insert into an error message, `{name}`.", "translation": "`forbiddenNameValidator` 工厂函数返回配置好的验证器函数。\n该函数接受一个 Angular 控制器对象,并在控制器值有效时返回 null,或无效时返回验证错误对象。\n验证错误对象通常有一个名为验证秘钥(`forbiddenName`)的属性。其值为一个任意词典,你可以用来插入错误信息(`{name}`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "CUSTOMASYNCVALIDATORSARESIMILARTOSYNCVALIDATORSBUTTHEYMUSTINSTEADRETURNAPROMISEOROBSERVABLETHATLATEREMITSNULLORAVALIDATIONERROROBJECTINTHECASEOFANOBSERVABLETHEOBSERVABLEMUSTCOMPLETEATWHICHPOINTTHEFORMUSESTHELASTVALUEEMITTEDFORVALIDATION", "original": "Custom async validators are similar to sync validators, but they must instead return a Promise or Observable\nthat later emits null or a validation error object. In the case of an Observable, the Observable must complete,\nat which point the form uses the last value emitted for validation.", "translation": "自定义异步验证器和同步验证器很像,只是它们必须返回一个稍后会输出 null 或“验证错误对象”的承诺(Promise)或可观察对象,如果是可观察对象,那么它必须在某个时间点被完成(complete),那时候这个表单就会使用它输出的最后一个值作为验证结果。(译注:HTTP 服务是自动完成的,但是某些自定义的可观察对象可能需要手动调用 complete 方法)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "###ADDINGTOREACTIVEFORMS", "original": "### Adding to reactive forms", "translation": "### 添加响应式表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "INREACTIVEFORMSCUSTOMVALIDATORSAREFAIRLYSIMPLETOADDALLYOUHAVETODOISPASSTHEFUNCTIONDIRECTLYTOTHEFORMCONTROL", "original": "In reactive forms, custom validators are fairly simple to add. All you have to do is pass the function directly \nto the `FormControl`.", "translation": "在响应式表单组件中,添加自定义验证器相当简单。你所要做的一切就是直接把这个函数传给 `FormControl` 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "###ADDINGTOTEMPLATEDRIVENFORMS", "original": "### Adding to template-driven forms", "translation": "### 添加到模板驱动表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "INTEMPLATEDRIVENFORMSYOUDONTHAVEDIRECTACCESSTOTHEFORMCONTROLINSTANCESOYOUCANTPASSTHEVALIDATORINLIKEYOUCANFORREACTIVEFORMSINSTEADYOUNEEDTOADDADIRECTIVETOTHETEMPLATE", "original": "In template-driven forms, you don't have direct access to the `FormControl` instance, so you can't pass the \nvalidator in like you can for reactive forms. Instead, you need to add a directive to the template.", "translation": "在模板驱动表单中,你不用直接访问 `FormControl` 实例。所以不能像响应式表单中那样把验证器传进去,而应该在模板中添加一个指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THECORRESPONDINGFORBIDDENVALIDATORDIRECTIVESERVESASAWRAPPERAROUNDTHEFORBIDDENNAMEVALIDATOR", "original": "The corresponding `ForbiddenValidatorDirective` serves as a wrapper around the `forbiddenNameValidator`.", "translation": "`ForbiddenValidatorDirective` 指令相当于 `forbiddenNameValidator` 的包装器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "ANGULARRECOGNIZESTHEDIRECTIVESROLEINTHEVALIDATIONPROCESSBECAUSETHEDIRECTIVEREGISTERSITSELFWITHTHENGVALIDATORSPROVIDERAPROVIDERWITHANEXTENSIBLECOLLECTIONOFVALIDATORS", "original": "Angular recognizes the directive's role in the validation process because the directive registers itself\nwith the `NG_VALIDATORS` provider, a provider with an extensible collection of validators.", "translation": "Angular 在验证流程中的识别出指令的作用,是因为指令把自己注册到了 `NG_VALIDATORS` 提供商中,该提供商拥有一组可扩展的验证器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THEDIRECTIVECLASSTHENIMPLEMENTSTHEVALIDATORINTERFACESOTHATITCANEASILYINTEGRATEWITHANGULARFORMSHEREISTHERESTOFTHEDIRECTIVETOHELPYOUGETANIDEAOFHOWITALLCOMESTOGETHER:", "original": "The directive class then implements the `Validator` interface, so that it can easily integrate \nwith Angular forms. Here is the rest of the directive to help you get an idea of how it all \ncomes together:", "translation": "然后该指令类实现了 `Validator` 接口,以便它能简单的与 Angular 表单集成在一起。这个指令的其余部分有助于你理解它们是如何协作的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "ONCETHEFORBIDDENVALIDATORDIRECTIVEISREADYYOUCANSIMPLYADDITSSELECTORAPPFORBIDDENNAMETOANYINPUTELEMENTTOACTIVATEITFOREXAMPLE:", "original": "Once the `ForbiddenValidatorDirective` is ready, you can simply add its selector, `appForbiddenName`, to any input element to activate it. For example:", "translation": "一旦 `ForbiddenValidatorDirective` 写好了,你只要把 `forbiddenName` 选择器添加到输入框上就可以激活这个验证器了。比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "YOUMAYHAVENOTICEDTHATTHECUSTOMVALIDATIONDIRECTIVEISINSTANTIATEDWITHUSEEXISTINGRATHERTHANUSECLASSTHEREGISTEREDVALIDATORMUSTBETHISINSTANCEOFTHEFORBIDDENVALIDATORDIRECTIVEMDASHTHEINSTANCEINTHEFORMWITHITSFORBIDDENNAMEPROPERTYBOUNDTOBOBIFYOUWERETOREPLACEUSEEXISTINGWITHUSECLASSTHENYOUDBEREGISTERINGANEWCLASSINSTANCEONETHATDOESNTHAVEAFORBIDDENNAME", "original": "You may have noticed that the custom validation directive is instantiated with `useExisting`\nrather than `useClass`. The registered validator must be _this instance_ of\nthe `ForbiddenValidatorDirective`—the instance in the form with\nits `forbiddenName` property bound to “bob\". If you were to replace\n`useExisting` with `useClass`, then you’d be registering a new class instance, one that\ndoesn’t have a `forbiddenName`.", "translation": "你可能注意到了自定义验证器指令是用 `useExisting` 而不是 `useClass` 来实例化的。注册的验证器必须是这个 `ForbiddenValidatorDirective` 实例本身,也就是表单中 `forbiddenName` 属性被绑定到了\"bob\"的那个。如果用 `useClass` 来代替 `useExisting`,就会注册一个新的类实例,而它是没有 `forbiddenName` 的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "##CONTROLSTATUSCSSCLASSES", "original": "## Control status CSS classes", "translation": "## 表示控件状态的 CSS 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "LIKEINANGULARJSANGULARAUTOMATICALLYMIRRORSMANYCONTROLPROPERTIESONTOTHEFORMCONTROLELEMENTASCSSCLASSESYOUCANUSETHESECLASSESTOSTYLEFORMCONTROLELEMENTSACCORDINGTOTHESTATEOFTHEFORMTHEFOLLOWINGCLASSESARECURRENTLYSUPPORTED:", "original": "Like in AngularJS, Angular automatically mirrors many control properties onto the form control element as CSS classes. You can use these classes to style form control elements according to the state of the form. The following classes are currently supported:", "translation": "像 AngularJS 中一样,Angular 会自动把很多控件属性作为 CSS 类映射到控件所在的元素上。你可以使用这些类来根据表单状态给表单控件元素添加样式。目前支持下列类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "THEHEROFORMUSESTHENGVALIDANDNGINVALIDCLASSESTOSETTHECOLOROFEACHFORMCONTROLSBORDER", "original": "The hero form uses the `.ng-valid` and `.ng-invalid` classes to \nset the color of each form control's border.", "translation": "这个英雄表单使用 `.ng-valid` 和 `.ng-invalid` 来设置每个表单控件的边框颜色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "YOUCANRUNTHELIVEEXAMPLELIVEEXAMPLETOSEETHECOMPLETEREACTIVEANDTEMPLATEDRIVENEXAMPLECODE", "original": "**You can run the <live-example></live-example> to see the complete reactive and template-driven example code.**", "translation": "**你可以运行<live-example></live-example>来查看完整的响应式和模板驱动表单的代码。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/form-validation.md" }, { + "key": "#FORMS", "original": "# Forms", "translation": "# 表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "FORMSARETHEMAINSTAYOFBUSINESSAPPLICATIONSYOUUSEFORMSTOLOGINSUBMITAHELPREQUESTPLACEANORDERBOOKAFLIGHTSCHEDULEAMEETINGANDPERFORMCOUNTLESSOTHERDATAENTRYTASKS", "original": "Forms are the mainstay of business applications.\nYou use forms to log in, submit a help request, place an order, book a flight,\nschedule a meeting, and perform countless other data-entry tasks.", "translation": "表单是商业应用的支柱,你用它来执行登录、求助、下单、预订机票、安排会议,以及不计其数的其它数据录入任务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "INDEVELOPINGAFORMITSIMPORTANTTOCREATEADATAENTRYEXPERIENCETHATGUIDESTHEUSEREFFICIENTLYANDEFFECTIVELYTHROUGHTHEWORKFLOW", "original": "In developing a form, it's important to create a data-entry experience that guides the\nuser efficiently and effectively through the workflow.", "translation": "在开发表单时,创建数据方面的体验是非常重要的,它能指引用户明细、高效的完成工作流程。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "DEVELOPINGFORMSREQUIRESDESIGNSKILLSWHICHAREOUTOFSCOPEFORTHISPAGEASWELLASFRAMEWORKSUPPORTFORTWOWAYDATABINDINGCHANGETRACKINGVALIDATIONANDERRORHANDLINGWHICHYOULLLEARNABOUTONTHISPAGE", "original": "Developing forms requires design skills (which are out of scope for this page), as well as framework support for\n*two-way data binding, change tracking, validation, and error handling*,\nwhich you'll learn about on this page.", "translation": "开发表单需要设计能力(那超出了本章的范围),而框架支持*双向数据绑定、变更检测、验证和错误处理*,而本章你将会学到它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THISPAGESHOWSYOUHOWTOBUILDASIMPLEFORMFROMSCRATCHALONGTHEWAYYOULLLEARNHOWTO:", "original": "This page shows you how to build a simple form from scratch. Along the way you'll learn how to:", "translation": "这个页面演示了如何从草稿构建一个简单的表单。这个过程中你将学会如何:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "BUILDANANGULARFORMWITHACOMPONENTANDTEMPLATE", "original": "* Build an Angular form with a component and template.", "translation": "用组件和模板构建 Angular 表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "USENGMODELTOCREATETWOWAYDATABINDINGSFORREADINGANDWRITINGINPUTCONTROLVALUES", "original": "* Use `ngModel` to create two-way data bindings for reading and writing input-control values.", "translation": "用 `ngModel` 创建双向数据绑定,以读取和写入输入控件的值", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "TRACKSTATECHANGESANDTHEVALIDITYOFFORMCONTROLS", "original": "* Track state changes and the validity of form controls.", "translation": "跟踪状态的变化,并验证表单控件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "PROVIDEVISUALFEEDBACKUSINGSPECIALCSSCLASSESTHATTRACKTHESTATEOFTHECONTROLS", "original": "* Provide visual feedback using special CSS classes that track the state of the controls.", "translation": "使用特殊的 CSS 类来跟踪控件的状态并给出视觉反馈", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "DISPLAYVALIDATIONERRORSTOUSERSANDENABLEDISABLEFORMCONTROLS", "original": "* Display validation errors to users and enable/disable form controls.", "translation": "向用户显示验证错误提示,以及启用/禁用表单控件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "SHAREINFORMATIONACROSSHTMLELEMENTSUSINGTEMPLATEREFERENCEVARIABLES", "original": "* Share information across HTML elements using template reference variables.", "translation": "使用模板引用变量在 HTML 元素之间共享信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCANRUNTHELIVEEXAMPLELIVEEXAMPLEINSTACKBLITZANDDOWNLOADTHECODEFROMTHERE", "original": "You can run the <live-example></live-example> in Stackblitz and download the code from there.", - "translation": "运行<live-example></live-example>来试用本页的代码。", + "translation": "你可以运行<live-example></live-example>,在 Stackblitz 中试用并下载本页的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##TEMPLATEDRIVENFORMS", "original": "## Template-driven forms", "translation": "## 模板驱动表单 (template-driven forms)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCANBUILDFORMSBYWRITINGTEMPLATESINTHEANGULARTEMPLATESYNTAXGUIDETEMPLATESYNTAXWITHTHEFORMSPECIFICDIRECTIVESANDTECHNIQUESDESCRIBEDINTHISPAGE", "original": "You can build forms by writing templates in the Angular [template syntax](guide/template-syntax) with\nthe form-specific directives and techniques described in this page.", "translation": "通常,使用 Angular [模板语法](guide/template-syntax)编写模板,结合本章所描述的表单专用指令和技术来构建表单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCANALSOUSEAREACTIVEORMODELDRIVENAPPROACHTOBUILDFORMSHOWEVERTHISPAGEFOCUSESONTEMPLATEDRIVENFORMS", "original": "You can also use a reactive (or model-driven) approach to build forms.\n However, this page focuses on template-driven forms.", "translation": "你还可以使用响应式(也叫模型驱动)的方式来构建表单。不过本章中只介绍模板驱动表单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCANBUILDALMOSTANYFORMWITHANANGULARTEMPLATEMDASHLOGINFORMSCONTACTFORMSANDPRETTYMUCHANYBUSINESSFORMYOUCANLAYOUTTHECONTROLSCREATIVELYBINDTHEMTODATASPECIFYVALIDATIONRULESANDDISPLAYVALIDATIONERRORSCONDITIONALLYENABLEORDISABLESPECIFICCONTROLSTRIGGERBUILTINVISUALFEEDBACKANDMUCHMORE", "original": "You can build almost any form with an Angular template—login forms, contact forms, and pretty much any business form.\nYou can lay out the controls creatively, bind them to data, specify validation rules and display validation errors,\nconditionally enable or disable specific controls, trigger built-in visual feedback, and much more.", "translation": "利用 Angular 模板,可以构建几乎所有表单 — 登录表单、联系人表单…… 以及任何的商务表单。\n 可以创造性的摆放各种控件、把它们绑定到数据、指定校验规则、显示校验错误、有条件的禁用或\n 启用特定的控件、触发内置的视觉反馈等等,不胜枚举。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ANGULARMAKESTHEPROCESSEASYBYHANDLINGMANYOFTHEREPETITIVEBOILERPLATETASKSYOUDOTHERWISEWRESTLEWITHYOURSELF", "original": "Angular makes the process easy by handling many of the repetitive, boilerplate tasks you'd\notherwise wrestle with yourself.", "translation": "它用起来很简单,这是因为 Angular 处理了大多数重复、单调的任务,这让你可以不必亲自操刀、身陷其中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOULLLEARNTOBUILDATEMPLATEDRIVENFORMTHATLOOKSLIKETHIS:", "original": "You'll learn to build a template-driven form that looks like this:", "translation": "你将学习构建如下的“模板驱动”表单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEHEROEMPLOYMENTAGENCYUSESTHISFORMTOMAINTAINPERSONALINFORMATIONABOUTHEROESEVERYHERONEEDSAJOBITSTHECOMPANYMISSIONTOMATCHTHERIGHTHEROWITHTHERIGHTCRISIS", "original": "The *Hero Employment Agency* uses this form to maintain personal information about heroes.\nEvery hero needs a job. It's the company mission to match the right hero with the right crisis.", "translation": "这里是*英雄职业介绍所*,使用这个表单来维护候选英雄们的个人信息。每个英雄都需要一份工作。\n公司的使命就是让合适的英雄去应对恰当的危机!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "TWOOFTHETHREEFIELDSONTHISFORMAREREQUIREDREQUIREDFIELDSHAVEAGREENBARONTHELEFTTOMAKETHEMEASYTOSPOT", "original": "Two of the three fields on this form are required. Required fields have a green bar on the left to make them easy to spot.", "translation": "表单中的三个字段,其中两个是必填的。必填的字段在左侧有个绿色的竖条,方便用户分辨哪些是必填项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "IFYOUDELETETHEHERONAMETHEFORMDISPLAYSAVALIDATIONERRORINANATTENTIONGRABBINGSTYLE:", "original": "If you delete the hero name, the form displays a validation error in an attention-grabbing style:", "translation": "如果删除了英雄的名字,表单就会用醒目的样式把验证错误显示出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOTETHATTHESUBMITBUTTONISDISABLEDANDTHEREQUIREDBARTOTHELEFTOFTHEINPUTCONTROLCHANGESFROMGREENTORED", "original": "Note that the *Submit* button is disabled, and the \"required\" bar to the left of the input control changes from green to red.", "translation": "注意,提交按钮被禁用了,而且输入控件左侧的“必填”条从绿色变为了红色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCANCUSTOMIZETHECOLORSANDLOCATIONOFTHEREQUIREDBARWITHSTANDARDCSS", "original": "You can customize the colors and location of the \"required\" bar with standard CSS.", "translation": "稍后,会使用标准 CSS 来定制“必填”条的颜色和位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOULLBUILDTHISFORMINSMALLSTEPS:", "original": "You'll build this form in small steps:", "translation": "你将一点点构建出此表单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1CREATETHEHEROMODELCLASS", "original": "1. Create the `Hero` model class.", "translation": "创建 `Hero` 模型类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1CREATETHECOMPONENTTHATCONTROLSTHEFORM", "original": "1. Create the component that controls the form.", "translation": "创建控制此表单的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1CREATEATEMPLATEWITHTHEINITIALFORMLAYOUT", "original": "1. Create a template with the initial form layout.", "translation": "创建具有初始表单布局的模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1BINDDATAPROPERTIESTOEACHFORMCONTROLUSINGTHENGMODELTWOWAYDATABINDINGSYNTAX", "original": "1. Bind data properties to each form control using the `ngModel` two-way data-binding syntax.", "translation": "使用 `ngModel` 双向数据绑定语法把数据属性绑定到每个表单输入控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1ADDANAMEATTRIBUTETOEACHFORMINPUTCONTROL", "original": "1. Add a `name` attribute to each form-input control.", "translation": "往每个表单输入控件上添加 `name` 属性 (attribute)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1ADDCUSTOMCSSTOPROVIDEVISUALFEEDBACK", "original": "1. Add custom CSS to provide visual feedback.", "translation": "添加自定义 CSS 来提供视觉反馈。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1SHOWANDHIDEVALIDATIONERRORMESSAGES", "original": "1. Show and hide validation-error messages.", "translation": "显示和隐藏有效性验证的错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1HANDLEFORMSUBMISSIONWITHNGSUBMIT", "original": "1. Handle form submission with *ngSubmit*.", "translation": "使用 **ngSubmit** 处理表单提交。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1DISABLETHEFORMSSUBMITBUTTONUNTILTHEFORMISVALID", "original": "1. Disable the form’s *Submit* button until the form is valid.", "translation": "禁用此表单的提交按钮,直到表单变为有效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##SETUP", "original": "## Setup", "translation": "## 准备工作", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "CREATEANEWPROJECTNAMEDCODEANGULARFORMSCODE:", "original": "Create a new project named <code>angular-forms</code>:", "translation": "创建一个名为 <code>angular-forms</code> 的新项目:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##CREATETHEHEROMODELCLASS", "original": "## Create the Hero model class", "translation": "## 创建 Hero 模型类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ASUSERSENTERFORMDATAYOULLCAPTURETHEIRCHANGESANDUPDATEANINSTANCEOFAMODELYOUCANTLAYOUTTHEFORMUNTILYOUKNOWWHATTHEMODELLOOKSLIKE", "original": "As users enter form data, you'll capture their changes and update an instance of a model.\nYou can't lay out the form until you know what the model looks like.", "translation": "当用户输入表单数据时,需要捕获它们的变化,并更新到模型的实例中。\n除非知道模型里有什么,否则无法设计表单的布局。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "AMODELCANBEASSIMPLEASAPROPERTYBAGTHATHOLDSFACTSABOUTATHINGOFAPPLICATIONIMPORTANCETHATDESCRIBESWELLTHEHEROCLASSWITHITSTHREEREQUIREDFIELDSIDNAMEPOWERANDONEOPTIONALFIELDALTEREGO", "original": "A model can be as simple as a \"property bag\" that holds facts about a thing of application importance.\nThat describes well the `Hero` class with its three required fields (`id`, `name`, `power`)\nand one optional field (`alterEgo`).", "translation": "最简单的模型是个“属性包”,用来存放应用中一件事物的事实。\n这里使用三个必备字段 (`id`、`name`、`power`),和一个可选字段 (`alterEgo`,译注:中文含义是第二人格,例如 X 战警中的 Jean / 黑凤凰)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "USINGTHEANGULARCLIGENERATEANEWCLASSNAMEDHERO:", "original": "Using the Angular CLI, generate a new class named `Hero`:", "translation": "使用 Angular CLI 生成一个名叫 `Hero` 的新类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "WITHTHISCONTENT:", "original": "With this content:", "translation": "内容如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ITSANANEMICMODELWITHFEWREQUIREMENTSANDNOBEHAVIORPERFECTFORTHEDEMO", "original": "It's an anemic model with few requirements and no behavior. Perfect for the demo.", "translation": "这是一个少量需求和零行为的贫血模型。对演示来说很完美。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THETYPESCRIPTCOMPILERGENERATESAPUBLICFIELDFOREACHPUBLICCONSTRUCTORPARAMETERANDAUTOMATICALLYASSIGNSTHEPARAMETERSVALUETOTHATFIELDWHENYOUCREATEHEROES", "original": "The TypeScript compiler generates a public field for each `public` constructor parameter and\nautomatically assigns the parameter’s value to that field when you create heroes.", "translation": "TypeScript 编译器为每个 `public` 构造函数参数生成一个公共字段,在创建新的英雄实例时,自动把参数值赋给这些公共字段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEALTEREGOISOPTIONALSOTHECONSTRUCTORLETSYOUOMITITNOTETHEQUESTIONMARKINALTEREGO", "original": "The `alterEgo` is optional, so the constructor lets you omit it; note the question mark (?) in `alterEgo?`.", "translation": "`alterEgo` 是可选的,调用构造函数时可省略,注意 `alterEgo?` 中的问号 (?)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCANCREATEANEWHEROLIKETHIS:", "original": "You can create a new hero like this:", "translation": "可以这样创建新英雄:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##CREATEAFORMCOMPONENT", "original": "## Create a form component", "translation": "## 创建表单组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ANANGULARFORMHASTWOPARTS:ANHTMLBASEDTEMPLATEANDACOMPONENTCLASSTOHANDLEDATAANDUSERINTERACTIONSPROGRAMMATICALLYBEGINWITHTHECLASSBECAUSEITSTATESINBRIEFWHATTHEHEROEDITORCANDO", "original": "An Angular form has two parts: an HTML-based _template_ and a component _class_\nto handle data and user interactions programmatically.\nBegin with the class because it states, in brief, what the hero editor can do.", "translation": "Angular 表单分为两部分:基于 HTML 的*模板*和组件*类*,用来程序处理数据和用户交互。\n先从组件类开始,是因为它可以简要说明英雄编辑器能做什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "USINGTHEANGULARCLIGENERATEANEWCOMPONENTNAMEDHEROFORM:", "original": "Using the Angular CLI, generate a new component named `HeroForm`:", "translation": "使用 Angular CLI 生成一个名叫 `HeroForm` 的新组件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "WITHTHISCONTENT:", "original": "With this content:", "translation": "内容如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THERESNOTHINGSPECIALABOUTTHISCOMPONENTNOTHINGFORMSPECIFICNOTHINGTODISTINGUISHITFROMANYCOMPONENTYOUVEWRITTENBEFORE", "original": "There’s nothing special about this component, nothing form-specific,\nnothing to distinguish it from any component you've written before.", "translation": "这个组件没有什么特别的地方,没有表单相关的东西,与之前写过的组件没什么不同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "UNDERSTANDINGTHISCOMPONENTREQUIRESONLYTHEANGULARCONCEPTSCOVEREDINPREVIOUSPAGES", "original": "Understanding this component requires only the Angular concepts covered in previous pages.", "translation": "只需要前面章节中学过的概念,就可以完全理解这个组件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THECODEIMPORTSTHEANGULARCORELIBRARYANDTHEHEROMODELYOUJUSTCREATED", "original": "* The code imports the Angular core library and the `Hero` model you just created.", "translation": "这段代码导入了 Angular 核心库以及你刚刚创建的 `Hero` 模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THECOMPONENTSELECTORVALUEOFHEROFORMMEANSYOUCANDROPTHISFORMINAPARENTTEMPLATEWITHAHEROFORMTAG", "original": "* The `@Component` selector value of \"hero-form\" means you can drop this form in a parent template with a `<hero-form>` tag.", "translation": "`@Component` 选择器“hero-form”表示可以用 `<hero-form>` 标签把这个表单放进父模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THETEMPLATEURLPROPERTYPOINTSTOASEPARATEFILEFORTHETEMPLATEHTML", "original": "* The `templateUrl` property points to a separate file for the template HTML.", "translation": "`moduleId: module.id` 属性设置了基地址,用于从相对模块路径加载 `templateUrl`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUDEFINEDDUMMYDATAFORMODELANDPOWERSASBEFITSADEMO", "original": "* You defined dummy data for `model` and `powers`, as befits a demo.", "translation": "`templateUrl` 属性指向一个独立的 HTML 模板文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "DOWNTHEROADYOUCANINJECTADATASERVICETOGETANDSAVEREALDATAORPERHAPSEXPOSETHESEPROPERTIESASINPUTSANDOUTPUTSSEEINPUTANDOUTPUTPROPERTIESGUIDETEMPLATESYNTAX#INPUTSOUTPUTSONTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGEFORBINDINGTOAPARENTCOMPONENTTHISISNOTACONCERNNOWANDTHESEFUTURECHANGESWONTAFFECTTHEFORM", "original": "Down the road, you can inject a data service to get and save real data\nor perhaps expose these properties as inputs and outputs\n(see [Input and output properties](guide/template-syntax#inputs-outputs) on the\n[Template Syntax](guide/template-syntax) page) for binding to a\nparent component. This is not a concern now and these future changes won't affect the form.", "translation": "接下来,你可以注入一个数据服务,以获取或保存真实的数据,或者把这些属性暴露为输入属性和输出属性(参见[Template Syntax](guide/template-syntax)中的[输入和输出属性](guide/template-syntax#inputs-outputs))来绑定到一个父组件。这不是现在需要关心的问题,未来的更改不会影响到这个表单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUADDEDADIAGNOSTICPROPERTYTORETURNAJSONREPRESENTATIONOFTHEMODELITLLHELPYOUSEEWHATYOUREDOINGDURINGDEVELOPMENTYOUVELEFTYOURSELFACLEANUPNOTETODISCARDITLATER", "original": "* You added a `diagnostic` property to return a JSON representation of the model.\nIt'll help you see what you're doing during development; you've left yourself a cleanup note to discard it later.", "translation": "你添加一个 `diagnostic` 属性,以返回这个模型的 JSON 形式。在开发过程中,它用于调试,最后清理时会丢弃它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##REVISEAPPMODULETS", "original": "## Revise *app.module.ts*", "translation": "## 修改 *app.module.ts*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "APPMODULETSDEFINESTHEAPPLICATIONSROOTMODULEINITYOUIDENTIFYTHEEXTERNALMODULESYOULLUSEINTHEAPPLICATIONANDDECLARETHECOMPONENTSTHATBELONGTOTHISMODULESUCHASTHEHEROFORMCOMPONENT", "original": "`app.module.ts` defines the application's root module. In it you identify the external modules you'll use in the application\nand declare the components that belong to this module, such as the `HeroFormComponent`.", "translation": "`app.module.ts` 定义了应用的根模块。其中标识即将用到的外部模块,以及声明属于本模块中的组件,例如 `HeroFormComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "BECAUSETEMPLATEDRIVENFORMSAREINTHEIROWNMODULEYOUNEEDTOADDTHEFORMSMODULETOTHEARRAYOFIMPORTSFORTHEAPPLICATIONMODULEBEFOREYOUCANUSEFORMS", "original": "Because template-driven forms are in their own module, you need to add the `FormsModule` to the array of\n`imports` for the application module before you can use forms.", "translation": "因为模板驱动的表单位于它们自己的模块,所以在使用表单之前,需要将 `FormsModule` 添加到应用模块的 `imports` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "UPDATEITWITHTHEFOLLOWING:", "original": "Update it with the following:", "translation": "对它做如下修改:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEREARETWOCHANGES:", "original": "There are two changes:", "translation": "有两处更改", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1YOUIMPORTFORMSMODULE", "original": "1. You import `FormsModule`.", "translation": "导入 `FormsModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1YOUADDTHEFORMSMODULETOTHELISTOFIMPORTSDEFINEDINTHENGMODULEDECORATORTHISGIVESTHEAPPLICATIONACCESSTOALLOFTHETEMPLATEDRIVENFORMSFEATURESINCLUDINGNGMODEL", "original": "1. You add the `FormsModule` to the list of `imports` defined in the `@NgModule` decorator. This gives the application\n access to all of the template-driven forms features, including `ngModel`.", "translation": "把 `FormsModule` 添加到 `ngModule` 装饰器的 `imports` 列表中,这样应用就能访问模板驱动表单的所有特性,包括 `ngModel`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "IFACOMPONENTDIRECTIVEORPIPEBELONGSTOAMODULEINTHEIMPORTSARRAYDONTREDECLAREITINTHEDECLARATIONSARRAYIFYOUWROTEITANDITSHOULDBELONGTOTHISMODULEDODECLAREITINTHEDECLARATIONSARRAY", "original": "If a component, directive, or pipe belongs to a module in the `imports` array, ​_don't_​ re-declare it in the `declarations` array.\n If you wrote it and it should belong to this module, ​_do_​ declare it in the `declarations` array.", "translation": "如果某个组件、指令或管道是属于 `imports` 中所导入的某个模块的,那就*不能再*把它再声明到本模块的 `declarations` 数组中。\n如果它是你自己写的,并且确实属于当前模块,*才应该*把它声明在 `declarations` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##REVISEAPPCOMPONENTHTML", "original": "## Revise *app.component.html*", "translation": "## 修改 *app.component.ts*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "APPCOMPONENTISTHEAPPLICATIONSROOTCOMPONENTITWILLHOSTTHENEWHEROFORMCOMPONENT", "original": "`AppComponent` is the application's root component. It will host the new `HeroFormComponent`.", "translation": "`AppComponent` 是应用的根组件,`HeroFormComponent` 将被放在其中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "REPLACETHECONTENTSOFITSTEMPLATEWITHTHEFOLLOWING:", "original": "Replace the contents of its template with the following:", "translation": "把模板中的内容替换成如下代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEREAREONLYTWOCHANGESTHETEMPLATEISSIMPLYTHENEWELEMENTTAGIDENTIFIEDBYTHECOMPONENTSSELECTORPROPERTYTHISDISPLAYSTHEHEROFORMWHENTHEAPPLICATIONCOMPONENTISLOADEDDONTFORGETTOREMOVETHENAMEFIELDFROMTHECLASSBODYASWELL", "original": "There are only two changes.\n The `template` is simply the new element tag identified by the component's `selector` property.\n This displays the hero form when the application component is loaded.\n Don't forget to remove the `name` field from the class body as well.", "translation": "这里只做了两处修改。\n`template` 中只剩下这个新的元素标签,即组件的 `selector` 属性。这样当应用组件被加载时,就会显示这个英雄表单。\n同样别忘了从类中移除了 `name` 字段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##CREATEANINITIALHTMLFORMTEMPLATE", "original": "## Create an initial HTML form template", "translation": "## 创建初始 HTML 表单模板", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "UPDATETHETEMPLATEFILEWITHTHEFOLLOWINGCONTENTS:", "original": "Update the template file with the following contents:", "translation": "修改模板文件,内容如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THELANGUAGEISSIMPLYHTML5YOUREPRESENTINGTWOOFTHEHEROFIELDSNAMEANDALTEREGOANDOPENINGTHEMUPFORUSERINPUTININPUTBOXES", "original": "The language is simply HTML5. You're presenting two of the `Hero` fields, `name` and `alterEgo`, and\nopening them up for user input in input boxes.", "translation": "这只是一段普通的旧式 HTML 5 代码。这里有两个 `Hero` 字段,`name` 和 `alterEgo`,供用户输入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THENAMEINPUTCONTROLHASTHEHTML5REQUIREDATTRIBUTETHEALTEREGOINPUTCONTROLDOESNOTBECAUSEALTEREGOISOPTIONAL", "original": "The *Name* `<input>` control has the HTML5 `required` attribute;\nthe *Alter Ego* `<input>` control does not because `alterEgo` is optional.", "translation": "*Name* `<input>` 控件具有 HTML5 的 `required` 属性;但 *Alter Ego* `<input>` 控件没有,因为 `alterEgo` 字段是可选的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUADDEDASUBMITBUTTONATTHEBOTTOMWITHSOMECLASSESONITFORSTYLING", "original": "You added a *Submit* button at the bottom with some classes on it for styling.", "translation": "在底部添加个 *Submit* 按钮,它还带一些 CSS 样式类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOURENOTUSINGANGULARYETTHEREARENOBINDINGSOREXTRADIRECTIVESJUSTLAYOUT", "original": "*You're not using Angular yet*. There are no bindings or extra directives, just layout.", "translation": "**你还没有真正用到 Angular**。没有绑定,没有额外的指令,只有布局。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "INTEMPLATEDRIVENFORMSIFYOUVEIMPORTEDFORMSMODULEYOUDONTHAVETODOANYTHINGTOTHEFORMTAGINORDERTOMAKEUSEOFFORMSMODULECONTINUEONTOSEEHOWTHISWORKS", "original": "In template driven forms, if you've imported `FormsModule`, you don't have to do anything\n to the `<form>` tag in order to make use of `FormsModule`. Continue on to see how this works.", "translation": "在模板驱动表单中,你只要导入了 `FormsModule` 就不用对 `<form>` 做任何改动来使用 `FormsModule`。接下来你会看到它的原理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THECONTAINERFORMGROUPFORMCONTROLANDBTNCLASSESCOMEFROMTWITTERBOOTSTRAPHTTP:GETBOOTSTRAPCOMCSSTHESECLASSESAREPURELYCOSMETICBOOTSTRAPGIVESTHEFORMALITTLESTYLE", "original": "The `container`, `form-group`, `form-control`, and `btn` classes\ncome from [Twitter Bootstrap](http://getbootstrap.com/css/). These classes are purely cosmetic.\nBootstrap gives the form a little style.", "translation": "`container`、`form-group`、`form-control` 和 `btn` 类来自 [Twitter Bootstrap](http://getbootstrap.com/css/)。这些类纯粹是装饰品。\nBootstrap 为这个表单提供了一些样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "HEADERANGULARFORMSDONTREQUIREASTYLELIBRARYHEADER", "original": "<header>Angular forms don't require a style library</header>", "translation": "<header>Angular 表单不需要任何样式库</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ANGULARMAKESNOUSEOFTHECONTAINERFORMGROUPFORMCONTROLANDBTNCLASSESORTHESTYLESOFANYEXTERNALLIBRARYANGULARAPPSCANUSEANYCSSLIBRARYORNONEATALL", "original": "Angular makes no use of the `container`, `form-group`, `form-control`, and `btn` classes or\n the styles of any external library. Angular apps can use any CSS library or none at all.", "translation": "Angular 不需要 `container`、`form-group`、`form-control` 和 `btn` 类,\n或者外部库的任何样式。Angular 应用可以使用任何 CSS 库…… ,或者啥都不用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "TOADDTHESTYLESHEETOPENSTYLESCSSANDADDTHEFOLLOWINGIMPORTLINEATTHETOP:", "original": "To add the stylesheet, open `styles.css` and add the following import line at the top:", "translation": "要添加样式表,就打开 `index.html`,并把下列链接添加到 `<head>` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##ADDPOWERSWITHNGFOR", "original": "## Add powers with _*ngFor_", "translation": "## 用 ***ngFor*** 添加超能力", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEHEROMUSTCHOOSEONESUPERPOWERFROMAFIXEDLISTOFAGENCYAPPROVEDPOWERSYOUMAINTAINTHATLISTINTERNALLYINHEROFORMCOMPONENT", "original": "The hero must choose one superpower from a fixed list of agency-approved powers.\nYou maintain that list internally (in `HeroFormComponent`).", "translation": "英雄必须从认证过的固定列表中选择一项超能力。\n 这个列表位于 `HeroFormComponent` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOULLADDASELECTTOTHEFORMANDBINDTHEOPTIONSTOTHEPOWERSLISTUSINGNGFORATECHNIQUESEENPREVIOUSLYINTHEDISPLAYINGDATAGUIDEDISPLAYINGDATAPAGE", "original": "You'll add a `select` to the\nform and bind the options to the `powers` list using `ngFor`,\na technique seen previously in the [Displaying Data](guide/displaying-data) page.", "translation": "在表单中添加 `select`,用 `ngFor` 把 `powers` 列表绑定到列表选项。\n之前的[显示数据](guide/displaying-data)一章中见过 `ngFor`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ADDTHEFOLLOWINGHTMLIMMEDIATELYBELOWTHEALTEREGOGROUP:", "original": "Add the following HTML *immediately below* the *Alter Ego* group:", "translation": "在 *Alter Ego* 的紧下方添加如下 HTML:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THISCODEREPEATSTHEOPTIONTAGFOREACHPOWERINTHELISTOFPOWERSTHEPOWTEMPLATEINPUTVARIABLEISADIFFERENTPOWERINEACHITERATIONYOUDISPLAYITSNAMEUSINGTHEINTERPOLATIONSYNTAX", "original": "This code repeats the `<option>` tag for each power in the list of powers.\nThe `pow` template input variable is a different power in each iteration;\nyou display its name using the interpolation syntax.", "translation": "列表中的每一项超能力都会渲染成 `<option>` 标签。\n模板输入变量 `pow` 在每个迭代指向不同的超能力,使用双花括号插值表达式语法来显示它的名称。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##TWOWAYDATABINDINGWITHNGMODEL", "original": "## Two-way data binding with _ngModel_", "translation": "## 使用 *ngModel* 进行双向数据绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "RUNNINGTHEAPPRIGHTNOWWOULDBEDISAPPOINTING", "original": "Running the app right now would be disappointing.", "translation": "如果立即运行此应用,你将会失望。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUDONTSEEHERODATABECAUSEYOURENOTBINDINGTOTHEHEROYETYOUKNOWHOWTODOTHATFROMEARLIERPAGESDISPLAYINGDATAGUIDEDISPLAYINGDATATEACHESPROPERTYBINDINGUSERINPUTGUIDEUSERINPUTSHOWSHOWTOLISTENFORDOMEVENTSWITHANEVENTBINDINGANDHOWTOUPDATEACOMPONENTPROPERTYWITHTHEDISPLAYEDVALUE", "original": "You don't see hero data because you're not binding to the `Hero` yet.\nYou know how to do that from earlier pages.\n[Displaying Data](guide/displaying-data) teaches property binding.\n[User Input](guide/user-input) shows how to listen for DOM events with an\nevent binding and how to update a component property with the displayed value.", "translation": "因为还没有绑定到某个英雄,所以看不到任何数据。\n解决方案见前面的章节。\n[显示数据](guide/displaying-data)介绍了属性绑定。\n[用户输入](guide/user-input)介绍了如何通过事件绑定来监听 DOM 事件,以及如何用显示值更新组件的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOWYOUNEEDTODISPLAYLISTENANDEXTRACTATTHESAMETIME", "original": "Now you need to display, listen, and extract at the same time.", "translation": "现在,需要同时进行显示、监听和提取。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCOULDUSETHETECHNIQUESYOUALREADYKNOWBUTINSTEADYOULLUSETHENEWNGMODELSYNTAXWHICHMAKESBINDINGTHEFORMTOTHEMODELEASY", "original": "You could use the techniques you already know, but\ninstead you'll use the new `[(ngModel)]` syntax, which\nmakes binding the form to the model easy.", "translation": "虽然可以在表单中再次使用这些技术。\n但是,这里将介绍个新东西,`[(ngModel)]` 语法,使表单绑定到模型的工作变得超级简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "FINDTHEINPUTTAGFORNAMEANDUPDATEITLIKETHIS:", "original": "Find the `<input>` tag for *Name* and update it like this:", "translation": "找到 *Name* 对应的 `<input>` 标签,并且像这样修改它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUADDEDADIAGNOSTICINTERPOLATIONAFTERTHEINPUTTAGSOYOUCANSEEWHATYOUREDOINGYOULEFTYOURSELFANOTETOTHROWITAWAYWHENYOUREDONE", "original": "You added a diagnostic interpolation after the input tag\n so you can see what you're doing.\n You left yourself a note to throw it away when you're done.", "translation": "在 input 标签后添加用于诊断的插值表达式,以看清正在发生什么事。\n给自己留个备注,提醒你完成后移除它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "FOCUSONTHEBINDINGSYNTAX:NGMODEL", "original": "Focus on the binding syntax: `[(ngModel)]=\"...\"`.", "translation": "聚焦到绑定语法 `[(ngModel)]=\"...\"` 上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUNEEDONEMOREADDITIONTODISPLAYTHEDATADECLAREATEMPLATEVARIABLEFORTHEFORMUPDATETHEFORMTAGWITH#HEROFORMNGFORMASFOLLOWS:", "original": "You need one more addition to display the data. Declare\na template variable for the form. Update the `<form>` tag with\n`#heroForm=\"ngForm\"` as follows:", "translation": "你需要更多的工作来显示数据。在表单中声明一个模板变量。往 `<form>` 标签中加入 `#heroForm=\"ngForm\"`,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEVARIABLEHEROFORMISNOWAREFERENCETOTHENGFORMDIRECTIVETHATGOVERNSTHEFORMASAWHOLE", "original": "The variable `heroForm` is now a reference to the `NgForm` directive that governs the form as a whole.", "translation": "`heroForm` 变量是一个到 `NgForm` 指令的引用,它代表该表单的整体。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "###THENGFORMDIRECTIVE", "original": "### The _NgForm_ directive", "translation": "### *NgForm* 指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "WHATNGFORMDIRECTIVEYOUDIDNTADDANNGFORMAPIFORMSNGFORMDIRECTIVE", "original": "What `NgForm` directive?\n You didn't add an [NgForm](api/forms/NgForm) directive.", "translation": "什么是 `NgForm` 指令?\n但你明明没有添加过[NgForm](api/forms/NgForm)指令啊!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ANGULARDIDANGULARAUTOMATICALLYCREATESANDATTACHESANNGFORMDIRECTIVETOTHEFORMTAG", "original": "Angular did. Angular automatically creates and attaches an `NgForm` directive to the `<form>` tag.", "translation": "Angular 替你做了。Angular 会在 `<form>` 标签上自动创建并附加一个 `NgForm` 指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THENGFORMDIRECTIVESUPPLEMENTSTHEFORMELEMENTWITHADDITIONALFEATURESITHOLDSTHECONTROLSYOUCREATEDFORTHEELEMENTSWITHANNGMODELDIRECTIVEANDNAMEATTRIBUTEANDMONITORSTHEIRPROPERTIESINCLUDINGTHEIRVALIDITYITALSOHASITSOWNVALIDPROPERTYWHICHISTRUEONLYIFEVERYCONTAINEDCONTROLISVALID", "original": "The `NgForm` directive supplements the `form` element with additional features.\n It holds the controls you created for the elements with an `ngModel` directive\n and `name` attribute, and monitors their properties, including their validity.\n It also has its own `valid` property which is true only *if every contained\n control* is valid.", "translation": "`NgForm` 指令为 `form` 增补了一些额外特性。\n它会控制那些带有 `ngModel` 指令和 `name` 属性的元素,监听他们的属性(包括其有效性)。\n它还有自己的 `valid` 属性,这个属性只有在*它包含的每个控件*都有效时才是真。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "IFYOURANTHEAPPNOWANDSTARTEDTYPINGINTHENAMEINPUTBOXADDINGANDDELETINGCHARACTERSYOUDSEETHEMAPPEARANDDISAPPEARFROMTHEINTERPOLATEDTEXTATSOMEPOINTITMIGHTLOOKLIKETHIS:", "original": "If you ran the app now and started typing in the *Name* input box,\nadding and deleting characters, you'd see them appear and disappear\nfrom the interpolated text.\nAt some point it might look like this:", "translation": "如果现在运行这个应用,开始在*姓名*输入框中键入,添加和删除字符,将看到它们从插值结果中显示和消失。\n某一瞬间,它可能是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEDIAGNOSTICISEVIDENCETHATVALUESREALLYAREFLOWINGFROMTHEINPUTBOXTOTHEMODELANDBACKAGAIN", "original": "The diagnostic is evidence that values really are flowing from the input box to the model and\nback again.", "translation": "诊断信息可以证明,数据确实从输入框流动到模型,再反向流动回来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THATSTWOWAYDATABINDINGFORMOREINFORMATIONSEETWOWAYBINDINGWITHNGMODELGUIDETEMPLATESYNTAX#NGMODELONTHETHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "That's *two-way data binding*.\n For more information, see\n [Two-way binding with NgModel](guide/template-syntax#ngModel) on the\n the [Template Syntax](guide/template-syntax) page.", "translation": "**这就是双向数据绑定!**要了解更多信息,参见[模板语法](guide/template-syntax)页的[使用 NgModel 进行双向绑定](guide/template-syntax#ngModel)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOTICETHATYOUALSOADDEDANAMEATTRIBUTETOTHEINPUTTAGANDSETITTONAMEWHICHMAKESSENSEFORTHEHEROSNAMEANYUNIQUEVALUEWILLDOBUTUSINGADESCRIPTIVENAMEISHELPFULDEFININGANAMEATTRIBUTEISAREQUIREMENTWHENUSINGNGMODELINCOMBINATIONWITHAFORM", "original": "Notice that you also added a `name` attribute to the `<input>` tag and set it to \"name\",\nwhich makes sense for the hero's name. Any unique value will do, but using a descriptive name is helpful.\nDefining a `name` attribute is a requirement when using `[(ngModel)]` in combination with a form.", "translation": "注意,`<input>` 标签还添加了 `name` 属性 (attribute),并设置为 \"name\",表示英雄的名字。\n使用任何唯一的值都可以,但使用具有描述性的名字会更有帮助。\n当在表单中使用 `[(ngModel)]` 时,必须要定义 `name` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "INTERNALLYANGULARCREATESFORMCONTROLINSTANCESANDREGISTERSTHEMWITHANNGFORMDIRECTIVETHATANGULARATTACHEDTOTHEFORMTAGEACHFORMCONTROLISREGISTEREDUNDERTHENAMEYOUASSIGNEDTOTHENAMEATTRIBUTEREADMOREINTHEPREVIOUSSECTIONTHENGFORMDIRECTIVEGUIDEFORMS#NGFORM", "original": "Internally, Angular creates `FormControl` instances and\n registers them with an `NgForm` directive that Angular attached to the `<form>` tag.\n Each `FormControl` is registered under the name you assigned to the `name` attribute.\n Read more in the previous section, [The NgForm directive](guide/forms#ngForm).", "translation": "在内部,Angular 创建了一些 `FormControl`,并把它们注册到 `NgForm` 指令,再将该指令附加到 `<form>` 标签。\n注册每个 `FormControl` 时,使用 `name` 属性值作为键值。[本章后面](guide/forms#ngForm)会讨论 `NgForm`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ADDSIMILARNGMODELBINDINGSANDNAMEATTRIBUTESTOALTEREGOANDHEROPOWERYOULLDITCHTHEINPUTBOXBINDINGMESSAGEANDADDANEWBINDINGATTHETOPTOTHECOMPONENTSDIAGNOSTICPROPERTYTHENYOUCANCONFIRMTHATTWOWAYDATABINDINGWORKSFORTHEENTIREHEROMODEL", "original": "Add similar `[(ngModel)]` bindings and `name` attributes to *Alter Ego* and *Hero Power*.\nYou'll ditch the input box binding message\nand add a new binding (at the top) to the component's `diagnostic` property.\nThen you can confirm that two-way data binding works *for the entire hero model*.", "translation": "为*第二人格*和*超能力*属性添加类似的 `[(ngModel)]` 绑定和 `name` 属性。\n抛弃输入框的绑定消息,在组件顶部添加到 `diagnostic` 属性的新绑定。\n这样就能确认双向数据绑定*在整个 Hero 模型上*都能正常工作了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "AFTERREVISIONTHECOREOFTHEFORMSHOULDLOOKLIKETHIS:", "original": "After revision, the core of the form should look like this:", "translation": "修改之后,这个表单的核心是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "EACHINPUTELEMENTHASANIDPROPERTYTHATISUSEDBYTHELABELELEMENTSFORATTRIBUTETOMATCHTHELABELTOITSINPUTCONTROL", "original": "* Each input element has an `id` property that is used by the `label` element's `for` attribute\n to match the label to its input control.", "translation": "每个 input 元素都有 `id` 属性,`label` 元素的 `for` 属性用它来匹配到对应的输入控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "EACHINPUTELEMENTHASANAMEPROPERTYTHATISREQUIREDBYANGULARFORMSTOREGISTERTHECONTROLWITHTHEFORM", "original": "* Each input element has a `name` property that is required by Angular forms to register the control with the form.", "translation": "每个 input 元素都有 `name` 属性,Angular 表单用它注册控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "IFYOURUNTHEAPPNOWANDCHANGEEVERYHEROMODELPROPERTYTHEFORMMIGHTDISPLAYLIKETHIS:", "original": "If you run the app now and change every hero model property, the form might display like this:", "translation": "如果现在运行本应用,修改 Hero 模型的每个属性,表单是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEDIAGNOSTICNEARTHETOPOFTHEFORMCONFIRMSTHATALLOFYOURCHANGESAREREFLECTEDINTHEMODEL", "original": "The diagnostic near the top of the form\nconfirms that all of your changes are reflected in the model.", "translation": "表单顶部的诊断信息反映出所做的一切更改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "DELETETHEDIAGNOSTICBINDINGATTHETOPASITHASSERVEDITSPURPOSE", "original": "*Delete* the `{{diagnostic}}` binding at the top as it has served its purpose.", "translation": "表单顶部的 `{{diagnostic}}` 绑定已经完成了它的使命,**删除**它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##TRACKCONTROLSTATEANDVALIDITYWITHNGMODEL", "original": "## Track control state and validity with _ngModel_", "translation": "## 通过 **ngModel** 跟踪修改状态与有效性验证", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "USINGNGMODELINAFORMGIVESYOUMORETHANJUSTTWOWAYDATABINDINGITALSOTELLSYOUIFTHEUSERTOUCHEDTHECONTROLIFTHEVALUECHANGEDORIFTHEVALUEBECAMEINVALID", "original": "Using `ngModel` in a form gives you more than just two-way data binding. It also tells\nyou if the user touched the control, if the value changed, or if the value became invalid.", "translation": "在表单中使用 `ngModel` 可以获得比仅使用双向数据绑定更多的控制权。它还会告诉你很多信息:用户碰过此控件吗?它的值变化了吗?数据变得无效了吗?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THENGMODELDIRECTIVEDOESNTJUSTTRACKSTATEITUPDATESTHECONTROLWITHSPECIALANGULARCSSCLASSESTHATREFLECTTHESTATEYOUCANLEVERAGETHOSECLASSNAMESTOCHANGETHEAPPEARANCEOFTHECONTROL", "original": "The *NgModel* directive doesn't just track state; it updates the control with special Angular CSS classes that reflect the state.\nYou can leverage those class names to change the appearance of the control.", "translation": "*NgModel* 指令不仅仅跟踪状态。它还使用特定的 Angular CSS 类来更新控件,以反映当前状态。\n可以利用这些 CSS 类来修改控件的外观,显示或隐藏消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "STATE", "original": "State", "translation": "状态", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "CLASSIFTRUE", "original": "Class if true", "translation": "为真时的 CSS 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "CLASSIFFALSE", "original": "Class if false", "translation": "为假时的 CSS 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THECONTROLHASBEENVISITED", "original": "The control has been visited.", "translation": "控件被访问过。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THECONTROLSVALUEHASCHANGED", "original": "The control's value has changed.", "translation": "控件的值变化了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THECONTROLSVALUEISVALID", "original": "The control's value is valid.", "translation": "控件的值有效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "TEMPORARILYADDATEMPLATEREFERENCEVARIABLEGUIDETEMPLATESYNTAX#REFVARSNAMEDSPYTOTHENAMEINPUTTAGANDUSEITTODISPLAYTHEINPUTSCSSCLASSES", "original": "Temporarily add a [template reference variable](guide/template-syntax#ref-vars) named `spy`\nto the _Name_ `<input>` tag and use it to display the input's CSS classes.", "translation": "往姓名 `<input>` 标签上添加名叫 **spy** 的临时[模板引用变量](guide/template-syntax#ref-vars),\n然后用这个 spy 来显示它上面的所有 CSS 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOWRUNTHEAPPANDLOOKATTHENAMEINPUTBOXFOLLOWTHESESTEPSPRECISELY:", "original": "Now run the app and look at the _Name_ input box.\nFollow these steps *precisely*:", "translation": "现在,运行本应用,并让*姓名*输入框获得焦点。\n然后严格按照下面四个步骤来做:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1LOOKBUTDONTTOUCH", "original": "1. Look but don't touch.", "translation": "查看输入框,但别碰它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1CLICKINSIDETHENAMEBOXTHENCLICKOUTSIDEIT", "original": "1. Click inside the name box, then click outside it.", "translation": "点击输入框,然后点击输入框外面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1ADDSLASHESTOTHEENDOFTHENAME", "original": "1. Add slashes to the end of the name.", "translation": "在名字的末尾添加些斜杠。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1ERASETHENAME", "original": "1. Erase the name.", "translation": "删除名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEACTIONSANDEFFECTSAREASFOLLOWS:", "original": "The actions and effects are as follows:", "translation": "动作和它对应的效果如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUSHOULDSEETHEFOLLOWINGTRANSITIONSANDCLASSNAMES:", "original": "You should see the following transitions and class names:", "translation": "你会看到下列转换及其类名:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THENGVALIDNGINVALIDPAIRISTHEMOSTINTERESTINGBECAUSEYOUWANTTOSENDASTRONGVISUALSIGNALWHENTHEVALUESAREINVALIDYOUALSOWANTTOMARKREQUIREDFIELDSTOCREATESUCHVISUALFEEDBACKADDDEFINITIONSFORTHENGCSSCLASSES", "original": "The `ng-valid`/`ng-invalid` pair is the most interesting, because you want to send a\nstrong visual signal when the values are invalid. You also want to mark required fields.\nTo create such visual feedback, add definitions for the `ng-*` CSS classes.", "translation": "(`ng-valid` | `ng-invalid`)这一对是最有趣的部分,因为当数据变得无效时,你希望发出强力的视觉信号,\n还想要标记出必填字段。可以通过加入自定义 CSS 来提供视觉反馈。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "DELETETHE#SPYTEMPLATEREFERENCEVARIABLEANDTHETODOASTHEYHAVESERVEDTHEIRPURPOSE", "original": "*Delete* the `#spy` template reference variable and the `TODO` as they have served their purpose.", "translation": "**删除**模板引用变量 `#spy` 和 `TODO`,因为它们已经完成了使命。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##ADDCUSTOMCSSFORVISUALFEEDBACK", "original": "## Add custom CSS for visual feedback", "translation": "## 添加用于视觉反馈的自定义 CSS", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCANMARKREQUIREDFIELDSANDINVALIDDATAATTHESAMETIMEWITHACOLOREDBARONTHELEFTOFTHEINPUTBOX:", "original": "You can mark required fields and invalid data at the same time with a colored bar\non the left of the input box:", "translation": "可以在输入框的左侧添加带颜色的竖条,用于标记必填字段和无效输入:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUACHIEVETHISEFFECTBYADDINGTHESECLASSDEFINITIONSTOANEWFORMSCSSFILETHATYOUADDTOTHEPROJECTASASIBLINGTOINDEXHTML:", "original": "You achieve this effect by adding these class definitions to a new `forms.css` file\nthat you add to the project as a sibling to `index.html`:", "translation": "在新建的 `forms.css` 文件中,添加两个样式来实现这一效果。把这个文件添加到项目中,与 `index.html` 相邻。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "UPDATETHEHEADOFINDEXHTMLTOINCLUDETHISSTYLESHEET:", "original": "Update the `<head>` of `index.html` to include this style sheet:", "translation": "修改 `index.html` 中的 `<head>`,以包含这个样式表:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##SHOWANDHIDEVALIDATIONERRORMESSAGES", "original": "## Show and hide validation error messages", "translation": "## 显示和隐藏验证错误信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCANIMPROVETHEFORMTHENAMEINPUTBOXISREQUIREDANDCLEARINGITTURNSTHEBARREDTHATSAYSSOMETHINGISWRONGBUTTHEUSERDOESNTKNOWWHATISWRONGORWHATTODOABOUTITLEVERAGETHECONTROLSSTATETOREVEALAHELPFULMESSAGE", "original": "You can improve the form. The _Name_ input box is required and clearing it turns the bar red.\nThat says something is wrong but the user doesn't know *what* is wrong or what to do about it.\nLeverage the control's state to reveal a helpful message.", "translation": "你还能做的更好。“Name” 输入框是必填的,清空它会让左侧的条变红。这表示*某些东西*是错的,但用户不知道错在哪里,或者如何纠正。\n 可以借助 `ng-invalid` 类来给出有用的提示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "WHENTHEUSERDELETESTHENAMETHEFORMSHOULDLOOKLIKETHIS:", "original": "When the user deletes the name, the form should look like this:", "translation": "当用户删除姓名时,应该是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "TOACHIEVETHISEFFECTEXTENDTHEINPUTTAGWITHTHEFOLLOWING:", "original": "To achieve this effect, extend the `<input>` tag with the following:", "translation": "要达到这个效果,在 `<input>` 标签中添加:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ATEMPLATEREFERENCEVARIABLEGUIDETEMPLATESYNTAX#REFVARS", "original": "* A [template reference variable](guide/template-syntax#ref-vars).", "translation": "[模板引用变量](guide/template-syntax#ref-vars)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEISREQUIREDMESSAGEINANEARBYDIVWHICHYOULLDISPLAYONLYIFTHECONTROLISINVALID", "original": "* The \"*is required*\" message in a nearby `<div>`, which you'll display only if the control is invalid.", "translation": "“is required”消息,放在邻近的 `<div>` 元素中,只有当控件无效时,才显示它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "HERESANEXAMPLEOFANERRORMESSAGEADDEDTOTHENAMEINPUTBOX:", "original": "Here's an example of an error message added to the _name_ input box:", "translation": "下面这个例子中把一条错误信息添加到了`name`输入框中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUNEEDATEMPLATEREFERENCEVARIABLETOACCESSTHEINPUTBOXSANGULARCONTROLFROMWITHINTHETEMPLATEHEREYOUCREATEDAVARIABLECALLEDNAMEANDGAVEITTHEVALUENGMODEL", "original": "You need a template reference variable to access the input box's Angular control from within the template.\nHere you created a variable called `name` and gave it the value \"ngModel\".", "translation": "模板引用变量可以访问模板中输入框的 Angular 控件。\n这里,创建了名叫 `name` 的变量,并且赋值为 \"ngModel\"。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "WHYNGMODELADIRECTIVESEXPORTASAPICOREDIRECTIVEPROPERTYTELLSANGULARHOWTOLINKTHEREFERENCEVARIABLETOTHEDIRECTIVEYOUSETNAMETONGMODELBECAUSETHENGMODELDIRECTIVESEXPORTASPROPERTYHAPPENSTOBENGMODEL", "original": "Why \"ngModel\"?\n A directive's [exportAs](api/core/Directive) property\n tells Angular how to link the reference variable to the directive.\n You set `name` to `ngModel` because the `ngModel` directive's `exportAs` property happens to be \"ngModel\".", "translation": "为什么是 “ngModel”?\n指令的 [exportAs](api/core/Directive) 属性告诉 Angular 如何链接模板引用变量到指令。\n这里把 `name` 设置为 `ngModel` 是因为 `ngModel` 指令的 `exportAs` 属性设置成了 “ngModel”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUCONTROLVISIBILITYOFTHENAMEERRORMESSAGEBYBINDINGPROPERTIESOFTHENAMECONTROLTOTHEMESSAGEDIVELEMENTSHIDDENPROPERTY", "original": "You control visibility of the name error message by binding properties of the `name`\ncontrol to the message `<div>` element's `hidden` property.", "translation": "你把 `div` 元素的 `hidden` 属性绑定到 `name` 控件的属性,这样就可以控制“姓名”字段错误信息的可见性了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "INTHISEXAMPLEYOUHIDETHEMESSAGEWHENTHECONTROLISVALIDORPRISTINEPRISTINEMEANSTHEUSERHASNTCHANGEDTHEVALUESINCEITWASDISPLAYEDINTHISFORM", "original": "In this example, you hide the message when the control is valid or pristine;\n\"pristine\" means the user hasn't changed the value since it was displayed in this form.", "translation": "上例中,当控件是有效的 (valid) 或全新的 (pristine) 时,隐藏消息。\n“全新的”意味着从它被显示在表单中开始,用户还从未修改过它的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THISUSEREXPERIENCEISTHEDEVELOPERSCHOICESOMEDEVELOPERSWANTTHEMESSAGETODISPLAYATALLTIMESIFYOUIGNORETHEPRISTINESTATEYOUWOULDHIDETHEMESSAGEONLYWHENTHEVALUEISVALIDIFYOUARRIVEINTHISCOMPONENTWITHANEWBLANKHEROORANINVALIDHEROYOULLSEETHEERRORMESSAGEIMMEDIATELYBEFOREYOUVEDONEANYTHING", "original": "This user experience is the developer's choice. Some developers want the message to display at all times.\nIf you ignore the `pristine` state, you would hide the message only when the value is valid.\nIf you arrive in this component with a new (blank) hero or an invalid hero,\nyou'll see the error message immediately, before you've done anything.", "translation": "这种用户体验取决于开发人员的选择。有些人会希望任何时候都显示这条消息。\n如果忽略了 `pristine` 状态,就会只在值有效时隐藏此消息。\n如果往这个组件中传入全新(空)的英雄,或者无效的英雄,将立刻看到错误信息 —— 虽然你还啥都没做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "SOMEDEVELOPERSWANTTHEMESSAGETODISPLAYONLYWHENTHEUSERMAKESANINVALIDCHANGEHIDINGTHEMESSAGEWHILETHECONTROLISPRISTINEACHIEVESTHATGOALYOULLSEETHESIGNIFICANCEOFTHISCHOICEWHENYOUADDANEWHEROTOTHEFORM", "original": "Some developers want the message to display only when the user makes an invalid change.\nHiding the message while the control is \"pristine\" achieves that goal.\nYou'll see the significance of this choice when you add a new hero to the form.", "translation": "有些人会为这种行为感到不安。它们希望只有在用户做出无效的更改时才显示这个消息。\n如果当控件是“全新”状态时也隐藏消息,就能达到这个目的。\n在往表单中添加新英雄时,将看到这种选择的重要性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEHEROALTEREGOISOPTIONALSOYOUCANLEAVETHATBE", "original": "The hero *Alter Ego* is optional so you can leave that be.", "translation": "英雄的*第二人格*是可选项,所以不用改它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "HEROPOWERSELECTIONISREQUIREDYOUCANADDTHESAMEKINDOFERRORHANDLINGTOTHESELECTIFYOUWANTBUTITSNOTIMPERATIVEBECAUSETHESELECTIONBOXALREADYCONSTRAINSTHEPOWERTOVALIDVALUES", "original": "Hero *Power* selection is required.\nYou can add the same kind of error handling to the `<select>` if you want,\nbut it's not imperative because the selection box already constrains the\npower to valid values.", "translation": "英雄的*超能力*选项是必填的。\n 只要愿意,可以往 `<select>` 上添加相同的错误处理。\n 但没有必要,这个选择框已经限制了“超能力”只能选有效值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOWYOULLADDANEWHEROINTHISFORMPLACEANEWHEROBUTTONATTHEBOTTOMOFTHEFORMANDBINDITSCLICKEVENTTOANEWHEROCOMPONENTMETHOD", "original": "Now you'll add a new hero in this form.\nPlace a *New Hero* button at the bottom of the form and bind its click event to a `newHero` component method.", "translation": "现在,你要在这个表单中添加新的英雄。\n 在表单的底部放置“New Hero(新增英雄)”按钮,并把它的点击事件绑定到 `newHero` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "RUNTHEAPPLICATIONAGAINCLICKTHENEWHEROBUTTONANDTHEFORMCLEARSTHEREQUIREDBARSTOTHELEFTOFTHEINPUTBOXAREREDINDICATINGINVALIDNAMEANDPOWERPROPERTIESTHATSUNDERSTANDABLEASTHESEAREREQUIREDFIELDSTHEERRORMESSAGESAREHIDDENBECAUSETHEFORMISPRISTINEYOUHAVENTCHANGEDANYTHINGYET", "original": "Run the application again, click the *New Hero* button, and the form clears.\nThe *required* bars to the left of the input box are red, indicating invalid `name` and `power` properties.\nThat's understandable as these are required fields.\nThe error messages are hidden because the form is pristine; you haven't changed anything yet.", "translation": "再次运行应用,点击 *New Hero* 按钮,表单被清空了。\n输入框左侧的*必填项*竖条是红色的,表示 `name` 和 `power` 属性是无效的。\n这可以理解,因为有一些必填字段。\n错误信息是隐藏的,因为表单还是全新的,还没有修改任何东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ENTERANAMEANDCLICKNEWHEROAGAINTHEAPPDISPLAYSANAMEISREQUIREDERRORMESSAGEYOUDONTWANTERRORMESSAGESWHENYOUCREATEANEWEMPTYHEROWHYAREYOUGETTINGONENOW", "original": "Enter a name and click *New Hero* again.\nThe app displays a _Name is required_ error message.\nYou don't want error messages when you create a new (empty) hero.\nWhy are you getting one now?", "translation": "输入名字,再次点击 *New Hero* 按钮。\n这次,出现了错误信息!为什么?你不希望显示新(空)的英雄时,出现错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "INSPECTINGTHEELEMENTINTHEBROWSERTOOLSREVEALSTHATTHENAMEINPUTBOXISNOLONGERPRISTINETHEFORMREMEMBERSTHATYOUENTEREDANAMEBEFORECLICKINGNEWHEROREPLACINGTHEHEROOBJECTDIDNOTRESTORETHEPRISTINESTATEOFTHEFORMCONTROLS", "original": "Inspecting the element in the browser tools reveals that the *name* input box is _no longer pristine_.\nThe form remembers that you entered a name before clicking *New Hero*.\nReplacing the hero object *did not restore the pristine state* of the form controls.", "translation": "使用浏览器工具审查这个元素就会发现,这个 *name* 输入框并不是全新的。\n表单记得你在点击 *New Hero* 前输入的名字。\n更换了英雄对象*并不会重置控件的“全新”状态*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUHAVETOCLEARALLOFTHEFLAGSIMPERATIVELYWHICHYOUCANDOBYCALLINGTHEFORMSRESETMETHODAFTERCALLINGTHENEWHEROMETHOD", "original": "You have to clear all of the flags imperatively, which you can do\nby calling the form's `reset()` method after calling the `newHero()` method.", "translation": "你必须清除所有标记,在调用 `newHero()` 方法后调用表单的 `reset()` 方法即可。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOWCLICKINGNEWHERORESETSBOTHTHEFORMANDITSCONTROLFLAGS", "original": "Now clicking \"New Hero\" resets both the form and its control flags.", "translation": "现在点击“New Hero”重设表单和它的控制标记。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##SUBMITTHEFORMWITHNGSUBMIT", "original": "## Submit the form with _ngSubmit_", "translation": "## 使用 *ngSubmit* 提交该表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEUSERSHOULDBEABLETOSUBMITTHISFORMAFTERFILLINGITINTHESUBMITBUTTONATTHEBOTTOMOFTHEFORMDOESNOTHINGONITSOWNBUTITWILLTRIGGERAFORMSUBMITBECAUSEOFITSTYPETYPESUBMIT", "original": "The user should be able to submit this form after filling it in.\nThe *Submit* button at the bottom of the form\ndoes nothing on its own, but it will\ntrigger a form submit because of its type (`type=\"submit\"`).", "translation": "在填表完成之后,用户还应该能提交这个表单。\n“Submit(提交)”按钮位于表单的底部,它自己不做任何事,但因为有特殊的 type 值 (`type=\"submit\"`),所以会触发表单提交。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "AFORMSUBMITISUSELESSATTHEMOMENTTOMAKEITUSEFULBINDTHEFORMSNGSUBMITEVENTPROPERTYTOTHEHEROFORMCOMPONENTSONSUBMITMETHOD:", "original": "A \"form submit\" is useless at the moment.\nTo make it useful, bind the form's `ngSubmit` event property\nto the hero form component's `onSubmit()` method:", "translation": "现在这样仅仅触发“表单提交”是没用的。\n要让它有用,就要把该表单的 `ngSubmit` 事件属性绑定到英雄表单组件的 `onSubmit()` 方法上:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOUDALREADYDEFINEDATEMPLATEREFERENCEVARIABLE#HEROFORMANDINITIALIZEDITWITHTHEVALUENGFORMNOWUSETHATVARIABLETOACCESSTHEFORMWITHTHESUBMITBUTTON", "original": "You'd already defined a template reference variable,\n`#heroForm`, and initialized it with the value \"ngForm\".\nNow, use that variable to access the form with the Submit button.", "translation": "你已经定义了一个模板引用变量 `#heroForm`,并且把赋值为“ngForm”。\n现在,就可以在“Submit”按钮中访问这个表单了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "YOULLBINDTHEFORMSOVERALLVALIDITYVIATHEHEROFORMVARIABLETOTHEBUTTONSDISABLEDPROPERTYUSINGANEVENTBINDINGHERESTHECODE:", "original": "You'll bind the form's overall validity via\nthe `heroForm` variable to the button's `disabled` property\nusing an event binding. Here's the code:", "translation": "你要把表单的总体有效性通过 `heroForm` 变量绑定到此按钮的 `disabled` 属性上,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "IFYOURUNTHEAPPLICATIONNOWYOUFINDTHATTHEBUTTONISENABLEDMDASHALTHOUGHITDOESNTDOANYTHINGUSEFULYET", "original": "If you run the application now, you find that the button is enabled—although\nit doesn't do anything useful yet.", "translation": "重新运行应用。表单打开时,状态是有效的,按钮是可用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOWIFYOUDELETETHENAMEYOUVIOLATETHEREQUIREDRULEWHICHISDULYNOTEDINTHEERRORMESSAGETHESUBMITBUTTONISALSODISABLED", "original": "Now if you delete the Name, you violate the \"required\" rule, which\nis duly noted in the error message.\nThe *Submit* button is also disabled.", "translation": "现在,如果你删除*姓名*,就会违反“必填姓名”规则,就会像以前那样显示出错误信息。同时,Submit 按钮也被禁用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOTIMPRESSEDTHINKABOUTITFORAMOMENTWHATWOULDYOUHAVETODOTOWIRETHEBUTTONSENABLEDISABLEDSTATETOTHEFORMSVALIDITYWITHOUTANGULARSHELP", "original": "Not impressed? Think about it for a moment. What would you have to do to\nwire the button's enable/disabled state to the form's validity without Angular's help?", "translation": "没感动吗?再想一会儿。如果没有 Angular `NgForm` 的帮助,又该怎么让按钮的禁用/启用状态和表单的有效性关联起来呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "FORYOUITWASASSIMPLEASTHIS:", "original": "For you, it was as simple as this:", "translation": "有了 Angular,它就是这么简单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "1DEFINEATEMPLATEREFERENCEVARIABLEONTHEENHANCEDFORMELEMENT", "original": "1. Define a template reference variable on the (enhanced) form element.", "translation": "定义模板引用变量,放在(强化过的)form 元素上", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "2REFERTOTHATVARIABLEINABUTTONMANYLINESAWAY", "original": "2. Refer to that variable in a button many lines away.", "translation": "从很多行之外的按钮上引用这个变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##TOGGLETWOFORMREGIONSEXTRACREDIT", "original": "## Toggle two form regions (extra credit)", "translation": "## 切换两个表单区域(额外的奖励)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "SUBMITTINGTHEFORMISNTTERRIBLYDRAMATICATTHEMOMENT", "original": "Submitting the form isn't terribly dramatic at the moment.", "translation": "提交表单还是不够激动人心。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ANUNSURPRISINGOBSERVATIONFORADEMOTOBEHONESTJAZZINGITUPWONTTEACHYOUANYTHINGNEWABOUTFORMSBUTTHISISANOPPORTUNITYTOEXERCISESOMEOFYOURNEWLYWONBINDINGSKILLSIFYOUARENTINTERESTEDSKIPTOTHISPAGESCONCLUSION", "original": "An unsurprising observation for a demo. To be honest,\n jazzing it up won't teach you anything new about forms.\n But this is an opportunity to exercise some of your newly won\n binding skills.\n If you aren't interested, skip to this page's conclusion.", "translation": "对演示来说,这个收场很平淡的。老实说,即使让它更出彩,也无法教给你任何关于表单的新知识。\n但这是练习新学到的绑定技能的好机会。\n如果你不感兴趣,可以跳到本章的总结部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "FORAMORESTRIKINGLYVISUALEFFECTHIDETHEDATAENTRYAREAANDDISPLAYSOMETHINGELSE", "original": "For a more strikingly visual effect,\nhide the data entry area and display something else.", "translation": "来实现一些更炫的视觉效果吧。\n 隐藏掉数据输入框,显示一些其它东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "WRAPTHEFORMINADIVANDBINDITSHIDDENPROPERTYTOTHEHEROFORMCOMPONENTSUBMITTEDPROPERTY", "original": "Wrap the form in a `<div>` and bind\nits `hidden` property to the `HeroFormComponent.submitted` property.", "translation": "先把表单包裹进 `<div>` 中,再把它的 `hidden` 属性绑定到 `HeroFormComponent.submitted` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEMAINFORMISVISIBLEFROMTHESTARTBECAUSETHESUBMITTEDPROPERTYISFALSEUNTILYOUSUBMITTHEFORMASTHISFRAGMENTFROMTHEHEROFORMCOMPONENTSHOWS:", "original": "The main form is visible from the start because the\n`submitted` property is false until you submit the form,\nas this fragment from the `HeroFormComponent` shows:", "translation": "主表单从一开始就是可见的,因为 `submitted` 属性是 false,直到提交了这个表单。\n来自 `HeroFormComponent` 的代码片段证实了这一点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "WHENYOUCLICKTHESUBMITBUTTONTHESUBMITTEDFLAGBECOMESTRUEANDTHEFORMDISAPPEARSASPLANNED", "original": "When you click the *Submit* button, the `submitted` flag becomes true and the form disappears\nas planned.", "translation": "当点击 Submit 按钮时,`submitted` 标志会变成 true,并且表单像预想中一样消失了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NOWTHEAPPNEEDSTOSHOWSOMETHINGELSEWHILETHEFORMISINTHESUBMITTEDSTATEADDTHEFOLLOWINGHTMLBELOWTHEDIVWRAPPERYOUJUSTWROTE:", "original": "Now the app needs to show something else while the form is in the submitted state.\nAdd the following HTML below the `<div>` wrapper you just wrote:", "translation": "现在,当表单处于已提交状态时,需要显示一些别的东西。\n在刚刚写的 `<div>` 包装下方,添加下列 HTML 语句:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THERESTHEHEROAGAINDISPLAYEDREADONLYWITHINTERPOLATIONBINDINGSTHISDIVAPPEARSONLYWHILETHECOMPONENTISINTHESUBMITTEDSTATE", "original": "There's the hero again, displayed read-only with interpolation bindings.\nThis `<div>` appears only while the component is in the submitted state.", "translation": "英雄又出现了,它通过插值表达式绑定显示为只读内容。\n这一小段 HTML 只在组件处于已提交状态时才会显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEHTMLINCLUDESANEDITBUTTONWHOSECLICKEVENTISBOUNDTOANEXPRESSIONTHATCLEARSTHESUBMITTEDFLAG", "original": "The HTML includes an *Edit* button whose click event is bound to an expression\nthat clears the `submitted` flag.", "translation": "这段 HTML 包含一个 “Edit(编辑)”按钮,将 click 事件绑定到表达式,用于清除 `submitted` 标志。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "WHENYOUCLICKTHEEDITBUTTONTHISBLOCKDISAPPEARSANDTHEEDITABLEFORMREAPPEARS", "original": "When you click the *Edit* button, this block disappears and the editable form reappears.", "translation": "当点 *Edit* 按钮时,这个只读块消失了,可编辑的表单重新出现了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEANGULARFORMDISCUSSEDINTHISPAGETAKESADVANTAGEOFTHEFOLLOWINGFRAMEWORKFEATURESTOPROVIDESUPPORTFORDATAMODIFICATIONVALIDATIONANDMORE:", "original": "The Angular form discussed in this page takes advantage of the following\nframework features to provide support for data modification, validation, and more:", "translation": "本章讨论的 Angular 表单技术利用了下列框架特性来支持数据修改、验证和更多操作:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "ANANGULARHTMLFORMTEMPLATE", "original": "* An Angular HTML form template.", "translation": "Angular HTML 表单模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "AFORMCOMPONENTCLASSWITHACOMPONENTDECORATOR", "original": "* A form component class with a `@Component` decorator.", "translation": "带有 `@Component` 装饰器的表单组件类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "HANDLINGFORMSUBMISSIONBYBINDINGTOTHENGFORMNGSUBMITEVENTPROPERTY", "original": "* Handling form submission by binding to the `NgForm.ngSubmit` event property.", "translation": "通过绑定到 `NgForm.ngSubmit` 事件属性来处理表单提交。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "TEMPLATEREFERENCEVARIABLESSUCHAS#HEROFORMAND#NAME", "original": "* Template-reference variables such as `#heroForm` and `#name`.", "translation": "模板引用变量,例如 `#heroForm` 和 `#name`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "NGMODELSYNTAXFORTWOWAYDATABINDING", "original": "* `[(ngModel)]` syntax for two-way data binding.", "translation": "`[(ngModel)]` 语法用来实现双向数据绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEUSEOFNAMEATTRIBUTESFORVALIDATIONANDFORMELEMENTCHANGETRACKING", "original": "* The use of `name` attributes for validation and form-element change tracking.", "translation": "`name` 属性的用途是有效性验证和对表单元素的变更进行追踪。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "THEREFERENCEVARIABLESVALIDPROPERTYONINPUTCONTROLSTOCHECKIFACONTROLISVALIDANDSHOWHIDEERRORMESSAGES", "original": "* The reference variable’s `valid` property on input controls to check if a control is valid and show/hide error messages.", "translation": "指向 input 控件的引用变量上的 `valid` 属性,可用于检查控件是否有效、是否显示/隐藏错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "CONTROLLINGTHESUBMITBUTTONSENABLEDSTATEBYBINDINGTONGFORMVALIDITY", "original": "* Controlling the *Submit* button's enabled state by binding to `NgForm` validity.", "translation": "通过绑定到 `NgForm` 的有效性状态,控制 *Submit* 按钮的禁用状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "CUSTOMCSSCLASSESTHATPROVIDEVISUALFEEDBACKTOUSERSABOUTINVALIDCONTROLS", "original": "* Custom CSS classes that provide visual feedback to users about invalid controls.", "translation": "定制 CSS 类来给用户提供无效控件的视觉反馈。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "HERESTHECODEFORTHEFINALVERSIONOFTHEAPPLICATION:", "original": "Here’s the code for the final version of the application:", "translation": "下面是该应用最终版本的代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/forms.md" }, { + "key": "#FREQUENTLYUSEDMODULES", "original": "# Frequently Used Modules", "translation": "# 常用模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "ABASICUNDERSTANDINGOFBOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "A basic understanding of [Bootstrapping](guide/bootstrapping).", - "translation": "对[引导](guide/bootstrapping)有基本的理解。", + "translation": "对[引导](guide/bootstrapping)有基本的了解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "ANANGULARAPPNEEDSATLEASTONEMODULETHATSERVESASTHEROOTMODULEASYOUADDFEATURESTOYOURAPPYOUCANADDTHEMINMODULESTHEFOLLOWINGAREFREQUENTLYUSEDANGULARMODULESWITHEXAMPLESOFSOMEOFTHETHINGSTHEYCONTAIN:", "original": "An Angular app needs at least one module that serves as the root module.\nAs you add features to your app, you can add them in modules.\nThe following are frequently used Angular modules with examples\nof some of the things they contain:", "translation": "Angular 应用需要不止一个模块,它们都为根模块服务。\n如果你要把某些特性添加到应用中,可以通过添加模块来实现。\n下列是一些常用的 Angular 模块,其中带有一些其内容物的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "IMPORTITFROM", "original": "Import it from", "translation": "导入自", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "WHYYOUUSEIT", "original": "Why you use it", "translation": "为何使用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "WHENYOUWANTTORUNYOURAPPINABROWSER", "original": "When you want to run your app in a browser", "translation": "当你想要在浏览器中运行应用时", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "WHENYOUWANTTOUSECODENGIFCODECODENGFORCODE", "original": "When you want to use <code>NgIf</code>, <code>NgFor</code>", "translation": "当你想要使用 <code>NgIf</code> 和 <code>NgFor</code> 时", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "WHENYOUBUILDTEMPLATEDRIVENFORMSINCLUDESCODENGMODELCODE", "original": "When you build template driven forms (includes <code>NgModel</code>)", "translation": "当要构建模板驱动表单时(它包含 <code>NgModel</code> )", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "WHENBUILDINGREACTIVEFORMS", "original": "When building reactive forms", "translation": "当要构建响应式表单时", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "FORROUTINGANDWHENYOUWANTTOUSECODEROUTERLINKCODECODEFORROOTCODEANDCODEFORCHILDCODE", "original": "For Routing and when you want to use <code>RouterLink</code>,<code>.forRoot()</code>, and <code>.forChild()</code>", "translation": "要使用路由功能,并且你要用到 <code>RouterLink</code>,<code>.forRoot()</code> 和 <code>.forChild()</code> 时", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "WHENYOUTOTALKTOASERVER", "original": "When you to talk to a server", "translation": "当你要和服务器对话时", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "##IMPORTINGMODULES", "original": "## Importing modules", "translation": "## 导入模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "WHENYOUUSETHESEANGULARMODULESIMPORTTHEMINAPPMODULEORYOURFEATUREMODULEASAPPROPRIATEANDLISTTHEMINTHENGMODULEIMPORTSARRAYFOREXAMPLEINTHEBASICAPPGENERATEDBYTHECLIBROWSERMODULEISTHEFIRSTIMPORTATTHETOPOFTHEAPPMODULEAPPMODULETS", "original": "When you use these Angular modules, import them in `AppModule`,\nor your feature module as appropriate, and list them in the `@NgModule`\n`imports` array. For example, in the basic app generated by the CLI,\n`BrowserModule` is the first import at the top of the `AppModule`,\n`app.module.ts`.", "translation": "当你使用这些 Angular 模块时,在 `AppModule`(或适当的特性模块)中导入它们,并把它们列在当前 `@NgModule` 的 `imports` 数组中。比如,在 CLI 生成的基本应用中,`BrowserModule` 会在 `app.module.ts` 中 `AppModule` 的顶部最先导入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "THEIMPORTSATTHETOPOFTHEARRAYAREJAVASCRIPTIMPORTSTATEMENTSWHILETHEIMPORTSARRAYWITHINNGMODULEISANGULARSPECIFICFORMOREINFORMATIONONTHEDIFFERENCESEEJAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "The imports at the top of the array are JavaScript import statements\nwhile the `imports` array within `@NgModule` is Angular specific.\nFor more information on the difference, see [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", "translation": "文件顶部的这些导入是 JavaScript 的导入语句,而 `@NgModule` 中的 `imports` 数组则是 Angular 特有的。\n要了解更多的不同点,参见 [JavaScript 模块 vs. NgModule](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "##BROWSERMODULEANDCOMMONMODULE", "original": "## `BrowserModule` and `CommonModule`", "translation": "## `BrowserModule` 和 `CommonModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "BROWSERMODULEIMPORTSCOMMONMODULEWHICHCONTRIBUTESMANYCOMMONDIRECTIVESSUCHASNGIFANDNGFORADDITIONALLYBROWSERMODULEREEXPORTSCOMMONMODULEMAKINGALLOFITSDIRECTIVESAVAILABLETOANYMODULETHATIMPORTSBROWSERMODULE", "original": "`BrowserModule` imports `CommonModule`, which contributes many common\ndirectives such as `ngIf` and `ngFor`. Additionally, `BrowserModule`\nre-exports `CommonModule` making all of its directives available\nto any module that imports `BrowserModule`.", "translation": "`BrowserModule` 导入了 `CommonModule`,它贡献了很多通用的指令,比如 `ngIf` 和 `ngFor`。\n另外,`BrowserModule` 重新导出了 `CommonModule`,以便它所有的指令在任何导入了 `BrowserModule` 的 Angular 模块中都可以使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "FORAPPSTHATRUNINTHEBROWSERIMPORTBROWSERMODULEINTHEROOTAPPMODULEBECAUSEITPROVIDESSERVICESTHATAREESSENTIALTOLAUNCHANDRUNABROWSERAPPBROWSERMODULESPROVIDERSAREFORTHEWHOLEAPPSOITSHOULDONLYBEINTHEROOTMODULENOTINFEATUREMODULESFEATUREMODULESONLYNEEDTHECOMMONDIRECTIVESINCOMMONMODULETHEYDONTNEEDTOREINSTALLAPPWIDEPROVIDERS", "original": "For apps that run in the browser, import `BrowserModule` in the\nroot `AppModule` because it provides services that are essential\nto launch and run a browser app. `BrowserModule`’s providers\nare for the whole app so it should only be in the root module,\nnot in feature modules. Feature modules only need the common\ndirectives in `CommonModule`; they don’t need to re-install app-wide providers.", "translation": "对于运行在浏览器中的应用来说,都必须在根模块中 `AppModule`,因为它提供了启动和运行浏览器应用时某些必须的服务。`BrowserModule` 的提供商是面向整个应用的,所以它只能在根模块中使用,而不是特性模块。\n特性模块只需要 `CommonModule` 中的常用指令,它们不需要重新安全所有全应用级的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "IFYOUDOIMPORTBROWSERMODULEINTOALAZYLOADEDFEATUREMODULEANGULARRETURNSANERRORTELLINGYOUTOUSECOMMONMODULEINSTEAD", "original": "If you do import `BrowserModule` into a lazy loaded feature module,\nAngular returns an error telling you to use `CommonModule` instead.", "translation": "如果你把 `BrowserModule` 导入了惰性加载的特性模块中,Angular 就会返回一个错误,并告诉你应该改用 `CommonModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "BOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "* [Bootstrapping](guide/bootstrapping).", - "translation": "[引导](guide/bootstrapping).", + "translation": "[引导启动](guide/bootstrapping)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "NGMODULESGUIDENGMODULES", "original": "* [NgModules](guide/ngmodules).", "translation": "[Angular 模块](guide/ngmodules).", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "JAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", - "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule).", + "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/frequent-ngmodules.md" }, { + "key": "#ANGULARGLOSSARY", "original": "# Angular Glossary", "translation": "# Angular 词汇表", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARHASITSOWNVOCABULARYMOSTANGULARTERMSARECOMMONENGLISHWORDSWITHASPECIFICMEANINGWITHINTHEANGULARSYSTEM", "original": "Angular has its own vocabulary.\nMost Angular terms are common English words\nwith a specific meaning within the Angular system.", "translation": "Angular 有自己的词汇表。\n虽然大多数 Angular 短语都是日常用语,但是在 Angular 体系中,它们有特别的含义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THISGLOSSARYLISTSTHEMOSTPROMINENTTERMSANDAFEWLESSFAMILIARONESTHATHAVEUNUSUALORUNEXPECTEDDEFINITIONS", "original": "This glossary lists the most prominent terms\nand a few less familiar ones that have unusual or\nunexpected definitions.", "translation": "本词汇表列出了常用术语和少量具有独特或反直觉含义的罕用术语。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##AHEADOFTIMEAOTCOMPILATION", "original": "## Ahead-of-time (AOT) compilation", "translation": "## 预 (ahead-of-time, AOT) 编译", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOUCANCOMPILEANGULARAPPLICATIONSATBUILDTIMEBYCOMPILINGYOURAPPLICATIONUSINGTHECOMPILERCLINGCYOUCANBOOTSTRAPDIRECTLYTOAMODULEFACTORYMEANINGYOUDONTNEEDTOINCLUDETHEANGULARCOMPILERINYOURJAVASCRIPTBUNDLEAHEADOFTIMECOMPILEDAPPLICATIONSALSOBENEFITFROMDECREASEDLOADTIMEANDINCREASEDPERFORMANCE", "original": "You can compile Angular applications at build time.\nBy compiling your application using the compiler-cli, `ngc`, you can bootstrap directly to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle.\nAhead-of-time compiled applications also benefit from decreased load time and increased performance.", "translation": "开发者可以在构造时 (build-time) 编译 Angular 应用程序。\n 通过 `compiler-cli` - `ngc` 编译应用程序,应用可以从一个模块工厂直接启动,\n 意味着不再需要把 Angular 编译器添加到 JavaScript 包中。\n 预编译的应用程序加载迅速,具有更高的性能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ANNOTATION", "original": "## Annotation", "translation": "## 注解", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "INPRACTICEASYNONYMFORDECORATIONGUIDEGLOSSARY#DECORATOR", "original": "In practice, a synonym for [Decoration](guide/glossary#decorator).", "translation": "实际上,是[装饰 (decoration)](guide/glossary#decorator) 的同义词。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ATTRIBUTEDIRECTIVES", "original": "## Attribute directives", "translation": "## 属性型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ACATEGORYOFDIRECTIVEGUIDEGLOSSARY#DIRECTIVETHATCANLISTENTOANDMODIFYTHEBEHAVIOROFOTHERHTMLELEMENTSATTRIBUTESPROPERTIESANDCOMPONENTSTHEYAREUSUALLYREPRESENTEDASHTMLATTRIBUTESHENCETHENAME", "original": "A category of [directive](guide/glossary#directive) that can listen to and modify the behavior of\nother HTML elements, attributes, properties, and components. They are usually represented\nas HTML attributes, hence the name.", "translation": "[指令 (directive)](guide/glossary#directive)的一种。可以监听或修改其它 HTML 元素、特性 (attribute)、属性 (property)、组件的行为。通常用作 HTML 属性,就像它的名字所暗示的那样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FOREXAMPLEYOUCANUSETHENGCLASSDIRECTIVETOADDANDREMOVECSSCLASSNAMES", "original": "For example, you can use the `ngClass` directive to add and remove CSS class names.", "translation": "例如,`ngClass` 指令就是典型的属性型指令。它可以添加或移除 CSS 类名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "LEARNABOUTTHEMINTHEATTRIBUTEDIRECTIVESGUIDEATTRIBUTEDIRECTIVESGUIDE", "original": "Learn about them in the [_Attribute Directives_](guide/attribute-directives) guide.", "translation": "要了解更多信息,请参见[*属性型指令*](guide/attribute-directives)页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##BARREL", "original": "## Barrel", "translation": "## 封装桶", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "AWAYTOROLLUPEXPORTSFROMSEVERALES2015MODULESINTOASINGLECONVENIENTES2015MODULETHEBARRELITSELFISANES2015MODULEFILETHATREEXPORTSSELECTEDEXPORTSOFOTHERES2015MODULES", "original": "A way to *roll up exports* from several ES2015 modules into a single convenient ES2015 module.\nThe barrel itself is an ES2015 module file that re-exports *selected* exports of other ES2015 modules.", "translation": "封装桶是把多个模块的*导出结果*汇总到单一的 ES2015 模块的一种方式。\n 封装桶本身是一个 ES2015 模块文件,它重新导出*选中的*导出,这些导入来自其它 ES2015 模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FOREXAMPLEIMAGINETHREEES2015MODULESINAHEROESFOLDER:", "original": "For example, imagine three ES2015 modules in a `heroes` folder:", "translation": "例如,设想在 `heroes` 目录下有三个 ES2015 模块:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "WITHOUTABARRELACONSUMERNEEDSTHREEIMPORTSTATEMENTS:", "original": "Without a barrel, a consumer needs three import statements:", "translation": "如果没有封装桶,消费者需要三条导入语句:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOUCANADDABARRELTOTHEHEROESFOLDERCALLEDINDEXBYCONVENTIONTHATEXPORTSALLOFTHESEITEMS:", "original": "You can add a barrel to the `heroes` folder (called `index`, by convention) that exports all of these items:", "translation": "在 `heroes` 目录下添加一个封装桶(按约定叫做 `index`),它导出所有这三项:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NOWACONSUMERCANIMPORTWHATITNEEDSFROMTHEBARREL", "original": "Now a consumer can import what it needs from the barrel.", "translation": "现在,消费者就就可以从这个封装桶中导入它需要的东西了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEANGULARSCOPEDPACKAGESGUIDEGLOSSARY#SCOPEDPACKAGEEACHHAVEABARRELNAMEDINDEX", "original": "The Angular [scoped packages](guide/glossary#scoped-package) each have a barrel named `index`.", "translation": "Angular 的每个[范围化包 (scoped package)](guide/glossary#scoped-package) 都有一个名为 `index` 的封装桶。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOUCANOFTENACHIEVETHESAMERESULTUSINGNGMODULESGUIDEGLOSSARY#NGMODULEINSTEAD", "original": "You can often achieve the same result using [NgModules](guide/glossary#ngmodule) instead.", "translation": "注意,你可以利用 [Angular 模块](guide/glossary#ngmodule)达到同样的目的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##BINDING", "original": "## Binding", "translation": "## 绑定 (binding)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "USUALLYREFERSTODATABINDINGGUIDEGLOSSARY#DATABINDINGANDTHEACTOFBINDINGANHTMLOBJECTPROPERTYTOADATAOBJECTPROPERTY", "original": "Usually refers to [data binding](guide/glossary#data-binding) and the act of\nbinding an HTML object property to a data object property.", "translation": "几乎都是指的[数据绑定 (data binding)](guide/glossary#data-binding) 和将 HTML 对象属性绑定到数据对象属性的行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "SOMETIMESREFERSTOADEPENDENCYINJECTIONGUIDEGLOSSARY#DEPENDENCYINJECTIONBINDINGBETWEENATOKENMDASHALSOREFERREDTOASAKEYMDASHANDADEPENDENCYPROVIDERGUIDEGLOSSARY#PROVIDER", "original": "Sometimes refers to a [dependency-injection](guide/glossary#dependency-injection) binding\nbetween a \"token\"—also referred to as a \"key\"—and a dependency [provider](guide/glossary#provider).", "translation": "有时也会指在“令牌”(也称为键)和依赖[提供商 (provider)](guide/glossary#provider)\n之间的[依赖注入 (dependency injection)](guide/glossary#dependency-injection) 绑定。\n这种用法很少,而且一般都会在上下文中写清楚。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##BOOTSTRAP", "original": "## Bootstrap", "translation": "## 启动/引导 (bootstrap)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOULAUNCHANANGULARAPPLICATIONBYBOOTSTRAPPINGITUSINGTHEAPPLICATIONROOTNGMODULEAPPMODULE", "original": "You launch an Angular application by \"bootstrapping\" it using the application root NgModule (`AppModule`).", "translation": "通过应用程序根 Angular 模块(`AppModule`)来启动 Angular 应用程序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "BOOTSTRAPPINGIDENTIFIESANAPPLICATIONSTOPLEVELROOTCOMPONENTGUIDEGLOSSARY#COMPONENTWHICHISTHEFIRSTCOMPONENTTHATISLOADEDFORTHEAPPLICATION", "original": "Bootstrapping identifies an application's top level \"root\" [component](guide/glossary#component),\nwhich is the first component that is loaded for the application.", "translation": "启动过程标识应用的顶级“根”[组件 (component)](guide/glossary#component),也就是应用加载的第一个组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOUCANBOOTSTRAPMULTIPLEAPPSINTHESAMEINDEXHTMLEACHAPPWITHITSOWNTOPLEVELROOT", "original": "You can bootstrap multiple apps in the same `index.html`, each app with its own top-level root.", "translation": "你可以在同一个 `index.html` 中引导多个应用,每个应用都有它自己的顶级根组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##CAMELCASE", "original": "## camelCase", "translation": "## 驼峰式命名法 (camelCase)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEPRACTICEOFWRITINGCOMPOUNDWORDSORPHRASESSUCHTHATEACHWORDORABBREVIATIONBEGINSWITHACAPITALLETTEREXCEPTTHEFIRSTLETTERWHICHISLOWERCASE", "original": "The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter\n_except the first letter, which is lowercase_.", "translation": "驼峰式命名法是书写复合词或短语的一种形式,除首字母要小写外,每个单词或缩写都以大写字母开头。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FUNCTIONPROPERTYANDMETHODNAMESARETYPICALLYSPELLEDINCAMELCASEFOREXAMPLESQUAREFIRSTNAMEANDGETHEROESNOTICETHATSQUAREISANEXAMPLEOFHOWYOUWRITEASINGLEWORDINCAMELCASE", "original": "Function, property, and method names are typically spelled in camelCase. For example, `square`, `firstName`, and `getHeroes`. Notice that `square` is an example of how you write a single word in camelCase.", "translation": "通常,函数、属性和方法命名使用驼峰式拼写法。例如,`square`, `firstName` 和 `getHeroes`。注意这里的 `square` 是如何用驼峰式命名法表示单一词的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "CAMELCASEISALSOKNOWNASLOWERCAMELCASETODISTINGUISHITFROMUPPERCAMELCASEORPASCALCASEGUIDEGLOSSARY#PASCALCASEINANGULARDOCUMENTATIONCAMELCASEALWAYSMEANSLOWERCAMELCASE", "original": "camelCase is also known as *lower camel case* to distinguish it from *upper camel case*, or [PascalCase](guide/glossary#pascalcase).\nIn Angular documentation, \"camelCase\" always means *lower camel case*.", "translation": "这种形式也叫做**小写驼峰式命名法 (lower camel case)**,以区分于**大写驼峰式命名法**,也称 [Pascal 命名法 (PascalCase)](guide/glossary#pascalcase)。\nAngular 文档中提到“驼峰式命名法 (camelCase) ”的时候,所指的都是小驼峰命名法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEANGULARCLIISACOMMANDLINEINTERFACETOOLTHATCANCREATEAPROJECTADDFILESANDPERFORMAVARIETYOFONGOINGDEVELOPMENTTASKSSUCHASTESTINGBUNDLINGANDDEPLOYMENT", "original": "The Angular CLI is a `command line interface` tool that can create a project, add files, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.", "translation": "Angular CLI 是个命令行接口(Command Line Interface)工具,它可以创建项目、添加文件以及执行各种正在进行的开发任务,比如测试、打包和部署。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "LEARNMOREINTHEGETTINGSTARTEDGUIDEQUICKSTARTGUIDE", "original": "Learn more in the [Getting Started](guide/quickstart) guide.", "translation": "要了解更多,参见[快速起步](guide/quickstart)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##COMPONENT", "original": "## Component", "translation": "## 组件 (component)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANANGULARCLASSRESPONSIBLEFOREXPOSINGDATATOAVIEWGUIDEGLOSSARY#VIEWANDHANDLINGMOSTOFTHEVIEWSDISPLAYANDUSERINTERACTIONLOGIC", "original": "An Angular class responsible for exposing data to a [view](guide/glossary#view) and handling most of the view’s display and user-interaction logic.", "translation": "组件是一个 Angular 类,用于把数据展示到[视图 (view)](guide/glossary#view),并处理几乎所有的视图显示和交互逻辑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THECOMPONENTISONEOFTHEMOSTIMPORTANTBUILDINGBLOCKSINTHEANGULARSYSTEMITISINFACTANANGULARDIRECTIVEGUIDEGLOSSARY#DIRECTIVEWITHACOMPANIONTEMPLATEGUIDEGLOSSARY#TEMPLATE", "original": "The *component* is one of the most important building blocks in the Angular system.\nIt is, in fact, an Angular [directive](guide/glossary#directive) with a companion [template](guide/glossary#template).", "translation": "*组件*是 Angular 系统中最重要的基本构造块之一。\n它其实是一个拥有[模板 (template)](guide/glossary#template)的[指令 (directive)](guide/glossary#directive)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "APPLYTHECOMPONENTDECORATORGUIDEGLOSSARY#DECORATORTOTHECOMPONENTCLASSTHEREBYATTACHINGTOTHECLASSTHEESSENTIALCOMPONENTMETADATATHATANGULARNEEDSTOCREATEACOMPONENTINSTANCEANDRENDERTHECOMPONENTWITHITSTEMPLATEASAVIEW", "original": "Apply the `@Component` [decorator](guide/glossary#decorator) to\nthe component class, thereby attaching to the class the essential component metadata\nthat Angular needs to create a component instance and render the component with its template\nas a view.", "translation": "需要将 `#@Component`[装饰器](guide/glossary#decorator)应用到一个组件类,从而把必要的组件元数据附加到类上。\nAngular 会需要元数据来创建一个组件实例,并把组件的模板作为视图渲染出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THOSEFAMILIARWITHMVCANDMVVMPATTERNSWILLRECOGNIZETHECOMPONENTINTHEROLEOFCONTROLLERORVIEWMODEL", "original": "Those familiar with \"MVC\" and \"MVVM\" patterns will recognize\nthe component in the role of \"controller\" or \"view model\".", "translation": "如果你熟悉 \"MVC\" 和 \"MVVM\" 模式,就会意识到组件充当了“控制器 (controller) ”和“视图模型 (view model) ”的角色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##DASHCASE", "original": "## dash-case", "translation": "## 中线命名法 (dash-case)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEPRACTICEOFWRITINGCOMPOUNDWORDSORPHRASESSUCHTHATEACHWORDISSEPARATEDBYADASHORHYPHENTHISFORMISALSOKNOWNASKEBABCASE", "original": "The practice of writing compound words or phrases such that each word is separated by a dash or hyphen (`-`).\nThis form is also known as kebab-case.", "translation": "中线命名法是书写复合词或短语的一种形式,使用中线 (`-`) 分隔每个单词。\n这种形式也称为烤串命名法 kebab-case。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "DIRECTIVEGUIDEGLOSSARY#DIRECTIVESELECTORSLIKEMYAPPANDTHEROOTOFFILENAMESSUCHASHEROLISTCOMPONENTTSAREOFTENSPELLEDINDASHCASE", "original": "[Directive](guide/glossary#directive) selectors (like `my-app`) and\nthe root of filenames (such as `hero-list.component.ts`) are often\nspelled in dash-case.", "translation": "[指令](guide/glossary#directive)的选择器(例如 `my-app`)和文件名(例如 `hero-list.component.ts`)通常是用中线命名法来命名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##DATABINDING", "original": "## Data binding", "translation": "## 数据绑定 (data binding)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "APPLICATIONSDISPLAYDATAVALUESTOAUSERANDRESPONDTOUSERACTIONSSUCHASCLICKSTOUCHESANDKEYSTROKES", "original": "Applications display data values to a user and respond to user\nactions (such as clicks, touches, and keystrokes).", "translation": "应用程序会将数据展示给用户,并对用户的操作(点击、触屏、按键)做出回应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "INDATABINDINGYOUDECLARETHERELATIONSHIPBETWEENANHTMLWIDGETANDDATASOURCEANDLETTHEFRAMEWORKHANDLETHEDETAILSDATABINDINGISANALTERNATIVETOMANUALLYPUSHINGAPPLICATIONDATAVALUESINTOHTMLATTACHINGEVENTLISTENERSPULLINGCHANGEDVALUESFROMTHESCREENANDUPDATINGAPPLICATIONDATAVALUES", "original": "In data binding, you declare the relationship between an HTML widget and data source\nand let the framework handle the details.\nData binding is an alternative to manually pushing application data values into HTML, attaching\nevent listeners, pulling changed values from the screen, and\nupdating application data values.", "translation": "在数据绑定机制下,你只要声明一下 HTML 部件和数据源之间的关系,把细节交给框架去处理。\n而以前的手动操作过程是:将数据推送到 HTML 页面中、添加事件监听器、从屏幕获取变化后的数据,并更新应用中的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARHASARICHDATABINDINGFRAMEWORKWITHAVARIETYOFDATABINDINGOPERATIONSANDSUPPORTINGDECLARATIONSYNTAX", "original": "Angular has a rich data-binding framework with a variety of data-binding\noperations and supporting declaration syntax.", "translation": "Angular 有一个非常强大的数据绑定框架,具有各种数据绑定操作,并支持声明式语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "READABOUTTHEFOLLOWINGFORMSOFBINDINGINTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE:", "original": "Read about the following forms of binding in the [Template Syntax](guide/template-syntax) page:", "translation": "更多的绑定形式,见[模板语法](guide/template-syntax):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "INTERPOLATIONGUIDETEMPLATESYNTAX#INTERPOLATION", "original": "* [Interpolation](guide/template-syntax#interpolation).", "translation": "[插值表达式 (interpolation)](guide/template-syntax#interpolation)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "PROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDING", "original": "* [Property binding](guide/template-syntax#property-binding).", "translation": "[property 绑定 (property binding)](guide/template-syntax#property-binding)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "EVENTBINDINGGUIDETEMPLATESYNTAX#EVENTBINDING", "original": "* [Event binding](guide/template-syntax#event-binding).", "translation": "[事件绑定 (event binding)](guide/template-syntax#event-binding)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ATTRIBUTEBINDINGGUIDETEMPLATESYNTAX#ATTRIBUTEBINDING", "original": "* [Attribute binding](guide/template-syntax#attribute-binding).", "translation": "[attribute 绑定 (attribute binding)](guide/template-syntax#attribute-binding)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "CLASSBINDINGGUIDETEMPLATESYNTAX#CLASSBINDING", "original": "* [Class binding](guide/template-syntax#class-binding).", "translation": "[CSS 类绑定 (class binding)](guide/template-syntax#class-binding)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "STYLEBINDINGGUIDETEMPLATESYNTAX#STYLEBINDING", "original": "* [Style binding](guide/template-syntax#style-binding).", "translation": "[样式绑定 (style binding)](guide/template-syntax#style-binding)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "TWOWAYDATABINDINGWITHNGMODELGUIDETEMPLATESYNTAX#NGMODEL", "original": "* [Two-way data binding with ngModel](guide/template-syntax#ngModel).", "translation": "[基于 ngModel 的双向数据绑定 (Two-way data binding with ngModel)](guide/template-syntax#ngModel)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##DECORATORDECORATION", "original": "## Decorator | decoration", "translation": "## 装饰器(decorator | decoration)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "AFUNCTIONTHATADDSMETADATATOACLASSITSMEMBERSPROPERTIESMETHODSANDFUNCTIONARGUMENTS", "original": "A *function* that adds metadata to a class, its members (properties, methods) and function arguments.", "translation": "装饰器是一个**函数**,它将元数据添加到类、类成员(属性、方法)和函数参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "DECORATORSAREANEXPERIMENTALSTAGE2JAVASCRIPTLANGUAGEFEATUREHTTPS:GITHUBCOMWYCATSJAVASCRIPTDECORATORSTYPESCRIPTADDSSUPPORTFORDECORATORS", "original": "Decorators are an experimental (stage 2), JavaScript language [feature](https://github.com/wycats/javascript-decorators). TypeScript adds support for decorators.", "translation": "装饰器是一个 JavaScript 的语言[特性](https://github.com/wycats/javascript-decorators),装饰器在 TypeScript 里已经实现,并被推荐到了 ES2016(也就是 ES7)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "TOAPPLYADECORATORPOSITIONITIMMEDIATELYABOVEORTOTHELEFTOFTHEITEMITDECORATES", "original": "To apply a decorator, position it immediately above or to the left of the item it decorates.", "translation": "要想应用装饰器,把它放到被装饰对象的上面或左边。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARHASITSOWNSETOFDECORATORSTOHELPITINTEROPERATEWITHYOURAPPLICATIONPARTSTHEFOLLOWINGEXAMPLEISACOMPONENTDECORATORTHATIDENTIFIESACLASSASANANGULARCOMPONENTGUIDEGLOSSARY#COMPONENTANDANINPUTDECORATORAPPLIEDTOTHENAMEPROPERTYOFTHATCOMPONENTTHEELIDEDOBJECTARGUMENTTOTHECOMPONENTDECORATORWOULDCONTAINTHEPERTINENTCOMPONENTMETADATA", "original": "Angular has its own set of decorators to help it interoperate with your application parts.\nThe following example is a `@Component` decorator that identifies a\nclass as an Angular [component](guide/glossary#component) and an `@Input` decorator applied to the `name` property\nof that component. The elided object argument to the `@Component` decorator would contain the pertinent component metadata.", "translation": "Angular 使用自己的一套装饰器来实现应用程序各部件之间的相互操作。\n下面的例子中使用了 `@Component` 装饰器来将一个类标记为 Angular [组件 (component)](guide/glossary#component),\n并将 `@Input` 装饰器来应用到组件的 `name` 属性。\n`@Component` 装饰器中省略的参数对象会包含与组件有关的元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THESCOPEOFADECORATORISLIMITEDTOTHELANGUAGEFEATURETHATITDECORATESNONEOFTHEDECORATIONSSHOWNHEREWILLLEAKTOOTHERCLASSESTHATFOLLOWITINTHEFILE", "original": "The scope of a decorator is limited to the language feature\nthat it decorates. None of the decorations shown here will \"leak\" to other\nclasses that follow it in the file.", "translation": "装饰器的作用域会被限制在它所装饰的语言特性。\n在同一文件中,装饰器不会“泄露”到它后面的其它类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ALWAYSINCLUDEPARENTHESESWHENAPPLYINGADECORATOR", "original": "Always include parentheses `()` when applying a decorator.", "translation": "永远别忘了在装饰器后面加括号 `()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##DEPENDENCYINJECTION", "original": "## Dependency injection", "translation": "## 依赖注入(dependency injection)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ADESIGNPATTERNANDMECHANISMFORCREATINGANDDELIVERINGPARTSOFANAPPLICATIONTOOTHERPARTSOFANAPPLICATIONTHATREQUESTTHEM", "original": "A design pattern and mechanism\nfor creating and delivering parts of an application to other\nparts of an application that request them.", "translation": "依赖注入既是设计模式,同时又是一种机制:当应用程序的一些部件需要另一些部件时,\n利用依赖注入来创建被请求的部件,并将它们注入到发出请求的部件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARDEVELOPERSPREFERTOBUILDAPPLICATIONSBYDEFININGMANYSIMPLEPARTSTHATEACHDOONETHINGWELLANDTHENWIRINGTHEMTOGETHERATRUNTIME", "original": "Angular developers prefer to build applications by defining many simple parts\nthat each do one thing well and then wiring them together at runtime.", "translation": "Angular 开发者构建应用程序时的首选方法是:定义许多简单部件,\n每个部件只做一件事并做好它,然后在运行时把它们装配在一起组成应用程序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THESEPARTSOFTENRELYONOTHERPARTSANANGULARCOMPONENTGUIDEGLOSSARY#COMPONENTPARTMIGHTRELYONASERVICEPARTTOGETDATAORPERFORMACALCULATIONWHENPARTARELIESONANOTHERPARTBYOUSAYTHATADEPENDSONBANDTHATBISADEPENDENCYOFA", "original": "These parts often rely on other parts. An Angular [component](guide/glossary#component)\npart might rely on a service part to get data or perform a calculation. When\npart \"A\" relies on another part \"B,\" you say that \"A\" depends on \"B\" and\nthat \"B\" is a dependency of \"A.\"", "translation": "这些部件通常会依赖其它部件。一个 Angular [组件 (component)](guide/glossary#component)\n可能依赖一个服务部件来获取数据或执行运算。\n如果部件 “A” 要靠另一个部件 “B” 才能工作,你就会说 “A” 依赖 “B” ,“B” 是 “A” 的依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOUCANASKADEPENDENCYINJECTIONSYSTEMTOCREATEAFORUSANDHANDLEALLTHEDEPENDENCIESIFANEEDSBANDBNEEDSCTHESYSTEMRESOLVESTHATCHAINOFDEPENDENCIESANDRETURNSAFULLYPREPAREDINSTANCEOFA", "original": "You can ask a \"dependency injection system\" to create \"A\"\nfor us and handle all the dependencies.\nIf \"A\" needs \"B\" and \"B\" needs \"C,\" the system resolves that chain of dependencies\nand returns a fully prepared instance of \"A.\"", "translation": "你可以要求“依赖注入系统”创建 “A” 并处理所有依赖。如果 “A” 需要 “B” ,“B” 需要 “C ”,\n系统将解析这个依赖链,返回一个完全准备好的 “A” 实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARPROVIDESANDRELIESUPONITSOWNSOPHISTICATEDDEPENDENCYINJECTIONSYSTEMTOASSEMBLEANDRUNAPPLICATIONSBYINJECTINGAPPLICATIONPARTSINTOOTHERAPPLICATIONPARTSWHEREANDWHENNEEDED", "original": "Angular provides and relies upon its own sophisticated\ndependency-injection system\nto assemble and run applications by \"injecting\" application parts\ninto other application parts where and when needed.", "translation": "Angular 提供并使用自己精心设计的[依赖注入 (dependency injection)](guide/dependency-injection)系统来组装和运行应用程序,在需要的地方和时刻,将一些部件“注入”到另一些部件里面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ATTHECOREANINJECTORGUIDEGLOSSARY#INJECTORRETURNSDEPENDENCYVALUESONREQUESTTHEEXPRESSIONINJECTORGETTOKENRETURNSTHEVALUEASSOCIATEDWITHTHEGIVENTOKEN", "original": "At the core, an [`injector`](guide/glossary#injector) returns dependency values on request.\nThe expression `injector.get(token)` returns the value associated with the given token.", "translation": "在 Angular 内核中有一个[注入器 (injector)](guide/glossary#injector),当请求时返回依赖值。\n表达式 `injector.get(token)` 返回与该 token(令牌)参数相关的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ATOKENISANANGULARTYPEINJECTIONTOKENYOURARELYNEEDTOWORKWITHTOKENSDIRECTLYMOSTMETHODSACCEPTACLASSNAMEFOOORASTRINGFOOANDANGULARCONVERTSITTOATOKENWHENYOUWRITEINJECTORGETFOOTHEINJECTORRETURNSTHEVALUEASSOCIATEDWITHTHETOKENFORTHEFOOCLASSTYPICALLYANINSTANCEOFFOOITSELF", "original": "A token is an Angular type (`InjectionToken`). You rarely need to work with tokens directly; most\nmethods accept a class name (`Foo`) or a string (\"foo\") and Angular converts it\nto a token. When you write `injector.get(Foo)`, the injector returns\nthe value associated with the token for the `Foo` class, typically an instance of `Foo` itself.", "translation": "令牌是一个 Angular 中的类型 (`InjectionToken`)。你很少直接处理令牌。\n绝大多数方法都接受类名 (`Foo`) 或字符串 (\"foo\"), Angular 会把这些类名称和字符串转换成令牌。\n当调用 `injector.get(Foo)` 时,注入器返回用 `Foo` 类生成的令牌所对应的依赖值,该依赖值通常是 `Foo` 类的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "DURINGMANYOFITSOPERATIONSANGULARMAKESSIMILARREQUESTSINTERNALLYSUCHASWHENITCREATESACOMPONENTGUIDEGLOSSARY#COMPONENTFORDISPLAY", "original": "During many of its operations, Angular makes similar requests internally, such as when it creates a [`component`](guide/glossary#component) for display.", "translation": "Angular 在内部执行很多类似的依赖注入请求,例如,在创建用于显示的[组件 (component)](guide/glossary#component)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEINJECTORMAINTAINSANINTERNALMAPOFTOKENSTODEPENDENCYVALUESIFTHEINJECTORCANTFINDAVALUEFORAGIVENTOKENITCREATESANEWVALUEUSINGAPROVIDERFORTHATTOKEN", "original": "The `Injector` maintains an internal map of tokens to dependency values.\nIf the `Injector` can't find a value for a given token, it creates\na new value using a `Provider` for that token.", "translation": "注入器 (`Injector`) 维护一个令牌到依赖值的映射表。\n如果注入器找不到给定令牌对应的依赖值,它会使用提供商 (`Provider`) 创建一个依赖值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "APROVIDERGUIDEGLOSSARY#PROVIDERISARECIPEFORCREATINGNEWINSTANCESOFADEPENDENCYVALUEASSOCIATEDWITHAPARTICULARTOKEN", "original": "A [provider](guide/glossary#provider) is a recipe for\ncreating new instances of a dependency value associated with a particular token.", "translation": "[提供商 (provider)](guide/glossary#provider)是一个“菜谱”,用于创建特定令牌对应的依赖实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANINJECTORCANONLYCREATEAVALUEFORAGIVENTOKENIFITHASAPROVIDERFORTHATTOKENINITSINTERNALPROVIDERREGISTRYREGISTERINGPROVIDERSISACRITICALPREPARATORYSTEP", "original": "An injector can only create a value for a given token if it has\na `provider` for that token in its internal provider registry.\nRegistering providers is a critical preparatory step.", "translation": "只有当注入器内部提供商注册表中存在与令牌对应的提供商时,\n注入器才能为这个令牌创建一个依赖值。所以注册提供商是一个非常关键的准备步骤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARREGISTERSSOMEOFITSOWNPROVIDERSWITHEVERYINJECTORYOUCANREGISTERYOUROWNPROVIDERS", "original": "Angular registers some of its own providers with every injector.\nYou can register your own providers.", "translation": "Angular 会为每个注册器注册很多内置提供商。\n你也可以注册自己的提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "READMOREINTHEDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONPAGE", "original": "Read more in the [Dependency Injection](guide/dependency-injection) page.", "translation": "更多信息,参见[依赖注入 (dependency injection)](guide/dependency-injection)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##DIRECTIVE", "original": "## Directive", "translation": "## 指令 (directive)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANANGULARCLASSRESPONSIBLEFORCREATINGRESHAPINGANDINTERACTINGWITHHTMLELEMENTSINTHEBROWSERDOMTHEDIRECTIVEISANGULARSMOSTFUNDAMENTALFEATURE", "original": "An Angular class responsible for creating, reshaping, and interacting with HTML elements\nin the browser DOM. The directive is Angular's most fundamental feature.", "translation": "指令是一个 Angular 类,负责创建和重塑浏览器 DOM 中的 HTML 元素,并与之互动。\n指令是 Angular 中最基本的特性之一。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ADIRECTIVEISUSUALLYASSOCIATEDWITHANHTMLELEMENTORATTRIBUTETHISELEMENTORATTRIBUTEISOFTENREFERREDTOASTHEDIRECTIVEITSELF", "original": "A directive is usually associated with an HTML element or attribute.\nThis element or attribute is often referred to as the directive itself.", "translation": "指令几乎总与 HTML 元素或属性 (attribute) 相关。\n通常把这些关联到的 HTML 元素或者属性 (attribute) 当做指令本身。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "WHENANGULARFINDSADIRECTIVEINANHTMLTEMPLATEITCREATESTHEMATCHINGDIRECTIVECLASSINSTANCEANDGIVESTHEINSTANCECONTROLOVERTHATPORTIONOFTHEBROWSERDOM", "original": "When Angular finds a directive in an HTML template,\nit creates the matching directive class instance\nand gives the instance control over that portion of the browser DOM.", "translation": "当 Angular 在 HTML 模板中遇到一个指令的时候,\n它会创建匹配的指令类的实例,并把浏览器中这部分 DOM 的控制权交给它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOUCANINVENTCUSTOMHTMLMARKUPFOREXAMPLEMYDIRECTIVETOASSOCIATEWITHYOURCUSTOMDIRECTIVESYOUADDTHISCUSTOMMARKUPTOHTMLTEMPLATESASIFYOUWEREWRITINGNATIVEHTMLINTHISWAYDIRECTIVESBECOMEEXTENSIONSOFHTMLITSELF", "original": "You can invent custom HTML markup (for example, `<my-directive>`) to\nassociate with your custom directives. You add this custom markup to HTML templates\nas if you were writing native HTML. In this way, directives become extensions of\nHTML itself.", "translation": "你可以自定义 HTML 标签(例如 `<my-directive>`)来关联自定义指令。\n然后,可以像写原生 HTML 一样把这些自定义标签放到 HTML 模板里。\n这样,指令就变成了 HTML 本身的拓展。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "DIRECTIVESFALLINTOONEOFTHEFOLLOWINGCATEGORIES:", "original": "Directives fall into one of the following categories:", "translation": "指令分为三类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "COMPONENTSGUIDEGLOSSARY#COMPONENTCOMBINEAPPLICATIONLOGICWITHANHTMLTEMPLATETORENDERAPPLICATIONVIEWSGUIDEGLOSSARY#VIEWCOMPONENTSAREUSUALLYREPRESENTEDASHTMLELEMENTSTHEYARETHEBUILDINGBLOCKSOFANANGULARAPPLICATION", "original": "* [Components](guide/glossary#component) combine application logic with an HTML template to\nrender application [views](guide/glossary#view). Components are usually represented as HTML elements.\nThey are the building blocks of an Angular application.", "translation": "[组件 (component)](guide/glossary#component): 用于组合程序逻辑和 HTML 模板,渲染出应用程序的[视图](guide/glossary#view)。\n 组件一般表示成 HTML 元素的形式,它们是构建 Angular 应用程序的基本单元。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ATTRIBUTEDIRECTIVESGUIDEGLOSSARY#ATTRIBUTEDIRECTIVECANLISTENTOANDMODIFYTHEBEHAVIOROFOTHERHTMLELEMENTSATTRIBUTESPROPERTIESANDCOMPONENTSTHEYAREUSUALLYREPRESENTEDASHTMLATTRIBUTESHENCETHENAME", "original": "* [Attribute directives](guide/glossary#attribute-directive) can listen to and modify the behavior of\nother HTML elements, attributes, properties, and components. They are usually represented\nas HTML attributes, hence the name.", "translation": "[属性型指令 (attribute directive)](guide/glossary#attribute-directive):可以监控和修改其它 HTML 元素、 \n HTML 属性 (attribute)、 DOM 属性 (property)、组件等行为等等。它们通常表示为 HTML 属性 (attibute),故名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "STRUCTURALDIRECTIVESGUIDEGLOSSARY#STRUCTURALDIRECTIVEARERESPONSIBLEFORSHAPINGORRESHAPINGHTMLLAYOUTTYPICALLYBYADDINGREMOVINGORMANIPULATINGELEMENTSANDTHEIRCHILDREN", "original": "* [Structural directives](guide/glossary#structural-directive) are responsible for\nshaping or reshaping HTML layout, typically by adding, removing, or manipulating\nelements and their children.", "translation": "[结构型指令 (structural directive)](guide/glossary#structural-directive):负责塑造或重塑 HTML\n布局。这一般是通过添加、删除或者操作 HTML 元素及其子元素来实现的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ECMASCRIPT", "original": "## ECMAScript", "translation": "## ECMAScript 语言", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEOFFICIALJAVASCRIPTLANGUAGESPECIFICATIONHTTPS:ENWIKIPEDIAORGWIKIECMASCRIPT", "original": "The [official JavaScript language specification](https://en.wikipedia.org/wiki/ECMAScript).", "translation": "[官方 JavaScript 语言规范](https://en.wikipedia.org/wiki/ECMAScript)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THELATESTAPPROVEDVERSIONOFJAVASCRIPTISECMASCRIPT2017HTTP:WWWECMAINTERNATIONALORGECMA26280ALSOKNOWNASES2017ORES8MANYANGULARDEVELOPERSWRITETHEIRAPPLICATIONSINES8ORADIALECTTHATSTRIVESTOBECOMPATIBLEWITHITSUCHASTYPESCRIPTGUIDEGLOSSARY#TYPESCRIPT", "original": "The latest approved version of JavaScript is\n[ECMAScript 2017](http://www.ecma-international.org/ecma-262/8.0/)\n(also known as \"ES2017\" or \"ES8\"). Many Angular developers write their applications\nin ES8 or a dialect that strives to be\ncompatible with it, such as [TypeScript](guide/glossary#typescript).", "translation": "最新批准的 JavaScript 版本是[ECMAScript 2016](http://www.ecma-international.org/ecma-262/7.0/)(也称“ES2016”或“ES7”)。\nAngular 的开发人员要么使用这个版本的语言,要么使用与之兼容的方言,例如 [TypeScript](guide/glossary#typescript)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "MOSTMODERNBROWSERSONLYSUPPORTTHEMUCHOLDERECMASCRIPT5ALSOKNOWNASES5STANDARDAPPLICATIONSWRITTENINES2017ES2016ES2015ORONEOFTHEIRDIALECTSMUSTBETRANSPILEDGUIDEGLOSSARY#TRANSPILETOES5JAVASCRIPT", "original": "Most modern browsers only support the much older \"ECMAScript 5\" (also known as \"ES5\") standard.\nApplications written in ES2017, ES2016, ES2015, or one of their dialects must be [transpiled](guide/glossary#transpile)\nto ES5 JavaScript.", "translation": "目前,几乎所有现代游览器只支持很老的“ECMAScript 5” (也称 ES5)标准。\n使用 ES2016、ES2015 或者其它方言开发的应用程序,必须“[转译 (transpile)](guide/glossary#transpile)”成 ES5 JavaScript。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARDEVELOPERSCANWRITEINES5DIRECTLY", "original": "Angular developers can write in ES5 directly.", "translation": "Angular 的开发人员也可以选择直接使用 ES5 编程。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ES2015", "original": "## ES2015", "translation": "## ES2015 语言", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "SHORTHANDFORECMASCRIPTGUIDEGLOSSARY#ECMASCRIPT2015", "original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.", "translation": "[ECMAScript](guide/glossary#ecmascript) 2015 的简写。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ES5", "original": "## ES5", "translation": "## ES5 语言", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "SHORTHANDFORECMASCRIPTGUIDEGLOSSARY#ECMASCRIPT5THEVERSIONOFJAVASCRIPTRUNBYMOSTMODERNBROWSERS", "original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 5, the version of JavaScript run by most modern browsers.", "translation": "“[ECMAScript](guide/glossary#ecmascript) 5”的简写,大部分现代浏览器使用的 JavaScript 版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ES6", "original": "## ES6", "translation": "## ES6 语言", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "SHORTHANDFORECMASCRIPTGUIDEGLOSSARY#ECMASCRIPT2015", "original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.", "translation": "[ECMAScript](guide/glossary#ecmascript) 2015 的简写。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##INJECTOR", "original": "## Injector", "translation": "## 注入器 (injector)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANOBJECTINTHEANGULARDEPENDENCYINJECTIONSYSTEMGUIDEGLOSSARY#DEPENDENCYINJECTIONTHATCANFINDANAMEDDEPENDENCYINITSCACHEORCREATEADEPENDENCYWITHAREGISTEREDPROVIDERGUIDEGLOSSARY#PROVIDER", "original": "An object in the Angular [dependency-injection system](guide/glossary#dependency-injection)\nthat can find a named dependency in its cache or create a dependency\nwith a registered [provider](guide/glossary#provider).", "translation": "Angular [依赖注入系统 (Dependency Injection System)](guide/glossary#dependency-injection)中的一个对象,\n它可以在自己的缓存中找到一个命名的“依赖”或者利用已注册的[提供商 (provider)](guide/glossary#provider) 创建这样一个依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##INPUT", "original": "## Input", "translation": "## 输入属性 (input)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ADIRECTIVEPROPERTYTHATCANBETHETARGETOFAPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDINGEXPLAINEDINDETAILINTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGEDATAVALUESFLOWINTOTHISPROPERTYFROMTHEDATASOURCEIDENTIFIEDINTHETEMPLATEEXPRESSIONTOTHERIGHTOFTHEEQUALSIGN", "original": "A directive property that can be the *target* of a\n[property binding](guide/template-syntax#property-binding) (explained in detail in the [Template Syntax](guide/template-syntax) page).\nData values flow *into* this property from the data source identified\nin the template expression to the right of the equal sign.", "translation": "输入属性是一个指令属性,可以作为[属性绑定 (property binding)](guide/template-syntax#property-binding)(详情参见[模板语法](guide/template-syntax)页)的目标。\n数据值会从模板表达式等号右侧的数据源流入这个属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "SEETHEINPUTANDOUTPUTPROPERTIESGUIDETEMPLATESYNTAX#INPUTSOUTPUTSSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "See the [Input and output properties](guide/template-syntax#inputs-outputs) section of the [Template Syntax](guide/template-syntax) page.", "translation": "参见[模板语法](guide/template-syntax)中的[输入与输出属性](guide/template-syntax#inputs-outputs)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##INTERPOLATION", "original": "## Interpolation", "translation": "## 插值表达式 (interpolation)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "AFORMOFPROPERTYDATABINDINGGUIDEGLOSSARY#DATABINDINGINWHICHATEMPLATEEXPRESSIONGUIDEGLOSSARY#TEMPLATEEXPRESSIONBETWEENDOUBLECURLYBRACESRENDERSASTEXTTHATTEXTMAYBECONCATENATEDWITHNEIGHBORINGTEXTBEFOREITISASSIGNEDTOANELEMENTPROPERTYORDISPLAYEDBETWEENELEMENTTAGSASINTHISEXAMPLE", "original": "A form of [property data binding](guide/glossary#data-binding) in which a\n[template expression](guide/glossary#template-expression) between double-curly braces\nrenders as text. That text may be concatenated with neighboring text\nbefore it is assigned to an element property\nor displayed between element tags, as in this example.", "translation": "[属性数据绑定 (property data binding)](guide/glossary#data-binding) 的一种形式,位于双大括号中的[模板表达式 (template expression)](guide/glossary#template-expression)会被渲染成文本。\n在被赋值给元素属性或者显示在元素标签中之前,这些文本可能会先与周边的文本合并,参见下面的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "READMOREABOUTINTERPOLATIONGUIDETEMPLATESYNTAX#INTERPOLATIONINTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "Read more about [interpolation](guide/template-syntax#interpolation) in the\n[Template Syntax](guide/template-syntax) page.", "translation": "更多信息,见[模板语法](guide/template-syntax)中的[插值表达式](guide/template-syntax#interpolation)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##JUSTINTIMEJITCOMPILATION", "original": "## Just-in-time (JIT) compilation", "translation": "## 即时 (just-in-time, JIT) 编译", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ABOOTSTRAPPINGMETHODOFCOMPILINGCOMPONENTSANDMODULESINTHEBROWSERANDLAUNCHINGTHEAPPLICATIONDYNAMICALLYJUSTINTIMEMODEISAGOODCHOICEDURINGDEVELOPMENTCONSIDERUSINGTHEAHEADOFTIMEGUIDEGLOSSARY#AOTMODEFORPRODUCTIONAPPS", "original": "A bootstrapping method of compiling components and modules in the browser\nand launching the application dynamically. Just-in-time mode is a good choice during development.\nConsider using the [ahead-of-time](guide/glossary#aot) mode for production apps.", "translation": "Angular 的即时编译在浏览器中启动并编译所有的组件和模块,动态运行应用程序。\n 它很适合在开发过程中使用。但是在产品发布时,推荐采用[预编译 (ahead-of-time)](guide/glossary#aot) 模式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##KEBABCASE", "original": "## kebab-case", "translation": "## 烤串命名法 (kebab-case)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "SEEDASHCASEGUIDEGLOSSARY#DASHCASE", "original": "See [dash-case](guide/glossary#dash-case).", "translation": "见[中线命名法 (dash-case)](guide/glossary#dash-case)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##LIFECYCLEHOOKS", "original": "## Lifecycle hooks", "translation": "## 生命周期钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "DIRECTIVESGUIDEGLOSSARY#DIRECTIVEANDCOMPONENTSGUIDEGLOSSARY#COMPONENTHAVEALIFECYCLEMANAGEDBYANGULARASITCREATESUPDATESANDDESTROYSTHEM", "original": "[Directives](guide/glossary#directive) and [components](guide/glossary#component) have a lifecycle\nmanaged by Angular as it creates, updates, and destroys them.", "translation": "[指令 (directive)](guide/glossary#directive) 和[组件 (component)](guide/glossary#component) 具有生命周期,由 Angular 在创建、更新和销毁它们的过程中进行管理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOUCANTAPINTOKEYMOMENTSINTHATLIFECYCLEBYIMPLEMENTINGONEORMOREOFTHELIFECYCLEHOOKINTERFACES", "original": "You can tap into key moments in that lifecycle by implementing\none or more of the lifecycle hook interfaces.", "translation": "你可以通过实现一个或多个生命周期钩子接口,切入到生命周期中的关键时间点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "EACHINTERFACEHASASINGLEHOOKMETHODWHOSENAMEISTHEINTERFACENAMEPREFIXEDWITHNGFOREXAMPLETHEONINITINTERFACEHASAHOOKMETHODNAMEDNGONINIT", "original": "Each interface has a single hook method whose name is the interface name prefixed with `ng`.\nFor example, the `OnInit` interface has a hook method named `ngOnInit`.", "translation": "每个接口只有一个钩子方法,方法名是接口名加前缀 `ng`。例如,`OnInit` 接口的钩子方法名为 `ngOnInit`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARCALLSTHESEHOOKMETHODSINTHEFOLLOWINGORDER:", "original": "Angular calls these hook methods in the following order:", "translation": "Angular 会按以下顺序调用钩子方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGONCHANGES:WHENANINPUTGUIDEGLOSSARY#INPUTOUTPUTGUIDEGLOSSARY#OUTPUTBINDINGVALUECHANGES", "original": "* `ngOnChanges`: when an [input](guide/glossary#input)/[output](guide/glossary#output) binding value changes.", "translation": "`ngOnChanges` - 在[输入属性 (input)](guide/glossary#input)/[输出属性 (output)](guide/glossary#output)的绑定值发生变化时调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGONINIT:AFTERTHEFIRSTNGONCHANGES", "original": "* `ngOnInit`: after the first `ngOnChanges`.", "translation": "`ngOnInit` - 在第一次 `ngOnChanges` 完成后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGDOCHECK:DEVELOPERSCUSTOMCHANGEDETECTION", "original": "* `ngDoCheck`: developer's custom change detection.", "translation": "`ngDoCheck` - 开发者自定义变更检测。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGAFTERCONTENTINIT:AFTERCOMPONENTCONTENTINITIALIZED", "original": "* `ngAfterContentInit`: after component content initialized.", "translation": "`ngAfterContentInit` - 在组件内容初始化后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGAFTERCONTENTCHECKED:AFTEREVERYCHECKOFCOMPONENTCONTENT", "original": "* `ngAfterContentChecked`: after every check of component content.", "translation": "`ngAfterContentChecked` - 在组件内容每次检查后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGAFTERVIEWINIT:AFTERACOMPONENTSVIEWSAREINITIALIZED", "original": "* `ngAfterViewInit`: after a component's views are initialized.", "translation": "`ngAfterViewInit` - 在组件视图初始化后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGAFTERVIEWCHECKED:AFTEREVERYCHECKOFACOMPONENTSVIEWS", "original": "* `ngAfterViewChecked`: after every check of a component's views.", "translation": "`ngAfterViewChecked` - 在组件视图每次检查后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGONDESTROY:JUSTBEFORETHEDIRECTIVEISDESTROYED", "original": "* `ngOnDestroy`: just before the directive is destroyed.", "translation": "`ngOnDestroy` - 在指令销毁前调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "READMOREINTHELIFECYCLEHOOKSGUIDELIFECYCLEHOOKSPAGE", "original": "Read more in the [Lifecycle Hooks](guide/lifecycle-hooks) page.", "translation": "更多信息,见[生命周期钩子 (lifecycle hook)](guide/lifecycle-hooks)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##MODULE", "original": "## Module", "translation": "## 模块 (module)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARHASTHEFOLLOWINGTYPESOFMODULES:", "original": "Angular has the following types of modules:", "translation": "Angular 有下列模块类型:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGMODULESGUIDEGLOSSARY#NGMODULEFORDETAILSANDEXAMPLESSEETHENGMODULESGUIDENGMODULESPAGE", "original": "* [NgModules](guide/glossary#ngmodule).\nFor details and examples, see the [NgModules](guide/ngmodules) page.", "translation": "[Angular 模块](guide/glossary#ngmodule),见[Angular 模块](guide/ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ES2015MODULESASDESCRIBEDINTHISSECTION", "original": "* ES2015 modules, as described in this section.", "translation": "ES2015 模块,如本节所述。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FORACOMPARISONSEEJAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "For a comparison, see [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", "translation": "要对比这两个概念,请参见[JavaScript 模块 vs. NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ACOHESIVEBLOCKOFCODEDEDICATEDTOASINGLEPURPOSE", "original": "A cohesive block of code dedicated to a single purpose.", "translation": "模块是一个内聚的代码块,具有单一用途。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARAPPSAREMODULAR", "original": "Angular apps are modular.", "translation": "Angular 应用程序是模块化的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "INGENERALYOUASSEMBLEANAPPLICATIONFROMMANYMODULESBOTHTHEONESYOUWRITEANDTHEONESYOUACQUIREFROMOTHERS", "original": "In general, you assemble an application from many modules, both the ones you write and the ones you acquire from others.", "translation": "一般来说,你用模块来组装应用程序,这些模块包含自己编写的模块和从其它地方获取的模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "AMODULEEXPORTSSOMETHINGOFVALUEINTHATCODETYPICALLYONETHINGSUCHASACLASSAMODULETHATNEEDSTHATCLASSIMPORTSIT", "original": "A module *exports* something of value in that code, typically one thing such as a class;\na module that needs that class *imports* it.", "translation": "模块会**导出 (export) **代码中的某些值,最典型的就是类。\n模块如果需要什么东西,那就**导入 (import) **它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THESTRUCTUREOFNGMODULESANDTHEIMPORTEXPORTSYNTAXISBASEDONTHEES2015MODULESTANDARDHTTP:WWW2ALITYCOM201409ES6MODULESFINALHTML", "original": "The structure of NgModules and the import/export syntax\nis based on the [ES2015 module standard](http://www.2ality.com/2014/09/es6-modules-final.html).", "translation": "Angular 的模块结构和导入/导出语法是基于 [ES2015 模块标准](http://www.2ality.com/2014/09/es6-modules-final.html)的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANAPPLICATIONTHATADHERESTOTHISSTANDARDREQUIRESAMODULELOADERTOLOADMODULESONREQUESTANDRESOLVEINTERMODULEDEPENDENCIESANGULARDOESNTINCLUDEAMODULELOADERANDDOESNTHAVEAPREFERENCEFORANYPARTICULARTHIRDPARTYLIBRARYYOUCANUSEANYMODULELIBRARYTHATCONFORMSTOTHESTANDARD", "original": "An application that adheres to this standard requires a module loader to\nload modules on request and resolve inter-module dependencies.\nAngular doesn't include a module loader and doesn't have a preference\nfor any particular third-party library.\nYou can use any module library that conforms to the standard.", "translation": "采用这个标准的应用程序需要一个模块加载器来按需加载模块,并解析模块间的依赖关系。\nAngular 不附带模块加载器,也不偏爱任何第三方库(虽然大多数例子使用 SystemJS)。\n你可以选择任何与这个标准兼容的模块化库。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "MODULESARETYPICALLYNAMEDAFTERTHEFILEINWHICHTHEEXPORTEDTHINGISDEFINEDTHEANGULARDATEPIPEHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERPACKAGESCOMMONSRCPIPESDATEPIPETSCLASSBELONGSTOAFEATUREMODULENAMEDDATEPIPEINTHEFILEDATEPIPETS", "original": "Modules are typically named after the file in which the exported thing is defined.\nThe Angular [DatePipe](https://github.com/angular/angular/blob/master/packages/common/src/pipes/date_pipe.ts)\nclass belongs to a feature module named `date_pipe` in the file `date_pipe.ts`.", "translation": "模块一般与它定义导出物的文件同名。例如,Angular 的 [DatePipe](https://github.com/angular/angular/blob/master/modules/angular2/src/common/pipes/date_pipe.ts) 类属于名叫 `date_pipe` 的特性模块,位于 `date_pipe.ts` 文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOURARELYACCESSANGULARFEATUREMODULESDIRECTLYYOUUSUALLYIMPORTTHEMFROMANANGULARSCOPEDPACKAGEGUIDEGLOSSARY#SCOPEDPACKAGESUCHASANGULARCORE", "original": "You rarely access Angular feature modules directly. You usually import them from an Angular [scoped package](guide/glossary#scoped-package) such as `@angular/core`.", "translation": "你很少需要直接访问 Angular 的特性模块。\n而通常会从一个 Angular [范围化包 (scoped package)](guide/glossary#scoped-package)中导入它们,例如 `@angular/core`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "HELPSYOUORGANIZEANAPPLICATIONINTOCOHESIVEBLOCKSOFFUNCTIONALITYANNGMODULEIDENTIFIESTHECOMPONENTSDIRECTIVESANDPIPESTHATTHEAPPLICATIONUSESALONGWITHTHELISTOFEXTERNALNGMODULESTHATTHEAPPLICATIONNEEDSSUCHASFORMSMODULE", "original": "Helps you organize an application into cohesive blocks of functionality.\nAn NgModule identifies the components, directives, and pipes that the application uses along with the list of external NgModules that the application needs, such as `FormsModule`.", "translation": "帮助你把应用组织成多个内聚的功能块。\nNgModule 表示应用的组件、指令和管道以及所用到的外部模块的列表,比如 `FormsModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "EVERYANGULARAPPLICATIONHASANAPPLICATIONROOTMODULECLASSBYCONVENTIONTHECLASSISCALLEDAPPMODULEANDRESIDESINAFILENAMEDAPPMODULETS", "original": "Every Angular application has an application root-module class. By convention, the class is\ncalled `AppModule` and resides in a file named `app.module.ts`.", "translation": "每个 Angular 应用都有一个应用级根模块类。这类通常叫做 `AppModule`,并且位于一个名叫 `app.module.ts` 的文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FORDETAILSANDEXAMPLESSEENGMODULESGUIDENGMODULESANDTHERELATEDFILESINTHATSECTION", "original": "For details and examples, see [NgModules](guide/ngmodules) and the \nrelated files in that section.", "translation": "要获得详情和范例,参见 [NgModule](guide/ngmodules) 及其相关文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##OBSERVABLE", "original": "## Observable", "translation": "## Observable 对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANARRAYWHOSEITEMSARRIVEASYNCHRONOUSLYOVERTIMEOBSERVABLESHELPYOUMANAGEASYNCHRONOUSDATASUCHASDATACOMINGFROMABACKENDSERVICEOBSERVABLESAREUSEDWITHINANGULARITSELFINCLUDINGANGULARSEVENTSYSTEMANDITSHTTPCLIENTSERVICE", "original": "An array whose items arrive asynchronously over time.\nObservables help you manage asynchronous data, such as data coming from a backend service.\nObservables are used within Angular itself, including Angular's event system and its HTTP client service.", "translation": "一个 `Observable` 是一个数组,其中的元素随着时间的流逝异步地到达。\n`Observable` 帮助你管理异步数据,例如来自后台服务的数据。\nAngular 自身使用了 `Observable`,包括 Angular 的事件系统和它的 http 客户端服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "TOUSEOBSERVABLESANGULARUSESATHIRDPARTYLIBRARYCALLEDREACTIVEEXTENSIONSRXJSOBSERVABLESAREAPROPOSEDFEATUREFORES2016THENEXTVERSIONOFJAVASCRIPT", "original": "To use observables, Angular uses a third-party library called Reactive Extensions (RxJS).\nObservables are a proposed feature for ES2016, the next version of JavaScript.", "translation": "为了使用 `Observable`, Angular 采用了名为 Reactive Extensions (RxJS) 的第三方包。\n在下个版本的 JavaScript - ES 2016 中,`Observable` 是建议的特性之一。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##OUTPUT", "original": "## Output", "translation": "## 输出属性 (output)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ADIRECTIVEPROPERTYTHATCANBETHETARGETOFEVENTBINDINGREADMOREINTHEEVENTBINDINGGUIDETEMPLATESYNTAX#EVENTBINDINGSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGEEVENTSSTREAMOUTOFTHISPROPERTYTOTHERECEIVERIDENTIFIEDINTHETEMPLATEEXPRESSIONTOTHERIGHTOFTHEEQUALSIGN", "original": "A directive property that can be the *target* of event binding\n(read more in the [event binding](guide/template-syntax#event-binding)\nsection of the [Template Syntax](guide/template-syntax) page).\nEvents stream *out* of this property to the receiver identified\nin the template expression to the right of the equal sign.", "translation": "输出属性是一个指令属性,可作为[事件绑定](guide/template-syntax.html#event-binding)的 **目标** 。\n事件流从这个属性流*出*到模板表达式等号的右边的接收者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "SEETHEINPUTANDOUTPUTPROPERTIESGUIDETEMPLATESYNTAX#INPUTSOUTPUTSSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "See the [Input and output properties](guide/template-syntax#inputs-outputs) section of the [Template Syntax](guide/template-syntax) page.", "translation": "参见[模板语法](guide/template-syntax)中的[输入与输出属性](guide/template-syntax#inputs-outputs)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##PASCALCASE", "original": "## PascalCase", "translation": "## Pascal 命名法 (PascalCase)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEPRACTICEOFWRITINGINDIVIDUALWORDSCOMPOUNDWORDSORPHRASESSUCHTHATEACHWORDORABBREVIATIONBEGINSWITHACAPITALLETTERCLASSNAMESARETYPICALLYSPELLEDINPASCALCASEFOREXAMPLEPERSONANDHERODETAILCOMPONENT", "original": "The practice of writing individual words, compound words, or phrases such that each word or abbreviation begins with a capital letter.\nClass names are typically spelled in PascalCase. For example, `Person` and `HeroDetailComponent`.", "translation": "Pascal 命名法是书写单词、复合词或短语的一种形式,每个单词或缩写都以大写开头。\n类名一般都采用 Pascal 命名法。例如 `Person` 和 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THISFORMISALSOKNOWNASUPPERCAMELCASETODISTINGUISHITFROMLOWERCAMELCASEORSIMPLYCAMELCASEGUIDEGLOSSARY#CAMELCASEINTHISDOCUMENTATIONPASCALCASEMEANSUPPERCAMELCASEANDCAMELCASEMEANSLOWERCAMELCASE", "original": "This form is also known as *upper camel case* to distinguish it from *lower camel case* or simply [camelCase](guide/glossary#camelcase).\nIn this documentation, \"PascalCase\" means *upper camel case* and \"camelCase\" means *lower camel case*.", "translation": "这种形式也称**大写驼峰式命名法**,以区别于**小写驼峰式命名法”或[驼峰式命名法 (camelCase)](guide/glossary#camelcase)** 。\n在本文档中,“Pascal 命名法”都是指的*大写驼峰式命名法*,“驼峰式命名法”指的都是*小写驼峰式命名法*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##PIPE", "original": "## Pipe", "translation": "## 管道 (pipe)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANANGULARPIPEISAFUNCTIONTHATTRANSFORMSINPUTVALUESTOOUTPUTVALUESFORDISPLAYINAVIEWGUIDEGLOSSARY#VIEWHERESANEXAMPLETHATUSESTHEBUILTINCURRENCYPIPETODISPLAYANUMERICVALUEINTHELOCALCURRENCY", "original": "An Angular pipe is a function that transforms input values to output values for\ndisplay in a [view](guide/glossary#view).\nHere's an example that uses the built-in `currency` pipe to display\na numeric value in the local currency.", "translation": "Angular 管道是一个函数,用于把输入值转换成输出值以供[视图 (view)](guide/glossary#view)显示。\n下面这个例子中,用内置的 `currency` 管道把数字值显示为本地货币格式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "YOUCANALSOWRITEYOUROWNCUSTOMPIPESREADMOREINTHEPAGEONPIPESGUIDEPIPES", "original": "You can also write your own custom pipes.\nRead more in the page on [pipes](guide/pipes).", "translation": "你还可以写自己的自定义管道。\n更多信息,见[管道](guide/pipes)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##PROVIDER", "original": "## Provider", "translation": "## 提供商 (provider)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "APROVIDERCREATESANEWINSTANCEOFADEPENDENCYFORTHEDEPENDENCYINJECTIONGUIDEGLOSSARY#DEPENDENCYINJECTIONSYSTEMITRELATESALOOKUPTOKENTOCODEMDASHSOMETIMESCALLEDARECIPEMDASHTHATCANCREATEADEPENDENCYVALUE", "original": "A _provider_ creates a new instance of a dependency for the\n[dependency injection](guide/glossary#dependency-injection) system.\nIt relates a lookup token to code—sometimes called a \"recipe\"—that can create a dependency value.", "translation": "依赖注入系统依靠提供商来创建依赖的实例。\n它把一个查找令牌和代码(有时也叫“配方”)关联到一起,以便创建依赖值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##REACTIVEFORMS", "original": "## Reactive forms", "translation": "## 响应式表单 (reactive forms)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ATECHNIQUEFORBUILDINGANGULARFORMSTHROUGHCODEINACOMPONENTTHEALTERNATIVETECHNIQUEISTEMPLATEDRIVENFORMSGUIDEGLOSSARY#TEMPLATEDRIVENFORMS", "original": "A technique for building Angular forms through code in a component.\nThe alternative technique is [template-driven forms](guide/glossary#template-driven-forms).", "translation": "通过组件中代码构建 Angular 表单的一种技术。\n另一种技术是[模板驱动表单](guide/glossary#template-driven-forms)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "WHENBUILDINGREACTIVEFORMS:", "original": "When building reactive forms:", "translation": "构建响应式表单时:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THESOURCEOFTRUTHISTHECOMPONENTTHEVALIDATIONISDEFINEDUSINGCODEINTHECOMPONENT", "original": "* The \"source of truth\" is the component. The validation is defined using code in the component.", "translation": "组件是“真理之源”。表单验证在组件代码中定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "EACHCONTROLISEXPLICITLYCREATEDINTHECOMPONENTCLASSWITHNEWFORMCONTROLORWITHFORMBUILDER", "original": "* Each control is explicitly created in the component class with `new FormControl()` or with `FormBuilder`.", "translation": "在组件类中,使用 `new FormControl()` 或者 `FormBuilder` 显性地创建每个控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THETEMPLATEINPUTELEMENTSDONOTUSENGMODEL", "original": "* The template input elements do *not* use `ngModel`.", "translation": "模板中的 `input` 元素**不**使用 `ngModel`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEASSOCIATEDANGULARDIRECTIVESAREALLPREFIXEDWITHFORMSUCHASFORMGROUPFORMCONTROLANDFORMCONTROLNAME", "original": "* The associated Angular directives are all prefixed with `Form`, such as `FormGroup`, `FormControl`, and `FormControlName`.", "translation": "相关联的 Angular 指令全部以 `Form` 开头,例如 `FormGroup`、`FormControl` 和 `FormControlName`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "REACTIVEFORMSAREPOWERFULFLEXIBLEANDAGOODCHOICEFORMORECOMPLEXDATAENTRYFORMSCENARIOSSUCHASDYNAMICGENERATIONOFFORMCONTROLS", "original": "Reactive forms are powerful, flexible, and a good choice for more complex data-entry form scenarios, such as dynamic generation of form controls.", "translation": "动态表单非常强大、灵活,它在复杂数据输入的场景下尤其好用,例如动态的生成表单控制器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ROUTER", "original": "## Router", "translation": "## 路由器 (router)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "MOSTAPPLICATIONSCONSISTOFMANYSCREENSORVIEWSGUIDEGLOSSARY#VIEWTHEUSERNAVIGATESAMONGTHEMBYCLICKINGLINKSANDBUTTONSANDPERFORMINGOTHERSIMILARACTIONSTHATCAUSETHEAPPLICATIONTOREPLACEONEVIEWWITHANOTHER", "original": "Most applications consist of many screens or [views](guide/glossary#view).\nThe user navigates among them by clicking links and buttons,\nand performing other similar actions that cause the application to\nreplace one view with another.", "translation": "大多数应用程序包含多个屏幕或[视图 (view)](guide/glossary#view)。\n用户通过点击链接、按钮和其它类似动作,在它们之间导航,使应用程序从一个视图切换到另一个视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEANGULARCOMPONENTROUTERISARICHLYFEATUREDMECHANISMFORCONFIGURINGANDMANAGINGTHEENTIREVIEWNAVIGATIONPROCESSINCLUDINGTHECREATIONANDDESTRUCTIONOFVIEWS", "original": "The Angular component router is a richly featured mechanism for configuring and managing the entire view navigation process, including the creation and destruction\nof views.", "translation": "Angular 的组件路由器是一个特性丰富的机制,可以配置和管理整个导航过程,包括建立和销毁视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "INMOSTCASESCOMPONENTSBECOMEATTACHEDTOAROUTERBYMEANSOFAROUTERCONFIGTHATDEFINESROUTESTOVIEWS", "original": "In most cases, components become attached to a router by means\nof a `RouterConfig` that defines routes to views.", "translation": "多数情况下,组件会通过 `RouterConfig` 中定义的路由到视图的对照表来附加到[路由器](guide/glossary#router)上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "AROUTINGCOMPONENTSGUIDEGLOSSARY#ROUTINGCOMPONENTTEMPLATEHASAROUTEROUTLETELEMENTWHEREITCANDISPLAYVIEWSPRODUCEDBYTHEROUTER", "original": "A [routing component's](guide/glossary#routing-component) template has a `RouterOutlet` element\nwhere it can display views produced by the router.", "translation": "[路由组件](guide/glossary#routing-component)的模板中带有一个 `RouterOutlet` 元素,那是显示路由器生成的视图的地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "OTHERVIEWSINTHEAPPLICATIONLIKELYHAVEANCHORTAGSORBUTTONSWITHROUTERLINKDIRECTIVESTHATUSERSCANCLICKTONAVIGATE", "original": "Other views in the application likely have anchor tags or buttons with `RouterLink`\ndirectives that users can click to navigate.", "translation": "应用中的其它视图中某些锚标签或按钮上带有 `RouterLink` 指令,用户可以点击它们进行导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FORMOREINFORMATIONSEETHEROUTINGNAVIGATIONGUIDEROUTERPAGE", "original": "For more information, see the [Routing & Navigation](guide/router) page.", "translation": "更多信息,见[路由与导航](guide/router)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ROUTERMODULE", "original": "## Router module", "translation": "## 路由器模块 (router module)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ASEPARATENGMODULEGUIDEGLOSSARY#NGMODULETHATPROVIDESTHENECESSARYSERVICEPROVIDERSANDDIRECTIVESFORNAVIGATINGTHROUGHAPPLICATIONVIEWS", "original": "A separate [NgModule](guide/glossary#ngmodule) that provides the necessary service providers and directives for navigating through application views.", "translation": "一个独立的 [Angular 模块](guide/glossary#ngmodule),用来提供导航所需的服务提供商和指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FORMOREINFORMATIONSEETHEROUTINGNAVIGATIONGUIDEROUTERPAGE", "original": "For more information, see the [Routing & Navigation](guide/router) page.", "translation": "更多信息,见[路由与导航](guide/router)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ROUTINGCOMPONENT", "original": "## Routing component", "translation": "## 路由组件 (routing component)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANANGULARCOMPONENTGUIDEGLOSSARY#COMPONENTWITHAROUTEROUTLETTHATDISPLAYSVIEWSBASEDONROUTERNAVIGATIONS", "original": "An Angular [component](guide/glossary#component) with a `RouterOutlet` that displays views based on router navigations.", "translation": "一个带有 RouterOutlet 的 Angular [组件](guide/glossary#component),根据路由器导航来显示视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FORMOREINFORMATIONSEETHEROUTINGNAVIGATIONGUIDEROUTERPAGE", "original": "For more information, see the [Routing & Navigation](guide/router) page.", "translation": "更多信息,见[路由与导航](guide/router)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##SCOPEDPACKAGE", "original": "## Scoped package", "translation": "## 范围化包 (scoped package)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "AWAYTOGROUPRELATEDNPMPACKAGESREADMOREATTHENPMSCOPEHTTPS:DOCSNPMJSCOMMISCSCOPEPAGE", "original": "A way to group related *npm* packages.\nRead more at the [npm-scope](https://docs.npmjs.com/misc/scope) page.", "translation": "对相关的 *npm* 包进行分组的一种方式,参阅[npm-scope](https://docs.npmjs.com/misc/scope)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "NGMODULESAREDELIVEREDWITHINSCOPEDPACKAGESSUCHASANGULARCOREANGULARCOMMONANGULARPLATFORMBROWSERDYNAMICANGULARHTTPANDANGULARROUTER", "original": "NgModules are delivered within *scoped packages* such as `@angular/core`,\n`@angular/common`, `@angular/platform-browser-dynamic`, `@angular/http`, and `@angular/router`.", "translation": "Angular 模块是用一系列*范围化包*的形式发布的,例如 `@angular/core`、`@angular/common`、`@angular/platform-browser-dynamic`、`@angular/http` 和 `@angular/router`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "IMPORTASCOPEDPACKAGETHESAMEWAYTHATYOUIMPORTANORMALPACKAGETHEONLYDIFFERENCEFROMACONSUMERPERSPECTIVEISTHATTHESCOPEDPACKAGENAMEBEGINSWITHTHEANGULARSCOPENAMEANGULAR", "original": "Import a scoped package the same way that you import a normal package.\nThe only difference, from a consumer perspective,\nis that the scoped package name begins with the Angular *scope name*, `@angular`.", "translation": "导入范围化包与导入*普通*包方式相同。\n 从消费者的视角看,唯一的不同是那些包的名字是用 Angular 的*范围化包名*`@angular` 开头的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##SERVICE", "original": "## Service", "translation": "## 服务 (service)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FORDATAORLOGICTHATISNOTASSOCIATEDWITHASPECIFICVIEWORTHATYOUWANTTOSHAREACROSSCOMPONENTSBUILDSERVICES", "original": "For data or logic that is not associated\nwith a specific view or that you want to share across components, build services.", "translation": "服务用于封装不与任何特定视图相关的数据和逻辑,或者用于在组件之间共享数据和逻辑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "APPLICATIONSOFTENREQUIRESERVICESSUCHASAHERODATASERVICEORALOGGINGSERVICE", "original": "Applications often require services such as a hero data service or a logging service.", "translation": "应用程序经常需要服务,例如英雄数据服务或者日志服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ASERVICEISACLASSWITHAFOCUSEDPURPOSEYOUOFTENCREATEASERVICETOIMPLEMENTFEATURESTHATAREINDEPENDENTFROMANYSPECIFICVIEWPROVIDESHAREDDATAORLOGICACROSSCOMPONENTSORENCAPSULATEEXTERNALINTERACTIONS", "original": "A service is a class with a focused purpose.\nYou often create a service to implement features that are\nindependent from any specific view,\nprovide shared data or logic across components, or encapsulate external interactions.", "translation": "服务是一个具有特定功能的类。\n你经常创建服务来实现不依赖任何特定视图的特征,\n在组件之间提供共享数据或逻辑,或者封装外部的交互。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "APPLICATIONSOFTENREQUIRESERVICESSUCHASADATASERVICEORALOGGINGSERVICE", "original": "Applications often require services such as a data service or a logging service.", "translation": "应用通常都需要服务,比如数据服务或者日志服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "FORMOREINFORMATIONSEETHESERVICESTUTORIALTOHPT4PAGEOFTHETOUROFHEROESTUTORIALTUTORIAL", "original": "For more information, see the [Services](tutorial/toh-pt4) page of the [Tour of Heroes](tutorial) tutorial.", "translation": "更多信息,见[英雄指南](tutorial)中的[服务](tutorial/toh-pt4)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##SNAKECASE", "original": "## snake_case", "translation": "## 蛇形命名法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEPRACTICEOFWRITINGCOMPOUNDWORDSORPHRASESSUCHTHATANUNDERSCORESEPARATESONEWORDFROMTHENEXTTHISFORMISALSOKNOWNASUNDERSCORECASE", "original": "The practice of writing compound words or phrases such that an\nunderscore (`_`) separates one word from the next. This form is also known as *underscore case*.", "translation": "写复合词或短语的一种方式,在多个词之间用下划线(`_`)分隔。也叫*下划线命名法*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##STRUCTURALDIRECTIVES", "original": "## Structural directives", "translation": "## 结构型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ACATEGORYOFDIRECTIVEGUIDEGLOSSARY#DIRECTIVETHATCANSHAPEORRESHAPEHTMLLAYOUTTYPICALLYBYADDINGANDREMOVINGELEMENTSINTHEDOMTHENGIFCONDITIONALELEMENTDIRECTIVEANDTHENGFORREPEATERDIRECTIVEAREWELLKNOWNEXAMPLES", "original": "A category of [directive](guide/glossary#directive) that can\nshape or reshape HTML layout, typically by adding and removing elements in the DOM.\nThe `ngIf` \"conditional element\" directive and the `ngFor` \"repeater\" directive are well-known examples.", "translation": "结构型指令是[指令 (directive)](guide/glossary#directive)一种,\n可以通过在 DOM 中添加、删除或操作元素和其各级子元素来塑造或重塑 HTML 布局。\n例如,`ngIf` 这个“条件化元素”指令,`ngFor` 这个“重复器”指令都是众所周知的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "READMOREINTHESTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVESPAGE", "original": "Read more in the [Structural Directives](guide/structural-directives) page.", "translation": "更多信息,见[结构型指令](guide/structural-directives)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##TEMPLATE", "original": "## Template", "translation": "## 模板 (template)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ACHUNKOFHTMLTHATANGULARUSESTORENDERAVIEWGUIDEGLOSSARY#VIEWWITHTHESUPPORTANDGUIDANCEOFANANGULARDIRECTIVEGUIDEGLOSSARY#DIRECTIVEMOSTNOTABLYACOMPONENTGUIDEGLOSSARY#COMPONENT", "original": "A chunk of HTML that Angular uses to render a [view](guide/glossary#view) with\nthe support and guidance of an Angular [directive](guide/glossary#directive),\nmost notably a [component](guide/glossary#component).", "translation": "模板是一大块 HTML。Angular 会在[指令 (directive)](guide/glossary#directive) 特别是[组件 (component)](guide/glossary#component)\n 的支持和持续指导下,用它来渲染[视图 (view)](guide/glossary#view)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##TEMPLATEDRIVENFORMS", "original": "## Template-driven forms", "translation": "## 模板驱动表单 (template-driven forms)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ATECHNIQUEFORBUILDINGANGULARFORMSUSINGHTMLFORMSANDINPUTELEMENTSINTHEVIEWTHEALTERNATETECHNIQUEISREACTIVEFORMSGUIDEGLOSSARY#REACTIVEFORMS", "original": "A technique for building Angular forms using HTML forms and input elements in the view.\nThe alternate technique is [Reactive Forms](guide/glossary#reactive-forms).", "translation": "一项在视图中使用 HTML 表单和输入类元素构建 Angular 表单的技术。\n 它的替代方案是[响应式表单](guide/glossary#reactive-forms)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "WHENBUILDINGTEMPLATEDRIVENFORMS:", "original": "When building template-driven forms:", "translation": "当构建模板驱动表单时:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THESOURCEOFTRUTHISTHETEMPLATETHEVALIDATIONISDEFINEDUSINGATTRIBUTESONTHEINDIVIDUALINPUTELEMENTS", "original": "* The \"source of truth\" is the template. The validation is defined using attributes on the individual input elements.", "translation": "模板是“真理之源”。使用属性 (attribute) 在单个输入元素上定义验证规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "TWOWAYBINDINGGUIDEGLOSSARY#DATABINDINGWITHNGMODELKEEPSTHECOMPONENTMODELSYNCHRONIZEDWITHTHEUSERSENTRYINTOTHEINPUTELEMENTS", "original": "* [Two-way binding](guide/glossary#data-binding) with `ngModel` keeps the component model synchronized with the user's entry into the input elements.", "translation": "使用 `ngModel` 进行[双向绑定](guide/glossary#data-binding),保持组件模型和用户输入之间的同步。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "BEHINDTHESCENESANGULARCREATESANEWCONTROLFOREACHINPUTELEMENTPROVIDEDYOUHAVESETUPANAMEATTRIBUTEANDTWOWAYBINDINGFOREACHINPUT", "original": "* Behind the scenes, Angular creates a new control for each input element, provided you have set up a `name` attribute and two-way binding for each input.", "translation": "在幕后,Angular 为每个带有 `name` 属性和双向绑定的输入元素创建了一个新的控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEASSOCIATEDANGULARDIRECTIVESAREALLPREFIXEDWITHNGSUCHASNGFORMNGMODELANDNGMODELGROUP", "original": "* The associated Angular directives are all prefixed with `ng` such as `ngForm`, `ngModel`, and `ngModelGroup`.", "translation": "相关的 Angular 指令都带有 `ng` 前缀,例如 `ngForm`、`ngModel` 和 `ngModelGroup`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "TEMPLATEDRIVENFORMSARECONVENIENTQUICKANDSIMPLETHEYAREAGOODCHOICEFORMANYBASICDATAENTRYFORMSCENARIOS", "original": "Template-driven forms are convenient, quick, and simple. They are a good choice for many basic data-entry form scenarios.", "translation": "模板驱动表单便捷、快速、简单,是很多基础型数据输入表单的最佳选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "READABOUTHOWTOBUILDTEMPLATEDRIVENFORMSINTHEFORMSGUIDEFORMSPAGE", "original": "Read about how to build template-driven forms\nin the [Forms](guide/forms) page.", "translation": "要了解如何构建模板驱动表单的更多信息,参见[表单](guide/forms)页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##TEMPLATEEXPRESSION", "original": "## Template expression", "translation": "## 模板表达式 (template expression)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ATYPESCRIPTLIKESYNTAXTHATANGULAREVALUATESWITHINADATABINDINGGUIDEGLOSSARY#DATABINDING", "original": "A TypeScript-like syntax that Angular evaluates within\na [data binding](guide/glossary#data-binding).", "translation": "Angular 用来在[数据绑定 (data binding)](guide/glossary#data-binding)内求值的、**类似**JavaScript 语法的表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "READABOUTHOWTOWRITETEMPLATEEXPRESSIONSINTHETEMPLATEEXPRESSIONSGUIDETEMPLATESYNTAX#TEMPLATEEXPRESSIONSSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGE", "original": "Read about how to write template expressions\nin the [Template expressions](guide/template-syntax#template-expressions) section\nof the [Template Syntax](guide/template-syntax) page.", "translation": "到[模板语法](guide/template-syntax)一章的[模板表达式](guide/template-syntax#template-expressions)部分了解更多模板表达式的知识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##TRANSPILE", "original": "## Transpile", "translation": "## 转译(transpile)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEPROCESSOFTRANSFORMINGCODEWRITTENINONEFORMOFJAVASCRIPTSUCHASTYPESCRIPTINTOANOTHERFORMOFJAVASCRIPTSUCHASES5GUIDEGLOSSARY#ES5", "original": "The process of transforming code written in one form of JavaScript\n(such as TypeScript) into another form of JavaScript (such as [ES5](guide/glossary#es5)).", "translation": "把一种形式的 JavaScript(例如 TypeScript)转换成另一种形式的 JavaScript(例如 [ES5](guide/glossary#es5))的过程。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##TYPESCRIPT", "original": "## TypeScript", "translation": "## TypeScript 语言", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "AVERSIONOFJAVASCRIPTTHATSUPPORTSMOSTECMASCRIPT2015GUIDEGLOSSARY#ES2015LANGUAGEFEATURESSUCHASDECORATORSGUIDEGLOSSARY#DECORATOR", "original": "A version of JavaScript that supports most [ECMAScript 2015](guide/glossary#es2015)\nlanguage features such as [decorators](guide/glossary#decorator).", "translation": "JavaScript 的一个版本,支持了几乎所有 [ECMAScript 2015](guide/glossary#es2015) 语言特性,例如[装饰器 (decorator)](guide/glossary#decorator))。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "TYPESCRIPTISALSONOTABLEFORITSOPTIONALTYPINGSYSTEMWHICHPROVIDESCOMPILETIMETYPECHECKINGANDSTRONGTOOLINGSUPPORTSUCHASINTELLISENSECODECOMPLETIONREFACTORINGANDINTELLIGENTSEARCHMANYCODEEDITORSANDIDESSUPPORTTYPESCRIPTEITHERNATIVELYORWITHPLUGINS", "original": "TypeScript is also notable for its optional typing system, which provides\ncompile-time type checking and strong tooling support (such as \"intellisense,\"\ncode completion, refactoring, and intelligent search). Many code editors\nand IDEs support TypeScript either natively or with plugins.", "translation": "TypeScript 还以它的可选类型系统而著称。\n该类型系统提供了编译时类型检查和强大的工具支持(例如 “Intellisense”,代码补齐,重构和智能搜索等)。\n许多代码编辑器和 IDE 都原生支持 TypeScript 或通过插件提供支持。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "TYPESCRIPTISTHEPREFERREDLANGUAGEFORANGULARDEVELOPMENTALTHOUGHYOUCANUSEOTHERJAVASCRIPTDIALECTSSUCHASES5GUIDEGLOSSARY#ES5", "original": "TypeScript is the preferred language for Angular development, although\nyou can use other JavaScript dialects such as [ES5](guide/glossary#es5).", "translation": "TypeScript 是 Angular 的首选语言,当然,你可以使用其它 JavaScript 方言,例如[ES5](guide/glossary#es5)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "READMOREABOUTTYPESCRIPTATTYPESCRIPTLANGORGHTTP:WWWTYPESCRIPTLANGORG", "original": "Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).", "translation": "更多信息,见[typescript.org](http://www.typescriptlang.org/)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##VIEW", "original": "## View", "translation": "## 视图 (view)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "APORTIONOFTHESCREENTHATDISPLAYSINFORMATIONANDRESPONDSTOUSERACTIONSSUCHASCLICKSMOUSEMOVESANDKEYSTROKES", "original": "A portion of the screen that displays information and responds\nto user actions such as clicks, mouse moves, and keystrokes.", "translation": "视图是屏幕中一小块,用来显示信息并响应用户动作,例如点击、移动鼠标和按键。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARRENDERSAVIEWUNDERTHECONTROLOFONEORMOREDIRECTIVESGUIDEGLOSSARY#DIRECTIVEESPECIALLYCOMPONENTGUIDEGLOSSARY#COMPONENTDIRECTIVESANDTHEIRCOMPANIONTEMPLATESGUIDEGLOSSARY#TEMPLATETHECOMPONENTPLAYSSUCHAPROMINENTROLETHATITSOFTENCONVENIENTTOREFERTOACOMPONENTASAVIEW", "original": "Angular renders a view under the control of one or more [directives](guide/glossary#directive),\nespecially [component](guide/glossary#component) directives and their companion [templates](guide/glossary#template).\nThe component plays such a prominent role that it's often\nconvenient to refer to a component as a view.", "translation": "Angular 在一个或多个[指令 (directive)](guide/glossary#directive) 的控制下渲染视图,\n尤其是[组件 (component)](guide/glossary#component) 指令及其[模板 (template)](guide/glossary#template)。\n组件扮演着非常重要的角色,以至于习惯上会把组件视为一种视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "VIEWSOFTENCONTAINOTHERVIEWSANYVIEWMIGHTBELOADEDANDUNLOADEDDYNAMICALLYASTHEUSERNAVIGATESTHROUGHTHEAPPLICATIONTYPICALLYUNDERTHECONTROLOFAROUTERGUIDEGLOSSARY#ROUTER", "original": "Views often contain other views. Any view might be loaded and unloaded\ndynamically as the user navigates through the application, typically\nunder the control of a [router](guide/glossary#router).", "translation": "视图一般包含其它视图,在用户在应用程序中导航时,\n任何视图都可能被动态加载或卸载,这一般会在[路由器 (router)](guide/glossary#router) 的控制下进行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "##ZONE", "original": "## Zone", "translation": "## 区域 (zone)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "AMECHANISMFORENCAPSULATINGANDINTERCEPTINGAJAVASCRIPTAPPLICATIONSASYNCHRONOUSACTIVITY", "original": "A mechanism for encapsulating and intercepting\na JavaScript application's asynchronous activity.", "translation": "区域是一种用来封装和截听 JavaScript 应用程序异步活动的机制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "THEBROWSERDOMANDJAVASCRIPTHAVEALIMITEDNUMBEROFASYNCHRONOUSACTIVITIESSUCHASDOMEVENTSFOREXAMPLECLICKSPROMISESHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCEGLOBALOBJECTSPROMISEANDXHRHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIXMLHTTPREQUESTCALLSTOREMOTESERVERS", "original": "The browser DOM and JavaScript have a limited number\nof asynchronous activities, such as DOM events (for example, clicks),\n[promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), and\n[XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)\ncalls to remote servers.", "translation": "浏览器中的 DOM 和 JavaScript 之间常会有一些数量有限的异步活动,\n 例如 DOM 事件(例如点击)、[承诺 (promise)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n 和通过 [XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) 调用远程服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ZONESINTERCEPTALLOFTHESEACTIVITIESANDGIVEAZONECLIENTTHEOPPORTUNITYTOTAKEACTIONBEFOREANDAFTERTHEASYNCACTIVITYFINISHES", "original": "Zones intercept all of these activities and give a \"zone client\" the opportunity\nto take action before and after the async activity finishes.", "translation": "区域能截听所有这些活动,并让“区域的客户”有机会在异步活动完成之前和之后采取行动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "ANGULARRUNSYOURAPPLICATIONINAZONEWHEREITCANRESPONDTOASYNCHRONOUSEVENTSBYCHECKINGFORDATACHANGESANDUPDATINGTHEINFORMATIONITDISPLAYSVIADATABINDINGSGUIDEGLOSSARY#DATABINDING", "original": "Angular runs your application in a zone where it can respond to\nasynchronous events by checking for data changes and updating\nthe information it displays via [data bindings](guide/glossary#data-binding).", "translation": "Angular 会在一个 Zone 区域中运行应用程序,在这个区域中,它可以对异步事件做出反应,可以通过检查数据变更、利用[数据绑定 (data bindings)](guide/glossary#data-binding) 来更新信息显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "LEARNMOREABOUTZONESINTHISBRIANFORDVIDEOHTTPS:WWWYOUTUBECOMWATCHV3IQTMUSCEU", "original": "Learn more about zones in this\n[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).", "translation": "更多信息,见 [Brian Ford 的视频](https://www.youtube.com/watch?v=3IqtmUscE_U)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/glossary.md" }, { + "key": "#HIERARCHICALDEPENDENCYINJECTORS", "original": "# Hierarchical Dependency Injectors", "translation": "# 多级依赖注入器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "YOULEARNEDTHEBASICSOFANGULARDEPENDENCYINJECTIONINTHEDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONGUIDE", "original": "You learned the basics of Angular Dependency injection in the\n[Dependency Injection](guide/dependency-injection) guide.", "translation": "在[依赖注入](guide/dependency-injection)一章中,你已经学过了 Angular 依赖注入的基础知识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "ANGULARHASAHIERARCHICALDEPENDENCYINJECTIONSYSTEMTHEREISACTUALLYATREEOFINJECTORSTHATPARALLELANAPPLICATIONSCOMPONENTTREEYOUCANRECONFIGURETHEINJECTORSATANYLEVELOFTHATCOMPONENTTREE", "original": "Angular has a _Hierarchical Dependency Injection_ system.\nThere is actually a tree of injectors that parallel an application's component tree.\nYou can reconfigure the injectors at any level of that component tree.", "translation": "Angular 有一个*多级依赖注入系统*。\n实际上,应用程序中有一个与组件树平行的注入器树(译注:平行是指结构完全相同且一一对应)。\n你可以在组件树中的任何级别上重新配置注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THISGUIDEEXPLORESTHISSYSTEMANDHOWTOUSEITTOYOURADVANTAGE", "original": "This guide explores this system and how to use it to your advantage.", "translation": "本文将浏览这个体系,并告诉你如何善用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "TRYTHELIVEEXAMPLELIVEEXAMPLE", "original": "Try the <live-example></live-example>.", "translation": "试试<live-example></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "##THEINJECTORTREE", "original": "## The injector tree", "translation": "## 注入器树", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "INTHEDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONGUIDEYOULEARNEDHOWTOCONFIGUREADEPENDENCYINJECTORANDHOWTORETRIEVEDEPENDENCIESWHEREYOUNEEDTHEM", "original": "In the [Dependency Injection](guide/dependency-injection) guide,\nyou learned how to configure a dependency injector and how to retrieve dependencies where you need them.", "translation": "在[依赖注入](guide/dependency-injection)一章中,你学过如何配置依赖注入器,以及如何在需要时用它获取依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "INFACTTHEREISNOSUCHTHINGASTHEINJECTORANAPPLICATIONMAYHAVEMULTIPLEINJECTORSANANGULARAPPLICATIONISATREEOFCOMPONENTSEACHCOMPONENTINSTANCEHASITSOWNINJECTORTHETREEOFCOMPONENTSPARALLELSTHETREEOFINJECTORS", "original": "In fact, there is no such thing as ***the*** injector.\nAn application may have multiple injectors.\nAn Angular application is a tree of components. Each component instance has its own injector.\nThe tree of components parallels the tree of injectors.", "translation": "实际上,没有***那个(唯一的)***注入器这回事,一个应用中可能有多个注入器。\n一个 Angular 应用是一个组件树。每个组件实例都有自己的注入器!\n组件的树与注入器的树平行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THECOMPONENTSINJECTORMAYBEAPROXYFORANANCESTORINJECTORHIGHERINTHECOMPONENTTREETHATSANIMPLEMENTATIONDETAILTHATIMPROVESEFFICIENCYYOUWONTNOTICETHEDIFFERENCEANDYOURMENTALMODELSHOULDBETHATEVERYCOMPONENTHASITSOWNINJECTOR", "original": "The component's injector may be a _proxy_ for an ancestor injector higher in the component tree.\nThat's an implementation detail that improves efficiency.\nYou won't notice the difference and\nyour mental model should be that every component has its own injector.", "translation": "组件的注入器可能是一个组件树中更高级的祖先注入器的*代理*。\n但这只是提升效率的实现细节,你不用在乎这点差异,在你的脑海里只要想象成每个组件都有自己的注入器就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "CONSIDERTHISGUIDESVARIATIONONTHETOUROFHEROESAPPLICATIONATTHETOPISTHEAPPCOMPONENTWHICHHASSOMESUBCOMPONENTSONEOFTHEMISTHEHEROESLISTCOMPONENTTHEHEROESLISTCOMPONENTHOLDSANDMANAGESMULTIPLEINSTANCESOFTHEHEROTAXRETURNCOMPONENTTHEFOLLOWINGDIAGRAMREPRESENTSTHESTATEOFTHETHISGUIDESTHREELEVELCOMPONENTTREEWHENTHEREARETHREEINSTANCESOFHEROTAXRETURNCOMPONENTOPENSIMULTANEOUSLY", "original": "Consider this guide's variation on the Tour of Heroes application.\nAt the top is the `AppComponent` which has some sub-components.\nOne of them is the `HeroesListComponent`.\nThe `HeroesListComponent` holds and manages multiple instances of the `HeroTaxReturnComponent`.\nThe following diagram represents the state of the this guide's three-level component tree when there are three instances of `HeroTaxReturnComponent`\nopen simultaneously.", "translation": "考虑《英雄指南》应用的一个简单变种。它的顶层是 `AppComponent` 组件,它有一些子组件。\n`HeroesListComponent` 组件保存和管理着 `HeroTaxReturnComponent` 的多个实例。\n下图展示了当 `HeroesCardComponent` 的三个 `HeroTaxReturnComponent` 实例同时展开时的三级组件树状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "###INJECTORBUBBLING", "original": "### Injector bubbling", "translation": "### 注入器冒泡", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "WHENACOMPONENTREQUESTSADEPENDENCYANGULARTRIESTOSATISFYTHATDEPENDENCYWITHAPROVIDERREGISTEREDINTHATCOMPONENTSOWNINJECTORIFTHECOMPONENTSINJECTORLACKSTHEPROVIDERITPASSESTHEREQUESTUPTOITSPARENTCOMPONENTSINJECTORIFTHATINJECTORCANTSATISFYTHEREQUESTITPASSESITALONGTOITSPARENTINJECTORTHEREQUESTSKEEPBUBBLINGUPUNTILANGULARFINDSANINJECTORTHATCANHANDLETHEREQUESTORRUNSOUTOFANCESTORINJECTORSIFITRUNSOUTOFANCESTORSANGULARTHROWSANERROR", "original": "When a component requests a dependency, Angular tries to satisfy that dependency with a provider registered in that component's own injector.\nIf the component's injector lacks the provider, it passes the request up to its parent component's injector.\nIf that injector can't satisfy the request, it passes it along to *its* parent injector.\nThe requests keep bubbling up until Angular finds an injector that can handle the request or runs out of ancestor injectors.\nIf it runs out of ancestors, Angular throws an error.", "translation": "当一个组件申请获得一个依赖时,Angular 先尝试用该组件自己的注入器来满足它。\n如果该组件的注入器没有找到对应的提供商,它就把这个申请转给它父组件的注入器来处理。\n如果那个注入器也无法满足这个申请,它就继续转给*它的*父组件的注入器。\n这个申请继续往上冒泡 —— 直到找到了一个能处理此申请的注入器或者超出了组件树中的祖先位置为止。\n如果超出了组件树中的祖先还未找到,Angular 就会抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "YOUCANCAPTHEBUBBLINGANINTERMEDIATECOMPONENTCANDECLARETHATITISTHEHOSTCOMPONENTTHEHUNTFORPROVIDERSWILLCLIMBNOHIGHERTHANTHEINJECTORFORTHATHOSTCOMPONENTTHISISATOPICFORANOTHERDAY", "original": "You can cap the bubbling. An intermediate component can declare that it is the \"host\" component.\nThe hunt for providers will climb no higher than the injector for that host component.\nThis is a topic for another day.", "translation": "你还可以“盖住”这次冒泡。一个中层的组件可以声称自己是“宿主”组件。\n向上查找提供商的过程会截止于这个“宿主”组件。\n这个问题先放一放,等改天再讨论它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "###REPROVIDINGASERVICEATDIFFERENTLEVELS", "original": "### Re-providing a service at different levels", "translation": "### 在不同层级再次提供同一个服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "YOUCANREREGISTERAPROVIDERFORAPARTICULARDEPENDENCYTOKENATMULTIPLELEVELSOFTHEINJECTORTREEYOUDONTHAVETOREREGISTERPROVIDERSYOUSHOULDNTDOSOUNLESSYOUHAVEAGOODREASONBUTYOUCAN", "original": "You can re-register a provider for a particular dependency token at multiple levels of the injector tree.\nYou don't *have* to re-register providers. You shouldn't do so unless you have a good reason.\nBut you *can*.", "translation": "你可以在注入器树中的多个层次上为指定的依赖令牌重新注册提供商。\n但*并非必须*重新注册,事实上,虽然可以重新注册,但除非有很好的理由,否则不应该这么做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "ASTHERESOLUTIONLOGICWORKSUPWARDSTHEFIRSTPROVIDERENCOUNTEREDWINSTHUSAPROVIDERINANINTERMEDIATEINJECTORINTERCEPTSAREQUESTFORASERVICEFROMSOMETHINGLOWERINTHETREEITEFFECTIVELYRECONFIGURESANDSHADOWSAPROVIDERATAHIGHERLEVELINTHETREE", "original": "As the resolution logic works upwards, the first provider encountered wins.\nThus, a provider in an intermediate injector intercepts a request for a service from something lower in the tree.\nIt effectively \"reconfigures\" and \"shadows\" a provider at a higher level in the tree.", "translation": "服务解析逻辑会自下而上查找,碰到的第一个提供商会胜出。\n因此,注入器树中间层注入器上的提供商,可以拦截来自底层的对特定服务的请求。\n这导致它可以“重新配置”和者说“遮蔽”高层的注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "IFYOUONLYSPECIFYPROVIDERSATTHETOPLEVELTYPICALLYTHEROOTAPPMODULETHETREEOFINJECTORSAPPEARSTOBEFLATALLREQUESTSBUBBLEUPTOTHEROOTCODENGMODULECODEINJECTORTHATYOUCONFIGUREDWITHTHEBOOTSTRAPMODULEMETHOD", "original": "If you only specify providers at the top level (typically the root `AppModule`), the tree of injectors appears to be flat.\nAll requests bubble up to the root <code>NgModule</code> injector that you configured with the `bootstrapModule` method.", "translation": "如果你只在顶级(通常是根模块 `AppModule`),这三个注入器看起来将是“平面”的。\n所有的申请都会冒泡到根<code>NgModule</code>进行处理,也就是你在 `bootstrapModule` 方法中配置的那个。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "##COMPONENTINJECTORS", "original": "## Component injectors", "translation": "## 组件注入器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THEABILITYTOCONFIGUREONEORMOREPROVIDERSATDIFFERENTLEVELSOPENSUPINTERESTINGANDUSEFULPOSSIBILITIES", "original": "The ability to configure one or more providers at different levels opens up interesting and useful possibilities.", "translation": "在不同层次上重新配置一个或多个提供商的能力,开启了一些既有趣又有用的可能性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "###SCENARIO:SERVICEISOLATION", "original": "### Scenario: service isolation", "translation": "### 场景:服务隔离", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "ARCHITECTURALREASONSMAYLEADYOUTORESTRICTACCESSTOASERVICETOTHEAPPLICATIONDOMAINWHEREITBELONGS", "original": "Architectural reasons may lead you to restrict access to a service to the application domain where it belongs.", "translation": "出于架构方面的考虑,可能会让你决定把一个服务限制到只能在它所属的特定领域中访问。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THEGUIDESAMPLEINCLUDESAVILLAINSLISTCOMPONENTTHATDISPLAYSALISTOFVILLAINSITGETSTHOSEVILLAINSFROMAVILLAINSSERVICE", "original": "The guide sample includes a `VillainsListComponent` that displays a list of villains.\nIt gets those villains from a `VillainsService`.", "translation": "本章的范例中包括一个 `VillainsListComponent`,它显示一个反派的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "WHILEYOUCOULDPROVIDEVILLAINSSERVICEINTHEROOTAPPMODULETHATSWHEREYOULLFINDTHEHEROESSERVICETHATWOULDMAKETHEVILLAINSSERVICEAVAILABLEEVERYWHEREINTHEAPPLICATIONINCLUDINGTHEHEROWORKFLOWS", "original": "While you _could_ provide `VillainsService` in the root `AppModule` (that's where you'll find the `HeroesService`),\nthat would make the `VillainsService` available everywhere in the application, including the _Hero_ workflows.", "translation": "虽然你也*可以*在根模块 `AppModule` 中提供 `VillainsService`(就像 `HeroesService` 那样),不过那样一来就会导致在整个应用中到处都能访问到 `VillainsService`,包括在*英雄*工作流中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "IFYOULATERMODIFIEDTHEVILLAINSSERVICEYOUCOULDBREAKSOMETHINGINAHEROCOMPONENTSOMEWHERETHATSNOTSUPPOSEDTOHAPPENBUTPROVIDINGTHESERVICEINTHEROOTAPPMODULECREATESTHATRISK", "original": "If you later modified the `VillainsService`, you could break something in a hero component somewhere.\nThat's not supposed to happen but providing the service in the root `AppModule` creates that risk.", "translation": "如果你以后修改了 `VillainsService`,那就可能会破坏英雄组件中的某些部分。\n这可不妙,但是在根模块 `AppModule` 中提供这个服务可能会导致这种风险。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "INSTEADPROVIDETHEVILLAINSSERVICEINTHEPROVIDERSMETADATAOFTHEVILLAINSLISTCOMPONENTLIKETHIS:", "original": "Instead, provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:", "translation": "可以换一种方案:在 `VillainsListComponent` 元数据的 `providers` 中提供 `VillainsService`,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "BYPROVIDINGVILLAINSSERVICEINTHEVILLAINSLISTCOMPONENTMETADATAANDNOWHEREELSETHESERVICEBECOMESAVAILABLEONLYINTHEVILLAINSLISTCOMPONENTANDITSSUBCOMPONENTTREEITSSTILLASINGLETONBUTITSASINGLETONTHATEXISTSOLELYINTHEVILLAINDOMAIN", "original": "By providing `VillainsService` in the `VillainsListComponent` metadata and nowhere else,\nthe service becomes available only in the `VillainsListComponent` and its sub-component tree.\nIt's still a singleton, but it's a singleton that exist solely in the _villain_ domain.", "translation": "在 `VillainsListComponent` 的元数据中而不是其它地方提供 `VillainsService` 服务,该服务就会只在 `VillainsListComponent` 及其子组件树中可用。\n它仍然是单例,但是这个单例只存在于*反派(villain)*这个领域中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "NOWYOUKNOWTHATAHEROCOMPONENTCANTACCESSITYOUVEREDUCEDYOUREXPOSURETOERROR", "original": "Now you know that a hero component can't access it. You've reduced your exposure to error.", "translation": "现在,你可以确信英雄组件不会访问它,因此减少了犯错误的机会。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "###SCENARIO:MULTIPLEEDITSESSIONS", "original": "### Scenario: multiple edit sessions", "translation": "### 场景:多重编辑会话", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "MANYAPPLICATIONSALLOWUSERSTOWORKONSEVERALOPENTASKSATTHESAMETIMEFOREXAMPLEINATAXPREPARATIONAPPLICATIONTHEPREPARERCOULDBEWORKINGONSEVERALTAXRETURNSSWITCHINGFROMONETOTHEOTHERTHROUGHOUTTHEDAY", "original": "Many applications allow users to work on several open tasks at the same time.\nFor example, in a tax preparation application, the preparer could be working on several tax returns,\nswitching from one to the other throughout the day.", "translation": "很多应用允许用户同时进行多个任务。\n比如,在纳税申报应用中,申报人可以打开多个报税单,随时可能从一个切换到另一个。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THISGUIDEDEMONSTRATESTHATSCENARIOWITHANEXAMPLEINTHETOUROFHEROESTHEMEIMAGINEANOUTERHEROLISTCOMPONENTTHATDISPLAYSALISTOFSUPERHEROES", "original": "This guide demonstrates that scenario with an example in the Tour of Heroes theme.\nImagine an outer `HeroListComponent` that displays a list of super heroes.", "translation": "本章要示范的场景仍然是基于《英雄指南》的。\n想象一个外层的 `HeroListComponent`,它显示一个超级英雄的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "TOOPENAHEROSTAXRETURNTHEPREPARERCLICKSONAHERONAMEWHICHOPENSACOMPONENTFOREDITINGTHATRETURNEACHSELECTEDHEROTAXRETURNOPENSINITSOWNCOMPONENTANDMULTIPLERETURNSCANBEOPENATTHESAMETIME", "original": "To open a hero's tax return, the preparer clicks on a hero name, which opens a component for editing that return.\nEach selected hero tax return opens in its own component and multiple returns can be open at the same time.", "translation": "要打开一个英雄的报税单,申报者点击英雄名,它就会打开一个组件来编辑那个申报单。\n每个选中的申报单都会在自己的组件中打开,并且可以同时打开多个申报单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "EACHTAXRETURNCOMPONENTHASTHEFOLLOWINGCHARACTERISTICS:", "original": "Each tax return component has the following characteristics:", "translation": "每个报税单组件都有下列特征:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "ISITSOWNTAXRETURNEDITINGSESSION", "original": "* Is its own tax return editing session.", "translation": "属于它自己的报税单会话。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "CANCHANGEATAXRETURNWITHOUTAFFECTINGARETURNINANOTHERCOMPONENT", "original": "* Can change a tax return without affecting a return in another component.", "translation": "可以修改一个报税单,而不会影响另一个组件中的申报单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "HASTHEABILITYTOSAVETHECHANGESTOITSTAXRETURNORCANCELTHEM", "original": "* Has the ability to save the changes to its tax return or cancel them.", "translation": "能把所做的修改保存到它的报税单中,或者放弃它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "ONEMIGHTSUPPOSETHATTHEHEROTAXRETURNCOMPONENTHASLOGICTOMANAGEANDRESTORECHANGESTHATWOULDBEAPRETTYEASYTASKFORASIMPLEHEROTAXRETURNINTHEREALWORLDWITHARICHTAXRETURNDATAMODELTHECHANGEMANAGEMENTWOULDBETRICKYYOUMIGHTDELEGATETHATMANAGEMENTTOAHELPERSERVICEASTHISEXAMPLEDOES", "original": "One might suppose that the `HeroTaxReturnComponent` has logic to manage and restore changes.\nThat would be a pretty easy task for a simple hero tax return.\nIn the real world, with a rich tax return data model, the change management would be tricky.\nYou might delegate that management to a helper service, as this example does.", "translation": "实现方式之一就是让 `HeroTaxReturnComponent` 有逻辑来管理和还原那些更改。\n这对于简单的报税单来说是很容易的。\n不过,在现实世界中,报税单的数据模型非常复杂,对这些修改的管理可能不得不投机取巧。\n于是你可以把这种管理任务委托给一个辅助服务,就像这个例子中所做的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "HEREISTHEHEROTAXRETURNSERVICEITCACHESASINGLEHEROTAXRETURNTRACKSCHANGESTOTHATRETURNANDCANSAVEORRESTOREITITALSODELEGATESTOTHEAPPLICATIONWIDESINGLETONHEROSERVICEWHICHITGETSBYINJECTION", "original": "Here is the `HeroTaxReturnService`.\nIt caches a single `HeroTaxReturn`, tracks changes to that return, and can save or restore it.\nIt also delegates to the application-wide singleton `HeroService`, which it gets by injection.", "translation": "这是一个报税单服务 `HeroTaxReturnService`。\n它缓存了单条 `HeroTaxReturn`,用于跟踪那个申报单的变更,并且可以保存或还原它。\n它还委托给了全应用级的单例服务 `HeroService`,它是通过依赖注入机制取得的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "HEREISTHEHEROTAXRETURNCOMPONENTTHATMAKESUSEOFIT", "original": "Here is the `HeroTaxReturnComponent` that makes use of it.", "translation": "下面是正在使用它的 `HeroTaxReturnComponent` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THETAXRETURNTOEDITARRIVESVIATHEINPUTPROPERTYWHICHISIMPLEMENTEDWITHGETTERSANDSETTERSTHESETTERINITIALIZESTHECOMPONENTSOWNINSTANCEOFTHEHEROTAXRETURNSERVICEWITHTHEINCOMINGRETURNTHEGETTERALWAYSRETURNSWHATTHATSERVICESAYSISTHECURRENTSTATEOFTHEHEROTHECOMPONENTALSOASKSTHESERVICETOSAVEANDRESTORETHISTAXRETURN", "original": "The _tax-return-to-edit_ arrives via the input property which is implemented with getters and setters.\nThe setter initializes the component's own instance of the `HeroTaxReturnService` with the incoming return.\nThe getter always returns what that service says is the current state of the hero.\nThe component also asks the service to save and restore this tax return.", "translation": "通过输入属性可以得到*要编辑的报税单*,这个属性被实现成了读取器(getter)和设置器(setter)。\n设置器根据传进来的报税单初始化了组件自己的 `HeroTaxReturnService` 实例。\n读取器总是返回该服务所存英雄的当前状态。\n组件也会请求该服务来保存或还原这个报税单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THEREDBEBIGTROUBLEIFTHISSERVICEWEREANAPPLICATIONWIDESINGLETONEVERYCOMPONENTWOULDSHARETHESAMESERVICEINSTANCEEACHCOMPONENTWOULDOVERWRITETHETAXRETURNTHATBELONGEDTOANOTHERHEROWHATAMESS", "original": "There'd be big trouble if _this_ service were an application-wide singleton.\nEvery component would share the same service instance.\nEach component would overwrite the tax return that belonged to another hero.\nWhat a mess!", "translation": "这里有个大问题,那就是如果*这个*服务是一个全应用范围的单例,每个组件就都会共享同一个服务实例,每个组件也都会覆盖属于其他英雄的报税单,真是一团糟!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "LOOKCLOSELYATTHEMETADATAFORTHEHEROTAXRETURNCOMPONENTNOTICETHEPROVIDERSPROPERTY", "original": "Look closely at the metadata for the `HeroTaxReturnComponent`. Notice the `providers` property.", "translation": "但仔细看 `HeroTaxReturnComponent` 的元数据,注意 `providers` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THEHEROTAXRETURNCOMPONENTHASITSOWNPROVIDEROFTHEHEROTAXRETURNSERVICERECALLTHATEVERYCOMPONENTINSTANCEHASITSOWNINJECTORPROVIDINGTHESERVICEATTHECOMPONENTLEVELENSURESTHATEVERYINSTANCEOFTHECOMPONENTGETSITSOWNPRIVATEINSTANCEOFTHESERVICENOTAXRETURNOVERWRITINGNOMESS", "original": "The `HeroTaxReturnComponent` has its own provider of the `HeroTaxReturnService`.\nRecall that every component _instance_ has its own injector.\nProviding the service at the component level ensures that _every_ instance of the component gets its own, private instance of the service.\nNo tax return overwriting. No mess.", "translation": "`HeroTaxReturnComponent` 有它自己的 `HeroTaxReturnService` 提供商。\n回忆一下,每个组件的*实例*都有它自己的注入器。\n在组件级提供服务可以确保组件的*每个*实例都得到一个自己的、私有的服务实例。\n报税单不会再被意外覆盖,这下清楚了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THERESTOFTHESCENARIOCODERELIESONOTHERANGULARFEATURESANDTECHNIQUESTHATYOUCANLEARNABOUTELSEWHEREINTHEDOCUMENTATIONYOUCANREVIEWITANDDOWNLOADITFROMTHELIVEEXAMPLELIVEEXAMPLE", "original": "The rest of the scenario code relies on other Angular features and techniques that you can learn about elsewhere in the documentation.\nYou can review it and download it from the <live-example></live-example>.", "translation": "该场景代码中的其它部分依赖另一些 Angular 的特性和技术,你将会在本文档的其它章节学到。\n你可以到<live-example></live-example>查看代码和下载它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "###SCENARIO:SPECIALIZEDPROVIDERS", "original": "### Scenario: specialized providers", "translation": "### 场景:专门的提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "ANOTHERREASONTOREPROVIDEASERVICEISTOSUBSTITUTEAMORESPECIALIZEDIMPLEMENTATIONOFTHATSERVICEDEEPERINTHECOMPONENTTREE", "original": "Another reason to re-provide a service is to substitute a _more specialized_ implementation of that service,\ndeeper in the component tree.", "translation": "重新提供服务的另一个原因,是在组件树的深层中把该服务替换为一个*更特殊的*实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "CONSIDERAGAINTHECAREXAMPLEFROMTHEDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONGUIDESUPPOSEYOUCONFIGUREDTHEROOTINJECTORMARKEDASAWITHGENERICPROVIDERSFORCARSERVICEENGINESERVICEANDTIRESSERVICE", "original": "Consider again the Car example from the [Dependency Injection](guide/dependency-injection) guide.\nSuppose you configured the root injector (marked as A) with _generic_ providers for\n`CarService`, `EngineService` and `TiresService`.", "translation": "再次考虑[依赖注入](guide/dependency-injection)一章中车辆(Car)的例子。\n假设你在根注入器(代号 A)中配置了*通用的*提供商:`CarService`、`EngineService` 和 `TiresService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "YOUCREATEACARCOMPONENTATHATDISPLAYSACARCONSTRUCTEDFROMTHESETHREEGENERICSERVICES", "original": "You create a car component (A) that displays a car constructed from these three generic services.", "translation": "你创建了一个车辆组件(A),它显示一个从另外三个通用服务构造出的车辆。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THENYOUCREATEACHILDCOMPONENTBTHATDEFINESITSOWNSPECIALIZEDPROVIDERSFORCARSERVICEANDENGINESERVICETHATHAVESPECIALCAPABILITESSUITABLEFORWHATEVERISGOINGONINCOMPONENTB", "original": "Then you create a child component (B) that defines its own, _specialized_ providers for `CarService` and `EngineService`\nthat have special capabilites suitable for whatever is going on in component (B).", "translation": "然后,你创建一个子组件(B),它为 `CarService` 和 `EngineService` 定义了自己的*特殊的*提供商,它们具有更特殊的能力,适用于组件 B 的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "COMPONENTBISTHEPARENTOFANOTHERCOMPONENTCTHATDEFINESITSOWNEVENMORESPECIALIZEDPROVIDERFORCARSERVICE", "original": "Component (B) is the parent of another component (C) that defines its own, even _more specialized_ provider for `CarService`.", "translation": "组件 B 是另一个组件 C 的父组件,而组件 C 又定义了自己的,*更特殊的*`CarService` 提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "BEHINDTHESCENESEACHCOMPONENTSETSUPITSOWNINJECTORWITHZEROONEORMOREPROVIDERSDEFINEDFORTHATCOMPONENTITSELF", "original": "Behind the scenes, each component sets up its own injector with zero, one, or more providers defined for that component itself.", "translation": "在幕后,每个组件都有自己的注入器,这个注入器带有为组件本身准备的 0 个、1 个或多个提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "WHENYOURESOLVEANINSTANCEOFCARATTHEDEEPESTCOMPONENTCITSINJECTORPRODUCESANINSTANCEOFCARRESOLVEDBYINJECTORCWITHANENGINERESOLVEDBYINJECTORBANDTIRESRESOLVEDBYTHEROOTINJECTORA", "original": "When you resolve an instance of `Car` at the deepest component (C),\nits injector produces an instance of `Car` resolved by injector (C) with an `Engine` resolved by injector (B) and\n`Tires` resolved by the root injector (A).", "translation": "当你在最深层的组件 C 解析 `Car` 的实例时,它使用注入器 C 解析生成了一个 `Car` 的实例,使用注入器 B 解析了 `Engine`,而 `Tires` 则是由根注入器 A 解析的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "THECODEFORTHISCARSSCENARIOISINTHECARCOMPONENTSTSANDCARSERVICESTSFILESOFTHESAMPLEWHICHYOUCANREVIEWANDDOWNLOADFROMTHELIVEEXAMPLELIVEEXAMPLE", "original": "The code for this _cars_ scenario is in the `car.components.ts` and `car.services.ts` files of the sample\nwhich you can review and download from the <live-example></live-example>.", "translation": "*车辆*场景下的代码位于 `car.components.ts` 和 `car.services.ts` 文件中,这个例子你可以在<live-example></live-example>查看和下载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/hierarchical-dependency-injection.md" }, { + "key": "MOSTFRONTENDAPPLICATIONSCOMMUNICATEWITHBACKENDSERVICESOVERTHEHTTPPROTOCOLMODERNBROWSERSSUPPORTTWODIFFERENTAPISFORMAKINGHTTPREQUESTS:THEXMLHTTPREQUESTINTERFACEANDTHEFETCHAPI", "original": "Most front-end applications communicate with backend services over the HTTP protocol. Modern browsers support two different APIs for making HTTP requests: the `XMLHttpRequest` interface and the `fetch()` API.", "translation": "大多数前端应用都需要通过 HTTP 协议与后端服务器通讯。现代浏览器支持使用两种不同的 API 发起 HTTP 请求:`XMLHttpRequest` 接口和 `fetch()` API。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEHTTPCLIENTINANGULARCOMMONHTTPOFFERSASIMPLIFIEDCLIENTHTTPAPIFORANGULARAPPLICATIONSTHATRESTSONTHEXMLHTTPREQUESTINTERFACEEXPOSEDBYBROWSERSADDITIONALBENEFITSOFHTTPCLIENTINCLUDETESTABILITYFEATURESTYPEDREQUESTANDRESPONSEOBJECTSREQUESTANDRESPONSEINTERCEPTIONOBSERVABLEAPISANDSTREAMLINEDERRORHANDLING", "original": "The `HttpClient` in `@angular/common/http` offers a simplified client HTTP API for Angular applications\nthat rests on the `XMLHttpRequest` interface exposed by browsers.\nAdditional benefits of `HttpClient` include testability features, typed request and response objects, request and response interception, `Observable` apis, and streamlined error handling.", "translation": "`@angular/common/http` 中的 `HttpClient` 类为 Angular 应用程序提供了一个简化的 API 来实现 HTTP 客户端功能。它基于浏览器提供的 `XMLHttpRequest` 接口。\n`HttpClient` 带来的其它优点包括:可测试性、强类型的请求和响应对象、发起请求与接收响应时的拦截器支持,以及更好的、基于可观察(Observable)对象的 API 以及流式错误处理机制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCANRUNTHELIVEEXAMPLELIVEEXAMPLETHATACCOMPANIESTHISGUIDE", "original": "You can run the <live-example></live-example> that accompanies this guide.", "translation": "你可以到 <live-example></live-example> 中运行本章的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESAMPLEAPPDOESNOTREQUIREADATASERVERITRELIESONTHEANGULARINMEMORYWEBAPIHTTPS:GITHUBCOMANGULARINMEMORYWEBAPIBLOBMASTERREADMEMDWHICHREPLACESTHEHTTPCLIENTMODULESHTTPBACKENDTHEREPLACEMENTSERVICESIMULATESTHEBEHAVIOROFARESTLIKEBACKEND", "original": "The sample app does not require a data server.\nIt relies on the \n[Angular _in-memory-web-api_](https://github.com/angular/in-memory-web-api/blob/master/README.md),\nwhich replaces the _HttpClient_ module's `HttpBackend`.\nThe replacement service simulates the behavior of a REST-like backend.", "translation": "该应用代码并不需要数据服务器。\n它基于 [Angular _in-memory-web-api_](https://github.com/angular/in-memory-web-api/blob/master/README.md) 库,该库会替换 `HttpClient` 模块中的 `HttpBackend`。用于替换的这个服务会模拟 REST 风格的后端的行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "LOOKATTHEAPPMODULEIMPORTSTOSEEHOWITISCONFIGURED", "original": "Look at the `AppModule` _imports_ to see how it is configured.", "translation": "到 `AppModule` 的 `imports` 中查看这个库是如何配置的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##SETUP", "original": "## Setup", "translation": "## 准备工作", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "BEFOREYOUCANUSETHEHTTPCLIENTYOUNEEDTOIMPORTTHEANGULARHTTPCLIENTMODULEMOSTAPPSDOSOINTHEROOTAPPMODULE", "original": "Before you can use the `HttpClient`, you need to import the Angular `HttpClientModule`. \nMost apps do so in the root `AppModule`.", "translation": "要想使用 `HttpClient`,就要先导入 Angular 的 `HttpClientModule`。大多数应用都会在根模块 `AppModule` 中导入它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "HAVINGIMPORTEDHTTPCLIENTMODULEINTOTHEAPPMODULEYOUCANINJECTTHEHTTPCLIENTINTOANAPPLICATIONCLASSASSHOWNINTHEFOLLOWINGCONFIGSERVICEEXAMPLE", "original": "Having imported `HttpClientModule` into the `AppModule`, you can inject the `HttpClient`\ninto an application class as shown in the following `ConfigService` example.", "translation": "在 `AppModule` 中导入 `HttpClientModule` 之后,你可以把 `HttpClient` 注入到应用类中,就像下面的 `ConfigService` 例子中这样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##GETTINGJSONDATA", "original": "## Getting JSON data", "translation": "## 获取 JSON 数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "APPLICATIONSOFTENREQUESTJSONDATAFROMTHESERVERFOREXAMPLETHEAPPMIGHTNEEDACONFIGURATIONFILEONTHESERVERCONFIGJSONTHATSPECIFIESRESOURCEURLS", "original": "Applications often request JSON data from the server. \nFor example, the app might need a configuration file on the server, `config.json`, \nthat specifies resource URLs.", "translation": "应用通常会从服务器上获取 JSON 数据。\n比如,该应用可能要从服务器上获取配置文件 `config.json`,其中指定了一些特定资源的 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECONFIGSERVICEFETCHESTHISFILEWITHAGETMETHODONHTTPCLIENT", "original": "The `ConfigService` fetches this file with a `get()` method on `HttpClient`.", "translation": "`ConfigService` 会通过 `HttpClient` 的 `get()` 方法取得这个文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ACOMPONENTSUCHASCONFIGCOMPONENTINJECTSTHECONFIGSERVICEANDCALLSTHEGETCONFIGSERVICEMETHOD", "original": "A component, such as `ConfigComponent`, injects the `ConfigService` and calls\nthe `getConfig` service method.", "translation": "像 `ConfigComponent` 这样的组件会注入 `ConfigService`,并调用其 `getConfig` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "BECAUSETHESERVICEMETHODRETURNSANOBSERVABLEOFCONFIGURATIONDATATHECOMPONENTSUBSCRIBESTOTHEMETHODSRETURNVALUETHESUBSCRIPTIONCALLBACKCOPIESTHEDATAFIELDSINTOTHECOMPONENTSCONFIGOBJECTWHICHISDATABOUNDINTHECOMPONENTTEMPLATEFORDISPLAY", "original": "Because the service method returns an `Observable` of configuration data,\nthe component **subscribes** to the method's return value.\nThe subscription callback copies the data fields into the component's `config` object,\nwhich is data-bound in the component template for display.", "translation": "这个服务方法返回配置数据的 `Observable` 对象,所以组件要**订阅(subscribe)** 该方法的返回值。\n订阅时的回调函数会把这些数据字段复制到组件的 `config` 对象中,它会在组件的模板中绑定,以供显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###WHYWRITEASERVICE", "original": "### Why write a service", "translation": "### 为什么要写服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THISEXAMPLEISSOSIMPLETHATITISTEMPTINGTOWRITETHEHTTPGETINSIDETHECOMPONENTITSELFANDSKIPTHESERVICE", "original": "This example is so simple that it is tempting to write the `Http.get()` inside the\ncomponent itself and skip the service.", "translation": "这个例子太简单,所以它也可以在组件本身的代码中调用 `Http.get()`,而不用借助服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "HOWEVERDATAACCESSRARELYSTAYSTHISSIMPLEYOUTYPICALLYPOSTPROCESSTHEDATAADDERRORHANDLINGANDMAYBESOMERETRYLOGICTOCOPEWITHINTERMITTENTCONNECTIVITY", "original": "However, data access rarely stays this simple.\nYou typically post-process the data, add error handling, and maybe some retry logic to\ncope with intermittent connectivity.", "translation": "不过,数据访问很少能一直这么简单。\n你通常要对数据做后处理、添加错误处理器,还可能加一些重试逻辑,以便应对网络抽风的情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECOMPONENTQUICKLYBECOMESCLUTTEREDWITHDATAACCESSMINUTIATHECOMPONENTBECOMESHARDERTOUNDERSTANDHARDERTOTESTANDTHEDATAACCESSLOGICCANTBEREUSEDORSTANDARDIZED", "original": "The component quickly becomes cluttered with data access minutia.\nThe component becomes harder to understand, harder to test, and the data access logic can't be re-used or standardized.", "translation": "该组件很快就会因为这些数据方式的细节而变得杂乱不堪。\n组件变得难以理解、难以测试,并且这些数据访问逻辑无法被复用,也无法标准化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THATSWHYITISABESTPRACTICETOSEPARATEPRESENTATIONOFDATAFROMDATAACCESSBYENCAPSULATINGDATAACCESSINASEPARATESERVICEANDDELEGATINGTOTHATSERVICEINTHECOMPONENTEVENINSIMPLECASESLIKETHISONE", "original": "That's why it is a best practice to separate presentation of data from data access by\nencapsulating data access in a separate service and delegating to that service in\nthe component, even in simple cases like this one.", "translation": "这就是为什么最佳实践中要求把数据展现逻辑从数据访问逻辑中拆分出去,也就是说把数据访问逻辑包装进一个单独的服务中,\n并且在组件中把数据访问逻辑委托给这个服务。就算是这么简单的应用也要如此。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###TYPECHECKINGTHERESPONSE", "original": "### Type-checking the response", "translation": "### 带类型检查的响应", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESUBSCRIBECALLBACKABOVEREQUIRESBRACKETNOTATIONTOEXTRACTTHEDATAVALUES", "original": "The subscribe callback above requires bracket notation to extract the data values.", "translation": "该订阅的回调需要用通过括号中的语句来提取数据的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCANTWRITEDATAHEROESURLBECAUSETYPESCRIPTCORRECTLYCOMPLAINSTHATTHEDATAOBJECTFROMTHESERVICEDOESNOTHAVEAHEROESURLPROPERTY", "original": "You can't write `data.heroesUrl` because TypeScript correctly complains that the `data` object from the service does not have a `heroesUrl` property.", "translation": "你没法写成 `data.heroesUrl` ,因为 TypeScript 会报告说来自服务器的 `data` 对象中没有名叫 `heroesUrl` 的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEHTTPCLIENTGETMETHODPARSEDTHEJSONSERVERRESPONSEINTOTHEANONYMOUSOBJECTTYPEITDOESNTKNOWWHATTHESHAPEOFTHATOBJECTIS", "original": "The `HttpClient.get()` method parsed the JSON server response into the anonymous `Object` type. It doesn't know what the shape of that object is.", "translation": "这是因为 `HttpClient.get()` 方法把 JSON 响应体解析成了匿名的 `Object` 类型。它不知道该对象的具体形态如何。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCANTELLHTTPCLIENTTHETYPEOFTHERESPONSETOMAKECONSUMINGTHEOUTPUTEASIERANDMOREOBVIOUS", "original": "You can tell `HttpClient` the type of the response to make consuming the output easier and more obvious.", "translation": "你可以告诉 `HttpClient` 该响应体的类型,以便让对这种输出的消费更容易、更明确。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "FIRSTDEFINEANINTERFACEWITHTHECORRECTSHAPE:", "original": "First, define an interface with the correct shape:", "translation": "首先,定义一个具有正确形态的接口:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THENSPECIFYTHATINTERFACEASTHEHTTPCLIENTGETCALLSTYPEPARAMETERINTHESERVICE:", "original": "Then, specify that interface as the `HttpClient.get()` call's type parameter in the service:", "translation": "然后,在服务器中把该接口指定为 `HttpClient.get()` 调用的类型参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECALLBACKINTHEUPDATEDCOMPONENTMETHODRECEIVESATYPEDDATAOBJECTWHICHISEASIERANDSAFERTOCONSUME:", "original": "The callback in the updated component method receives a typed data object, which is\neasier and safer to consume:", "translation": "修改后的组件方法,其回调函数中获取一个带类型的对象,它易于使用,且消费起来更安全:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###READINGTHEFULLRESPONSE", "original": "### Reading the full response", "translation": "### 读取完整的响应体", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THERESPONSEBODYDOESNTRETURNALLTHEDATAYOUMAYNEEDSOMETIMESSERVERSRETURNSPECIALHEADERSORSTATUSCODESTOINDICATECERTAINCONDITIONSTHATAREIMPORTANTTOTHEAPPLICATIONWORKFLOW", "original": "The response body doesn't return all the data you may need. Sometimes servers return special headers or status codes to indicate certain conditions that are important to the application workflow.", "translation": "响应体可能并不包含你需要的全部信息。有时候服务器会返回一个特殊的响应头或状态码,以标记出特定的条件,因此读取它们可能是必要的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "TELLHTTPCLIENTTHATYOUWANTTHEFULLRESPONSEWITHTHEOBSERVEOPTION:", "original": "Tell `HttpClient` that you want the full response with the `observe` option:", "translation": "要这样做,你就要通过 `observe` 选项来告诉 `HttpClient`,你想要完整的响应信息,而不是只有响应体:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOWHTTPCLIENTGETRETURNSANOBSERVABLEOFTYPEDHTTPRESPONSERATHERTHANJUSTTHEJSONDATA", "original": "Now `HttpClient.get()` returns an `Observable` of typed `HttpResponse` rather than just the JSON data.", "translation": "现在 `HttpClient.get()` 会返回一个 `HttpResponse` 类型的 `Observable`,而不只是 JSON 数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECOMPONENTSSHOWCONFIGRESPONSEMETHODDISPLAYSTHERESPONSEHEADERSASWELLASTHECONFIGURATION:", "original": "The component's `showConfigResponse()` method displays the response headers as well as the configuration:", "translation": "该组件的 `showConfigResponse()` 方法会像显示配置数据一样显示响应头:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ASYOUCANSEETHERESPONSEOBJECTHASABODYPROPERTYOFTHECORRECTTYPE", "original": "As you can see, the response object has a `body` property of the correct type.", "translation": "如你所见,该响应对象具有一个带有正确类型的 `body` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##ERRORHANDLING", "original": "## Error handling", "translation": "## 错误处理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "WHATHAPPENSIFTHEREQUESTFAILSONTHESERVERORIFAPOORNETWORKCONNECTIONPREVENTSITFROMEVENREACHINGTHESERVERHTTPCLIENTWILLRETURNANERROROBJECTINSTEADOFASUCCESSFULRESPONSE", "original": "What happens if the request fails on the server, or if a poor network connection prevents it from even reaching the server? `HttpClient` will return an _error_ object instead of a successful response.", "translation": "如果这个请求导致了服务器错误怎么办?甚至,在烂网络下请求都没到服务器该怎么办?`HttpClient` 就会返回一个错误(error)而不再是成功的响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCOULDHANDLEINTHECOMPONENTBYADDINGASECONDCALLBACKTOTHESUBSCRIBE:", "original": "You _could_ handle in the component by adding a second callback to the `.subscribe()`:", "translation": "通过在 `.subscribe()` 中添加第二个回调函数,你*可以*在组件中处理它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ITSCERTAINLYAGOODIDEATOGIVETHEUSERSOMEKINDOFFEEDBACKWHENDATAACCESSFAILSBUTDISPLAYINGTHERAWERROROBJECTRETURNEDBYHTTPCLIENTISFARFROMTHEBESTWAYTODOIT", "original": "It's certainly a good idea to give the user some kind of feedback when data access fails.\nBut displaying the raw error object returned by `HttpClient` is far from the best way to do it.", "translation": "在数据访问失败时给用户一些反馈,确实是个好主意。\n不过,直接显示由 `HttpClient` 返回的原始错误数据还远远不够。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###GETTINGERRORDETAILS", "original": "### Getting error details", "translation": "### 获取错误详情", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "DETECTINGTHATANERROROCCURREDISONETHINGINTERPRETINGTHATERRORANDCOMPOSINGAUSERFRIENDLYRESPONSEISABITMOREINVOLVED", "original": "Detecting that an error occurred is one thing.\nInterpreting that error and composing a user-friendly response is a bit more involved.", "translation": "检测错误的发生是第一步,不过如果知道具体发生了什么错误才会更有用。上面例子中传给回调函数的 `err` 参数的类型是 `HttpErrorResponse`,它包含了这个错误中一些很有用的信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "TWOTYPESOFERRORSCANOCCURTHESERVERBACKENDMIGHTREJECTTHEREQUESTRETURNINGANHTTPRESPONSEWITHASTATUSCODESUCHAS404OR500THESEAREERRORRESPONSES", "original": "Two types of errors can occur. The server backend might reject the request, returning an HTTP response with a status code such as 404 or 500. These are error _responses_.", "translation": "可能发生的错误分为两种。如果后端返回了一个失败的返回码(如 404、500 等),它会返回一个错误响应体。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ORSOMETHINGCOULDGOWRONGONTHECLIENTSIDESUCHASANETWORKERRORTHATPREVENTSTHEREQUESTFROMCOMPLETINGSUCCESSFULLYORANEXCEPTIONTHROWNINANRXJSOPERATORTHESEERRORSPRODUCEJAVASCRIPTERROREVENTOBJECTS", "original": "Or something could go wrong on the client-side such as a network error that prevents the request from completing successfully or an exception thrown in an RxJS operator. These errors produce JavaScript `ErrorEvent` objects.", "translation": "或者,如果在客户端这边出了错误(比如在 RxJS 操作符 (operator) 中抛出的异常或某些阻碍完成这个请求的网络错误),就会抛出一个 `Error` 类型的异常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEHTTPCLIENTCAPTURESBOTHKINDSOFERRORSINITSHTTPERRORRESPONSEANDYOUCANINSPECTTHATRESPONSETOFIGUREOUTWHATREALLYHAPPENED", "original": "The `HttpClient` captures both kinds of errors in its `HttpErrorResponse` and you can inspect that response to figure out what really happened.", "translation": "`HttpClient` 会在 `HttpErrorResponse` 中捕获所有类型的错误信息,你可以查看这个响应体以了解到底发生了什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ERRORINSPECTIONINTERPRETATIONANDRESOLUTIONISSOMETHINGYOUWANTTODOINTHESERVICENOTINTHECOMPONENT", "original": "Error inspection, interpretation, and resolution is something you want to do in the _service_, \nnot in the _component_.", "translation": "错误的探查、解释和解决是你应该在*服务*中做的事情,而不是在*组件*中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUMIGHTFIRSTDEVISEANERRORHANDLERLIKETHISONE:", "original": "You might first devise an error handler like this one:", "translation": "你可能首先要设计一个错误处理器,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOTICETHATTHISHANDLERRETURNSANRXJSERROROBSERVABLE#RXJSWITHAUSERFRIENDLYERRORMESSAGECONSUMERSOFTHESERVICEEXPECTSERVICEMETHODSTORETURNANOBSERVABLEOFSOMEKINDEVENABADONE", "original": "Notice that this handler returns an RxJS [`ErrorObservable`](#rxjs) with a user-friendly error message.\nConsumers of the service expect service methods to return an `Observable` of some kind,\neven a \"bad\" one.", "translation": "注意,该处理器返回一个带有用户友好的错误信息的 RxJS [`ErrorObservable`](#rxjs) 对象。\n该服务的消费者期望服务的方法返回某种形式的 `Observable`,就算是“错误的”也可以。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOWYOUTAKETHEOBSERVABLESRETURNEDBYTHEHTTPCLIENTMETHODSANDPIPETHEMTHROUGHTOTHEERRORHANDLER", "original": "Now you take the `Observables` returned by the `HttpClient` methods\nand _pipe them through_ to the error handler.", "translation": "现在,你获取了由 `HttpClient` 方法返回的 `Observable`,并*把它们通过管道*传给错误处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "SOMETIMESTHEERRORISTRANSIENTANDWILLGOAWAYAUTOMATICALLYIFYOUTRYAGAINFOREXAMPLENETWORKINTERRUPTIONSARECOMMONINMOBILESCENARIOSANDTRYINGAGAINMAYPRODUCEASUCCESSFULRESULT", "original": "Sometimes the error is transient and will go away automatically if you try again.\nFor example, network interruptions are common in mobile scenarios, and trying again\nmay produce a successful result.", "translation": "有时候,错误只是临时性的,只要重试就可能会自动消失。\n比如,在移动端场景中可能会遇到网络中断的情况,只要重试一下就能拿到正确的结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THERXJSLIBRARY#RXJSOFFERSSEVERALRETRYOPERATORSTHATAREWORTHEXPLORINGTHESIMPLESTISCALLEDRETRYANDITAUTOMATICALLYRESUBSCRIBESTOAFAILEDOBSERVABLEASPECIFIEDNUMBEROFTIMESRESUBSCRIBINGTOTHERESULTOFANHTTPCLIENTMETHODCALLHASTHEEFFECTOFREISSUINGTHEHTTPREQUEST", "original": "The [RxJS library](#rxjs) offers several _retry_ operators that are worth exploring.\nThe simplest is called `retry()` and it automatically re-subscribes to a failed `Observable` a specified number of times. _Re-subscribing_ to the result of an `HttpClient` method call has the effect of reissuing the HTTP request.", "translation": "[RxJS 库](#rxjs)提供了几个 `retry` 操作符,它们值得仔细看看。\n其中最简单的是 `retry()`,它可以对失败的 `Observable` 自动重新订阅几次。对 `HttpClient` 方法调用的结果进行*重新订阅*会导致重新发起 HTTP 请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "PIPEITONTOTHEHTTPCLIENTMETHODRESULTJUSTBEFORETHEERRORHANDLER", "original": "_Pipe_ it onto the `HttpClient` method result just before the error handler.", "translation": "把它插入到 `HttpClient` 方法结果的*管道*中,就放在错误处理器的紧前面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##OBSERVABLESANDOPERATORS", "original": "## Observables and operators", "translation": "## 可观察对象 (Observable) 与操作符 (operator)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEPREVIOUSSECTIONSOFTHISGUIDEREFERREDTORXJSOBSERVABLESANDOPERATORSSUCHASCATCHERRORANDRETRYYOUWILLENCOUNTERMORERXJSARTIFACTSASYOUCONTINUEBELOW", "original": "The previous sections of this guide referred to RxJS `Observables` and operators such as `catchError` and `retry`.\nYou will encounter more RxJS artifacts as you continue below.", "translation": "本章的前一节中引用了 RxJS 的 `Observable` 和 `operator`,比如 `catchError` 和 `retry`。\n接下来你还会遇到更多 RxJS 中的概念。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "RXJSHTTP:REACTIVEXIORXJSISALIBRARYFORCOMPOSINGASYNCHRONOUSANDCALLBACKBASEDCODEINAFUNCTIONALREACTIVESTYLEMANYANGULARAPISINCLUDINGHTTPCLIENTPRODUCEANDCONSUMERXJSOBSERVABLES", "original": "[RxJS](http://reactivex.io/rxjs/) is a library for composing asynchronous and callback-based code\nin a _functional, reactive style_.\nMany Angular APIs, including `HttpClient`, produce and consume RxJS `Observables`.", "translation": "[RxJS](http://reactivex.io/rxjs/) 是一个库,用于把异步调用和基于回调的代码组合成*函数式(functional)的*、*响应式(reactive)的*风格。\n很多 Angular API,包括 `HttpClient` 都会生成和消费 RxJS 的 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "RXJSITSELFISOUTOFSCOPEFORTHISGUIDEYOUWILLFINDMANYLEARNINGRESOURCESONTHEWEBWHILEYOUCANGETBYWITHAMINIMUMOFRXJSKNOWLEDGEYOULLWANTTOGROWYOURRXJSSKILLSOVERTIMEINORDERTOUSEHTTPCLIENTEFFECTIVELY", "original": "RxJS itself is out-of-scope for this guide. You will find many learning resources on the web.\nWhile you can get by with a minimum of RxJS knowledge, you'll want to grow your RxJS skills over time in order to use `HttpClient` effectively.", "translation": "RxJS 本身超出了本章的范围。你可以在网络上找到更多的学习资源。\n虽然只用少量的 RxJS 知识就可以获得解决方案,不过以后你会逐步提高 RxJS 技能,以便更高效的使用 `HttpClient`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFYOUREFOLLOWINGALONGWITHTHESECODESNIPPETSNOTETHATYOUMUSTIMPORTTHERXJSOBSERVABLEANDOPERATORSYMBOLSTHATAPPEARINTHOSESNIPPETSTHESECONFIGSERVICEIMPORTSARETYPICAL", "original": "If you're following along with these code snippets, note that you must import the RxJS observable and operator symbols that appear in those snippets. These `ConfigService` imports are typical.", "translation": "如果你在跟着教程敲下面这些代码片段,要注意你要自己导入这里出现的 RxJS 的可观察对象和操作符。就像 `ConfigService` 中的这些导入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##REQUESTINGNONJSONDATA", "original": "## Requesting non-JSON data", "translation": "## 请求非 JSON 格式的数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOTALLAPISRETURNJSONDATAINTHISNEXTEXAMPLEADOWNLOADERSERVICEMETHODREADSATEXTFILEFROMTHESERVERANDLOGSTHEFILECONTENTSBEFORERETURNINGTHOSECONTENTSTOTHECALLERASANOBSERVABLESTRING", "original": "Not all APIs return JSON data. In this next example,\na `DownloaderService` method reads a text file from the server\nand logs the file contents, before returning those contents to the caller\nas an `Observable<string>`.", "translation": "不是所有的 API 都会返回 JSON 数据。在下面这个例子中,`DownloaderService` 中的方法会从服务器读取文本文件,\n并把文件的内容记录下来,然后把这些内容使用 `Observable<string>` 的形式返回给调用者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "HTTPCLIENTGETRETURNSASTRINGRATHERTHANTHEDEFAULTJSONBECAUSEOFTHERESPONSETYPEOPTION", "original": "`HttpClient.get()` returns a string rather than the default JSON because of the `responseType` option.", "translation": "这里的 `HttpClient.get()` 返回字符串而不是默认的 JSON 对象,因为它的 `responseType` 选项是 `'text'`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THERXJSTAPOPERATORASINWIRETAPLETSTHECODEINSPECTGOODANDERRORVALUESPASSINGTHROUGHTHEOBSERVABLEWITHOUTDISTURBINGTHEM", "original": "The RxJS `tap` operator (as in \"wiretap\") lets the code inspect good and error values passing through the observable without disturbing them.", "translation": "RxJS 的 `tap` 操作符(可看做 wiretap - 窃听),让这段代码探查由可观察对象传过来的正确值和错误值,而不用打扰它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ADOWNLOADMETHODINTHEDOWNLOADERCOMPONENTINITIATESTHEREQUESTBYSUBSCRIBINGTOTHESERVICEMETHOD", "original": "A `download()` method in the `DownloaderComponent` initiates the request by subscribing to the service method.", "translation": "在 `DownloaderComponent` 中的 `download()` 方法通过订阅这个服务中的方法来发起一次请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##SENDINGDATATOTHESERVER", "original": "## Sending data to the server", "translation": "## 把数据发送到服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "INADDITIONTOFETCHINGDATAFROMTHESERVERHTTPCLIENTSUPPORTSMUTATINGREQUESTSTHATISSENDINGDATATOTHESERVERWITHOTHERHTTPMETHODSSUCHASPUTPOSTANDDELETE", "original": "In addition to fetching data from the server, `HttpClient` supports mutating requests, that is, sending data to the server with other HTTP methods such as PUT, POST, and DELETE.", "translation": "除了从服务器获取数据之外,`HttpClient` 还支持修改型的请求,也就是说,通过 `PUT`、`POST`、`DELETE` 这样的 HTTP 方法把数据发送到服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESAMPLEAPPFORTHISGUIDEINCLUDESASIMPLIFIEDVERSIONOFTHETOUROFHEROESEXAMPLETHATFETCHESHEROESANDENABLESUSERSTOADDDELETEANDUPDATETHEM", "original": "The sample app for this guide includes a simplified version of the \"Tour of Heroes\" example\nthat fetches heroes and enables users to add, delete, and update them.", "translation": "本指南中的这个范例应用包括一个简化版本的《英雄指南》,它会获取英雄数据,并允许用户添加、删除和修改它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEFOLLOWINGSECTIONSEXCERPTMETHODSOFTHESAMPLESHEROESSERVICE", "original": "The following sections excerpt methods of the sample's `HeroesService`.", "translation": "下面的这些章节中包括该范例的 `HeroesService` 中的一些方法片段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###ADDINGHEADERS", "original": "### Adding headers", "translation": "### 添加请求头", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "MANYSERVERSREQUIREEXTRAHEADERSFORSAVEOPERATIONSFOREXAMPLETHEYMAYREQUIREACONTENTTYPEHEADERTOEXPLICITLYDECLARETHEMIMETYPEOFTHEREQUESTBODYORPERHAPSTHESERVERREQUIRESANAUTHORIZATIONTOKEN", "original": "Many servers require extra headers for save operations.\nFor example, they may require a \"Content-Type\" header to explicitly declare \nthe MIME type of the request body.\nOr perhaps the server requires an authorization token.", "translation": "很多服务器在进行保存型操作时需要额外的请求头。\n比如,它们可能需要一个 `Content-Type` 头来显式定义请求体的 MIME 类型。\n也可能服务器会需要一个认证用的令牌(token)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEHEROESSERVICEDEFINESSUCHHEADERSINANHTTPOPTIONSOBJECTTHATWILLBEPASSEDTOEVERYHTTPCLIENTSAVEMETHOD", "original": "The `HeroesService` defines such headers in an `httpOptions` object that will be passed\nto every `HttpClient` save method.", "translation": "`HeroesService` 在 `httpOptions` 对象中就定义了一些这样的请求头,并把它传给每个 `HttpClient` 的保存型方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###MAKINGAPOSTREQUEST", "original": "### Making a POST request", "translation": "### 发起一个 POST 请求", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "APPSOFTENPOSTDATATOASERVERTHEYPOSTWHENSUBMITTINGAFORMINTHEFOLLOWINGEXAMPLETHEHEROSERVICEPOSTSWHENADDINGAHEROTOTHEDATABASE", "original": "Apps often POST data to a server. They POST when submitting a form. \nIn the following example, the `HeroService` posts when adding a hero to the database.", "translation": "应用经常把数据 `POST` 到服务器。它们会在提交表单时进行 `POST`。\n下面这个例子中,`HeroService` 在把英雄添加到数据库中时,就会使用 `POST`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEHTTPCLIENTPOSTMETHODISSIMILARTOGETINTHATITHASATYPEPARAMETERYOUREEXPECTINGTHESERVERTORETURNTHENEWHEROANDITTAKESARESOURCEURL", "original": "The `HttpClient.post()` method is similar to `get()` in that it has a type parameter\n(you're expecting the server to return the new hero)\nand it takes a resource URL.", "translation": "`HttpClient.post()` 方法像 `get()` 一样也有类型参数(你会希望服务器返回一个新的英雄对象),它包含一个资源 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ITTAKESTWOMOREPARAMETERS:", "original": "It takes two more parameters:", "translation": "它还接受另外两个参数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "1HEROTHEDATATOPOSTINTHEBODYOFTHEREQUEST", "original": "1. `hero` - the data to POST in the body of the request.", "translation": "`hero` - 要 `POST` 的请求体数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "1HTTPOPTIONSTHEMETHODOPTIONSWHICHINTHISCASESPECIFYREQUIREDHEADERS#ADDINGHEADERS", "original": "1. `httpOptions` - the method options which, in this case, [specify required headers](#adding-headers).", "translation": "`httpOptions` - 这个例子中,该方法的选项[指定了所需的请求头](#adding-headers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "OFCOURSEITCATCHESERRORSINMUCHTHESAMEMANNERDESCRIBEDABOVE#ERRORDETAILSITALSOTAPSTHERETURNEDOBSERVABLEINORDERTOLOGTHESUCCESSFULPOST", "original": "Of course it catches errors in much the same manner [described above](#error-details).\nIt also _taps_ the returned observable in order to log the successful POST.", "translation": "当然,它捕获错误的方式很像[前面描述的](#error-details)操作方式。\n它还*窃听*了可观察对象的返回值,以记录成功的 `POST`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEHEROESCOMPONENTINITIATESTHEACTUALPOSTOPERATIONBYSUBSCRIBINGTOTHEOBSERVABLERETURNEDBYTHISSERVICEMETHOD", "original": "The `HeroesComponent` initiates the actual POST operation by subscribing to \nthe `Observable` returned by this service method.", "translation": "`HeroesComponent` 通过订阅该服务方法返回的 `Observable` 发起了一次实际的 `POST` 操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "WHENTHESERVERRESPONDSSUCCESSFULLYWITHTHENEWLYADDEDHEROTHECOMPONENTADDSTHATHEROTOTHEDISPLAYEDHEROESLIST", "original": "When the server responds successfully with the newly added hero, the component adds\nthat hero to the displayed `heroes` list.", "translation": "当服务器成功做出响应时,会带有这个新创建的英雄,然后该组件就会把这个英雄添加到正在显示的 `heroes` 列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###MAKINGADELETEREQUEST", "original": "### Making a DELETE request", "translation": "### 发起 `DELETE` 请求", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THISAPPLICATIONDELETESAHEROWITHTHEHTTPCLIENTDELETEMETHODBYPASSINGTHEHEROSIDINTHEREQUESTURL", "original": "This application deletes a hero with the `HttpClient.delete` method by passing the hero's id\nin the request URL.", "translation": "该应用可以把英雄的 id 传给 `HttpClient.delete` 方法的请求 URL 来删除一个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEHEROESCOMPONENTINITIATESTHEACTUALDELETEOPERATIONBYSUBSCRIBINGTOTHEOBSERVABLERETURNEDBYTHISSERVICEMETHOD", "original": "The `HeroesComponent` initiates the actual DELETE operation by subscribing to \nthe `Observable` returned by this service method.", "translation": "当 `HeroesComponent` 订阅了该服务方法返回的 `Observable` 时,就会发起一次实际的 `DELETE` 操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUMUSTCALLSUBSCRIBEORNOTHINGHAPPENS", "original": "You must call _subscribe()_ or nothing happens!", "translation": "你必须调用 `subscribe()`,否则什么都不会发生。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECOMPONENTISNTEXPECTINGARESULTFROMTHEDELETEOPERATIONANDSUBSCRIBESWITHOUTACALLBACKTHEBARESUBSCRIBESEEMSPOINTLESS", "original": "The component isn't expecting a result from the delete operation and\nsubscribes without a callback.\nThe bare `.subscribe()` _seems_ pointless.", "translation": "该组件不关心删除操作返回的结果,订阅时也没有回调函数。\n单纯的 `.subscribe()` 方法看似毫无意义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "INFACTITISESSENTIALMERELYCALLINGHEROSERVICEDELETEHERODOESNOTINITIATETHEDELETEREQUEST", "original": "In fact, it is essential.\nMerely calling `HeroService.deleteHero()` **does not initiate the DELETE request.**", "translation": "但实际上,它是必备的。\n否则调用 `HeroService.deleteHero()` 时**不会发起 DELETE 请求**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###ALWAYSSUBSCRIBE", "original": "### Always _subscribe_!", "translation": "### 别忘了*订阅*!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ANHTTPCLIENTMETHODDOESNOTBEGINITSHTTPREQUESTUNTILYOUCALLSUBSCRIBEONTHEOBSERVABLERETURNEDBYTHATMETHODTHISISTRUEFORALLHTTPCLIENTMETHODS", "original": "An `HttpClient` method does not begin its HTTP request until you call `subscribe()` on the observable returned by that method. This is true for _all_ `HttpClient` _methods_.", "translation": "在调用方法返回的可观察对象的 `subscribe()` 方法之前,`HttpClient` 方法不会发起 HTTP 请求。这适用于 `HttpClient` 的*所有方法*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEASYNCPIPEAPICOMMONASYNCPIPESUBSCRIBESANDUNSUBSCRIBESFORYOUAUTOMATICALLY", "original": "The [`AsyncPipe`](api/common/AsyncPipe) subscribes (and unsubscribes) for you automatically.", "translation": "[`AsyncPipe`](api/common/AsyncPipe) 会自动为你订阅(以及取消订阅)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ALLOBSERVABLESRETURNEDFROMHTTPCLIENTMETHODSARECOLDBYDESIGNEXECUTIONOFTHEHTTPREQUESTISDEFERREDALLOWINGYOUTOEXTENDTHEOBSERVABLEWITHADDITIONALOPERATIONSSUCHASTAPANDCATCHERRORBEFOREANYTHINGACTUALLYHAPPENS", "original": "All observables returned from `HttpClient` methods are _cold_ by design.\nExecution of the HTTP request is _deferred_, allowing you to extend the\nobservable with additional operations such as `tap` and `catchError`\n before anything actually happens.", "translation": "`HttpClient` 的所有方法返回的可观察对象都设计为*冷的*。\nHTTP 请求的执行都是*延期执行的*,让你可以用 `tap` 和 `catchError` 这样的操作符来在实际执行什么之前,先对这个可观察对象进行扩展。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "CALLINGSUBSCRIBETRIGGERSEXECUTIONOFTHEOBSERVABLEANDCAUSESHTTPCLIENTTOCOMPOSEANDSENDTHEHTTPREQUESTTOTHESERVER", "original": "Calling `subscribe(...)` triggers execution of the observable and causes\n`HttpClient` to compose and send the HTTP request to the server.", "translation": "调用 `subscribe(...)` 会触发这个可观察对象的执行,并导致 `HttpClient` 组合并把 HTTP 请求发给服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCANTHINKOFTHESEOBSERVABLESASBLUEPRINTSFORACTUALHTTPREQUESTS", "original": "You can think of these observables as _blueprints_ for actual HTTP requests.", "translation": "你可以把这些可观察对象看做实际 HTTP 请求的*蓝图*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "INFACTEACHSUBSCRIBEINITIATESASEPARATEINDEPENDENTEXECUTIONOFTHEOBSERVABLESUBSCRIBINGTWICERESULTSINTWOHTTPREQUESTS", "original": "In fact, each `subscribe()` initiates a separate, independent execution of the observable.\nSubscribing twice results in two HTTP requests.", "translation": "实际上,每个 `subscribe()` 都会初始化此可观察对象的一次单独的、独立的执行。\n订阅两次就会导致发起两个 HTTP 请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###MAKINGAPUTREQUEST", "original": "### Making a PUT request", "translation": "### 发起 PUT 请求", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ANAPPWILLSENDAPUTREQUESTTOCOMPLETELYREPLACEARESOURCEWITHUPDATEDDATATHEFOLLOWINGHEROSERVICEEXAMPLEISJUSTLIKETHEPOSTEXAMPLE", "original": "An app will send a PUT request to completely replace a resource with updated data.\nThe following `HeroService` example is just like the POST example.", "translation": "应用可以发送 PUT 请求,来使用修改后的数据完全替换掉一个资源。\n下面的 `HeroService` 例子和 POST 的例子很像。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "FORTHEREASONSEXPLAINEDABOVE#ALWAYSSUBSCRIBETHECALLERHEROESCOMPONENTUPDATEINTHISCASEMUSTSUBSCRIBETOTHEOBSERVABLERETURNEDFROMTHEHTTPCLIENTPUTINORDERTOINITIATETHEREQUEST", "original": "For the reasons [explained above](#always-subscribe), the caller (`HeroesComponent.update()` in this case) must `subscribe()` to the observable returned from the `HttpClient.put()`\nin order to initiate the request.", "translation": "因为[前面解释过的](#always-subscribe)原因,调用者(这里是 `HeroesComponent.update()`)必须 `subscribe()` 由 `HttpClient.put()` 返回的可观察对象,以发起这个调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##ADVANCEDUSAGE", "original": "## Advanced usage", "translation": "## 高级用法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEABOVESECTIONSDETAILHOWTOUSETHEBASICHTTPFUNCTIONALITYINANGULARCOMMONHTTPBUTSOMETIMESYOUNEEDTODOMORETHANMAKESIMPLEREQUESTSANDGETDATABACK", "original": "The above sections detail how to use the basic HTTP functionality in `@angular/common/http`, but sometimes you need to do more than make simple requests and get data back.", "translation": "上面这个小节中详细讲解了如何使用 `@angular/common/http` 中提供的基本 HTTP 功能,但有时候除了单纯发起请求和取回数据之外,你还要再做点别的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###CONFIGURINGTHEREQUEST", "original": "### Configuring the request", "translation": "### 配置请求", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "OTHERASPECTSOFANOUTGOINGREQUESTCANBECONFIGUREDVIATHEOPTIONSOBJECTPASSEDASTHELASTARGUMENTTOTHEHTTPCLIENTMETHOD", "original": "Other aspects of an outgoing request can be configured via the options object\npassed as the last argument to the `HttpClient` method.", "translation": "待发送请求的其它方面可以通过传给 `HttpClient` 方法最后一个参数中的配置对象进行配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUSAWEARLIER#ADDINGHEADERSTHATTHEHEROSERVICESETSTHEDEFAULTHEADERSBYPASSINGANOPTIONSOBJECTHTTPOPTIONSTOITSSAVEMETHODSYOUCANDOMORE", "original": "You [saw earlier](#adding-headers) that the `HeroService` sets the default headers by\npassing an options object (`httpOptions`) to its save methods.\nYou can do more.", "translation": "[以前你曾在](#adding-headers) `HeroService` 中通过在其保存方法中传入配置对象 `httpOptions` 设置过默认头。\n你还可以做更多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####UPDATEHEADERS", "original": "#### Update headers", "translation": "#### 修改这些头", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCANTDIRECTLYMODIFYTHEEXISTINGHEADERSWITHINTHEPREVIOUSOPTIONSOBJECTBECAUSEINSTANCESOFTHEHTTPHEADERSCLASSAREIMMUTABLE", "original": "You can't directly modify the existing headers within the previous options\nobject because instances of the `HttpHeaders` class are immutable.", "translation": "你没法直接修改前述配置对象中的现有头,因为这个 `HttpHeaders` 类的实例是不可变的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "USETHESETMETHODINSTEADITRETURNSACLONEOFTHECURRENTINSTANCEWITHTHENEWCHANGESAPPLIED", "original": "Use the `set()` method instead. \nIt returns a clone of the current instance with the new changes applied.", "translation": "改用 `set()` 方法代替。\n它会返回当前实例的一份克隆,其中应用了这些新修改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "HERESHOWYOUMIGHTUPDATETHEAUTHORIZATIONHEADERAFTERTHEOLDTOKENEXPIREDBEFOREMAKINGTHENEXTREQUEST", "original": "Here's how you might update the authorization header (after the old token expired) \nbefore making the next request.", "translation": "比如在发起下一个请求之前,如果旧的令牌已经过期了,你可能还要修改认证头。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####URLPARAMETERS", "original": "#### URL Parameters", "translation": "#### URL 参数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ADDINGURLSEARCHPARAMETERSWORKSASIMILARWAYHEREISASEARCHHEROESMETHODTHATQUERIESFORHEROESWHOSENAMESCONTAINTHESEARCHTERM", "original": "Adding URL search parameters works a similar way.\nHere is a `searchHeroes` method that queries for heroes whose names contain the search term.", "translation": "添加 URL 搜索参数也与此类似。\n这里的 `searchHeroes` 方法会查询名字中包含搜索词的英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFTHEREISASEARCHTERMTHECODECONSTRUCTSANOPTIONSOBJECTWITHANHTMLURLENCODEDSEARCHPARAMETERIFTHETERMWEREFOOTHEGETREQUESTURLWOULDBEAPIHEROESNAMEFOO", "original": "If there is a search term, the code constructs an options object with an HTML URL encoded search parameter. If the term were \"foo\", the GET request URL would be `api/heroes/?name=foo`.", "translation": "如果有搜索词,这段代码就会构造一个包含进行过 URL 编码的搜索词的选项对象。如果这个搜索词是“foo”,这个 GET 请求的 URL 就会是 `api/heroes/?name=foo`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { - "original": "The `HttpParams` are immutable so you'll have to use the `set()` method to update the options.", + "key": "THEHTTPPARMSAREIMMUTABLESOYOULLHAVETOUSETHESETMETHODTOUPDATETHEOPTIONS", + "original": "The `HttpParms` are immutable so you'll have to use the `set()` method to update the options.", "translation": "`HttpParams` 是不可变的,所以你也要使用 `set()` 方法来修改这些选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###DEBOUNCINGREQUESTS", "original": "### Debouncing requests", "translation": "### 请求的防抖(debounce)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESAMPLEINCLUDESANNPMPACKAGESEARCHFEATURE", "original": "The sample includes an _npm package search_ feature.", "translation": "这个例子还包含了*搜索 npm 包*的特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "WHENTHEUSERENTERSANAMEINASEARCHBOXTHEPACKAGESEARCHCOMPONENTSENDSASEARCHREQUESTFORAPACKAGEWITHTHATNAMETOTHENPMWEBAPI", "original": "When the user enters a name in a search-box, the `PackageSearchComponent` sends\na search request for a package with that name to the NPM web api.", "translation": "当用户在搜索框中输入名字时,`PackageSearchComponent` 就会把一个根据名字搜索包的请求发送给 NPM 的 web api。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "HERESAPERTINENTEXCERPTFROMTHETEMPLATE:", "original": "Here's a pertinent excerpt from the template:", "translation": "下面是模板中的相关代码片段:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEKEYUPEVENTBINDINGSENDSEVERYKEYSTROKETOTHECOMPONENTSSEARCHMETHOD", "original": "The `(keyup)` event binding sends every keystroke to the component's `search()` method.", "translation": "`(keyup)` 事件绑定把每次击键都发送给了组件的 `search()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "SENDINGAREQUESTFOREVERYKEYSTROKECOULDBEEXPENSIVEITSBETTERTOWAITUNTILTHEUSERSTOPSTYPINGANDTHENSENDAREQUESTTHATSEASYTOIMPLEMENTWITHRXJSOPERATORSASSHOWNINTHISEXCERPT", "original": "Sending a request for every keystroke could be expensive.\nIt's better to wait until the user stops typing and then send a request.\nThat's easy to implement with RxJS operators, as shown in this excerpt.", "translation": "如果每次击键都发送一次请求就太昂贵了。\n最好能等到用户停止输入时才发送请求。\n使用 RxJS 的操作符就能轻易实现它,参见下面的代码片段:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESEARCHTEXTISTHESEQUENCEOFSEARCHBOXVALUESCOMINGFROMTHEUSERITSDEFINEDASANRXJSSUBJECTWHICHMEANSITISANOBSERVABLETHATCANALSOPRODUCEVALUESFORITSELFBYCALLINGNEXTVALUEASHAPPENSINTHESEARCHMETHOD", "original": "The `searchText$` is the sequence of search-box values coming from the user.\nIt's defined as an RxJS `Subject`, which means it is an `Observable`\nthat can also produce values for itself by calling `next(value)`,\nas happens in the `search()` method.", "translation": "`searchText$` 是一个序列,包含用户输入到搜索框中的所有值。\n它定义成了 RxJS 的 `Subject` 对象,这表示它是一个 `Observable`,同时还可以自行调用 `next(value)` 来产生值。\n`search()` 方法中就是这么做的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "RATHERTHANFORWARDEVERYSEARCHTEXTVALUEDIRECTLYTOTHEINJECTEDPACKAGESEARCHSERVICETHECODEINNGONINITPIPESSEARCHVALUESTHROUGHTHREEOPERATORS:", "original": "Rather than forward every `searchText` value directly to the injected `PackageSearchService`,\nthe code in `ngOnInit()` _pipes_ search values through three operators:", "translation": "除了把每个 `searchText` 的值都直接转发给 `PackageSearchService` 之外,`ngOnInit()` 中的代码还通过下列三个操作符对这些搜索值进行*管道*处理:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "1DEBOUNCETIME500WAITFORTHEUSERTOSTOPTYPING12SECONDINTHISCASE", "original": "1. `debounceTime(500)` - wait for the user to stop typing (1/2 second in this case).", "translation": "`debounceTime(500)` - 等待,直到用户停止输入(这个例子中是停止 1/2 秒)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "1DISTINCTUNTILCHANGEDWAITUNTILTHESEARCHTEXTCHANGES", "original": "1. `distinctUntilChanged()` - wait until the search text changes.", "translation": "`distinctUntilChanged()` - 等待,直到搜索内容发生了变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "1SWITCHMAPSENDTHESEARCHREQUESTTOTHESERVICE", "original": "1. `switchMap()` - send the search request to the service.", "translation": "`switchMap()` - 把搜索请求发送给服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECODESETSPACKAGESTOTHISRECOMPOSEDOBSERVABLEOFSEARCHRESULTSTHETEMPLATESUBSCRIBESTOPACKAGESWITHTHEASYNCPIPEAPICOMMONASYNCPIPEANDDISPLAYSSEARCHRESULTSASTHEYARRIVE", "original": "The code sets `packages$` to this re-composed `Observable` of search results.\nThe template subscribes to `packages$` with the [AsyncPipe](api/common/AsyncPipe)\nand displays search results as they arrive.", "translation": "这些代码把 `packages$` 设置成了使用搜索结果组合出的 `Observable` 对象。\n模板中使用 [AsyncPipe](api/common/AsyncPipe) 订阅了 `packages$`,一旦搜索结果的值发回来了,就显示这些搜索结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ASEARCHVALUEREACHESTHESERVICEONLYIFITSANEWVALUEANDTHEUSERHASSTOPPEDTYPING", "original": "A search value reaches the service only if it's a new value and the user has stopped typing.", "translation": "这样,只有当用户停止了输入且搜索值和以前不一样的时候,搜索值才会传给服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEWITHREFRESHOPTIONISEXPLAINEDBELOW#CACHEREFRESH", "original": "The `withRefresh` option is explained [below](#cache-refresh).", "translation": "[稍后](#cache-refresh) 解释了这个 `withRefresh` 选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESWITCHMAPOPERATORHASTHREEIMPORTANTCHARACTERISTICS", "original": "The `switchMap()` operator has three important characteristics.", "translation": "这个 `switchMap()` 操作符有三个重要的特征:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "1ITTAKESAFUNCTIONARGUMENTTHATRETURNSANOBSERVABLEPACKAGESEARCHSERVICESEARCHRETURNSANOBSERVABLEASOTHERDATASERVICEMETHODSDO", "original": "1. It takes a function argument that returns an `Observable`.\n`PackageSearchService.search` returns an `Observable`, as other data service methods do.", "translation": "它的参数是一个返回 `Observable` 的函数。`PackageSearchService.search` 会返回 `Observable`,其它数据服务也一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "2IFAPREVIOUSSEARCHREQUESTISSTILLINFLIGHTASWHENTHECONNECTIONISPOORITCANCELSTHATREQUESTANDSENDSANEWONE", "original": "2. If a previous search request is still _in-flight_ (as when the connection is poor),\nit cancels that request and sends a new one.", "translation": "如果以前的搜索结果仍然是*在途*状态(这会出现在慢速网络中),它会取消那个请求,并发起这个新的搜索。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "3ITRETURNSSERVICERESPONSESINTHEIRORIGINALREQUESTORDEREVENIFTHESERVERRETURNSTHEMOUTOFORDER", "original": "3. It returns service responses in their original request order, even if the\nserver returns them out of order.", "translation": "它会按照原始的请求顺序返回这些服务的响应,而不用关心服务器实际上是以乱序返回的它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFYOUTHINKYOULLREUSETHISDEBOUNCINGLOGICCONSIDERMOVINGITTOAUTILITYFUNCTIONORINTOTHEPACKAGESEARCHSERVICEITSELF", "original": "If you think you'll reuse this debouncing logic,\nconsider moving it to a utility function or into the `PackageSearchService` itself.", "translation": "如果你觉得将来会复用这些防抖逻辑,\n可以把它移到单独的工具函数中,或者移到 `PackageSearchService` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###INTERCEPTINGREQUESTSANDRESPONSES", "original": "### Intercepting requests and responses", "translation": "### 拦截请求和响应", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "HTTPINTERCEPTIONISAMAJORFEATUREOFANGULARCOMMONHTTPWITHINTERCEPTIONYOUDECLAREINTERCEPTORSTHATINSPECTANDTRANSFORMHTTPREQUESTSFROMYOURAPPLICATIONTOTHESERVERTHESAMEINTERCEPTORSMAYALSOINSPECTANDTRANSFORMTHESERVERSRESPONSESONTHEIRWAYBACKTOTHEAPPLICATIONMULTIPLEINTERCEPTORSFORMAFORWARDANDBACKWARDCHAINOFREQUESTRESPONSEHANDLERS", "original": "_HTTP Interception_ is a major feature of `@angular/common/http`. \nWith interception, you declare _interceptors_ that inspect and transform HTTP requests from your application to the server.\nThe same interceptors may also inspect and transform the server's responses on their way back to the application.\nMultiple interceptors form a _forward-and-backward_ chain of request/response handlers.", "translation": "*HTTP* 拦截机制是 `@angular/common/http` 中的主要特性之一。\n使用这种拦截机制,你可以声明*一些拦截器*,用它们监视和转换从应用发送到服务器的 HTTP 请求。\n拦截器还可以用监视和转换从服务器返回到本应用的那些响应。\n多个选择器会构成一个“请求/响应处理器”的双向链表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "INTERCEPTORSCANPERFORMAVARIETYOFIMPLICITTASKSFROMAUTHENTICATIONTOLOGGINGINAROUTINESTANDARDWAYFOREVERYHTTPREQUESTRESPONSE", "original": "Interceptors can perform a variety of _implicit_ tasks, from authentication to logging, in a routine, standard way, for every HTTP request/response.", "translation": "拦截器可以用一种常规的、标准的方式对每一次 HTTP 的请求/响应任务执行从认证到记日志等很多种*隐式*任务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "WITHOUTINTERCEPTIONDEVELOPERSWOULDHAVETOIMPLEMENTTHESETASKSEXPLICITLYFOREACHHTTPCLIENTMETHODCALL", "original": "Without interception, developers would have to implement these tasks _explicitly_ \nfor each `HttpClient` method call.", "translation": "如果没有拦截机制,那么开发人员将不得不对每次 `HttpClient` 调用*显式*实现这些任务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####WRITEANINTERCEPTOR", "original": "#### Write an interceptor", "translation": "#### 编写拦截器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "TOIMPLEMENTANINTERCEPTORDECLAREACLASSTHATIMPLEMENTSTHEINTERCEPTMETHODOFTHEHTTPINTERCEPTORINTERFACE", "original": "To implement an interceptor, declare a class that implements the `intercept()` method of the `HttpInterceptor` interface.", "translation": "要实现拦截器,就要实现一个实现了 `HttpInterceptor` 接口中的 `intercept()` 方法的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "HEREISADONOTHINGNOOPINTERCEPTORTHATSIMPLYPASSESTHEREQUESTTHROUGHWITHOUTTOUCHINGIT:", "original": "Here is a do-nothing _noop_ interceptor that simply passes the request through without touching it:", "translation": "这里是一个什么也不做的*空白*拦截器,它只会不做任何修改的传递这个请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEINTERCEPTMETHODTRANSFORMSAREQUESTINTOANOBSERVABLETHATEVENTUALLYRETURNSTHEHTTPRESPONSEINTHISSENSEEACHINTERCEPTORISFULLYCAPABLEOFHANDLINGTHEREQUESTENTIRELYBYITSELF", "original": "The `intercept` method transforms a request into an `Observable` that eventually returns the HTTP response. \nIn this sense, each interceptor is fully capable of handling the request entirely by itself.", "translation": "`intercept` 方法会把请求转换成一个最终返回 HTTP 响应体的 `Observable`。\n在这个场景中,每个拦截器都完全能自己处理这个请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "MOSTINTERCEPTORSINSPECTTHEREQUESTONTHEWAYINANDFORWARDTHEPERHAPSALTEREDREQUESTTOTHEHANDLEMETHODOFTHENEXTOBJECTWHICHIMPLEMENTSTHEHTTPHANDLERAPICOMMONHTTPHTTPHANDLERINTERFACE", "original": "Most interceptors inspect the request on the way in and forward the (perhaps altered) request to the `handle()` method of the `next` object which implements the [`HttpHandler`](api/common/http/HttpHandler) interface.", "translation": "大多数拦截器拦截都会在传入时检查请求,然后把(可能被修改过的)请求转发给 `next` 对象的 `handle()` 方法,而 `next` 对象实现了 [`HttpHandler`](api/common/http/HttpHandler) 接口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "LIKEINTERCEPTTHEHANDLEMETHODTRANSFORMSANHTTPREQUESTINTOANOBSERVABLEOFHTTPEVENTS#HTTPEVENTSWHICHULTIMATELYINCLUDETHESERVERSRESPONSETHEINTERCEPTMETHODCOULDINSPECTTHATOBSERVABLEANDALTERITBEFORERETURNINGITTOTHECALLER", "original": "Like `intercept()`, the `handle()` method transforms an HTTP request into an `Observable` of [`HttpEvents`](#httpevents) which ultimately include the server's response. The `intercept()` method could inspect that observable and alter it before returning it to the caller.", "translation": "像 `intercept()` 一样,`handle()` 方法也会把 HTTP 请求转换成 [`HttpEvents`](#httpevents) 组成的 `Observable`,它最终包含的是来自服务器的响应。\n`intercept()` 函数可以检查这个可观察对象,并在把它返回给调用者之前修改它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THISNOOPINTERCEPTORSIMPLYCALLSNEXTHANDLEWITHTHEORIGINALREQUESTANDRETURNSTHEOBSERVABLEWITHOUTDOINGATHING", "original": "This _no-op_ interceptor simply calls `next.handle()` with the original request and returns the observable without doing a thing.", "translation": "这个*无操作的*拦截器,会直接使用原始的请求调用 `next.handle()`,并返回它返回的可观察对象,而不做任何后续处理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####THENEXTOBJECT", "original": "#### The _next_ object", "translation": "#### `next` 对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THENEXTOBJECTREPRESENTSTHENEXTINTERCEPTORINTHECHAINOFINTERCEPTORSTHEFINALNEXTINTHECHAINISTHEHTTPCLIENTBACKENDHANDLERTHATSENDSTHEREQUESTTOTHESERVERANDRECEIVESTHESERVERSRESPONSE", "original": "The `next` object represents the next interceptor in the chain of interceptors. \nThe final `next` in the chain is the `HttpClient` backend handler that sends the request to the server and receives the server's response.", "translation": "`next` 对象表示拦截器链表中的下一个拦截器。\n这个链表中的最后一个 `next` 对象就是 `HttpClient` 的后端处理器(backend handler),它会把请求发给服务器,并接收服务器的响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "MOSTINTERCEPTORSCALLNEXTHANDLESOTHATTHEREQUESTFLOWSTHROUGHTOTHENEXTINTERCEPTORANDEVENTUALLYTHEBACKENDHANDLERANINTERCEPTORCOULDSKIPCALLINGNEXTHANDLESHORTCIRCUITTHECHAINANDRETURNITSOWNOBSERVABLE#CACHINGWITHANARTIFICIALSERVERRESPONSE", "original": "Most interceptors call `next.handle()` so that the request flows through to the next interceptor and, eventually, the backend handler.\nAn interceptor _could_ skip calling `next.handle()`, short-circuit the chain, and [return its own `Observable`](#caching) with an artificial server response.", "translation": "大多数的拦截器都会调用 `next.handle()`,以便这个请求流能走到下一个拦截器,并最终传给后端处理器。\n拦截器也*可以*不调用 `next.handle()`,使这个链路短路,并返回一个带有人工构造出来的服务器响应的 [自己的 `Observable`](#caching)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THISISACOMMONMIDDLEWAREPATTERNFOUNDINFRAMEWORKSSUCHASEXPRESSJS", "original": "This is a common middleware pattern found in frameworks such as Express.js.", "translation": "这是一种常见的中间件模式,在像 Express.js 这样的框架中也会找到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####PROVIDETHEINTERCEPTOR", "original": "#### Provide the interceptor", "translation": "#### 提供这个拦截器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THENOOPINTERCEPTORISASERVICEMANAGEDBYANGULARSDEPENDENCYINJECTIONDIGUIDEDEPENDENCYINJECTIONSYSTEMLIKEOTHERSERVICESYOUMUSTPROVIDETHEINTERCEPTORCLASSBEFORETHEAPPCANUSEIT", "original": "The `NoopInterceptor` is a service managed by Angular's [dependency injection (DI)](guide/dependency-injection) system. \nLike other services, you must provide the interceptor class before the app can use it.", "translation": "这个 `NoopInterceptor` 就是一个由 Angular [依赖注入 (DI)](guide/dependency-injection)系统管理的服务。\n像其它服务一样,你也必须先提供这个拦截器类,应用才能使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "BECAUSEINTERCEPTORSAREOPTIONALDEPENDENCIESOFTHEHTTPCLIENTSERVICEYOUMUSTPROVIDETHEMINTHESAMEINJECTORORAPARENTOFTHEINJECTORTHATPROVIDESHTTPCLIENTINTERCEPTORSPROVIDEDAFTERDICREATESTHEHTTPCLIENTAREIGNORED", "original": "Because interceptors are (optional) dependencies of the `HttpClient` service, \nyou must provide them in the same injector (or a parent of the injector) that provides `HttpClient`. \nInterceptors provided _after_ DI creates the `HttpClient` are ignored.", "translation": "由于拦截器是 `HttpClient` 服务的(可选)依赖,所以你必须在提供 `HttpClient` 的同一个(或其各级父注入器)注入器中提供这些拦截器。\n那些在 DI 创建完 `HttpClient` *之后*再提供的拦截器将会被忽略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THISAPPPROVIDESHTTPCLIENTINTHEAPPSROOTINJECTORASASIDEEFFECTOFIMPORTINGTHEHTTPCLIENTMODULEINAPPMODULEYOUSHOULDPROVIDEINTERCEPTORSINAPPMODULEASWELL", "original": "This app provides `HttpClient` in the app's root injector, as a side-effect of importing the `HttpClientModule` in `AppModule`.\nYou should provide interceptors in `AppModule` as well.", "translation": "由于在 `AppModule` 中导入了 `HttpClientModule`,导致本应用在其根注入器中提供了 `HttpClient`。所以你也同样要在 `AppModule` 中提供这些拦截器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "AFTERIMPORTINGTHEHTTPINTERCEPTORSINJECTIONTOKENFROMANGULARCOMMONHTTPWRITETHENOOPINTERCEPTORPROVIDERLIKETHIS:", "original": "After importing the `HTTP_INTERCEPTORS` injection token from `@angular/common/http`,\nwrite the `NoopInterceptor` provider like this:", "translation": "在从 `@angular/common/http` 中导入了 `HTTP_INTERCEPTORS` 注入令牌之后,编写如下的 `NoopInterceptor` 提供商注册语句:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOTETHEMULTI:TRUEOPTIONTHISREQUIREDSETTINGTELLSANGULARTHATHTTPINTERCEPTORSISATOKENFORAMULTIPROVIDERTHATINJECTSANARRAYOFVALUESRATHERTHANASINGLEVALUE", "original": "Note the `multi: true` option. \nThis required setting tells Angular that `HTTP_INTERCEPTORS` is a token for a _multiprovider_ \nthat injects an array of values, rather than a single value.", "translation": "注意 `multi: true` 选项。\n这个必须的选项会告诉 Angular `HTTP_INTERCEPTORS` 是一个*多重提供商*的令牌,表示它会注入一个多值的数组,而不是单一的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCOULDADDTHISPROVIDERDIRECTLYTOTHEPROVIDERSARRAYOFTHEAPPMODULEHOWEVERITSRATHERVERBOSEANDTHERESAGOODCHANCETHATYOULLCREATEMOREINTERCEPTORSANDPROVIDETHEMINTHESAMEWAYYOUMUSTALSOPAYCLOSEATTENTIONTOTHEORDER#INTERCEPTORORDERINWHICHYOUPROVIDETHESEINTERCEPTORS", "original": "You _could_ add this provider directly to the providers array of the `AppModule`.\nHowever, it's rather verbose and there's a good chance that \nyou'll create more interceptors and provide them in the same way.\nYou must also pay [close attention to the order](#interceptor-order) \nin which you provide these interceptors.", "translation": "你*也可以*直接把这个提供商添加到 `AppModule` 中的提供商数组中,不过那样会非常啰嗦。况且,你将来还会用这种方式创建更多的拦截器并提供它们。\n你还要[特别注意提供这些拦截器的顺序](#interceptor-order)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "CONSIDERCREATINGABARRELFILETHATGATHERSALLTHEINTERCEPTORPROVIDERSINTOANHTTPINTERCEPTORPROVIDERSARRAYSTARTINGWITHTHISFIRSTONETHENOOPINTERCEPTOR", "original": "Consider creating a \"barrel\" file that gathers all the interceptor providers into an `httpInterceptorProviders` array, starting with this first one, the `NoopInterceptor`.", "translation": "认真考虑创建一个封装桶(barrel)文件,用于把所有拦截器都收集起来,一起提供给 `httpInterceptorProviders` 数组,可以先从这个 `NoopInterceptor` 开始。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THENIMPORTANDADDITTOTHEAPPMODULEPROVIDERSARRAYLIKETHIS:", "original": "Then import and add it to the `AppModule` _providers array_ like this:", "translation": "然后导入它,并把它加到 `AppModule` 的 *`providers` 数组*中,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ASYOUCREATENEWINTERCEPTORSADDTHEMTOTHEHTTPINTERCEPTORPROVIDERSARRAYANDYOUWONTHAVETOREVISITTHEAPPMODULE", "original": "As you create new interceptors, add them to the `httpInterceptorProviders` array and\nyou won't have to revisit the `AppModule`.", "translation": "当你再创建新的拦截器时,就同样把它们添加到 `httpInterceptorProviders` 数组中,而不用再修改 `AppModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEREAREMANYMOREINTERCEPTORSINTHECOMPLETESAMPLECODE", "original": "There are many more interceptors in the complete sample code.", "translation": "在完整版的范例代码中还有更多的拦截器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####INTERCEPTORORDER", "original": "#### Interceptor order", "translation": "#### 拦截器的顺序", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ANGULARAPPLIESINTERCEPTORSINTHEORDERTHATYOUPROVIDETHEMIFYOUPROVIDEINTERCEPTORSATHENBTHENCREQUESTSWILLFLOWINABCANDRESPONSESWILLFLOWOUTCBA", "original": "Angular applies interceptors in the order that you provide them.\nIf you provide interceptors _A_, then _B_, then _C_, requests will flow in _A->B->C_ and\nresponses will flow out _C->B->A_.", "translation": "Angular 会按照你提供它们的顺序应用这些拦截器。\n如果你提供拦截器的顺序是先 *A*,再 *B*,再 *C*,那么请求阶段的执行顺序就是 *A->B->C*,而响应阶段的执行顺序则是\n *C->B->A*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCANNOTCHANGETHEORDERORREMOVEINTERCEPTORSLATERIFYOUNEEDTOENABLEANDDISABLEANINTERCEPTORDYNAMICALLYYOULLHAVETOBUILDTHATCAPABILITYINTOTHEINTERCEPTORITSELF", "original": "You cannot change the order or remove interceptors later.\nIf you need to enable and disable an interceptor dynamically, you'll have to build that capability into the interceptor itself.", "translation": "以后你就再也不能修改这些顺序或移除某些拦截器了。\n如果你需要动态启用或禁用某个拦截器,那就要在那个拦截器中自行实现这个功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUMAYHAVEEXPECTEDTHEINTERCEPTANDHANDLEMETHODSTORETURNOBSERVABLESOFHTTPRESPONSEANYASMOSTHTTPCLIENTMETHODSDO", "original": "You may have expected the `intercept()` and `handle()` methods to return observables of `HttpResponse<any>` as most `HttpClient` methods do.", "translation": "你可能会期望 `intercept()` 和 `handle()` 方法会像大多数 `HttpClient` 中的方法那样返回 `HttpResponse<any>` 的可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "INSTEADTHEYRETURNOBSERVABLESOFHTTPEVENTANY", "original": "Instead they return observables of `HttpEvent<any>`.", "translation": "然而并没有,它们返回的是 `HttpEvent<any>` 的可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THATSBECAUSEINTERCEPTORSWORKATALOWERLEVELTHANTHOSEHTTPCLIENTMETHODSASINGLEHTTPREQUESTCANGENERATEMULTIPLEEVENTSINCLUDINGUPLOADANDDOWNLOADPROGRESSEVENTSTHEHTTPRESPONSECLASSITSELFISACTUALLYANEVENTWHOSETYPEISHTTPEVENTTYPEHTTPRESPONSEEVENT", "original": "That's because interceptors work at a lower level than those `HttpClient` methods. A single HTTP request can generate multiple _events_, including upload and download progress events. The `HttpResponse` class itself is actually an event, whose type is `HttpEventType.HttpResponseEvent`.", "translation": "这是因为拦截器工作的层级比那些 `HttpClient` 方法更低一些。每个 HTTP 请求都可能会生成很多个*事件*,包括上传和下载的进度事件。\n实际上,`HttpResponse` 类本身就是一个事件,它的类型(`type`)是 `HttpEventType.HttpResponseEvent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "MANYINTERCEPTORSAREONLYCONCERNEDWITHTHEOUTGOINGREQUESTANDSIMPLYRETURNTHEEVENTSTREAMFROMNEXTHANDLEWITHOUTMODIFYINGIT", "original": "Many interceptors are only concerned with the outgoing request and simply return the event stream from `next.handle()` without modifying it.", "translation": "很多拦截器只关心发出的请求,而对 `next.handle()` 返回的事件流不会做任何修改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "BUTINTERCEPTORSTHATEXAMINEANDMODIFYTHERESPONSEFROMNEXTHANDLEWILLSEEALLOFTHESEEVENTSYOURINTERCEPTORSHOULDRETURNEVERYEVENTUNTOUCHEDUNLESSITHASACOMPELLINGREASONTODOOTHERWISE", "original": "But interceptors that examine and modify the response from `next.handle()` \nwill see all of these events. \nYour interceptor should return _every event untouched_ unless it has a _compelling reason to do otherwise_.", "translation": "但那些要检查和修改来自 `next.handle()` 的响应体的拦截器希望看到所有这些事件。\n所以,你的拦截器应该返回*你没碰过的所有事件*,除非你*有充分的理由不这么做*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####IMMUTABILITY", "original": "#### Immutability", "translation": "#### 不可变性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ALTHOUGHINTERCEPTORSARECAPABLEOFMUTATINGREQUESTSANDRESPONSESTHEHTTPREQUESTANDHTTPRESPONSEINSTANCEPROPERTIESAREREADONLYRENDERINGTHEMLARGELYIMMUTABLE", "original": "Although interceptors are capable of mutating requests and responses,\nthe `HttpRequest` and `HttpResponse` instance properties are `readonly`,\nrendering them largely immutable.", "translation": "虽然拦截器有能力改变请求和响应,但 `HttpRequest` 和 `HttpResponse` 实例的属性却是只读(`readonly`)的,\n因此,它们在很大意义上说是不可变对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEYAREIMMUTABLEFORAGOODREASON:THEAPPMAYRETRYAREQUESTSEVERALTIMESBEFOREITSUCCEEDSWHICHMEANSTHATTHEINTERCEPTORCHAINMAYREPROCESSTHESAMEREQUESTMULTIPLETIMESIFANINTERCEPTORCOULDMODIFYTHEORIGINALREQUESTOBJECTTHERETRIEDOPERATIONWOULDSTARTFROMTHEMODIFIEDREQUESTRATHERTHANTHEORIGINALIMMUTABILITYENSURESTHATINTERCEPTORSSEETHESAMEREQUESTFOREACHTRY", "original": "They are immutable for a good reason: the app may retry a request several times before it succeeds, which means that the interceptor chain may re-process the same request multiple times.\nIf an interceptor could modify the original request object, the re-tried operation would start from the modified request rather than the original. Immutability ensures that interceptors see the same request for each try.", "translation": "有充足的理由把它们做成不可变对象:应用可能会重试发送很多次请求之后才能成功,这就意味着这个拦截器链表可能会多次重复处理同一个请求。\n如果拦截器可以修改原始的请求对象,那么重试阶段的操作就会从修改过的请求开始,而不是原始请求。\n而这种不可变性,可以确保这些拦截器在每次重试时看到的都是同样的原始请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "TYPESCRIPTWILLPREVENTYOUFROMSETTINGHTTPREQUESTREADONLYPROPERTIES", "original": "TypeScript will prevent you from setting `HttpRequest` readonly properties.", "translation": "通过把 `HttpRequest` 的属性设置为只读的,TypeScript 可以防止你犯这种错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "TOALTERTHEREQUESTCLONEITFIRSTANDMODIFYTHECLONEBEFOREPASSINGITTONEXTHANDLEYOUCANCLONEANDMODIFYTHEREQUESTINASINGLESTEPASINTHISEXAMPLE", "original": "To alter the request, clone it first and modify the clone before passing it to `next.handle()`. \nYou can clone and modify the request in a single step as in this example.", "translation": "要想修改该请求,就要先克隆它,并修改这个克隆体,然后再把这个克隆体传给 `next.handle()`。\n你可以用一步操作中完成对请求的克隆和修改,例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECLONEMETHODSHASHARGUMENTALLOWSYOUTOMUTATESPECIFICPROPERTIESOFTHEREQUESTWHILECOPYINGTHEOTHERS", "original": "The `clone()` method's hash argument allows you to mutate specific properties of the request while copying the others.", "translation": "这个 `clone()` 方法的哈希型参数允许你在复制出克隆体的同时改变该请求的某些特定属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "#####THEREQUESTBODY", "original": "##### The request body", "translation": "##### 请求体", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEREADONLYASSIGNMENTGUARDCANTPREVENTDEEPUPDATESANDINPARTICULARITCANTPREVENTYOUFROMMODIFYINGAPROPERTYOFAREQUESTBODYOBJECT", "original": "The `readonly` assignment guard can't prevent deep updates and, in particular, \nit can't prevent you from modifying a property of a request body object.", "translation": "`readonly` 这种赋值保护,无法防范深修改(修改子对象的属性),也不能防范你修改请求体对象中的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFYOUMUSTMUTATETHEREQUESTBODYCOPYITFIRSTCHANGETHECOPYCLONETHEREQUESTANDSETTHECLONESBODYWITHTHENEWBODYASINTHEFOLLOWINGEXAMPLE", "original": "If you must mutate the request body, copy it first, change the copy, \n`clone()` the request, and set the clone's body with the new body, as in the following example.", "translation": "如果你必须修改请求体,那么就要先复制它,然后修改这个复本,`clone()` 这个请求,然后把这个请求体的复本作为新的请求体,例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "#####CLEARINGTHEREQUESTBODY", "original": "##### Clearing the request body", "translation": "##### 清空请求体", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "SOMETIMESYOUNEEDTOCLEARTHEREQUESTBODYRATHERTHANREPLACEITIFYOUSETTHECLONEDREQUESTBODYTOUNDEFINEDANGULARASSUMESYOUINTENDTOLEAVETHEBODYASISTHATISNOTWHATYOUWANTIFYOUSETTHECLONEDREQUESTBODYTONULLANGULARKNOWSYOUINTENDTOCLEARTHEREQUESTBODY", "original": "Sometimes you need to clear the request body rather than replace it.\nIf you set the cloned request body to `undefined`, Angular assumes you intend to leave the body as is.\nThat is not what you want.\nIf you set the cloned request body to `null`, Angular knows you intend to clear the request body.", "translation": "有时你需要清空请求体,而不是替换它。\n如果你把克隆后的请求体设置成 `undefined`,Angular 会认为你是想让这个请求体保持原样。\n这显然不是你想要的。\n但如果把克隆后的请求体设置成 `null`,那 Angular 就知道你是想清空这个请求体了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####SETDEFAULTHEADERS", "original": "#### Set default headers", "translation": "#### 设置默认请求头", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "APPSOFTENUSEANINTERCEPTORTOSETDEFAULTHEADERSONOUTGOINGREQUESTS", "original": "Apps often use an interceptor to set default headers on outgoing requests.", "translation": "应用通常会使用拦截器来设置外发请求的默认请求头。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESAMPLEAPPHASANAUTHSERVICETHATPRODUCESANAUTHORIZATIONTOKENHEREISITSAUTHINTERCEPTORTHATINJECTSTHATSERVICETOGETTHETOKENANDADDSANAUTHORIZATIONHEADERWITHTHATTOKENTOEVERYOUTGOINGREQUEST:", "original": "The sample app has an `AuthService` that produces an authorization token.\nHere is its `AuthInterceptor` that injects that service to get the token and\nadds an authorization header with that token to every outgoing request:", "translation": "该范例应用具有一个 `AuthService`,它会生成一个认证令牌。\n在这里,`AuthInterceptor` 会注入该服务以获取令牌,并对每一个外发的请求添加一个带有该令牌的认证头:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEPRACTICEOFCLONINGAREQUESTTOSETNEWHEADERSISSOCOMMONTHATTHERESASETHEADERSSHORTCUTFORIT:", "original": "The practice of cloning a request to set new headers is so common that \nthere's a `setHeaders` shortcut for it:", "translation": "这种在克隆请求的同时设置新请求头的操作太常见了,因此它还有一个快捷方式 `setHeaders`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ANINTERCEPTORTHATALTERSHEADERSCANBEUSEDFORANUMBEROFDIFFERENTOPERATIONSINCLUDING:", "original": "An interceptor that alters headers can be used for a number of different operations, including:", "translation": "这种可以修改头的拦截器可以用于很多不同的操作,比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "AUTHENTICATIONAUTHORIZATION", "original": "* Authentication/authorization", "translation": "认证 / 授权", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "CACHINGBEHAVIORFOREXAMPLEIFMODIFIEDSINCE", "original": "* Caching behavior; for example, `If-Modified-Since`", "translation": "控制缓存行为。比如 `If-Modified-Since`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "XSRFPROTECTION", "original": "* XSRF protection", "translation": "XSRF 防护", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####LOGGING", "original": "#### Logging", "translation": "#### 记日志", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "BECAUSEINTERCEPTORSCANPROCESSTHEREQUESTANDRESPONSETOGETHERTHEYCANDOTHINGSLIKETIMEANDLOGANENTIREHTTPOPERATION", "original": "Because interceptors can process the request and response _together_, they can do things like time and log \nan entire HTTP operation.", "translation": "因为拦截器可以*同时*处理请求和响应,所以它们也可以对整个 HTTP 操作进行计时和记录日志。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "CONSIDERTHEFOLLOWINGLOGGINGINTERCEPTORWHICHCAPTURESTHETIMEOFTHEREQUESTTHETIMEOFTHERESPONSEANDLOGSTHEOUTCOMEWITHTHEELAPSEDTIMEWITHTHEINJECTEDMESSAGESERVICE", "original": "Consider the following `LoggingInterceptor`, which captures the time of the request,\nthe time of the response, and logs the outcome with the elapsed time\nwith the injected `MessageService`.", "translation": "考虑下面这个 `LoggingInterceptor`,它捕获请求的发起时间、响应的接收时间,并使用注入的 `MessageService` 来发送总共花费的时间。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THERXJSTAPOPERATORCAPTURESWHETHERTHEREQUESTSUCCEEDORFAILEDTHERXJSFINALIZEOPERATORISCALLEDWHENTHERESPONSEOBSERVABLEEITHERERRORSORCOMPLETESWHICHITMUSTANDREPORTSTHEOUTCOMETOTHEMESSAGESERVICE", "original": "The RxJS `tap` operator captures whether the request succeed or failed.\nThe RxJS `finalize` operator is called when the response observable either errors or completes (which it must),\nand reports the outcome to the `MessageService`.", "translation": "RxJS 的 `tap` 操作符会捕获请求成功了还是失败了。\nRxJS 的 `finalize` 操作符无论在响应成功还是失败时都会调用(这是必须的),然后把结果汇报给 `MessageService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NEITHERTAPNORFINALIZETOUCHTHEVALUESOFTHEOBSERVABLESTREAMRETURNEDTOTHECALLER", "original": "Neither `tap` nor `finalize` touch the values of the observable stream returned to the caller.", "translation": "在这个可观察对象的流中,无论是 `tap` 还是 `finalize` 接触过的值,都会照常发送给调用者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####CACHING", "original": "#### Caching", "translation": "#### 缓存", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "INTERCEPTORSCANHANDLEREQUESTSBYTHEMSELVESWITHOUTFORWARDINGTONEXTHANDLE", "original": "Interceptors can handle requests by themselves, without forwarding to `next.handle()`.", "translation": "拦截器还可以自行处理这些请求,而不用转发给 `next.handle()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "FOREXAMPLEYOUMIGHTDECIDETOCACHECERTAINREQUESTSANDRESPONSESTOIMPROVEPERFORMANCEYOUCANDELEGATECACHINGTOANINTERCEPTORWITHOUTDISTURBINGYOUREXISTINGDATASERVICES", "original": "For example, you might decide to cache certain requests and responses to improve performance.\nYou can delegate caching to an interceptor without disturbing your existing data services.", "translation": "比如,你可能会想缓存某些请求和响应,以便提升性能。\n你可以把这种缓存操作委托给某个拦截器,而不破坏你现有的各个数据服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECACHINGINTERCEPTORDEMONSTRATESTHISAPPROACH", "original": "The `CachingInterceptor` demonstrates this approach.", "translation": "`CachingInterceptor` 演示了这种方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEISCACHABLEFUNCTIONDETERMINESIFTHEREQUESTISCACHABLEINTHISSAMPLEONLYGETREQUESTSTOTHENPMPACKAGESEARCHAPIARECACHABLE", "original": "The `isCachable()` function determines if the request is cachable.\nIn this sample, only GET requests to the npm package search api are cachable.", "translation": "`isCachable()` 函数用于决定该请求是否允许缓存。\n在这个例子中,只有发到 npm 包搜索 API 的 GET 请求才是可以缓存的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFTHEREQUESTISNOTCACHABLETHEINTERCEPTORSIMPLYFORWARDSTHEREQUESTTOTHENEXTHANDLERINTHECHAIN", "original": "If the request is not cachable, the interceptor simply forwards the request \nto the next handler in the chain.", "translation": "如果该请求是不可缓存的,该拦截器只会把该请求转发给链表中的下一个处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFACACHABLEREQUESTISFOUNDINTHECACHETHEINTERCEPTORRETURNSANOFOBSERVABLEWITHTHECACHEDRESPONSEBYPASSINGTHENEXTHANDLERANDALLOTHERINTERCEPTORSDOWNSTREAM", "original": "If a cachable request is found in the cache, the interceptor returns an `of()` _observable_ with\nthe cached response, by-passing the `next` handler (and all other interceptors downstream).", "translation": "如果可缓存的请求在缓存中找到了,该拦截器就会通过 `of()` 函数返回一个已缓存的响应体的*可观察对象*,然后把它传给 `next` 处理器(以及所有其它下游拦截器)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFACACHABLEREQUESTISNOTINCACHETHECODECALLSSENDREQUEST", "original": "If a cachable request is not in cache, the code calls `sendRequest`.", "translation": "如果可缓存的请求在缓存中没找到,代码就会调用 `sendRequest`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESENDREQUESTFUNCTIONCREATESAREQUESTCLONE#IMMUTABILITYWITHOUTHEADERSBECAUSETHENPMAPIFORBIDSTHEM", "original": "The `sendRequest` function creates a [request clone](#immutability) without headers\nbecause the npm api forbids them.", "translation": "`sendRequest` 函数创建了一个不带请求头的[请求克隆体](#immutability),因为 npm API 不会接受它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ITFORWARDSTHATREQUESTTONEXTHANDLEWHICHULTIMATELYCALLSTHESERVERANDRETURNSTHESERVERSRESPONSE", "original": "It forwards that request to `next.handle()` which ultimately calls the server and\nreturns the server's response.", "translation": "它会把这个请求转发给 `next.handle()`,它最终会调用服务器,并且返回服务器的响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOTEHOWSENDREQUESTINTERCEPTSTHERESPONSEONITSWAYBACKTOTHEAPPLICATIONITPIPESTHERESPONSETHROUGHTHETAPOPERATORWHOSECALLBACKADDSTHERESPONSETOTHECACHE", "original": "Note how `sendRequest` _intercepts the response_ on its way back to the application.\nIt _pipes_ the response through the `tap()` operator,\nwhose callback adds the response to the cache.", "translation": "注意 `sendRequest` 是如何在发回给应用之前*拦截这个响应的*。\n它会通过 `tap()` 操作符对响应进行管道处理,并在其回调中把响应加到缓存中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEORIGINALRESPONSECONTINUESUNTOUCHEDBACKUPTHROUGHTHECHAINOFINTERCEPTORSTOTHEAPPLICATIONCALLER", "original": "The original response continues untouched back up through the chain of interceptors\nto the application caller.", "translation": "然后,原始的响应会通过这些拦截器链,原封不动的回到服务器的调用者那里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "DATASERVICESSUCHASPACKAGESEARCHSERVICEAREUNAWARETHATSOMEOFTHEIRHTTPCLIENTREQUESTSACTUALLYRETURNCACHEDRESPONSES", "original": "Data services, such as `PackageSearchService`, are unaware that \nsome of their `HttpClient` requests actually return cached responses.", "translation": "数据服务,比如 `PackageSearchService`,并不知道它们收到的某些 `HttpClient` 请求实际上是从缓存的请求中返回来的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####RETURNAMULTIVALUEDOBSERVABLE", "original": "#### Return a multi-valued _Observable_", "translation": "#### 返回多值可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEHTTPCLIENTGETMETHODNORMALLYRETURNSANOBSERVABLETHATEITHEREMITSTHEDATAORANERRORSOMEFOLKSDESCRIBEITASAONEANDDONEOBSERVABLE", "original": "The `HttpClient.get()` method normally returns an _observable_ \nthat either emits the data or an error. \nSome folks describe it as a \"_one and done_\" observable.", "translation": "`HttpClient.get()` 方法正常情况下只会返回一个*可观察对象*,它或者发出数据,或者发出错误。\n有些人说它是“一次性完成”的可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "BUTANINTERCEPTORCANCHANGETHISTOANOBSERVABLETHATEMITSMORETHANONCE", "original": "But an interceptor can change this to an _observable_ that emits more than once.", "translation": "但是拦截器也可以把这个修改成发出多个值的*可观察对象*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "AREVISEDVERSIONOFTHECACHINGINTERCEPTOROPTIONALLYRETURNSANOBSERVABLETHATIMMEDIATELYEMITSTHECACHEDRESPONSESENDSTHEREQUESTTOTHENPMWEBAPIANYWAYANDEMITSAGAINLATERWITHTHEUPDATEDSEARCHRESULTS", "original": "A revised version of the `CachingInterceptor` optionally returns an _observable_ that\nimmediately emits the cached response, sends the request to the npm web api anyway,\nand emits again later with the updated search results.", "translation": "修改后的 `CachingInterceptor` 版本可以返回一个立即发出缓存的响应,然后仍然把请求发送到 npm 的 Web API,然后再把修改过的搜索结果重新发出一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THECACHETHENREFRESHOPTIONISTRIGGEREDBYTHEPRESENCEOFACUSTOMXREFRESHHEADER", "original": "The _cache-then-refresh_ option is triggered by the presence of a **custom `x-refresh` header**.", "translation": "这种*缓存并刷新*的选项是由**自定义的 `x-refresh` 头**触发的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ACHECKBOXONTHEPACKAGESEARCHCOMPONENTTOGGLESAWITHREFRESHFLAGWHICHISONEOFTHEARGUMENTSTOPACKAGESEARCHSERVICESEARCHTHATSEARCHMETHODCREATESTHECUSTOMXREFRESHHEADERANDADDSITTOTHEREQUESTBEFORECALLINGHTTPCLIENTGET", "original": "A checkbox on the `PackageSearchComponent` toggles a `withRefresh` flag,\nwhich is one of the arguments to `PackageSearchService.search()`.\nThat `search()` method creates the custom `x-refresh` header\nand adds it to the request before calling `HttpClient.get()`.", "translation": "`PackageSearchComponent` 中的一个检查框会切换 `withRefresh` 标识,\n它是 `PackageSearchService.search()` 的参数之一。\n`search()` 方法创建了自定义的 `x-refresh` 头,并在调用 `HttpClient.get()` 前把它添加到请求里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEREVISEDCACHINGINTERCEPTORSETSUPASERVERREQUESTWHETHERTHERESACACHEDVALUEORNOTUSINGTHESAMESENDREQUESTMETHODDESCRIBEDABOVE#SENDREQUESTTHERESULTSOBSERVABLEWILLMAKETHEREQUESTWHENSUBSCRIBED", "original": "The revised `CachingInterceptor` sets up a server request \nwhether there's a cached value or not, \nusing the same `sendRequest()` method described [above](#send-request).\nThe `results$` observable will make the request when subscribed.", "translation": "修改后的 `CachingInterceptor` 会发起一个服务器请求,而不管有没有缓存的值。\n就像 [前面](#send-request) 的 `sendRequest()` 方法一样进行订阅。\n在订阅 `results$` 可观察对象时,就会发起这个请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFTHERESNOCACHEDVALUETHEINTERCEPTORRETURNSRESULTS", "original": "If there's no cached value, the interceptor returns `results$`.", "translation": "如果没有缓存的值,拦截器直接返回 `result$`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFTHEREISACACHEDVALUETHECODEPIPESTHECACHEDRESPONSEONTORESULTSPRODUCINGARECOMPOSEDOBSERVABLETHATEMITSTWICETHECACHEDRESPONSEFIRSTANDIMMEDIATELYFOLLOWEDLATERBYTHERESPONSEFROMTHESERVERSUBSCRIBERSSEEASEQUENCEOFTWORESPONSES", "original": "If there is a cached value, the code _pipes_ the cached response onto\n`results$`, producing a recomposed observable that emits twice,\nthe cached response first (and immediately), followed later\nby the response from the server.\nSubscribers see a sequence of _two_ responses.", "translation": "如果有缓存的值,这些代码就会把缓存的响应加入到 `result$` 的管道中,使用重组后的可观察对象进行处理,并发出两次。\n先立即发出一次缓存的响应体,然后发出来自服务器的响应。\n订阅者将会看到一个包含这*两个*响应的序列。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###LISTENINGTOPROGRESSEVENTS", "original": "### Listening to progress events", "translation": "### 监听进度事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "SOMETIMESAPPLICATIONSTRANSFERLARGEAMOUNTSOFDATAANDTHOSETRANSFERSCANTAKEALONGTIMEFILEUPLOADSAREATYPICALEXAMPLEGIVETHEUSERSABETTEREXPERIENCEBYPROVIDINGFEEDBACKONTHEPROGRESSOFSUCHTRANSFERS", "original": "Sometimes applications transfer large amounts of data and those transfers can take a long time.\nFile uploads are a typical example. \nGive the users a better experience by providing feedback on the progress of such transfers.", "translation": "有事,应用会传输大量数据,并且这些传输可能会花费很长时间。\n典型的例子是文件上传。\n可以通过在传输过程中提供进度反馈,来提升用户体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "TOMAKEAREQUESTWITHPROGRESSEVENTSENABLEDYOUCANCREATEANINSTANCEOFHTTPREQUESTWITHTHEREPORTPROGRESSOPTIONSETTRUETOENABLETRACKINGOFPROGRESSEVENTS", "original": "To make a request with progress events enabled, you can create an instance of `HttpRequest` \nwith the `reportProgress` option set true to enable tracking of progress events.", "translation": "要想开启进度事件的响应,你可以创建一个把 `reportProgress` 选项设置为 `true` 的 `HttpRequest` 实例,以开启进度跟踪事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "EVERYPROGRESSEVENTTRIGGERSCHANGEDETECTIONSOONLYTURNTHEMONIFYOUTRULYINTENDTOREPORTPROGRESSINTHEUI", "original": "Every progress event triggers change detection, so only turn them on if you truly intend to report progress in the UI.", "translation": "每个进度事件都会触发变更检测,所以,你应该只有当确实希望在 UI 中报告进度时才打开这个选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NEXTPASSTHISREQUESTOBJECTTOTHEHTTPCLIENTREQUESTMETHODWHICHRETURNSANOBSERVABLEOFHTTPEVENTSTHESAMEEVENTSPROCESSEDBYINTERCEPTORS:", "original": "Next, pass this request object to the `HttpClient.request()` method, which\nreturns an `Observable` of `HttpEvents`, the same events processed by interceptors:", "translation": "接下来,把这个请求对象传给 `HttpClient.request()` 方法,它返回一个 `HttpEvents` 的 `Observable`,同样也可以在拦截器中处理这些事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THEGETEVENTMESSAGEMETHODINTERPRETSEACHTYPEOFHTTPEVENTINTHEEVENTSTREAM", "original": "The `getEventMessage` method interprets each type of `HttpEvent` in the event stream.", "translation": "`getEventMessage` 方法会解释事件流中的每一个 `HttpEvent` 类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THESAMPLEAPPFORTHISGUIDEDOESNTHAVEASERVERTHATACCEPTSUPLOADEDFILESTHEUPLOADINTERCEPTORINAPPHTTPINTERCEPTORSUPLOADINTERCEPTORTSINTERCEPTSANDSHORTCIRCUITSUPLOADREQUESTSBYRETURNINGANOBSERVABLEOFSIMULATEDEVENTS", "original": "The sample app for this guide doesn't have a server that accepts uploaded files.\nThe `UploadInterceptor` in `app/http-interceptors/upload-interceptor.ts` \nintercepts and short-circuits upload requests\nby returning an observable of simulated events.", "translation": "这个范例应用中并没有一个用来接收上传的文件的真实的服务器。\n`app/http-interceptors/upload-interceptor.ts` 中的 `UploadInterceptor` 会拦截并短路掉上传请求,改为返回一个带有各个模拟事件的可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##SECURITY:XSRFPROTECTION", "original": "## Security: XSRF Protection", "translation": "## 安全:XSRF 防护", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "CROSSSITEREQUESTFORGERYXSRFHTTPS:ENWIKIPEDIAORGWIKICROSSSITEREQUESTFORGERYISANATTACKTECHNIQUEBYWHICHTHEATTACKERCANTRICKANAUTHENTICATEDUSERINTOUNKNOWINGLYEXECUTINGACTIONSONYOURWEBSITEHTTPCLIENTSUPPORTSACOMMONMECHANISMHTTPS:ENWIKIPEDIAORGWIKICROSSSITEREQUESTFORGERY#COOKIETOHEADERTOKENUSEDTOPREVENTXSRFATTACKSWHENPERFORMINGHTTPREQUESTSANINTERCEPTORREADSATOKENFROMACOOKIEBYDEFAULTXSRFTOKENANDSETSITASANHTTPHEADERXXSRFTOKENSINCEONLYCODETHATRUNSONYOURDOMAINCOULDREADTHECOOKIETHEBACKENDCANBECERTAINTHATTHEHTTPREQUESTCAMEFROMYOURCLIENTAPPLICATIONANDNOTANATTACKER", "original": "[Cross-Site Request Forgery (XSRF)](https://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by which the attacker can trick an authenticated user into unknowingly executing actions on your website. `HttpClient` supports a [common mechanism](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-Header_Token) used to prevent XSRF attacks. When performing HTTP requests, an interceptor reads a token from a cookie, by default `XSRF-TOKEN`, and sets it as an HTTP header, `X-XSRF-TOKEN`. Since only code that runs on your domain could read the cookie, the backend can be certain that the HTTP request came from your client application and not an attacker.", "translation": "[跨站请求伪造 (XSRF)](https://en.wikipedia.org/wiki/Cross-site_request_forgery)是一个攻击技术,它能让攻击者假冒一个已认证的用户在你的网站上执行未知的操作。`HttpClient` 支持一种[通用的机制](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-Header_Token)来防范 XSRF 攻击。当执行 HTTP 请求时,一个拦截器会从 cookie 中读取 XSRF 令牌(默认名字为 `XSRF-TOKEN`),并且把它设置为一个 HTTP 头 `X-XSRF-TOKEN`,由于只有运行在你自己的域名下的代码才能读取这个 cookie,因此后端可以确认这个 HTTP 请求真的来自你的客户端应用,而不是攻击者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "BYDEFAULTANINTERCEPTORSENDSTHISCOOKIEONALLMUTATINGREQUESTSPOSTETCTORELATIVEURLSBUTNOTONGETHEADREQUESTSORONREQUESTSWITHANABSOLUTEURL", "original": "By default, an interceptor sends this cookie on all mutating requests (POST, etc.)\nto relative URLs but not on GET/HEAD requests or\non requests with an absolute URL.", "translation": "默认情况下,拦截器会在所有的修改型请求中(比如 POST 等)把这个 cookie 发送给使用相对 URL 的请求。但不会在 GET/HEAD 请求中发送,也不会发送给使用绝对 URL 的请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "TOTAKEADVANTAGEOFTHISYOURSERVERNEEDSTOSETATOKENINAJAVASCRIPTREADABLESESSIONCOOKIECALLEDXSRFTOKENONEITHERTHEPAGELOADORTHEFIRSTGETREQUESTONSUBSEQUENTREQUESTSTHESERVERCANVERIFYTHATTHECOOKIEMATCHESTHEXXSRFTOKENHTTPHEADERANDTHEREFOREBESURETHATONLYCODERUNNINGONYOURDOMAINCOULDHAVESENTTHEREQUESTTHETOKENMUSTBEUNIQUEFOREACHUSERANDMUSTBEVERIFIABLEBYTHESERVERTHISPREVENTSTHECLIENTFROMMAKINGUPITSOWNTOKENSSETTHETOKENTOADIGESTOFYOURSITESAUTHENTICATIONCOOKIEWITHASALTFORADDEDSECURITY", "original": "To take advantage of this, your server needs to set a token in a JavaScript readable session cookie called `XSRF-TOKEN` on either the page load or the first GET request. On subsequent requests the server can verify that the cookie matches the `X-XSRF-TOKEN` HTTP header, and therefore be sure that only code running on your domain could have sent the request. The token must be unique for each user and must be verifiable by the server; this prevents the client from making up its own tokens. Set the token to a digest of your site's authentication\ncookie with a salt for added security.", "translation": "要获得这种优点,你的服务器需要在页面加载或首个 GET 请求中把一个名叫 `XSRF-TOKEN` 的令牌写入可被 JavaScript 读到的会话 cookie 中。\n而在后续的请求中,服务器可以验证这个 cookie 是否与 HTTP 头 `X-XSRF-TOKEN` 的值一致,以确保只有运行在你自己域名下的代码才能发起这个请求。这个令牌必须对每个用户都是唯一的,并且必须能被服务器验证,因此不能由客户端自己生成令牌。把这个令牌设置为你的站点认证信息并且加了盐(salt)的摘要,以提升安全性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "INORDERTOPREVENTCOLLISIONSINENVIRONMENTSWHEREMULTIPLEANGULARAPPSSHARETHESAMEDOMAINORSUBDOMAINGIVEEACHAPPLICATIONAUNIQUECOOKIENAME", "original": "In order to prevent collisions in environments where multiple Angular apps share the same domain or subdomain, give each application a unique cookie name.", "translation": "为了防止多个 Angular 应用共享同一个域名或子域时出现冲突,要给每个应用分配一个唯一的 cookie 名称。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOTETHATHTTPCLIENTSUPPORTSONLYTHECLIENTHALFOFTHEXSRFPROTECTIONSCHEMEYOURBACKENDSERVICEMUSTBECONFIGUREDTOSETTHECOOKIEFORYOURPAGEANDTOVERIFYTHATTHEHEADERISPRESENTONALLELIGIBLEREQUESTSIFNOTANGULARSDEFAULTPROTECTIONWILLBEINEFFECTIVE", "original": "*Note that `HttpClient` supports only the client half of the XSRF protection scheme.* \nYour backend service must be configured to set the cookie for your page, and to verify that \nthe header is present on all eligible requests. \nIf not, Angular's default protection will be ineffective.", "translation": "*注意,`HttpClient` 支持的只是 XSRF 防护方案的客户端这一半。* 你的后端服务必须配置为给页面设置 cookie ,并且要验证请求头,以确保全都是合法的请求。否则,Angular 默认的这种防护措施就会失效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###CONFIGURINGCUSTOMCOOKIEHEADERNAMES", "original": "### Configuring custom cookie/header names", "translation": "### 配置自定义 cookie/header 名称", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFYOURBACKENDSERVICEUSESDIFFERENTNAMESFORTHEXSRFTOKENCOOKIEORHEADERUSEHTTPCLIENTXSRFMODULEWITHOPTIONSTOOVERRIDETHEDEFAULTS", "original": "If your backend service uses different names for the XSRF token cookie or header, \nuse `HttpClientXsrfModule.withOptions()` to override the defaults.", "translation": "如果你的后端服务中对 XSRF 令牌的 cookie 或 头使用了不一样的名字,就要使用 `HttpClientXsrfModule.withConfig()` 来覆盖掉默认值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "##TESTINGHTTPREQUESTS", "original": "## Testing HTTP requests", "translation": "## 测试 HTTP 请求", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "LIKEANYEXTERNALDEPENDENCYTHEHTTPBACKENDNEEDSTOBEMOCKEDSOYOURTESTSCANSIMULATEINTERACTIONWITHAREMOTESERVERTHEANGULARCOMMONHTTPTESTINGLIBRARYMAKESSETTINGUPSUCHMOCKINGSTRAIGHTFORWARD", "original": "Like any external dependency, the HTTP backend needs to be mocked\nso your tests can simulate interaction with a remote server. \nThe `@angular/common/http/testing` library makes \nsetting up such mocking straightforward.", "translation": "如同所有的外部依赖一样,HTTP 后端也需要在良好的测试实践中被 Mock 掉。`@angular/common/http` 提供了一个测试库 `@angular/common/http/testing`,它让你可以直截了当的进行这种 Mock 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###MOCKINGPHILOSOPHY", "original": "### Mocking philosophy", "translation": "### Mock 方法论", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ANGULARSHTTPTESTINGLIBRARYISDESIGNEDFORAPATTERNOFTESTINGWHEREINTHETHEAPPEXECUTESCODEANDMAKESREQUESTSFIRST", "original": "Angular's HTTP testing library is designed for a pattern of testing wherein \nthe the app executes code and makes requests first.", "translation": "Angular 的 HTTP 测试库是专为其中的测试模式而设计的。在这种模式下,会首先在应用中执行代码并发起请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THENATESTEXPECTSTHATCERTAINREQUESTSHAVEORHAVENOTBEENMADEPERFORMSASSERTIONSAGAINSTTHOSEREQUESTSANDFINALLYPROVIDERESPONSESBYFLUSHINGEACHEXPECTEDREQUEST", "original": "Then a test expects that certain requests have or have not been made, \nperforms assertions against those requests, \nand finally provide responses by \"flushing\" each expected request.", "translation": "然后,每个测试会期待发起或未发起过某个请求,对这些请求进行断言,\n最终对每个所预期的请求进行刷新(flush)来对这些请求提供响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ATTHEENDTESTSMAYVERIFYTHATTHEAPPHASMADENOUNEXPECTEDREQUESTS", "original": "At the end, tests may verify that the app has made no unexpected requests.", "translation": "最终,测试可能会验证这个应用不曾发起过非预期的请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUCANRUNLIVEEXAMPLESTACKBLITZSPECSTHESESAMPLETESTSLIVEEXAMPLEINALIVECODINGENVIRONMENT", "original": "You can run <live-example stackblitz=\"specs\">these sample tests</live-example> \nin a live coding environment.", "translation": "你可以到在线编程环境中运行<live-example stackblitz=\"specs\">这些范例测试</live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THETESTSDESCRIBEDINTHISGUIDEAREINSRCTESTINGHTTPCLIENTSPECTSTHEREAREALSOTESTSOFANAPPLICATIONDATASERVICETHATCALLHTTPCLIENTINSRCAPPHEROESHEROESSERVICESPECTS", "original": "The tests described in this guide are in `src/testing/http-client.spec.ts`.\nThere are also tests of an application data service that call `HttpClient` in\n`src/app/heroes/heroes.service.spec.ts`.", "translation": "本章所讲的这些测试位于 `src/testing/http-client.spec.ts` 中。\n在 `src/app/heroes/heroes.service.spec.ts` 中还有一些测试,用于测试那些调用了 `HttpClient` 的数据服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###SETUP", "original": "### Setup", "translation": "### 环境设置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "TOBEGINTESTINGCALLSTOHTTPCLIENTIMPORTTHEHTTPCLIENTTESTINGMODULEANDTHEMOCKINGCONTROLLERHTTPTESTINGCONTROLLERALONGWITHTHEOTHERSYMBOLSYOURTESTSREQUIRE", "original": "To begin testing calls to `HttpClient`, \nimport the `HttpClientTestingModule` and the mocking controller, `HttpTestingController`,\nalong with the other symbols your tests require.", "translation": "要开始测试那些通过 `HttpClient` 发起的请求,就要导入 `HttpClientTestingModule` 模块,并把它加到你的 `TestBed` 设置里去,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THENADDTHEHTTPCLIENTTESTINGMODULETOTHETESTBEDANDCONTINUEWITHTHESETUPOFTHESERVICEUNDERTEST", "original": "Then add the `HttpClientTestingModule` to the `TestBed` and continue with\nthe setup of the _service-under-test_.", "translation": "然后把 `HTTPClientTestingModule` 添加到 `TestBed` 中,并继续设置*被测服务*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOWREQUESTSMADEINTHECOURSEOFYOURTESTSWILLHITTHETESTINGBACKENDINSTEADOFTHENORMALBACKEND", "original": "Now requests made in the course of your tests will hit the testing backend instead of the normal backend.", "translation": "现在,在测试中发起的这些请求将会被这些测试后端(testing backend)处理,而不是标准的后端。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THISSETUPALSOCALLSTESTBEDGETTOINJECTTHEHTTPCLIENTSERVICEANDTHEMOCKINGCONTROLLERSOTHEYCANBEREFERENCEDDURINGTHETESTS", "original": "This setup also calls `TestBed.get()` to inject the `HttpClient` service and the mocking controller\nso they can be referenced during the tests.", "translation": "这种设置还会调用 `TestBed.get()`,来获取注入的 `HttpClient` 服务和模拟对象的控制器 `HttpTestingController`,以便在测试期间引用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###EXPECTINGANDANSWERINGREQUESTS", "original": "### Expecting and answering requests", "translation": "### 期待并回复请求", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "NOWYOUCANWRITEATESTTHATEXPECTSAGETREQUESTTOOCCURANDPROVIDESAMOCKRESPONSE", "original": "Now you can write a test that expects a GET Request to occur and provides a mock response.", "translation": "现在,你就可以编写测试,等待 GET 请求并给出模拟响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "THELASTSTEPVERIFYINGTHATNOREQUESTSREMAINOUTSTANDINGISCOMMONENOUGHFORYOUTOMOVEITINTOANAFTEREACHSTEP:", "original": "The last step, verifying that no requests remain outstanding, is common enough for you to move it into an `afterEach()` step:", "translation": "最后一步,验证没有发起过预期之外的请求,足够通用,因此你可以把它移到 `afterEach()` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####CUSTOMREQUESTEXPECTATIONS", "original": "#### Custom request expectations", "translation": "#### 自定义对请求的预期", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFMATCHINGBYURLISNTSUFFICIENTITSPOSSIBLETOIMPLEMENTYOUROWNMATCHINGFUNCTIONFOREXAMPLEYOUCOULDLOOKFORANOUTGOINGREQUESTTHATHASANAUTHORIZATIONHEADER:", "original": "If matching by URL isn't sufficient, it's possible to implement your own matching function. \nFor example, you could look for an outgoing request that has an authorization header:", "translation": "如果仅根据 URL 匹配还不够,你还可以自行实现匹配函数。\n比如,你可以验证外发的请求是否带有某个认证头:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "ASWITHTHEPREVIOUSEXPECTONETHETESTWILLFAILIF0OR2REQUESTSSATISFYTHISPREDICATE", "original": "As with the previous `expectOne()`, \nthe test will fail if 0 or 2+ requests satisfy this predicate.", "translation": "和前面根据 URL 进行测试时一样,如果零或两个以上的请求匹配上了这个期待,它就会抛出异常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "####HANDLINGMORETHANONEREQUEST", "original": "#### Handling more than one request", "translation": "#### 处理一个以上的请求", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "IFYOUNEEDTORESPONDTODUPLICATEREQUESTSINYOURTESTUSETHEMATCHAPIINSTEADOFEXPECTONEITTAKESTHESAMEARGUMENTSBUTRETURNSANARRAYOFMATCHINGREQUESTSONCERETURNEDTHESEREQUESTSAREREMOVEDFROMFUTUREMATCHINGANDYOUARERESPONSIBLEFORFLUSHINGANDVERIFYINGTHEM", "original": "If you need to respond to duplicate requests in your test, use the `match()` API instead of `expectOne()`.\nIt takes the same arguments but returns an array of matching requests. \nOnce returned, these requests are removed from future matching and \nyou are responsible for flushing and verifying them.", "translation": "如果你需要在测试中对重复的请求进行响应,可以使用 `match()` API 来代替 `expectOne()`,它的参数不变,但会返回一个与这些请求相匹配的数组。一旦返回,这些请求就会从将来要匹配的列表中移除,你要自己验证和刷新(flush)它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "###TESTINGFORERRORS", "original": "### Testing for errors", "translation": "### 测试对错误的预期", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "YOUSHOULDTESTTHEAPPSDEFENSESAGAINSTHTTPREQUESTSTHATFAIL", "original": "You should test the app's defenses against HTTP requests that fail.", "translation": "你还要测试应用对于 HTTP 请求失败时的防护。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "CALLREQUESTERRORWITHANERROREVENTINSTEADOFREQUESTFLUSHASINTHISEXAMPLE", "original": "Call `request.error()` with an `ErrorEvent` instead of `request.flush()`, as in this example.", "translation": "那就调用 `request.error()`,并给它传入一个 `ErrorEvent`,而不是 `request.flush()`。例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/http.md" }, { + "key": "#INTERNATIONALIZATIONI18N", "original": "# Internationalization (i18n)", "translation": "# 国际化(i18n)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "APPLICATIONINTERNATIONALIZATIONISAMANYFACETEDAREAOFDEVELOPMENTFOCUSEDONMAKINGAPPLICATIONSAVAILABLEANDUSERFRIENDLYTOAWORLDWIDEAUDIENCETHISPAGEDESCRIBESANGULARSINTERNATIONALIZATIONI18NTOOLSWHICHCANHELPYOUMAKEYOURAPPAVAILABLEINMULTIPLELANGUAGES", "original": "Application internationalization is a many-faceted area of development, focused on making\napplications available and user-friendly to a worldwide audience. This page describes Angular's\ninternationalization (i18n) tools, which can help you make your app available in multiple languages.", "translation": "应用程序的国际化涉及到开发的很多方面,主要是如何让应用可以被全世界的用户使用而且用起来比较友好。\n本页面讲的是 Angular 的*国际化*(*i18n*)工具,它可以帮助你使用多个语言发布应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "SEETHELIVEEXAMPLEDOWNLOADONLYNAMEI18NI18NEXAMPLELIVEEXAMPLEFORASIMPLEEXAMPLEOFANAOTCOMPILEDAPPTRANSLATEDINTOFRENCH", "original": "See the <live-example downloadOnly name=\"i18n\">i18n Example</live-example> for a simple example of\nan AOT-compiled app, translated into French.", "translation": "可以把这个翻译为法语版的 AOT 应用<live-example downloadOnly name=\"i18n\">i18n 例子</live-example>作为一个简单的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##ANGULARANDI18N", "original": "## Angular and i18n", "translation": "## Angular 与 i18n", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ANGULARSIMPLIFIESTHEFOLLOWINGASPECTSOFINTERNATIONALIZATION:", "original": "Angular simplifies the following aspects of internationalization:", "translation": "Angular 简化了国际化工作的下列几个方面:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "DISPLAYINGDATESNUMBERPERCENTAGESANDCURRENCIESINALOCALFORMAT", "original": "* Displaying dates, number, percentages, and currencies in a local format.", "translation": "用本地格式显示日期、数字、百分比以及货币。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TRANSLATINGTEXTINCOMPONENTTEMPLATES", "original": "* Translating text in component templates.", "translation": "翻译组件模板中的文本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "HANDLINGPLURALFORMSOFWORDS", "original": "* Handling plural forms of words.", "translation": "处理单词的复数形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "HANDLINGALTERNATIVETEXT", "original": "* Handling alternative text.", "translation": "处理候选文本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THISDOCUMENTFOCUSESONANGULARCLIHTTPS:CLIANGULARIOPROJECTSINWHICHTHEANGULARCLIGENERATESMOSTOFTHEBOILERPLATENECESSARYTOWRITEYOURAPPINMULTIPLELANGUAGES", "original": "This document focuses on [**Angular CLI**](https://cli.angular.io/) projects, in which the Angular\nCLI generates most of the boilerplate necessary to write your app in multiple languages.", "translation": "本文档集中讲解 [**Angular CLI**](https://cli.angular.io/) 项目,Angular CLI 为它生成了写多语言应用时必须的大部分样板代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##SETTINGUPTHELOCALEOFYOURAPP", "original": "## Setting up the locale of your app", "translation": "## 为你的应用设置地区(locale)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ALOCALEISANIDENTIFIERIDTHATREFERSTOASETOFUSERPREFERENCESTHATTENDTOBESHAREDWITHINAREGIONOFTHEWORLDSUCHASCOUNTRYTHISDOCUMENTREFERSTOALOCALEIDENTIFIERASALOCALEORLOCALEID", "original": "A locale is an identifier (id) that refers to a set of user preferences that tend to be shared\nwithin a region of the world, such as country. This document refers to a locale identifier as a\n\"locale\" or \"locale id\".", "translation": "地区是一个唯一性标识,它代表的是世界某个区域(比如国家)中共享的一组用户首选项。本文档中提到的“地区”就是指这个地区标识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "AUNICODELOCALEIDENTIFIERISCOMPOSEDOFAUNICODELANGUAGEIDENTIFIERANDOPTIONALLYTHECHARACTERFOLLOWEDBYALOCALEEXTENSIONFORHISTORICALREASONSTHECHARACTERISSUPPORTEDASANALTERNATIVETOFOREXAMPLEINTHELOCALEIDFRCATHEFRREFERSTOTHEFRENCHLANGUAGEIDENTIFIERANDTHECAREFERSTOTHELOCALEEXTENSIONCANADA", "original": "A Unicode locale identifier is composed of a Unicode language identifier and (optionally) the\ncharacter `-` followed by a locale extension. (For historical reasons the character `_` is supported\nas an alternative to `-`.) For example, in the locale id `fr-CA` the `fr` refers to the French\nlanguage identifier, and the `CA` refers to the locale extension Canada.", "translation": "Unicode 的地区标识是由 Unicode 语言标识、一个可选的 `-` 字符,后跟一个地区扩展项组合而成的。(由于历史的原因,还支持用 `_` 作为 `-` 的替代品。)比如,地区标识 `fr-CA` 中的 `fr` 代表法语的语言标识,而 `CA` 代表的是加拿大的语言扩展。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ANGULARFOLLOWSTHEUNICODELDMLCONVENTIONTHATUSESSTABLEIDENTIFIERSUNICODELOCALEIDENTIFIERSBASEDONTHENORMBCP47HTTP:WWWRFCEDITORORGRFCBCPBCP47TXTITISVERYIMPORTANTTHATYOUFOLLOWTHISCONVENTIONWHENYOUDEFINEYOURLOCALEBECAUSETHEANGULARI18NTOOLSUSETHISLOCALEIDTOFINDTHECORRECTCORRESPONDINGLOCALEDATA", "original": "Angular follows the Unicode LDML convention that uses stable identifiers (Unicode locale identifiers)\nbased on the norm [BCP47](http://www.rfc-editor.org/rfc/bcp/bcp47.txt). It is very important that\nyou follow this convention when you define your locale, because the Angular i18n tools use this\nlocale id to find the correct corresponding locale data.", "translation": "Angular 遵循 Unicode 的 LDML 惯例,它使用基于 [BCP47](http://www.rfc-editor.org/rfc/bcp/bcp47.txt) 标准的稳定标识(Unicode 的地区标识)。当你要定义自己的地区时,遵循这个惯例非常重要,因为 Angular 的 i18n 工具会使用这种地区标识来查找相应的本地化数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "BYDEFAULTANGULARUSESTHELOCALEENUSWHICHISENGLISHASSPOKENINTHEUNITEDSTATESOFAMERICA", "original": "By default, Angular uses the locale `en-US`, which is English as spoken in the United States of America.", "translation": "默认情况下,Angular 使用的地区标识是 `en-US`,它表示美国英语。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TOSETYOURAPPSLOCALETOANOTHERVALUEUSETHECLIPARAMETERLOCALEWITHTHEVALUEOFTHELOCALEIDTHATYOUWANTTOUSE:", "original": "To set your app's locale to another value, use the CLI parameter `--locale` with the value\nof the locale id that you want to use:", "translation": "要把你的应用的地区改为其它值,可以使用 CLI 参数 `--locale` 来传入你要使用的地区标识:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IFYOUUSEJITYOUALSONEEDTODEFINETHELOCALEIDPROVIDERINYOURMAINMODULE:", "original": "If you use JIT, you also need to define the `LOCALE_ID` provider in your main module:", "translation": "如果要使用 JIT,你就得在你的主模块中定义 `LOCALE_ID` 这个服务提供商:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "FORMOREINFORMATIONABOUTUNICODELOCALEIDENTIFIERSSEETHECLDRCORESPECHTTP:CLDRUNICODEORGCORESPEC#UNICODELANGUAGEANDLOCALEIDENTIFIERS", "original": "For more information about Unicode locale identifiers, see the \n[CLDR core spec](http://cldr.unicode.org/core-spec#Unicode_Language_and_Locale_Identifiers).", "translation": "要了解关于 Unicode 地区标识的更多信息,参见 [CLDR 核心规范](http://cldr.unicode.org/core-spec#Unicode_Language_and_Locale_Identifiers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "FORACOMPLETELISTOFLOCALESSUPPORTEDBYANGULARSEETHEANGULARREPOSITORYHTTPS:GITHUBCOMANGULARANGULARTREEMASTERPACKAGESCOMMONLOCALES", "original": "For a complete list of locales supported by Angular, see \n[the Angular repository](https://github.com/angular/angular/tree/master/packages/common/locales).", "translation": "要查看 Angular 支持的地区总表,参见 [Angular 源码仓库](https://github.com/angular/angular/tree/master/packages/common/locales)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THELOCALEIDENTIFIERSUSEDBYCLDRANDANGULARAREBASEDONBCP47HTTP:WWWRFCEDITORORGRFCBCPBCP47TXTTHESESPECIFICATIONSCHANGEOVERTIMETHEFOLLOWINGTABLEMAPSPREVIOUSIDENTIFIERSTOCURRENTONESATTIMEOFWRITING:", "original": "The locale identifiers used by CLDR and Angular are based on [BCP47](http://www.rfc-editor.org/rfc/bcp/bcp47.txt).\nThese specifications change over time; the following table maps previous identifiers to current ones at\ntime of writing:", "translation": "CLDR 和 Angular 使用的地区标识基于 [BCP47](http://www.rfc-editor.org/rfc/bcp/bcp47.txt)。\n这些规范可能会随时间而变化,下表中是本文编写时地区标识的新旧版本对照表:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "LOCALENAMEOLDLOCALEIDNEWLOCALEIDINDONESIANINIDHEBREWIWHEROMANIANMOLDOVAMOROMDNORWEGIANBOKMLNONONONBSERBIANLATINSHSRLATNFILIPINOTLFILPORTUGUESEBRAZILPTBRPTCHINESESIMPLIFIEDZHCNZHHANSCNZHHANSCHINESETRADITIONALZHTWZHHANTTWZHHANTCHINESETRADITIONALHONGKONGZHHKZHHANTHK", + "original": "| Locale name | Old locale id | New locale id |\n|-------------------------------|-------------------|---------------|\n| Indonesian | in | id |\n| Hebrew | iw | he |\n| Romanian Moldova | mo | ro-MD |\n| Norwegian Bokmål | no, no-NO | nb |\n| Serbian Latin | sh | sr-Latn |\n| Filipino | tl | fil |\n| Portuguese Brazil | pt-BR | pt |\n| Chinese Simplified | zh-cn, zh-Hans-CN | zh-Hans |\n| Chinese Traditional | zh-tw, zh-Hant-TW | zh-Hant |\n| Chinese Traditional Hong Kong | zh-hk | zh-Hant-HK |", + "translation": "| <t>Locale name</t><t>地区名称</t> | <t>Old locale id</t><t>旧 ID</t> | <t>New locale id</t><t>新 ID</t> |\n|-------------------------------|-------------------|---------------|\n| <t>Indonesian</t><t>印度尼西亚</t> | in | id |\n| <t>Hebrew</t><t>希伯来</t> | iw | he |\n| <t>Romanian Moldova</t><t>罗马尼亚摩尔多瓦</t> | mo | ro-MD |\n| <t>Norwegian Bokmål</t><t>挪威 Bokmål</t> | no, no-NO | nb |\n| <t>Serbian Latin</t><t>塞尔维亚拉丁语</t> | sh | sr-Latn |\n| <t>Filipino</t><t>菲律宾</t> | tl | fil |\n| <t>Portuguese Brazil</t><t>葡萄牙巴西</t> | pt-BR | pt |\n| <t>Chinese Simplified</t><t>中文简体</t> | zh-cn, zh-Hans-CN | zh-Hans |\n| <t>Chinese Traditional</t><t>中文繁体</t> | zh-tw, zh-Hant-TW | zh-Hant |\n| <t>Chinese Traditional Hong Kong</t><t>中文繁体(香港)</t> | zh-hk | zh-Hant-HK |", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" + }, + { + "key": "##I18NPIPES", "original": "## i18n pipes", "translation": "## i18n 管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ANGULARPIPESCANHELPYOUWITHINTERNATIONALIZATION:THEDATEPIPECURRENCYPIPEDECIMALPIPEANDPERCENTPIPEUSELOCALEDATATOFORMATDATABASEDONTHELOCALEID", "original": "Angular pipes can help you with internationalization: the `DatePipe`, `CurrencyPipe`, `DecimalPipe`\nand `PercentPipe` use locale data to format data based on the `LOCALE_ID`.", "translation": "Angular 的管道可以帮助你进行国际化:`DatePipe`、`CurrencyPipe`、`DecimalPipe` 和 `PercentPipe` 都使用本地化数据来根据 `LOCALE_ID` 格式化数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "BYDEFAULTANGULARONLYCONTAINSLOCALEDATAFORENUSIFYOUSETTHEVALUEOFLOCALEIDTOANOTHERLOCALEYOUMUSTIMPORTLOCALEDATAFORTHATNEWLOCALETHECLIIMPORTSTHELOCALEDATAFORYOUWHENYOUUSETHEPARAMETERLOCALEWITHNGSERVEANDNGBUILD", "original": "By default, Angular only contains locale data for `en-US`. If you set the value of\n`LOCALE_ID` to another locale, you must import locale data for that new locale.\nThe CLI imports the locale data for you when you use the parameter `--locale` with `ng serve` and\n`ng build`.", "translation": "默认情况下,Angular 只包含 `en-US` 的本地化数据。如果你要把 `LOCALE_ID` 的值设置为其它地区,就必须为那个新地区导入本地化数据。\n当你使用 `ng serve` 和 `ng build` 的 `--locale` 参数时,CLI 会自动帮你导入相应的本地化数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IFYOUWANTTOIMPORTLOCALEDATAFOROTHERLANGUAGESYOUCANDOITMANUALLY:", "original": "If you want to import locale data for other languages, you can do it manually:", "translation": "如果还要为其它语言导入本地化数据,你可以手工完成它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEFIRSTPARAMETERISANOBJECTCONTAININGTHELOCALEDATAIMPORTEDFROMANGULARCOMMONLOCALESBYDEFAULTTHEIMPORTEDLOCALEDATAISREGISTEREDWITHTHELOCALEIDTHATISDEFINEDINTHEANGULARLOCALEDATAITSELFIFYOUWANTTOREGISTERTHEIMPORTEDLOCALEDATAWITHANOTHERLOCALEIDUSETHESECONDPARAMETERTOSPECIFYACUSTOMLOCALEIDFOREXAMPLEANGULARSLOCALEDATADEFINESTHELOCALEIDFORFRENCHASFRYOUCANUSETHESECONDPARAMETERTOASSOCIATETHEIMPORTEDFRENCHLOCALEDATAWITHTHECUSTOMLOCALEIDFRFRINSTEADOFFR", "original": "The first parameter is an object containing the locale data imported from `@angular/common/locales`.\nBy default, the imported locale data is registered with the locale id that is defined in the Angular\nlocale data itself.\nIf you want to register the imported locale data with another locale id, use the second parameter to\nspecify a custom locale id. For example, Angular's locale data defines the locale id for French as\n\"fr\". You can use the second parameter to associate the imported French locale data with the custom\nlocale id \"fr-FR\" instead of \"fr\".", "translation": "第一个参数是一个包含从 `@angular/common/locales` 中导入的本地化数据的对象。\n默认情况下,导入 Angular 自带的本地化数据时会使用数据中自带的一个地区标识进行注册。\n如果你要使用其它地区标识来注册这个导入的本地化数据,可以在第二个参数中指定一个自定义的地区标识。\n比如,Angular 为法语定义的地区标识是 “fr”,你可以通过第二个参数为这些导入的法语本地化数据指定一个自定义的地区标识 “fr-FR”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEFILESINANGULARCOMMONLOCALESCONTAINMOSTOFTHELOCALEDATATHATYOUNEEDBUTSOMEADVANCEDFORMATTINGOPTIONSMIGHTONLYBEAVAILABLEINTHEEXTRADATASETTHATYOUCANIMPORTFROMANGULARCOMMONLOCALESEXTRAANERRORMESSAGEINFORMSYOUWHENTHISISTHECASE", "original": "The files in `@angular/common/locales` contain most of the locale data that you \nneed, but some advanced formatting options might only be available in the extra dataset that you can\nimport from `@angular/common/locales/extra`. An error message informs you when this is the case.", "translation": "`@angular/common/locales` 中的文件包含你需要的大多数本地化数据,\n不过有些高级的格式选项只存在于从 `@angular/common/locales/extra` 中导入的扩展数据集中。遇到这种情况,你就会收到一条错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ALLLOCALEDATAUSEDBYANGULARAREEXTRACTEDFROMTHEUNICODECONSORTIUMSAHREFHTTP:CLDRUNICODEORGTITLECLDRCOMMONLOCALEDATAREPOSITORYCLDRA", "original": "All locale data used by Angular are extracted from the Unicode Consortium's\n <a href=\"http://cldr.unicode.org/\" title=\"CLDR\">Common Locale Data Repository (CLDR)</a>.", "translation": "Angular 中使用的所有本地化数据都是从 Unicode 联盟的<a href=\"http://cldr.unicode.org/\" title=\"CLDR\">常用本地化数据仓库 (CLDR)</a> 中提取的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##TEMPLATETRANSLATIONS", "original": "## Template translations", "translation": "## 模板翻译", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THISDOCUMENTREFERSTOAUNITOFTRANSLATABLETEXTASTEXTAMESSAGEORATEXTMESSAGE", "original": "This document refers to a unit of translatable text as \"text,\" a \"message\", or a \n \"text message.\"", "translation": "本文档中会把翻译文本的最小单元称为“文本”、“消息”或“文本消息”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEI18NTEMPLATETRANSLATIONPROCESSHASFOURPHASES:", "original": "The i18n template translation process has four phases:", "translation": "i18n 模板的翻译过程分为四个阶段", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "1MARKSTATICTEXTMESSAGESINYOURCOMPONENTTEMPLATESFORTRANSLATION", "original": "1. Mark static text messages in your component templates for translation.", "translation": "在组件模板中标记需要翻译的静态文本信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "2ANANGULARI18NTOOLEXTRACTSTHEMARKEDTEXTINTOANINDUSTRYSTANDARDTRANSLATIONSOURCEFILE", "original": "2. An Angular i18n tool extracts the marked text into an industry standard translation source file.", "translation": "Angular的 i18n 工具将标记的信息提取到一个行业标准的翻译源文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "3ATRANSLATOREDITSTHATFILETRANSLATINGTHEEXTRACTEDTEXTINTOTHETARGETLANGUAGEANDRETURNSTHEFILETOYOU", "original": "3. A translator edits that file, translating the extracted text into the target language,\nand returns the file to you.", "translation": "翻译人员编辑该文件,翻译提取出来的文本信息到目标语言,并将该文件还给你。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "4THEANGULARCOMPILERIMPORTSTHECOMPLETEDTRANSLATIONFILESREPLACESTHEORIGINALMESSAGESWITHTRANSLATEDTEXTANDGENERATESANEWVERSIONOFTHEAPPINTHETARGETLANGUAGE", "original": "4. The Angular compiler imports the completed translation files,\nreplaces the original messages with translated text, and generates a new version of the app\nin the target language.", "translation": "Angular编译器导入完成翻译的文件,使用翻译的文本替换原始信息,并生成新的目标语言版本的应用程序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUNEEDTOBUILDANDDEPLOYASEPARATEVERSIONOFTHEAPPFOREACHSUPPORTEDLANGUAGE", "original": "You need to build and deploy a separate version of the app for each supported language.", "translation": "你可以为每种支持的语言构建和部署单独的应用程序版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###MARKTEXTWITHTHEI18NATTRIBUTE", "original": "### Mark text with the i18n attribute", "translation": "### 使用 `i18n` 属性标记文本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEANGULARI18NATTRIBUTEMARKSTRANSLATABLECONTENTPLACEITONEVERYELEMENTTAGWHOSEFIXEDTEXTISTOBETRANSLATED", "original": "The Angular `i18n` attribute marks translatable content. Place it on every element tag whose fixed\ntext is to be translated.", "translation": "Angular的`i18n`属性是可翻译内容的标记。\n将它放到每个固定文本需要翻译的元素标签中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "INTHEEXAMPLEBELOWANH1TAGDISPLAYSASIMPLEENGLISHLANGUAGEGREETINGHELLOI18N", "original": "In the example below, an `<h1>` tag displays a simple English language greeting, \"Hello i18n!\"", "translation": "在下面的例子中,`<h1>`标签显示了一句简单的英文问候语,“Hello i18n!”", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TOMARKTHEGREETINGFORTRANSLATIONADDTHEI18NATTRIBUTETOTHEH1TAG", "original": "To mark the greeting for translation, add the `i18n` attribute to the `<h1>` tag.", "translation": "要想把它标记为需要翻译的文本,就给 `<h1>` 标签添加上 `i18n` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "I18NISACUSTOMATTRIBUTERECOGNIZEDBYANGULARTOOLSANDCOMPILERSAFTERTRANSLATIONTHECOMPILERREMOVESITITISNOTANANGULARDIRECTIVE", "original": "`i18n` is a custom attribute, recognized by Angular tools and compilers.\n After translation, the compiler removes it. It is not an Angular directive.", "translation": "`i18n` 是一个自定义属性,会被 Angular 工具和编译器识别。\n 翻译之后,编译器就会移除它。它不是 Angular 指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###HELPTHETRANSLATORWITHADESCRIPTIONANDMEANING", "original": "### Help the translator with a description and meaning", "translation": "### 用描述和意图来帮助翻译人员", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TOTRANSLATEATEXTMESSAGEACCURATELYTHETRANSLATORMAYNEEDADDITIONALINFORMATIONORCONTEXT", "original": "To translate a text message accurately, the translator may need additional information or context.", "translation": "要想翻译的更准确,翻译人员可能需要待翻译文本的额外信息或场景说明。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANADDADESCRIPTIONOFTHETEXTMESSAGEASTHEVALUEOFTHEI18NATTRIBUTEASSHOWNINTHEEXAMPLEBELOW:", "original": "You can add a description of the text message as the value of the `i18n` attribute, as shown in the\nexample below:", "translation": "你可以用 `i18n` 属性的值来添加这些文本信息的描述,例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THETRANSLATORMAYALSONEEDTOKNOWTHEMEANINGORINTENTOFTHETEXTMESSAGEWITHINTHISPARTICULARAPPCONTEXT", "original": "The translator may also need to know the meaning or intent of the text message within this particular \napp context.", "translation": "为了给出正确的翻译,翻译者需要知道你这段文本在特定情境下的*含义*或*真实意图*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUADDCONTEXTBYBEGINNINGTHEI18NATTRIBUTEVALUEWITHTHEMEANINGANDSEPARATINGITFROMTHEDESCRIPTIONWITHTHECHARACTER:MEANINGDESCRIPTION", "original": "You add context by beginning the `i18n` attribute value with the _meaning_ and\nseparating it from the _description_ with the `|` character: `<meaning>|<description>`", "translation": "在描述的前面,你可以用 `i18n` 开头的属性值来为指定的字符串添加一些上下文含义,用 `|` 将其与描述文字隔开(`<意图>|<描述>`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ALLOCCURRENCESOFATEXTMESSAGETHATHAVETHESAMEMEANINGWILLHAVETHESAMETRANSLATIONATEXTMESSAGETHATISASSOCIATEDWITHDIFFERENTMEANINGSCANHAVEDIFFERENTTRANSLATIONS", "original": "All occurrences of a text message that have the same meaning will have the same translation.\nA text message that is associated with different meanings can have different translations.", "translation": "如果所有地方出现的文本具有**相同**含义时,它们应该有**相同**的翻译,\n但是如果在某些地方它具有**不同含义**,那么它应该有不同的翻译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEANGULAREXTRACTIONTOOLPRESERVESBOTHTHEMEANINGANDTHEDESCRIPTIONINTHETRANSLATIONSOURCEFILETOFACILITATECONTEXTUALLYSPECIFICTRANSLATIONSBUTONLYTHECOMBINATIONOFMEANINGANDTEXTMESSAGEAREUSEDTOGENERATETHESPECIFICIDOFATRANSLATIONIFYOUHAVETWOSIMILARTEXTMESSAGESWITHDIFFERENTMEANINGSTHEYAREEXTRACTEDSEPARATELYIFYOUHAVETWOSIMILARTEXTMESSAGESWITHDIFFERENTDESCRIPTIONSNOTDIFFERENTMEANINGSTHENTHEYAREEXTRACTEDONLYONCE", "original": "The Angular extraction tool preserves both the meaning and the description in the translation\nsource file to facilitate contextually-specific translations, but only the combination of meaning\nand text message are used to generate the specific id of a translation. If you have two\nsimilar text messages with different meanings, they are extracted separately. If you have two similar\ntext messages with different descriptions (not different meanings), then they are extracted only once.", "translation": "Angular 的提取工具会在翻译源文件中保留**含义**和**描述**,以支持符合特定上下文的翻译。但它只会使用含义和文本消息的组合来为待翻译文本生成明确的 id。如果你有两个相同的文本消息,但是含义不同,它们就会被分别提取。如果你有两个相同的文本消息,但是描述不同(但含义相同),它们就只会提取一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###SETACUSTOMIDFORPERSISTENCEANDMAINTENANCE", "original": "### Set a custom id for persistence and maintenance", "translation": "### 设置一个自定义的 `id` 来提升可搜索性和可维护性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEANGULARI18NEXTRACTORTOOLGENERATESAFILEWITHATRANSLATIONUNITENTRYFOREACHI18NATTRIBUTEINATEMPLATEBYDEFAULTITASSIGNSEACHTRANSLATIONUNITAUNIQUEIDSUCHASTHISONE:", "original": "The angular i18n extractor tool generates a file with a translation unit entry for each `i18n`\nattribute in a template. By default, it assigns each translation unit a unique id such as this one:", "translation": "Angular 的 `i18n` 提取工具会为模板中每个带有 `i18n` 属性的元素生成一个*翻译单元(translation unit)*条目,并保存到一个文件中。默认情况下,它为每个翻译单元指定一个唯一的 `id`,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "WHENYOUCHANGETHETRANSLATABLETEXTTHEEXTRACTORTOOLGENERATESANEWIDFORTHATTRANSLATIONUNITYOUMUSTTHENUPDATETHETRANSLATIONFILEWITHTHENEWID", "original": "When you change the translatable text, the extractor tool generates a new id for that translation unit.\nYou must then update the translation file with the new id.", "translation": "当你修改这段可翻译的文字时,提取工具会为那个翻译单元生成一个新的 `id`。\n你就要使用这个新的 id 来修改这个翻译文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ALTERNATIVELYYOUCANSPECIFYACUSTOMIDINTHEI18NATTRIBUTEBYUSINGTHEPREFIXTHEEXAMPLEBELOWDEFINESTHECUSTOMIDINTRODUCTIONHEADER:", "original": "Alternatively, you can specify a custom id in the `i18n` attribute by using the prefix `@@`.\nThe example below defines the custom id `introductionHeader`:", "translation": "另一种方案是,你可以使用 `@@` 前缀在 `i18n` 属性中指定一个自定义的 id。\n下面这个例子就定义了一个自定义 id `introductionHeader`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "WHENYOUSPECIFYACUSTOMIDTHEEXTRACTORTOOLANDCOMPILERGENERATEATRANSLATIONUNITWITHTHATCUSTOMID", "original": "When you specify a custom id, the extractor tool and compiler generate a translation unit with that\ncustom id.", "translation": "一旦你指定了自定义 id,提取工具和编译器就会用*你的自定义 id` 生成一个翻译单元,而不会再改变它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THECUSTOMIDISPERSISTENTTHEEXTRACTORTOOLDOESNOTCHANGEITWHENTHETRANSLATABLETEXTCHANGESTHEREFOREYOUDONOTNEEDTOUPDATETHETRANSLATIONTHISAPPROACHMAKESMAINTENANCEEASIER", "original": "The custom id is persistent. The extractor tool does not change it when the translatable text changes.\nTherefore, you do not need to update the translation. This approach makes maintenance easier.", "translation": "自定义 id 是永久性的,翻译工具待翻译文本发生变化时不会修改它。\n因此,你不必修改翻译结果。这种方式可以让维护变得更简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "####USEACUSTOMIDWITHADESCRIPTION", "original": "#### Use a custom id with a description", "translation": "#### 在描述中使用自定义 id", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANUSEACUSTOMIDINCOMBINATIONWITHADESCRIPTIONBYINCLUDINGBOTHINTHEVALUEOFTHEI18NATTRIBUTEINTHEEXAMPLEBELOWTHEI18NATTRIBUTEVALUEINCLUDESADESCRIPTIONFOLLOWEDBYTHECUSTOMID:", "original": "You can use a custom id in combination with a description by including both in the value of the\n`i18n` attribute. In the example below, the `i18n` attribute value includes a description, followed\nby the custom `id`:", "translation": "你可以在 `i18n` 属性的值中使用自定义 id 与描述信息的组合。\n下面的例子中,`i18n` 的属性中中就包含了一条跟在自定义 `id` 后面的描述信息:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUALSOCANADDAMEANINGASSHOWNINTHISEXAMPLE:", "original": "You also can add a meaning, as shown in this example:", "translation": "你还可以添加含义,例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "####DEFINEUNIQUECUSTOMIDS", "original": "#### Define unique custom ids", "translation": "#### 定义唯一的自定义 ID", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "BESURETODEFINECUSTOMIDSTHATAREUNIQUEIFYOUUSETHESAMEIDFORTWODIFFERENTTEXTMESSAGESONLYTHEFIRSTONEISEXTRACTEDANDITSTRANSLATIONISUSEDINPLACEOFBOTHORIGINALTEXTMESSAGES", "original": "Be sure to define custom ids that are unique. If you use the same id for two different text messages,\nonly the first one is extracted, and its translation is used in place of both original text messages.", "translation": "要确保自定义 id 是唯一的。如果你对两个*不同的*文本块使用了同一个 id,那么就只有一个会被提取出来,然后其翻译结果会被用于全部原始文本消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "INTHEEXAMPLEBELOWTHECUSTOMIDMYIDISUSEDFORTWODIFFERENTMESSAGES:", "original": "In the example below the custom id `myId` is used for two different messages:", "translation": "在下面这个例子中,自定义的 id `myId` 就被用在了两个不同的消息上:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "CONSIDERTHISTRANSLATIONTOFRENCH:", "original": "Consider this translation to French:", "translation": "考虑下列法文翻译:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "BECAUSETHECUSTOMIDISTHESAMEBOTHOFTHEELEMENTSINTHERESULTINGTRANSLATIONCONTAINTHESAMETEXTBONJOUR:", "original": "Because the custom id is the same, both of the elements in the resulting translation contain\nthe same text, `Bonjour`:", "translation": "由于自定义 id 都是一样的,所以翻译结果中所有的元素都包含同样的文本 `Bonjour`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###TRANSLATETEXTWITHOUTCREATINGANELEMENT", "original": "### Translate text without creating an element", "translation": "### 翻译文本,而不必创建元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IFTHEREISASECTIONOFTEXTTHATYOUWOULDLIKETOTRANSLATEYOUCANWRAPITINASPANTAGHOWEVERIFYOUDONTWANTTOCREATEANEWDOMELEMENTMERELYTOFACILITATETRANSLATIONYOUCANWRAPTHETEXTINANNGCONTAINERELEMENTTHENGCONTAINERISTRANSFORMEDINTOANHTMLCOMMENT:", "original": "If there is a section of text that you would like to translate, you can wrap it in a `<span>` tag.\nHowever, if you don't want to create a new DOM element merely to facilitate translation,\nyou can wrap the text in an `<ng-container>` element.\nThe `<ng-container>` is transformed into an html comment:", "translation": "如果要翻译一段纯文本,你就可以把它用 `<span>` 标签包裹起来。\n但如果由于某些原因(比如 CSS 结构方面的考虑),你可能不希望仅仅为了翻译而创建一个新的 DOM 元素,那么也可以把这段文本包裹进一个 `<ng-container>` 元素中。`<ng-container>` 将被转换成一个 HTML 注释:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##ADDI18NTRANSLATIONATTRIBUTES", "original": "## Add i18n translation attributes", "translation": "## 添加 *i18n* 翻译属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUALSOCANTRANSLATEATTRIBUTESFOREXAMPLEASSUMETHATYOURTEMPLATEHASANIMAGEWITHATITLEATTRIBUTE:", "original": "You also can translate attributes.\nFor example, assume that your template has an image with a `title` attribute:", "translation": "你还可以翻译属性。\n比如,假设你的模板中有一个带 `title` 属性的图片:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THISTITLEATTRIBUTENEEDSTOBETRANSLATED", "original": "This `title` attribute needs to be translated.", "translation": "这个 `title` 属性也需要翻译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TOMARKANATTRIBUTEFORTRANSLATIONADDANATTRIBUTEINTHEFORMOFI18NXWHEREXISTHENAMEOFTHEATTRIBUTETOTRANSLATETHEFOLLOWINGEXAMPLESHOWSHOWTOMARKTHETITLEATTRIBUTEFORTRANSLATIONBYADDINGTHEI18NTITLEATTRIBUTEONTHEIMGTAG:", "original": "To mark an attribute for translation, add an attribute in the form of `i18n-x`,\nwhere `x` is the name of the attribute to translate. The following example shows how to mark the\n`title` attribute for translation by adding the `i18n-title` attribute on the `img` tag:", "translation": "要把一个属性标记为需要翻译的,就添加一个形如 `i18n-x` 的属性,其中的 `x` 是要翻译的属性的名字。\n下面的例子中演示了如何通过给 `img` 标签添加 `i18n-title` 属性来把 `title` 属性标记为待翻译的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THISTECHNIQUEWORKSFORANYATTRIBUTEOFANYELEMENT", "original": "This technique works for any attribute of any element.", "translation": "这个技巧适用于任何元素上的任何属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUALSOCANASSIGNAMEANINGDESCRIPTIONANDIDWITHTHEI18NXMEANINGDESCRIPTIONIDSYNTAX", "original": "You also can assign a meaning, description, and id with the `i18n-x=\"<meaning>|<description>@@<id>\"`\nsyntax.", "translation": "你也同样可以使用 `i18n-x=\"<meaning>|<description>@@<id>\"` 语法来指定一个含义和描述。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##TRANSLATESINGULARANDPLURAL", "original": "## Translate singular and plural", "translation": "## 翻译单数与复数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "DIFFERENTLANGUAGESHAVEDIFFERENTPLURALIZATIONRULES", "original": "Different languages have different pluralization rules.", "translation": "不同的语言有不同的单复数规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "SUPPOSETHATYOUWANTTOSAYTHATSOMETHINGWASUPDATEDXMINUTESAGOINENGLISHDEPENDINGUPONTHENUMBEROFMINUTESYOUCOULDDISPLAYJUSTNOWONEMINUTEAGOORXMINUTESAGOWITHXBEINGTHEACTUALNUMBEROTHERLANGUAGESMIGHTEXPRESSTHECARDINALITYDIFFERENTLY", "original": "Suppose that you want to say that something was \"updated x minutes ago\".\nIn English, depending upon the number of minutes, you could display \"just now\", \"one minute ago\",\nor \"x minutes ago\" (with x being the actual number).\nOther languages might express the cardinality differently.", "translation": "假设你要说某些东西“updated x minutes ago(在 x 分钟前修改了)”。\n在英语中,根据分钟数,可能要显示为 \"just now\"、\"one minute ago\" 或 \"x minutes ago\"(这里的 x 是实际的数量)。\n而在其它语言中则可能会有不同的基数规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEEXAMPLEBELOWSHOWSHOWTOUSEAPLURALICUEXPRESSIONTODISPLAYONEOFTHOSETHREEOPTIONSBASEDONWHENTHEUPDATEOCCURRED:", "original": "The example below shows how to use a `plural` ICU expression to display one of those three options\nbased on when the update occurred:", "translation": "下面这个例子示范了如何使用 ICU 表达式 `plural` 来根据这次修改发生的时间显示这三个选项之一:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEFIRSTPARAMETERISTHEKEYITISBOUNDTOTHECOMPONENTPROPERTYMINUTESWHICHDETERMINESTHENUMBEROFMINUTES", "original": "* The first parameter is the key. It is bound to the component property (`minutes`), which determines\nthe number of minutes.", "translation": "第一个参数是 key。它绑定到了组件中表示分钟数的 `minutes` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THESECONDPARAMETERIDENTIFIESTHISASAPLURALTRANSLATIONTYPE", "original": "* The second parameter identifies this as a `plural` translation type.", "translation": "第二个参数表示这是一个 `plural`(复数)翻译类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THETHIRDPARAMETERDEFINESAPLURALIZATIONPATTERNCONSISTINGOFPLURALIZATIONCATEGORIESANDTHEIRMATCHINGVALUES", "original": "* The third parameter defines a pluralization pattern consisting of pluralization categories and their matching values.", "translation": "第三个参数定义了一组复数表示模式,这个模式由复数类别和它们所匹配的值组成。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THISSYNTAXCONFORMSTOTHEAHREFHTTP:USERGUIDEICUPROJECTORGFORMATPARSEMESSAGESTITLEICUMESSAGEFORMATICUMESSAGEFORMATAASSPECIFIEDINTHEAHREFHTTP:CLDRUNICODEORGINDEXCLDRSPECPLURALRULESTITLEPLURALIZATIONRULESCLDRPLURALIZATIONRULESA", "original": "This syntax conforms to the\n <a href=\"http://userguide.icu-project.org/formatparse/messages\" title=\"ICU Message Format\">ICU Message Format</a>\n as specified in the\n <a href=\"http://cldr.unicode.org/index/cldr-spec/plural-rules\" title=\"Pluralization Rules\">CLDR pluralization rules</a>.", "translation": "这种语法遵守 <a href=\"http://cldr.unicode.org/index/cldr-spec/plural-rules\" title=\"Pluralization Rules\">CLDR 复数规则</a> 中指定的\n <a href=\"http://userguide.icu-project.org/formatparse/messages\" title=\"ICU Message Format\">ICU 消息格式</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "PLURALIZATIONCATEGORIESINCLUDEDEPENDINGONTHELANGUAGE:", "original": "Pluralization categories include (depending on the language):", "translation": "复数类别包括(取决于语言):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "0ORANYOTHERNUMBER", "original": "* =0 (or any other number)", "translation": "=0 (或其它数字)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ZERO", "original": "* zero", "translation": "zero(零)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ONE", "original": "* one", "translation": "one(一个)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TWO", "original": "* two", "translation": "two(两个)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "FEW", "original": "* few", "translation": "few(少数)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "MANY", "original": "* many", "translation": "many(很多)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "OTHER", "original": "* other", "translation": "other(其它)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "AFTERTHEPLURALIZATIONCATEGORYPUTTHEDEFAULTENGLISHTEXTINBRACES", "original": "After the pluralization category, put the default English text in braces (`{}`).", "translation": "复数类别之后的括号(`{}`)中是默认的*英语*文本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "INTHEEXAMPLEABOVETHETHREEOPTIONSARESPECIFIEDACCORDINGTOTHATPLURALIZATIONPATTERNFORTALKINGABOUTABOUTZEROMINUTESYOUUSE0JUSTNOWFORONEMINUTEYOUUSE1ONEMINUTEANYUNMATCHEDCARDINALITYUSESOTHERMINUTESMINUTESAGOYOUCOULDCHOOSETOADDPATTERNSFORTWOTHREEORANYOTHERNUMBERIFTHEPLURALIZATIONRULESWEREDIFFERENTFORTHEEXAMPLEOFMINUTEONLYTHESETHREEPATTERNSARENECESSARYINENGLISH", "original": "In the example above, the three options are specified according to that pluralization pattern. For\ntalking about about zero minutes, you use `=0 {just now}`. For one minute, you use `=1 {one minute}`.\nAny unmatched cardinality uses `other {{{minutes}} minutes ago}`. You could choose to add patterns\nfor two, three, or any other number if the pluralization rules were different. For the example of\n\"minute\", only these three patterns are necessary in English.", "translation": "在上面的例子中,这三个选项都是根据复数模式来指定的。要说零分钟,就用 `=0 {just now}`。一分钟就用 `=1 {one minute}`。\n无法匹配的数量就用 `other {{{minutes}} minutes ago}`。如果复数规则与此不同,你还可以为两个、三个火任意数量添加更多的模式。对于这个 “minute” 的例子,英语中只要这三种模式就够了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANUSEINTERPOLATIONSANDHTMLMARKUPINSIDEOFYOURTRANSLATIONS", "original": "You can use interpolations and html markup inside of your translations.", "translation": "你可以在翻译结果中使用插值表达式和 HTML 标记。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##SELECTAMONGALTERNATIVETEXTMESSAGES", "original": "## Select among alternative text messages", "translation": "## 在候选文本中选择", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IFYOURTEMPLATENEEDSTODISPLAYDIFFERENTTEXTMESSAGESDEPENDINGONTHEVALUEOFAVARIABLEYOUNEEDTOTRANSLATEALLOFTHOSEALTERNATIVETEXTMESSAGES", "original": "If your template needs to display different text messages depending on the value of a variable, you\nneed to translate all of those alternative text messages.", "translation": "如果你的模板中需要根据某个变量的值显示出不同的文本消息,你还需要对所有这些候选文本进行翻译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANHANDLETHISWITHASELECTICUEXPRESSIONITISSIMILARTOTHEPLURALICUEXPRESSIONSEXCEPTTHATYOUCHOOSEAMONGALTERNATIVETRANSLATIONSBASEDONASTRINGVALUEINSTEADOFANUMBERANDYOUDEFINETHOSESTRINGVALUES", "original": "You can handle this with a `select` ICU expression. It is similar to the `plural` ICU expressions\nexcept that you choose among alternative translations based on a string value instead of a number,\nand you define those string values.", "translation": "你可以使用 ICU 表达式 `select` 来翻译这些。它与 ICU 表达式 `plural` 类似,只是你要根据一个字符串值而不是数字来选择这些候选翻译文本,而这些字符串值是你自己定义的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEFOLLOWINGFORMATMESSAGEINTHECOMPONENTTEMPLATEBINDSTOTHECOMPONENTSGENDERPROPERTYWHICHOUTPUTSONEOFTHEFOLLOWINGSTRINGVALUES:MFOROTHEMESSAGEMAPSTHOSEVALUESTOTHEAPPROPRIATETRANSLATIONS:", "original": "The following format message in the component template binds to the component's `gender` property,\nwhich outputs one of the following string values: \"m\", \"f\" or \"o\".\nThe message maps those values to the appropriate translations:", "translation": "组件模板中的下列消息格式绑定到了组件的 `gender` 属性,这个属性的取值是 \"m\" 或 \"f\" 或 \"o\"。\n这个消息会把那些值映射到适当的翻译文本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##NESTINGPLURALANDSELECTICUEXPRESSIONS", "original": "## Nesting plural and select ICU expressions", "translation": "## 把\"复数\"与\"选择\"表达式嵌套在一起", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANALSONESTDIFFERENTICUEXPRESSIONSTOGETHERASSHOWNINTHISEXAMPLE:", "original": "You can also nest different ICU expressions together, as shown in this example:", "translation": "你也可以把不同的 ICU 表达式嵌套在一起,比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##CREATEATRANSLATIONSOURCEFILEWITHNGXI18N", "original": "## Create a translation source file with _ng xi18n_", "translation": "## 使用 *ng-xi18n* 工具创建翻译源文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "USETHENGXI18NCOMMANDPROVIDEDBYTHECLITOEXTRACTTHETEXTMESSAGESMARKEDWITHI18NINTOATRANSLATIONSOURCEFILE", "original": "Use the `ng xi18n` command provided by the CLI to extract the text messages marked with `i18n` into\na translation source file.", "translation": "使用 CLI 提供的 `ng xi18n` 命令来将带 `i18n` 标记的文本消息提取到一个翻译源文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "OPENATERMINALWINDOWATTHEROOTOFTHEAPPPROJECTANDENTERTHENGXI18NCOMMAND:", "original": "Open a terminal window at the root of the app project and enter the `ng xi18n` command:", "translation": "在应用的项目根目录打开一个终端窗口,并输入 `ng xi18n` 命令:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "BYDEFAULTTHETOOLGENERATESATRANSLATIONFILENAMEDMESSAGESXLFINTHEAHREFHTTPS:ENWIKIPEDIAORGWIKIXLIFFXMLLOCALIZATIONINTERCHANGEFILEFORMATXLIFFVERSION12A", "original": "By default, the tool generates a translation file named `messages.xlf` in the\n<a href=\"https://en.wikipedia.org/wiki/XLIFF\">XML Localization Interchange File Format\n(XLIFF, version 1.2)</a>.", "translation": "本工具默认会生成一个名叫 `messages.xlf` 的翻译文件,格式为<a href=\"https://en.wikipedia.org/wiki/XLIFF\" target=\"_blank\">XML本土化互换文件格式(XLIFF, version 1.2)</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IFYOUDONTUSETHECLIYOUHAVETWOOPTIONS:", "original": "If you don't use the CLI, you have two options:", "translation": "如果你不使用 CLI,那么你有两个选择:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANUSETHENGXI18NTOOLDIRECTLYFROMTHEANGULARCOMPILERCLIPACKAGEFORMOREINFORMATIONSEEI18NINTHECLIDOCUMENTATIONHTTPS:GITHUBCOMANGULARANGULARCLIWIKIXI18N", "original": "* You can use the `ng-xi18n` tool directly from the `@angular/compiler-cli` package.\nFor more information, see [i18n in the CLI documentation](https://github.com/angular/angular-cli/wiki/xi18n).", "translation": "你可以直接使用来自 `@angular/compiler-cli` 包中的 `ng-xi18n` 工具。更多信息,参见 [CLI 文档中的 i18n 部分](https://github.com/angular/angular-cli/wiki/xi18n)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANUSETHECLIWEBPACKPLUGINANGULARCOMPILERPLUGINFROMTHENGTOOLSWEBPACKPACKAGESETTHEPARAMETERSI18NOUTFILEANDI18NOUTFORMATTOTRIGGERTHEEXTRACTIONFORMOREINFORMATIONSEETHEANGULARAHEADOFTIMEWEBPACKPLUGINDOCUMENTATIONHTTPS:GITHUBCOMANGULARANGULARCLITREEMASTERPACKAGES40NGTOOLSWEBPACK", "original": "* You can use the CLI Webpack plugin `AngularCompilerPlugin` from the `@ngtools/webpack` package.\nSet the parameters `i18nOutFile` and `i18nOutFormat` to trigger the extraction.\nFor more information, see the [Angular Ahead-of-Time Webpack Plugin documentation](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack).", "translation": "你可以使用 CLI 中来自 `@ngtools/webpack` 包中的 Webpack 插件。设置其 `i18nOutFile` 和 `i18nOutFormat` 参数进行触发。\n 更多信息,参见 [Angular AOT Webpack 插件文档](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###OTHERTRANSLATIONFORMATS", "original": "### Other translation formats", "translation": "### 其它翻译格式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ANGULARI18NTOOLINGSUPPORTSTHREETRANSLATIONFORMATS:", "original": "Angular i18n tooling supports three translation formats:", "translation": "Angular 的 i18n 工具支持三种翻译格式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "XLIFF12DEFAULT", "original": "* XLIFF 1.2 (default)", "translation": "XLIFF 1.2 (默认)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "AHREFHTTP:CLDRUNICODEORGDEVELOPMENTDEVELOPMENTPROCESSDESIGNPROPOSALSXMBXMLMESSAGEBUNDLEXMBA", "original": "* <a href=\"http://cldr.unicode.org/development/development-process/design-proposals/xmb\" >XML Message\nBundle (XMB)</a>", "translation": "<a href=\"http://cldr.unicode.org/development/development-process/design-proposals/xmb\" >XML 消息包 (XMB)</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANSPECIFYTHETRANSLATIONFORMATEXPLICITLYWITHTHEI18NFORMATFLAGASILLUSTRATEDINTHESEEXAMPLECOMMANDS:", "original": "You can specify the translation format explicitly with the `--i18nFormat` flag as illustrated in\nthese example commands:", "translation": "你可以使用 `--i18nFormat` 来明确指定想用的格式,范例如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THESAMPLEINTHISGUIDEUSESTHEDEFAULTXLIFF12FORMAT", "original": "The sample in this guide uses the default XLIFF 1.2 format.", "translation": "本章的范例使用默认的 XLIFF 1.2 格式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "XLIFFFILESHAVETHEEXTENSIONXLFTHEXMBFORMATGENERATESXMBSOURCEFILESBUTUSESXTBXMLTRANSLATIONBUNDLE:XTBTRANSLATIONFILES", "original": "XLIFF files have the extension .xlf. The XMB format generates .xmb source files but uses\n .xtb (XML Translation Bundle: XTB) translation files.", "translation": "XLIFF 文件带有 .xlf 扩展名。XMB 格式会生成 .xmb 格式的源文件,但使用 .xtb(XML 翻译包)格式的翻译文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###OTHEROPTIONS", "original": "### Other options", "translation": "### 其它选项", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANSPECIFYTHEOUTPUTPATHUSEDBYTHECLITOEXTRACTYOURTRANSLATIONSOURCEFILEWITHTHEPARAMETEROUTPUTPATH:", "original": "You can specify the output path used by the CLI to extract your translation source file with\nthe parameter `--outputPath`:", "translation": "你还可以使用 `--outputPath` 参数在 CLI 提取翻译源文件时指定输出路径:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANCHANGETHENAMEOFTHETRANSLATIONSOURCEFILETHATISGENERATEDBYTHEEXTRACTIONTOOLWITHTHEPARAMETEROUTFILE:", "original": "You can change the name of the translation source file that is generated by the extraction tool with\nthe parameter `--outFile`:", "translation": "你还可以使用 `--outFile` 参数来为提取工具生成的翻译源文件改名:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANSPECIFYTHEBASELOCALEOFYOURAPPWITHTHEPARAMETERLOCALE:", "original": "You can specify the base locale of your app with the parameter `--locale`:", "translation": "你还可以使用 `--locale` 参数来指定应用的基本地区:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEEXTRACTIONTOOLUSESTHELOCALETOADDTHEAPPLOCALEINFORMATIONINTOYOURTRANSLATIONSOURCEFILETHISINFORMATIONISNOTUSEDBYANGULARBUTEXTERNALTRANSLATIONTOOLSMAYNEEDIT", "original": "The extraction tool uses the locale to add the app locale information into your translation source\nfile. This information is not used by Angular, but external translation tools may need it.", "translation": "该提取工具会用这个地区标识把本地化信息添加到你的翻译源文件中。这个信息对 Angular 来说没用,不过外部翻译工具可能会需要它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##TRANSLATETEXTMESSAGES", "original": "## Translate text messages", "translation": "## 翻译文本信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THENGXI18NCOMMANDGENERATESATRANSLATIONSOURCEFILENAMEDMESSAGESXLFINTHEPROJECTSRCFOLDER", "original": "The `ng xi18n` command generates a translation source file named `messages.xlf` in the project `src`\nfolder.", "translation": "`ng xi18n` 命令会在项目根目录生成一个名为 `messages.xlf` 的翻译源文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THENEXTSTEPISTOTRANSLATETHISSOURCEFILEINTOTHESPECIFICLANGUAGETRANSLATIONFILESTHEEXAMPLEINTHISGUIDECREATESAFRENCHTRANSLATIONFILE", "original": "The next step is to translate this source file into the specific language\ntranslation files. The example in this guide creates a French translation file.", "translation": "下一步是将英文模板文本翻译到指定语言的翻译文件。\n这个例子中创建了一个法语翻译文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###CREATEALOCALIZATIONFOLDER", "original": "### Create a localization folder", "translation": "### 新建一个本土化目录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "MOSTAPPSARETRANSLATEDINTOMORETHANONEOTHERLANGUAGEFORTHISREASONITISSTANDARDPRACTICEFORTHEPROJECTSTRUCTURETOREFLECTTHEENTIREINTERNATIONALIZATIONEFFORT", "original": "Most apps are translated into more than one other language. For this reason, it is standard practice\nfor the project structure to reflect the entire internationalization effort.", "translation": "大多数应用都要被翻译成多种其它语言,因此,为全部国际化工作做适当的调整项目目录结构是一种标准实践。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ONEAPPROACHISTODEDICATEAFOLDERTOLOCALIZATIONANDSTORERELATEDASSETSSUCHASINTERNATIONALIZATIONFILESTHERE", "original": "One approach is to dedicate a folder to localization and store related assets, such as\ninternationalization files, there.", "translation": "方法之一是为本土化和相关资源(比如国际化文件)创建一个专门的目录。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "LOCALIZATIONANDINTERNATIONALIZATIONAREAHREFHTTPS:ENWIKIPEDIAORGWIKIINTERNATIONALIZATIONANDLOCALIZATIONDIFFERENTBUTCLOSELYRELATEDTERMSA", "original": "Localization and internationalization are\n <a href=\"https://en.wikipedia.org/wiki/Internationalization_and_localization\">different but\n closely related terms</a>.", "translation": "本土化和国际化是<a href=\"https://en.wikipedia.org/wiki/Internationalization_and_localization\" target=\"_blank\">不同但是很相近的概念</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THISGUIDEFOLLOWSTHATAPPROACHITHASALOCALEFOLDERUNDERSRCASSETSWITHINTHATFOLDERHAVEAFILENAMEEXTENSIONTHATMATCHESTHEIRASSOCIATEDLOCALE", "original": "This guide follows that approach. It has a `locale` folder under `src/`.\nAssets within that folder have a filename extension that matches their associated locale.", "translation": "本指南遵循了这种方式。在`src/`目录下,有一个专门的`locale`目录,该目录中的文件都带一个与相关地区匹配的扩展名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###CREATETHETRANSLATIONFILES", "original": "### Create the translation files", "translation": "### 创建翻译文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "FOREACHTRANSLATIONSOURCEFILETHEREMUSTBEATLEASTONELANGUAGETRANSLATIONFILEFORTHERESULTINGTRANSLATION", "original": "For each translation source file, there must be at least one language translation file for the\nresulting translation.", "translation": "对每个翻译文件来说,都必须至少有一个语言的翻译文件作为翻译结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "FORTHISEXAMPLE:", "original": "For this example:", "translation": "对于这个例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "1MAKEACOPYOFTHEMESSAGESXLFFILE", "original": "1. Make a copy of the `messages.xlf` file.", "translation": "复制一份 `messages.xlf` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "2PUTTHECOPYINTHELOCALEFOLDER", "original": "2. Put the copy in the `locale` folder.", "translation": "把这个副本放进 `locale` 目录下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "3RENAMETHECOPYTOMESSAGESFRXLFFORTHEFRENCHLANGUAGETRANSLATION", "original": "3. Rename the copy to `messages.fr.xlf` for the French language translation.", "translation": "把这个副本改名为 `messages.fr.xlf` 以作为法语翻译结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IFYOUWERETRANSLATINGTOOTHERLANGUAGESYOUWOULDREPEATTHESESTEPSFOREACHTARGETLANGUAGE", "original": "If you were translating to other languages, you would repeat these steps for each target language.", "translation": "如果你要翻译为其他语言,那就为每一个目标语种重复上述步骤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###TRANSLATETEXTNODES", "original": "### Translate text nodes", "translation": "### 翻译文本节点", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "INALARGETRANSLATIONPROJECTYOUWOULDSENDTHEMESSAGESFRXLFFILETOAFRENCHTRANSLATORWHOWOULDENTERTHETRANSLATIONSUSINGANXLIFFFILEEDITOR", "original": "In a large translation project, you would send the `messages.fr.xlf` file to a French translator who\nwould enter the translations using an XLIFF file editor.", "translation": "在现实世界中,`messages.fr.xlf` 文件会被发给法语翻译,他们会使用某种 XLIFF 文件编辑器来翻译它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THISSAMPLEFILEISEASYTOTRANSLATEWITHOUTASPECIALEDITORORKNOWLEDGEOFFRENCH", "original": "This sample file is easy to translate without a special editor or knowledge of French.", "translation": "你不需要任何编辑器或者法语知识就可以轻易的翻译本例子文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "1OPENMESSAGESFRXLFANDFINDTHEFIRSTTRANSUNITSECTION:", "original": "1. Open `messages.fr.xlf` and find the first `<trans-unit>` section:", "translation": "打开 `messages.fr.xlf` 并找到第一个 `<trans-unit>` 区:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THISXMLELEMENTREPRESENTSTHETRANSLATIONOFTHEH1GREETINGTAGTHATYOUMARKEDWITHTHEI18NATTRIBUTEEARLIERINTHISGUIDE", "original": "> This XML element represents the translation of the `<h1>` greeting tag that you marked with the\n `i18n` attribute earlier in this guide.", "translation": "> 这个 XML 元素表示前面你加过 `i18n` 属性的那个打招呼用的 `<h1>` 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "NOTETHATTHETRANSLATIONUNITIDINTRODUCTIONHEADERISDERIVEDFROMTHECUSTOMID#CUSTOMIDSETACUSTOMIDTHATYOUSETEARLIERBUTWITHOUTTHEPREFIXREQUIREDINTHESOURCEHTML", "original": "> Note that the translation unit `id=introductionHeader` is derived from the\n [custom `id`](#custom-id \"Set a custom id\") that you set earlier, but\n without the `@@` prefix required in the source HTML.", "translation": "> 注意这个 `id=introductionHeader` 的翻译单元是来自你以前设置过的[自定义 `id`](#custom-id \"Set a custom id\")的。但是并没有源 HTML 所需的 `@@` 前缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "2DUPLICATETHESOURCETAGRENAMEITTARGETANDTHENREPLACEITSCONTENTWITHTHEFRENCHGREETINGIFYOUWEREWORKINGWITHAMORECOMPLEXTRANSLATIONYOUCOULDUSETHETHEINFORMATIONANDCONTEXTPROVIDEDBYTHESOURCEDESCRIPTIONANDMEANINGELEMENTSTOGUIDEYOURSELECTIONOFTHEAPPROPRIATEFRENCHTRANSLATION", "original": "2. Duplicate the `<source/>` tag, rename it `target`, and then replace its content with the French\n greeting. If you were working with a more complex translation, you could use the the information\n and context provided by the source, description, and meaning elements to guide your selection of\n the appropriate French translation.", "translation": "复制 `<source/>` 标记,把它改名为 `target`,并把它的内容改为法语版的 “greeting”。\n 如果你要做的是更复杂的翻译,可能会使用由源文本、描述信息和含义等提供的信息和上下文来给出更恰当的法语翻译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "3TRANSLATETHEOTHERTEXTNODESTHESAMEWAY:", "original": "3. Translate the other text nodes the same way:", "translation": "用同样的方式翻译其它文本节点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEANGULARI18NTOOLSGENERATEDTHEIDSFORTHESETRANSLATIONUNITSDONTCHANGETHEMEACHIDDEPENDSUPONTHECONTENTOFTHETEMPLATETEXTANDITSASSIGNEDMEANINGIFYOUCHANGEEITHERTHETEXTORTHEMEANINGTHENTHEIDCHANGESFORMOREINFORMATIONSEETHETRANSLATIONFILEMAINTENANCEDISCUSSION#CUSTOMID", "original": "**The Angular i18n tools generated the ids for these translation units. Don't change them.**\n Each `id` depends upon the content of the template text and its assigned meaning.\n If you change either the text or the meaning, then the `id` changes.\n For more information, see the **[translation file maintenance discussion](#custom-id)**.", "translation": "**Angular 的 i18n 工具会为这些翻译单元生成一些 id,不要修改它们。**\n 每个 `id` 都是根据模板文本的内容及其含义来生成的。\n 无论你修改了文本还是含义,它们的 `id` 都会改变。\n 要了解更多信息,参见 **[关于翻译文件可维护性的讨论](#custom-id)**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##TRANSLATEPLURALANDSELECTEXPRESSIONS", "original": "## Translate plural and select expressions", "translation": "## 翻译复数(plural)和选择(select)表达式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "PLURALANDSELECTICUEXPRESSIONSAREEXTRACTEDSEPARATELYSOTHEYREQUIRESPECIALATTENTIONWHENPREPARINGFORTRANSLATION", "original": "_Plural_ and _select_ ICU expressions are extracted separately, so they require special attention\nwhen preparing for translation.", "translation": "*复数*和*选择*的 ICU 表达式都是分别提取的,所以在准备翻译时,它们需要格外注意。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "LOOKFORTHESEEXPRESSIONSINRELATIONTOOTHERTRANSLATIONUNITSTHATYOURECOGNIZEFROMELSEWHEREINTHESOURCETEMPLATEINTHISEXAMPLEYOUKNOWTHETRANSLATIONUNITFORTHESELECTMUSTBEJUSTBELOWTHETRANSLATIONUNITFORTHELOGO", "original": "Look for these expressions in relation to other translation units that you recognize from\nelsewhere in the source template. In this example, you know the translation unit for the `select`\nmust be just below the translation unit for the logo.", "translation": "你要从原始模板中其它地方识别出来的翻译单元来找到这些表达式之间的联系。\n比如在这个例子中,你知道 `select` 一定会出现在 logo 的翻译单元的紧下方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###TRANSLATEPLURAL", "original": "### Translate _plural_", "translation": "### 翻译*复数*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TOTRANSLATEAPLURALTRANSLATEITSICUFORMATMATCHVALUES:", "original": "To translate a `plural`, translate its ICU format match values:", "translation": "要翻译一个复数,就要翻译它的 ICU 格式中匹配的值:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUCANADDORREMOVEPLURALCASESWITHEACHLANGUAGEHAVINGITSOWNCARDINALITYSEECLDRPLURALRULESHTTP:WWWUNICODEORGCLDRCHARTSLATESTSUPPLEMENTALLANGUAGEPLURALRULESHTML", "original": "You can add or remove plural cases, with each language having its own cardinality. (See \n[CLDR plural rules](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html).)", "translation": "你可以添加或删除复数的情况,每种语言都有自己的基数规则。(参见 [CLDR 复数规则](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html))。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###TRANSLATESELECT", "original": "### Translate _select_", "translation": "### 翻译*选择*(select)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "BELOWISTHECONTENTOFOUREXAMPLESELECTICUEXPRESSIONINTHECOMPONENTTEMPLATE:", "original": "Below is the content of our example `select` ICU expression in the component template:", "translation": "下面是组件模板中的 ICU 表达式 `select` 的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEEXTRACTIONTOOLBROKETHATINTOTWOTRANSLATIONUNITSBECAUSEICUEXPRESSIONSAREEXTRACTEDSEPARATELY", "original": "The extraction tool broke that into two translation units because ICU expressions are extracted\nseparately.", "translation": "提取工具会把它拆成*两个*翻译单元,因为 ICU 表达式是分别提取的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEFIRSTUNITCONTAINSTHETEXTTHATWASOUTSIDEOFTHESELECTINPLACEOFTHESELECTISAPLACEHOLDERXIDICUTHATREPRESENTSTHESELECTMESSAGETRANSLATETHETEXTANDMOVEAROUNDTHEPLACEHOLDERIFNECESSARYBUTDONTREMOVEITIFYOUREMOVETHEPLACEHOLDERTHEICUEXPRESSIONWILLNOTBEPRESENTINYOURTRANSLATEDAPP", "original": "The first unit contains the text that was outside of the `select`.\nIn place of the `select` is a placeholder, `<x id=\"ICU\">`, that represents the `select` message.\nTranslate the text and move around the placeholder if necessary, but don't remove it. If you remove\nthe placeholder, the ICU expression will not be present in your translated app.", "translation": "第一个单元包含 `select` 之外的文本。\n这里的 `select` 是一个占位符 `<x id=\"ICU\">`,用来表示 `select` 中的消息。\n翻译这段文本,如果需要就把占位符放在那里,但不要删除它。\n如果删除了占位符,ICU 表达式就不会出现在翻译后的应用中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THESECONDTRANSLATIONUNITIMMEDIATELYBELOWTHEFIRSTONECONTAINSTHESELECTMESSAGETRANSLATETHATASWELL", "original": "The second translation unit, immediately below the first one, contains the `select` message.\nTranslate that as well.", "translation": "第一个翻译单元的紧下方就是第二个翻译单元,包含 `select` 中的消息。照样翻译它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "HERETHEYARETOGETHERAFTERTRANSLATION:", "original": "Here they are together, after translation:", "translation": "在翻译之后,它们会放在一起:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###TRANSLATEANESTEDEXPRESSION", "original": "### Translate a nested expression", "translation": "### 翻译嵌套的表达式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ANESTEDEXPRESSIONISSIMILARTOTHEPREVIOUSEXAMPLESASINTHEPREVIOUSEXAMPLETHEREARETWOTRANSLATIONUNITSTHEFIRSTONECONTAINSTHETEXTOUTSIDEOFTHENESTEDEXPRESSION:", "original": "A nested expression is similar to the previous examples. As in the previous example, there are \ntwo translation units. The first one contains the text outside of the nested expression:", "translation": "嵌套的表达式和前一节没有什么不同。就像上一个例子中那样,这里有*两个*翻译单元。\n第一个包含嵌套表达式之外的文本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THESECONDUNITCONTAINSTHECOMPLETENESTEDEXPRESSION:", "original": "The second unit contains the complete nested expression:", "translation": "第二个包含完整的嵌套表达式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ANDBOTHTOGETHER:", "original": "And both together:", "translation": "放在一起时:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEENTIRETEMPLATETRANSLATIONISCOMPLETETHENEXTSECTIONDESCRIBESHOWTOLOADTHATTRANSLATIONINTOTHEAPP", "original": "The entire template translation is complete. The next section describes how to load that translation\ninto the app.", "translation": "整个模板的翻译就完成了。下一节会讲如何翻译结果加载到应用程序中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###THEAPPANDITSTRANSLATIONFILE", "original": "### The app and its translation file", "translation": "### 应用及其翻译文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THESAMPLEAPPANDITSTRANSLATIONFILEARENOWASFOLLOWS:", "original": "The sample app and its translation file are now as follows:", "translation": "下面是例子应用及其翻译文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "##MERGETHECOMPLETEDTRANSLATIONFILEINTOTHEAPP", "original": "## Merge the completed translation file into the app", "translation": "## 合并已经翻译的文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TOMERGETHETRANSLATEDTEXTINTOCOMPONENTTEMPLATESCOMPILETHEAPPWITHTHECOMPLETEDTRANSLATIONFILEPROVIDETHEANGULARCOMPILERWITHTHREETRANSLATIONSPECIFICPIECESOFINFORMATION:", "original": "To merge the translated text into component templates, compile the app with the completed\ntranslation file. Provide the Angular compiler with three translation-specific pieces of information:", "translation": "要把已经翻译的文件合并到组件模板,就要用翻译过的文件编译应用。\n为 Angular 编译器提供三种与翻译有关的信息:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THETRANSLATIONFILE", "original": "* The translation file.", "translation": "翻译文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THETRANSLATIONFILEFORMAT", "original": "* The translation file format.", "translation": "翻译文件的格式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THELOCALEFRORENUSFORINSTANCE", "original": "* The locale (`fr` or `en-US` for instance).", "translation": "目标地区(比如 `fr` 或 `en-US`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THECOMPILATIONPROCESSISTHESAMEWHETHERTHETRANSLATIONFILEISINXLFFORMATORINANOTHERFORMATTHATANGULARUNDERSTANDSSUCHASXTB", "original": "The compilation process is the same whether the translation file is in `.xlf` format or in another\nformat that Angular understands, such as `.xtb`.", "translation": "无论翻译文件是 `.xlf` 还是 Angular 支持的其它格式(比如 `.xtb`),其编译过程都是一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "HOWYOUPROVIDETHISINFORMATIONDEPENDSUPONWHETHERYOUCOMPILEWITHTHEJITCOMPILERORTHEAOTCOMPILER", "original": "How you provide this information depends upon whether you compile with\nthe JIT compiler or the AOT compiler.", "translation": "你如何提供这些信息取决于你使用的是JIT(即时)编译器还是AOT(预先)编译器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "WITHAOTGUIDEI18N#MERGEAOTYOUPASSTHEINFORMATIONASACLIPARAMETER", "original": "* With [AOT](guide/i18n#merge-aot), you pass the information as a CLI parameter.", "translation": "使用[AOT](guide/i18n#merge-aot)时,用在 CLI 的参数里传入这些信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "WITHJITGUIDEI18N#MERGEJITYOUPROVIDETHEINFORMATIONATBOOTSTRAPTIME", "original": "* With [JIT](guide/i18n#merge-jit), you provide the information at bootstrap time.", "translation": "使用[JIT](guide/i18n#merge-jit)时,在引导时提供。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###MERGEWITHTHEAOTCOMPILER", "original": "### Merge with the AOT compiler", "translation": "### 使用 AOT 编译器合并", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEAOTAHEADOFTIMECOMPILERISPARTOFABUILDPROCESSTHATPRODUCESASMALLFASTREADYTORUNAPPLICATIONPACKAGE", "original": "The AOT (_Ahead-of-Time_) compiler is part of a build process that produces a small, fast,\nready-to-run application package.", "translation": "AOT(*预先*)编译器是构建过程的一部分,它可以生成又小又快,直接可用的应用包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "WHENYOUINTERNATIONALIZEWITHTHEAOTCOMPILERYOUMUSTPREBUILDASEPARATEAPPLICATIONPACKAGEFOREACHLANGUAGEANDSERVETHEAPPROPRIATEPACKAGEBASEDONEITHERSERVERSIDELANGUAGEDETECTIONORURLPARAMETERS", "original": "When you internationalize with the AOT compiler, you must pre-build a separate application\npackage for each language and serve the appropriate package based on either server-side language\ndetection or url parameters.", "translation": "当你使用 AOT 编译器进行国际化时,你必须为每种语言预先编译一个独立的应用包,并且依靠服务端语言检测或 URL 参数来找出合适的包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "YOUALSONEEDTOINSTRUCTTHEAOTCOMPILERTOUSEYOURTRANSLATIONFILETODOSOYOUUSETHREEOPTIONSWITHTHENGSERVEORNGBUILDCOMMANDS:", "original": "You also need to instruct the AOT compiler to use your translation file. To do so, you use three\noptions with the `ng serve` or `ng build` commands:", "translation": "你还要指示 AOT 编译器使用你的翻译结果文件,要这么做,你就要在 `ng serve` 或 `ng build` 命令中使用三个选项:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "I18NFILE:THEPATHTOTHETRANSLATIONFILE", "original": "* `--i18nFile`: the path to the translation file.", "translation": "`--i18nFile`: 翻译文件的路径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "I18NFORMAT:THEFORMATOFTHETRANSLATIONFILE", "original": "* `--i18nFormat`: the format of the translation file.", "translation": "`--i18nFormat`: 翻译文件的格式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "LOCALE:THELOCALEID", "original": "* `--locale`: the locale id.", "translation": "`--locale`: 地区的 ID。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEEXAMPLEBELOWSHOWSHOWTOSERVETHEFRENCHLANGUAGEFILECREATEDINPREVIOUSSECTIONSOFTHISGUIDE:", "original": "The example below shows how to serve the French language file created in previous sections of this\nguide:", "translation": "下面的例子演示了如何使用前面部分创建的法语文件来启动开发服务器:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###MERGEWITHTHEJITCOMPILER", "original": "### Merge with the JIT compiler", "translation": "### 用 JIT 编译器合并", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEJITCOMPILERCOMPILESTHEAPPINTHEBROWSERASTHEAPPLOADSTRANSLATIONWITHTHEJITCOMPILERISADYNAMICPROCESSOF:", "original": "The JIT compiler compiles the app in the browser as the app loads.\nTranslation with the JIT compiler is a dynamic process of:", "translation": "JIT(即时)编译器在应用程序加载时,在浏览器中编译应用。\n在使用 JIT 编译器的环境中翻译是一个动态的流程,包括:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "1IMPORTINGTHEAPPROPRIATELANGUAGETRANSLATIONFILEASASTRINGCONSTANT", "original": "1. Importing the appropriate language translation file as a string constant.", "translation": "把合适的语言翻译文件导入成一个字符串常量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "2CREATINGCORRESPONDINGTRANSLATIONPROVIDERSFORTHEJITCOMPILER", "original": "2. Creating corresponding translation providers for the JIT compiler.", "translation": "为 JIT 编译器创建相应的翻译提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "3BOOTSTRAPPINGTHEAPPWITHTHOSEPROVIDERS", "original": "3. Bootstrapping the app with those providers.", "translation": "使用这些提供商来启动应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THREEPROVIDERSTELLTHEJITCOMPILERHOWTOTRANSLATETHETEMPLATETEXTSFORAPARTICULARLANGUAGEWHILECOMPILINGTHEAPP:", "original": "Three providers tell the JIT compiler how to translate the template texts for a particular language\nwhile compiling the app:", "translation": "三种提供商帮助 JIT 编译在编译应用时,将模板文本翻译到某种语言:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TRANSLATIONSISASTRINGCONTAININGTHECONTENTOFTHETRANSLATIONFILE", "original": "* `TRANSLATIONS` is a string containing the content of the translation file.", "translation": "`TRANSLATIONS` 是含有翻译文件内容的字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "TRANSLATIONSFORMATISTHEFORMATOFTHEFILE:XLFXLF2ORXTB", "original": "* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlf2`, or `xtb`.", "translation": "`TRANSLATIONS_FORMAT` 是文件的格式: `xlf`、`xlif` 或 `xtb`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "LOCALEIDISTHELOCALEOFTHETARGETLANGUAGE", "original": "* `LOCALE_ID` is the locale of the target language.", "translation": "`LOCALE_ID` 是目标语言的语言环境。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THEANGULARBOOTSTRAPMODULEMETHODHASASECONDCOMPILEROPTIONSPARAMETERTHATCANINFLUENCETHEBEHAVIOROFTHECOMPILERYOUCANUSEITTOPROVIDETHETRANSLATIONPROVIDERS:", "original": "The Angular `bootstrapModule` method has a second `compilerOptions` parameter that can influence the\nbehavior of the compiler. You can use it to provide the translation providers:", "translation": "在下面的 `src/app/i18n-providers.ts` 文件的 `getTranslationProviders()` 函数中,根据用户的**语言环境**和对应的翻译文件构建这些提供商:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "THENPROVIDETHELOCALEIDINTHEMAINMODULE:", "original": "Then provide the `LOCALE_ID` in the main module:", "translation": "然后在主文件包中提供 `LOCALE_ID`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "###REPORTMISSINGTRANSLATIONS", "original": "### Report missing translations", "translation": "### 汇报缺失的翻译", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "BYDEFAULTWHENATRANSLATIONISMISSINGTHEBUILDSUCCEEDSBUTGENERATESAWARNINGSUCHASMISSINGTRANSLATIONFORMESSAGEFOOYOUCANCONFIGURETHELEVELOFWARNINGTHATISGENERATEDBYTHEANGULARCOMPILER:", "original": "By default, when a translation is missing, the build succeeds but generates a warning such as\n`Missing translation for message \"foo\"`. You can configure the level of warning that is generated by\nthe Angular compiler:", "translation": "默认情况下,如果缺少了某个翻译文件,构建工具会成功但给出警告(如`Missing translation for message \"foo\"`)。你可以配置 Angular 编译器生成的警告级别:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "ERROR:THROWANERRORIFYOUAREUSINGAOTCOMPILATIONTHEBUILDWILLFAILIFYOUAREUSINGJITCOMPILATIONTHEAPPWILLFAILTOLOAD", "original": "* Error: throw an error. If you are using AOT compilation, the build will fail. If you are using JIT\ncompilation, the app will fail to load.", "translation": "Error(错误):抛出错误,如果你使用的是 AOT 编译器,构建就会失败。如果使用的是 JIT 编译器,应用的加载就会失败。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "WARNINGDEFAULT:SHOWAMISSINGTRANSLATIONWARNINGINTHECONSOLEORSHELL", "original": "* Warning (default): show a 'Missing translation' warning in the console or shell.", "translation": "Warning(警告 - 默认):在控制台中显示一条 “Missing translation” 警告。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IGNORE:DONOTHING", "original": "* Ignore: do nothing.", "translation": "Ignore(忽略):什么也不做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IFYOUUSETHEAOTCOMPILERSPECIFYTHEWARNINGLEVELBYUSINGTHECLIPARAMETERMISSINGTRANSLATIONTHEEXAMPLEBELOWSHOWSHOWTOSETTHEWARNINGLEVELTOERROR:", "original": "If you use the AOT compiler, specify the warning level by using the CLI parameter\n`--missingTranslation`. The example below shows how to set the warning level to error:", "translation": "如果你使用 AOT 编译器,可以使用 CLI 参数 `--missingTranslation` 来指定警告级别。下面的例子示范了如何把警告级别设置为 `error`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "IFYOUUSETHEJITCOMPILERSPECIFYTHEWARNINGLEVELINTHECOMPILERCONFIGATBOOTSTRAPBYADDINGTHEMISSINGTRANSLATIONSTRATEGYPROPERTYTHEEXAMPLEBELOWSHOWSHOWTOSETTHEWARNINGLEVELTOERROR:", "original": "If you use the JIT compiler, specify the warning level in the compiler config at bootstrap by adding\nthe 'MissingTranslationStrategy' property. The example below shows how to set the warning level to\nerror:", "translation": "如果你要使用 JIT 编译器,就在启动时往编译器的配置中添加一个 `MissingTranslationStrategy` 属性来指定警告级别。下面的例子示范了如何把警告级别设置为 `error`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/i18n.md" }, { + "key": "#ANGULARLANGUAGESERVICE", "original": "# Angular Language Service", "translation": "# Angular 语言服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "THEANGULARLANGUAGESERVICEISAWAYTOGETCOMPLETIONSERRORSHINTSANDNAVIGATIONINSIDEYOURANGULARTEMPLATESWHETHERTHEYAREEXTERNALINANHTMLFILEOREMBEDDEDINANNOTATIONSDECORATORSINASTRINGTHEANGULARLANGUAGESERVICEAUTODETECTSTHATYOUAREOPENINGANANGULARFILEREADSYOURTSCONFIGJSONFILEFINDSALLTHETEMPLATESYOUHAVEINYOURAPPLICATIONANDTHENPROVIDESLANGUAGESERVICESFORANYTEMPLATESTHATYOUOPEN", "original": "The Angular Language Service is a way to get completions, errors, \nhints, and navigation inside your Angular templates whether they \nare external in an HTML file or embedded in annotations/decorators \nin a string. The Angular Language Service autodetects that you are \nopening an Angular file, reads your `tsconfig.json` file, finds all the \ntemplates you have in your application, and then provides language \nservices for any templates that you open.", "translation": "Angular 语言服务让你能在模板内获得自动完成、错误检查、给出提示和内部导航等功能,而不用管这些模板位于外部 HTML 文件中还是内嵌在注解/装饰器的字符串中。\nAngular 语言服务会自动检测你要打开的文件(从你的 `tsconfig.json` 中读取),找出应用中所需的所有模板,然后为你打开的这些模板提供语言服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "##AUTOCOMPLETION", "original": "## Autocompletion", "translation": "## 自动完成", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "AUTOCOMPLETIONCANSPEEDUPYOURDEVELOPMENTTIMEBYPROVIDINGYOUWITHCONTEXTUALPOSSIBILITIESANDHINTSASYOUTYPETHISEXAMPLESHOWSAUTOCOMPLETEINANINTERPOLATIONASYOUTYPEITOUTYOUCANHITTABTOCOMPLETE", "original": "Autocompletion can speed up your development time by providing you with \ncontextual possibilities and hints as you type. This example shows \nautocomplete in an interpolation. As you type it out, \nyou can hit tab to complete.", "translation": "自动完成可以在输入时为你提供当前情境下的候选内容和提示,从而提高开发速度。下面这个例子展示了插值表达式中的自动完成功能。当你进行输入的时候,就可以按 tab 键来自动完成。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "THEREAREALSOCOMPLETIONSWITHINELEMENTSANYELEMENTSYOUHAVEASACOMPONENTSELECTORWILLSHOWUPINTHECOMPLETIONLIST", "original": "There are also completions within \nelements. Any elements you have as a component selector will \nshow up in the completion list.", "translation": "还有对元素的自动完成。你定义的任何组件的选择器都会显示在自动完成列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "##ERRORCHECKING", "original": "## Error checking", "translation": "## 错误检查", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "THEANGULARLANGUAGESERVICECANALSOFOREWARNYOUOFMISTAKESINYOURCODEINTHISEXAMPLEANGULARDOESNTKNOWWHATORDERSISORWHEREITCOMESFROM", "original": "The Angular Language Service can also forewarn you of mistakes in your code. \nIn this example, Angular doesn't know what `orders` is or where it comes from.", "translation": "Angular 语言服务还能对代码中存在的错误进行预警。在这个例子中,Angular 不知道什么是 `orders` 或者它来自哪里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "##NAVIGATION", "original": "## Navigation", "translation": "## 导航", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "NAVIGATIONALLOWSYOUTOHOVERTOSEEWHEREACOMPONENTDIRECTIVEMODULEETCISFROMANDTHENCLICKANDPRESSF12TOGODIRECTLYTOITSDEFINITION", "original": "Navigation allows you to hover to \nsee where a component, directive, module, etc. is from and then \nclick and press F12 to go directly to its definition.", "translation": "导航可以让你在鼠标悬浮时看到某个组件、指令、模块等来自哪里,然后可以点击并按 F12 直接跳转到它的定义处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "##ANGULARLANGUAGESERVICEINYOUREDITOR", "original": "## Angular Language Service in your editor", "translation": "## 编辑器中的 Angular 语言服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "ANGULARLANGUAGESERVICEISCURRENTLYAVAILABLEFORVISUALSTUDIOCODEHTTPS:CODEVISUALSTUDIOCOMANDWEBSTORMHTTPS:WWWJETBRAINSCOMWEBSTORM", "original": "Angular Language Service is currently available for [Visual Studio Code](https://code.visualstudio.com/) and \n[WebStorm](https://www.jetbrains.com/webstorm).", "translation": "Angular 语言服务目前在[Visual Studio Code](https://code.visualstudio.com/)和[WebStorm](https://www.jetbrains.com/webstorm)中都是可用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "###VISUALSTUDIOCODE", "original": "### Visual Studio Code", "translation": "### Visual Studio Code 中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "INVISUALSTUDIOCODEINSTALLANGULARLANGUAGESERVICEFROMTHESTOREWHICHISACCESSIBLEFROMTHEBOTTOMICONONTHELEFTMENUPANEYOUCANALSOUSETHEVSQUICKOPENPTOSEARCHFORTHEEXTENSIONWHENYOUVEOPENEDITENTERTHEFOLLOWINGCOMMAND:", "original": "In Visual Studio Code, install Angular Language Service from the store, \nwhich is accessible from the bottom icon on the left menu pane. \nYou can also use the VS Quick Open (⌘+P) to search for the extension. When you've opened it, \nenter the following command:", "translation": "Visual Studio Code 可以从商店中安装语言服务,这个功能就在左侧菜单面板最底下的那个图标。\n你也可以使用 VS 的快速打开(⌘+P)功能来查找这个扩展插件。打开它之后就输入下列命令:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "THENCLICKTHEINSTALLBUTTONTOINSTALLTHEANGULARLANGUAGESERVICE", "original": "Then click the install button to install the Angular Language Service.", "translation": "然后点击安装按钮来安装 Angular 语言服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "###WEBSTORM", "original": "### WebStorm", "translation": "### WebStorm 中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "INWEBSTORMYOUHAVETOINSTALLTHELANGUAGESERVICEASADEVDEPENDENCYWHENANGULARSEESTHISDEVDEPENDENCYITPROVIDESTHELANGUAGESERVICEINSIDEOFWEBSTORMWEBSTORMTHENGIVESYOUCOLORIZATIONINSIDETHETEMPLATEANDAUTOCOMPLETEINADDITIONTOTHEANGULARLANGUAGESERVICE", "original": "In webstorm, you have to install the language service as a dev dependency. \nWhen Angular sees this dev dependency, it provides the \nlanguage service inside of WebStorm. Webstorm then gives you \ncolorization inside the template and autocomplete in addition to the Angular Language Service.", "translation": "在 WebStorm 中,你必须把语言服务安装为一个开发依赖。\n当 Angular 看到这个开发依赖时,它就会在 WebStorm 中提供语言服务。除了 Angular 语言服务之外,WebStorm 还会为你提供模板中的代码高亮和自动完成功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "HERESTHEDEVDEPENDENCYYOUNEEDTOHAVEINPACKAGEJSON:", "original": "Here's the dev dependency \nyou need to have in `package.json`:", "translation": "下面这个开发依赖需要添加到 `package.json` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "THENINTHETERMINALWINDOWATTHEROOTOFYOURPROJECTINSTALLTHEDEVDEPENDENCIESWITHNPMORYARN:", "original": "Then in the terminal window at the root of your project, \ninstall the `devDependencies` with `npm` or `yarn`:", "translation": "然后,打开终端窗口,在项目根目录下使用 `npm` 或 `yarn` 来安装这些 `devDependencies`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "OR", "original": "*OR*", "translation": "*或*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "OR", "original": "*OR*", "translation": "*或*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "###SUBLIMETEXT", "original": "### Sublime Text", "translation": "### Sublime Text 编辑器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "INSUBLIMETEXTHTTPS:WWWSUBLIMETEXTCOMYOUFIRSTNEEDANEXTENSIONTOALLOWTYPESCRIPTINSTALLTHELATESTVERSIONOFTYPESCRIPTINALOCALNODEMODULESDIRECTORY:", "original": "In [Sublime Text](https://www.sublimetext.com/), you first need an extension to allow Typescript. \nInstall the latest version of typescript in a local `node_modules` directory:", "translation": "在[Sublime Text](https://www.sublimetext.com/)中,你首先需要一个扩展来支持 TypeScript。\n把最新版本的 TypeScript 安装到本地的 `node_modules` 目录下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "THENINSTALLTHEANGULARLANGUAGESERVICEINTHESAMELOCATION:", "original": "Then install the Angular Language Service in the same location:", "translation": "然后把 Angular 语言服务安装到同一位置:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "STARTINGWITHTYPESCRIPT23TYPESCRIPTHASALANGUAGESERVICEPLUGINMODELTHATTHELANGUAGESERVICECANUSE", "original": "Starting with TypeScript 2.3, TypeScript has a language service plugin model that the language service can use.", "translation": "从 TypeScript 2.3 开始,TypeScript 提供了一种插件模式的语言服务可以用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "NEXTINYOURUSERPREFERENCESCMDORCTRLADD:", "original": "Next, in your user preferences (`Cmd+,` or `Ctrl+,`), add:", "translation": "接下来,在你的用户首选项中(按 `Cmd+,` 或 `Ctrl+,`)添加:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "##INSTALLINGINYOURPROJECT", "original": "## Installing in your project", "translation": "## 安装到项目中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "YOUCANALSOINSTALLANGULARLANGUAGESERVICEINYOURPROJECTWITHTHEFOLLOWINGNPMCOMMAND:", "original": "You can also install Angular Language Service in your project with the \nfollowing `npm` command:", "translation": "你还可以使用下列 `npm` 命令来把 Angular 语言服务安装到项目中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "ADDITIONALLYADDTHEFOLLOWINGTOTHECOMPILEROPTIONSSECTIONOFYOURPROJECTSTSCONFIGJSON", "original": "Additionally, add the following to the `\"compilerOptions\"` section of \nyour project's `tsconfig.json`.", "translation": "另外,还要在项目的 `tsconfig.json` 中添加下列 `\"compilerOptions\"` 区域:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "NOTETHATTHISONLYPROVIDESDIAGNOSTICSANDCOMPLETIONSINTSFILESYOUNEEDACUSTOMSUBLIMEPLUGINORMODIFICATIONSTOTHECURRENTPLUGINFORCOMPLETIONSINHTMLFILES", "original": "Note that this only provides diagnostics and completions in `.ts` \nfiles. You need a custom sublime plugin (or modifications to the current plugin) \nfor completions in HTML files.", "translation": "注意,这只是提供了 `.ts` 文件中的诊断与自动完成。你需要一个自定义的 sublime 插件(或修改现有插件)来在 HTML 文件中提供自动完成功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "##HOWTHELANGUAGESERVICEWORKS", "original": "## How the Language Service works", "translation": "## 语言服务的工作原理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "WHENYOUUSEANEDITORWITHALANGUAGESERVICETHERESANEDITORPROCESSWHICHSTARTSASEPARATELANGUAGEPROCESSSERVICETOWHICHITSPEAKSTHROUGHANRPCHTTPS:ENWIKIPEDIAORGWIKIREMOTEPROCEDURECALLANYTIMEYOUTYPEINSIDEOFTHEEDITORITSENDSINFORMATIONTOTHEOTHERPROCESSTOTRACKTHESTATEOFYOURPROJECTWHENYOUTRIGGERACOMPLETIONLISTWITHINATEMPLATETHEEDITORPROCESSFIRSTPARSESTHETEMPLATEINTOANHTMLASTORABSTRACTSYNTAXTREEHTTPS:ENWIKIPEDIAORGWIKIABSTRACTSYNTAXTREETHENTHEANGULARCOMPILERINTERPRETSWHATMODULETHETEMPLATEISPARTOFTHESCOPEYOUREINANDTHECOMPONENTSELECTORTHENITFIGURESOUTWHEREINTHETEMPLATEASTYOURCURSORISWHENITDETERMINESTHECONTEXTITCANTHENDETERMINEWHATTHECHILDRENCANBE", "original": "When you use an editor with a language service, there's an \neditor process which starts a separate language process/service \nto which it speaks through an [RPC](https://en.wikipedia.org/wiki/Remote_procedure_call). \nAny time you type inside of the editor, it sends information to the other process to \ntrack the state of your project. When you trigger a completion list within a template, the editor process first parses the template into an HTML AST, or [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree). Then the Angular compiler interprets \nwhat module the template is part of, the scope you're in, and the component selector. Then it figures out where in the template AST your cursor is. When it determines the \ncontext, it can then determine what the children can be.", "translation": "当使用带有语言服务的编辑器时,就会有一个编辑器进程,它会启动一个独立的语言服务进程/服务,它们通过[RPC](https://en.wikipedia.org/wiki/Remote_procedure_call)彼此交谈。\n当你在编辑器中输入的时候,它把这些信息发送到另一个进程中,以便追踪项目的状态。\n当你在模板中触发一个自动完成列表时,编辑器进程就会先把这个模板解析成 HTML AST,或者叫[抽象语法树](https://en.wikipedia.org/wiki/Abstract_syntax_tree)。然后,Angular 编译器就会解释模板所属的模块以及模板选择器。然后它找出光标目前正在模板 AST 的什么位置。一旦它确定了情境,就可以决定其子节点可以是什么了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "ITSALITTLEMOREINVOLVEDIFYOUAREINANINTERPOLATIONIFYOUHAVEANINTERPOLATIONOFDATAINSIDEADIVANDNEEDTHECOMPLETIONLISTAFTERDATATHECOMPILERCANTUSETHEHTMLASTTOFINDTHEANSWERTHEHTMLASTCANONLYTELLTHECOMPILERTHATTHEREISSOMETEXTWITHTHECHARACTERSDATATHATSWHENTHETEMPLATEPARSERPRODUCESANEXPRESSIONASTWHICHRESIDESWITHINTHETEMPLATEASTTHEANGULARLANGUAGESERVICESTHENLOOKSATDATAWITHINITSCONTEXTANDASKSTHETYPESCRIPTLANGUAGESERVICEWHATTHEMEMBERSOFDATAARETYPESCRIPTTHENRETURNSTHELISTOFPOSSIBILITIES", "original": "It's a little more involved if you are in an interpolation. If you have an interpolation of `{{data.---}}` inside a `div` and need the completion list after `data.---`, the compiler can't use the HTML AST to find the answer. The HTML AST can only tell the compiler that there is some text with the characters \"`{{data.---}}`\". That's when the template parser produces an expression AST, which resides within the template AST. The Angular Language Services then looks at `data.---` within its context and asks the TypeScript Language Service what the members of data are. TypeScript then returns the list of possibilities.", "translation": "如果是在插值表达式中,还会牵扯到更多东西。如果你在 `div` 元素中有一个插值表达式 `{{data.---}}`,并且需要在输入了 `data.` 之后提供自动完成列表,编译器就没办法使用 HTML AST 来找出答案了。\nHTML AST 只能告诉编译器,有一些具有 \"`{{data.---}}`\" 特征的文本。也就是说模板解析器会生成表达式的 AST ,并且放在模板的 AST 中。Angular 语言服务然后在这个情境下查找 `data.---`,并向 TypeScript 语言服务询问这些数据都有哪些成员。然后 TypeScript 就会返回一个可能的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "FORMOREINDEPTHINFORMATIONSEETHEANGULARLANGUAGESERVICEAPIHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERPACKAGESLANGUAGESERVICESRCTYPESTS", "original": "For more in-depth information, see the \n[Angular Language Service API](https://github.com/angular/angular/blob/master/packages/language-service/src/types.ts)", "translation": "要了解更多更深入的信息,参见 [Angular 语言服务 API](https://github.com/angular/angular/blob/master/packages/language-service/src/types.ts)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "##MOREONINFORMATION", "original": "## More on Information", "translation": "## 更多信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "FORMOREINFORMATIONSEECHUCKJAZDZEWSKISPRESENTATIONHTTPS:WWWYOUTUBECOMWATCHVEZ3R0GI4Z5AT368SONTHEANGULARLANGUAGESERVICEFROMNGCONFHTTPS:WWWNGCONFORG2017", "original": "For more information, see [Chuck Jazdzewski's presentation](https://www.youtube.com/watch?v=ez3R0Gi4z5A&t=368s) on the Angular Language \nService from [ng-conf](https://www.ng-conf.org/) 2017.", "translation": "要了解更多信息,参见 [ng-conf](https://www.ng-conf.org/) 2017 中 [Chuck Jazdzewski 的演讲](https://www.youtube.com/watch?v=ez3R0Gi4z5A&t=368s) 中讲解的 Angular 语言服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/language-service.md" }, { + "key": "#LAZYLOADINGFEATUREMODULES", "original": "# Lazy Loading Feature Modules", "translation": "# 惰性加载的特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWING:", "original": "A basic understanding of the following:", "translation": "对下列知识有基本的了解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "FEATUREMODULESGUIDEFEATUREMODULES", "original": "* [Feature Modules](guide/feature-modules).", - "translation": "[特性模块](guide/feature-modules).", + "translation": "[特性模块](guide/feature-modules)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "JAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", - "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule).", + "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "FREQUENTLYUSEDMODULESGUIDEFREQUENTNGMODULES", "original": "* [Frequently Used Modules](guide/frequent-ngmodules).", - "translation": "[常用模块](guide/frequent-ngmodules).", + "translation": "[常用模块](guide/frequent-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "TYPESOFFEATUREMODULESGUIDEMODULETYPES", "original": "* [Types of Feature Modules](guide/module-types).", - "translation": "[特性模块的分类](guide/module-types).", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "* [Routing and Navigation](guide/router).", - "translation": "[路由与导航](guide/router).", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "For the final sample app with two lazy loaded modules that this page describes, see the\n<live-example></live-example>.", - "translation": "如果需要本页描述的具有两个惰性加载模块的范例应用,参见<live-example></live-example>。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## High level view", - "translation": "## 高层视角", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "There are three main steps to setting up a lazy loaded feature module:", - "translation": "要想建立一个惰性加载的特性模块,有三个主要步骤:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "1. Create the feature module.", - "translation": "创建该特性模块。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "1. Create the feature module’s routing module.", - "translation": "创建该特性模块的路由模块。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "1. Configure the routes.", - "translation": "配置相关路由。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## Set up an app", - "translation": "## 建立应用", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "If you don’t already have an app, you can follow the steps below to\ncreate one with the CLI. If you do already have an app, skip to\n[Configure the routes](#config-routes). Enter the following command\nwhere `customer-app` is the name of your app:", - "translation": "如果你还没有应用,可以遵循下面的步骤使用 CLI 创建一个。如果已经有了,可以直接跳到 [配置路由](#config-routes)部分。\n输入下列命令,其中的 `customer-app` 表示你的应用名称:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "This creates an app called `customer-app` and the `--routing` flag\ngenerates a file called `app-routing.module.ts`, which is one of\nthe files you need for setting up lazy loading for your feature module.\nNavigate into the project by issuing the command `cd customer-app`.", - "translation": "这会创建一个名叫 `customer-app` 的应用,而 `--routing` 标识生成了一个名叫 `app-routing.module.ts` 的文件,它是你建立惰性加载的特性模块时所必须的。\n输入命令 `cd customer-app` 进入该项目。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## Create a feature module with routing", - "translation": "## 创建一个带路由的特性模块", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Next, you’ll need a feature module to route to. To make one, enter\nthe following command at the terminal window prompt where `customers` is the name of the module:", - "translation": "接下来,你需要一个要路由到的特性模块。要生成一个,请输入下列命令,其中的 `customers` 是该模块的名字:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "This creates a customers folder with two files inside; `CustomersModule`\nand `CustomersRoutingModule`. `CustomersModule` will act as the gatekeeper\nfor anything that concerns customers. `CustomersRoutingModule` will handle\nany customer-related routing. This keeps the app’s structure organized as\nthe app grows and allows you to reuse this module while easily keeping its routing intact.", - "translation": "这会创建一个 `customers` 目录,其中有两个文件:`CustomersModule` 和 `CustomersRoutingModule`。\n`CustomersModule` 扮演的是与客户紧密相关的所有事物的管理员。`CustomersRoutingModule` 则会处理任何与客户有关的路由。\n这样就可以在应用不断成长时保持应用的良好结构,并且当复用本模块时,你可以轻松的让其路由保持完好。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "The CLI imports the `CustomersRoutingModule` into the `CustomersModule` by\nadding a JavaScript import statement at the top of the file and adding\n`CustomersRoutingModule` to the `@NgModule` `imports` array.", - "translation": "CLI 会把 `CustomersRoutingModule` 自动导入到 `CustomersModule`。它会在文件的顶部添加一条 JavaScript 的 `import` 语句,并把 `CustomersRoutingModule` 添加到 `@NgModule` 的 `imports` 数组中。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## Add a component to the feature module", - "translation": "## 向特性模块中添加组件", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "In order to see the module being lazy loaded in the browser, create a component to render some HTML when the app loads `CustomersModule`. At the command line, enter the following:", - "translation": "要想在浏览器中看出该模块惰性加载成功了,就创建一个组件用来在应用加载 `CustomersModule` 之后渲染出一些 HTML。在命令行中输入如下命令:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "This creates a folder inside of `customers` called `customer-list`\nwith the four files that make up the component.", - "translation": "这会在 `customers` 目录中创建一个名叫 `customer-list` 的文件夹,其中包含该组件的四个文件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Just like with the routing module, the CLI imports the\n`CustomerListComponent` into the `CustomersModule`.", - "translation": "就像路由模块一样,CLI 也自动把 `CustomerListComponent` 导入了 `CustomersModule`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## Add another feature module", - "translation": "## 再添加一个特性模块", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "For another place to route to, create a second feature module with routing:", - "translation": "为了提供另一个可路由到的地点,再创建第二个带路由的特性模块:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "This makes a new folder called `orders` containing an `OrdersModule` and an `OrdersRoutingModule`.", - "translation": "这会创建一个名叫 `orders` 的新文件夹,其中包含 `OrdersModule` 和 `OrdersRoutingModule`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Now, just like with the `CustomersModule`, give it some content:", - "translation": "现在,像 `CustomersModule` 一样,给它添加一些内容:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## Set up the UI", - "translation": "## 建立 UI", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Though you can type the URL into the address bar, a nav\nis easier for the user and more common. Replace the default\nplaceholder markup in `app.component.html` with a custom nav\nso you can easily navigate to your modules in the browser:", - "translation": "虽然你也可以在地址栏中输入 URL,不过导航菜单会更好用,而且更常见。\n把 `app.component.html` 中的占位脚本替换成一个自定义的导航,以便你在浏览器中能轻松地在模块之间导航。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "To see your app in the browser so far, enter the following command in the terminal window:", - "translation": "要想在浏览器中看到你的应用,就在终端窗口中输入下列命令:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Then go to `localhost:4200` where you should see “app works!” and three buttons.", - "translation": "然后,跳转到 `localhost:4200`,这时你应该看到 “app works!” 和三个按钮。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "To make the buttons work, you need to configure the routing modules.", - "translation": "要想让这些按钮生效,你需要配置一下这些路由模块。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## Configure the routes", - "translation": "## 配置路由", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "The two feature modules, `OrdersModule` and `CustomersModule`, have to be\nwired up to the `AppRoutingModule` so the router knows about them. The structure is as follows:", - "translation": "这两个特性模块(`OrdersModule` 和 `CustomersModule`)应该挂接到 `AppRoutingModule` 中,来让路由器知道它们。其结构如下:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Each feature module acts as a doorway via the router. In the `AppRoutingModule`, you configure the routes to the feature modules, in this case `OrdersModule` and `CustomersModule`. This way, the router knows to go to the feature module. The feature module then connects the `AppRoutingModule` to the `CustomersRoutingModule` or the `OrdersRoutingModule`. Those routing modules tell the router where to go to load relevant components.", - "translation": "每个特性模块都是路由器中的一个“门口”。在 `AppRoutingModule` 中,你配置了一些路由指向这些特性模块(即 `OrderModule` 和 `CustomersModule`)。\n通过这种方式,路由器就知道了如何跳转到特性模块。然后,特性模块就把 `AppRoutingModule` 和 `CustomersRoutingModule` 或 `OrdersRoutingModule` 连接到一起。这些路由模块会告诉路由器该到哪里去加载相应的组件。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "### Routes at the app level", - "translation": "### 顶层的路由", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "In `AppRoutingModule`, update the `routes` array with the following:", - "translation": "在 `AppRoutingModule` 中,把 `routes` 数组修改成这样:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "The import statements stay the same. The first two paths are the routes to the `CustomersModule` and the `OrdersModule` respectively. Notice that the lazy loading syntax uses `loadChildren` followed by a string that is the path to the module, a hash mark or `#`, and the module’s class name.", - "translation": "这些 `import` 语句没有变化。前两个路径分别路由到了 `CustomersModule` 和 `OrdersModule`。注意看惰性加载的语法:`loadChildren` 后面紧跟着一个字符串,它指向模块路径,然后是一个 `#`,然后是该模块的类名。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "### Inside the feature module", - "translation": "### 特性模块内部", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Next, take a look at `customers.module.ts`. If you’re using the CLI and following the steps outlined in this page, you don’t have to do anything here. The feature module is like a connector between the `AppRoutingModule` and the feature routing module. The `AppRoutingModule` imports the feature module, `CustomersModule`, and `CustomersModule` in turn imports the `CustomersRoutingModule`.", - "translation": "接下来看看 `customers.module.ts`。如果你使用的是 CLI,并遵循本页面中给出的步骤,那么在这里你不必做任何事。\n特性模块就像是 `AppRoutingModule` 和该特性自己的路由模块之间的连接器。\n`AppRoutingModule` 导入了特性模块 `CustomersModule`,而 `CustomersModule` 又导入了 `CustomersRoutingModule`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "The `customers.module.ts` file imports the `CustomersRoutingModule` and `CustomerListComponent` so the `CustomersModule` class can have access to them. `CustomersRoutingModule` is then listed in the `@NgModule` `imports` array giving `CustomersModule` access to its own routing module, and `CustomerListComponent` is in the `declarations` array, which means `CustomerListComponent` belongs to the `CustomersModule`.", - "translation": "`customers.module.ts` 文件导入了 `CustomersRoutingModule` 和 `CustomerListComponent`,所以 `CustomersModule` 类可以访问它们。\n接着 `CustomersRoutingModule` 出现在了 `@NgModule` 的 `imports` 数组中,这让 `CustomersModule` 可以访问它的路由模块。而 `CustomerListComponent` 出现在了 `declarations` 数组中,这表示 `CustomerListComponent` 属于 `CustomersModule`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "### Configure the feature module’s routes", - "translation": "### 配置该特性模块的路由", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "The next step is in `customers-routing.module.ts`. First, import the component at the top of the file with the other JavaScript import statements. Then, add the route to `CustomerListComponent`.", - "translation": "接下来的步骤位于 `customers-routing.module.ts` 中。首先,在文件的顶部使用 JS 的 `import` 语句导入该组件。然后添加指向 `CustomerListComponent` 的路由。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Notice that the `path` is set to an empty string. This is because the path in `AppRoutingModule` is already set to `customers`, so this route in the `CustomersRoutingModule`, is already within the `customers` context. Every route in this routing module is a child route.", - "translation": "注意,`path` 被设置成了空字符串。这是因为 `AppRoutingModule` 中的路径已经设置为了 `customers`,所以 `CustomersRoutingModule` 中的这个路由定义已经位于 `customers` 这个上下文中了。也就是说这个路由模块中的每个路由其实都是子路由。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Repeat this last step of importing the `OrdersListComponent` and configuring the Routes array for the `orders-routing.module.ts`:", - "translation": "重复这个步骤以导入 `OrdersListComponent`,并为 `orders-routing.module.ts` 配置路由树组:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Now, if you view the app in the browser, the three buttons take you to each module.", - "translation": "现在,如果你在浏览器中查看该应用,这三个按钮会把你带到每个模块去。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## Confirm it’s working", - "translation": "## 确认它工作正常", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "You can check to see that a module is indeed being lazy loaded with the Chrome developer tools. In Chrome, open the dev tools by pressing `Cmd+Option+i` on a Mac or `Ctrl+Alt+i` on a PC and go to the Network Tab.", - "translation": "你可以使用 Chrome 开发者工具来确认一下这些模块真的是惰性加载的。\n在 Chrome 中,按 `Cmd+Option+i`(Mac)或 `Ctrl+Alt+i`(PC),并选中 `Network` 页标签。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Click on the Orders or Customers button. If you see a chunk appear, you’ve wired everything up properly and the feature module is being lazy loaded. A chunk should appear for Orders and for Customers but will only appear once for each.", - "translation": "点击 Orders 或 Customers 按钮。如果你看到某个 chunk 文件出现了,就表示你已经惰性加载并接入了这个特性模块。Orders 和 Customers 都应该出现一次 chunk,并且它们各自只应该出现一次。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "To see it again, or to test after working in the project, clear everything out by clicking the circle with a line through it in the upper left of the Network Tab:", - "translation": "要想再次查看它或测试本项目后面的行为,只要点击 Network 页左上放的“清除”图标即可。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "Then reload with `Cmd+r` or `Ctrl+r`, depending on your platform.", - "translation": "然后,使用 `Cmd+r`(Mac) 或 `Ctrl+r`(PC) 重新加载页面。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## `forRoot()` and `forChild()`", - "translation": "## `forRoot()` 与 `forChild()`", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "You might have noticed that the CLI adds `RouterModule.forRoot(routes)` to the `app-routing.module.ts` `imports` array. This lets Angular know that this module,\n`AppRoutingModule`, is a routing module and `forRoot()` specifies that this is the root\nrouting module. It configures all the\nroutes you pass to it, gives you access to the router directives, and registers the `RouterService`.\nUse `forRoot()` in the `AppRoutingModule`—that is, one time in the app at the root level.", - "translation": "你可能已经注意到了,CLI 会把 `RouterModule.forRoot(routes)` 添加到 `app-routing.module.ts` 的 `imports` 数组中。\n这会让 Angular 知道 `AppRoutingModule` 是一个路由模块,而 `forRoot()` 表示这是一个根路由模块。\n它会配置你传入的所有路由、让你能访问路由器指令并注册 `RouterService`。\n在 `AppRoutingModule` 中使用 `forRoot()`,在本应用中这只会在顶层模块中写一次。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "The CLI also adds `RouterModule.forChild(routes)` to feature routing modules. This way, Angular\nknows that the route list is only responsible for providing additional routes and is intended for feature modules. You can use `forChild()` in multiple modules.", - "translation": "CLI 还会把 `RouterModule.forChild(routes)` 添加到各个特性模块中。这种方式下 Angular 就会知道这个路由列表只负责提供额外的路由并且其设计意图是作为特性模块使用。你可以在多个模块中使用 `forChild()`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "`forRoot()` contains injector configuration which is global; such as configuring the Router. `forChild()` has no injector configuration, only directives such as `RouterOutlet` and `RouterLink`.", - "translation": "`forRoot()` 包含的注入器配置是全局性的,比如对路由器的配置。`forChild()` 中没有注入器配置,只有像 `RouterOutlet` 和 `RouterLink` 这样的指令。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "## More on NgModules and routing", - "translation": "## 更多关于 NgModule 和路由的知识", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" - }, - { - "original": "You may also be interested in the following:", - "translation": "你可能对下列内容感兴趣:", + "translation": "[特性模块的分类](guide/module-types)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "ROUTINGANDNAVIGATIONGUIDEROUTER", "original": "* [Routing and Navigation](guide/router).", "translation": "[路由与导航](guide/router)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "FORTHEFINALSAMPLEAPPWITHTWOLAZYLOADEDMODULESTHATTHISPAGEDESCRIBESSEETHELIVEEXAMPLELIVEEXAMPLE", + "original": "For the final sample app with two lazy loaded modules that this page describes, see the\n<live-example></live-example>.", + "translation": "如果需要本页描述的具有两个惰性加载模块的范例应用,参见<live-example></live-example>。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##HIGHLEVELVIEW", + "original": "## High level view", + "translation": "## 高层视角", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THEREARETHREEMAINSTEPSTOSETTINGUPALAZYLOADEDFEATUREMODULE:", + "original": "There are three main steps to setting up a lazy loaded feature module:", + "translation": "要想建立一个惰性加载的特性模块,有三个主要步骤:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "1CREATETHEFEATUREMODULE", + "original": "1. Create the feature module.", + "translation": "创建该特性模块。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "1CREATETHEFEATUREMODULESROUTINGMODULE", + "original": "1. Create the feature module’s routing module.", + "translation": "创建该特性模块的路由模块。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "1CONFIGURETHEROUTES", + "original": "1. Configure the routes.", + "translation": "配置相关路由。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##SETUPANAPP", + "original": "## Set up an app", + "translation": "## 建立应用", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "IFYOUDONTALREADYHAVEANAPPYOUCANFOLLOWTHESTEPSBELOWTOCREATEONEWITHTHECLIIFYOUDOALREADYHAVEANAPPSKIPTOCONFIGURETHEROUTES#CONFIGROUTESENTERTHEFOLLOWINGCOMMANDWHERECUSTOMERAPPISTHENAMEOFYOURAPP:", + "original": "If you don’t already have an app, you can follow the steps below to\ncreate one with the CLI. If you do already have an app, skip to\n[Configure the routes](#config-routes). Enter the following command\nwhere `customer-app` is the name of your app:", + "translation": "如果你还没有应用,可以遵循下面的步骤使用 CLI 创建一个。如果已经有了,可以直接跳到 [配置路由](#config-routes)部分。\n输入下列命令,其中的 `customer-app` 表示你的应用名称:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THISCREATESANAPPCALLEDCUSTOMERAPPANDTHEROUTINGFLAGGENERATESAFILECALLEDAPPROUTINGMODULETSWHICHISONEOFTHEFILESYOUNEEDFORSETTINGUPLAZYLOADINGFORYOURFEATUREMODULENAVIGATEINTOTHEPROJECTBYISSUINGTHECOMMANDCDCUSTOMERAPP", + "original": "This creates an app called `customer-app` and the `--routing` flag\ngenerates a file called `app-routing.module.ts`, which is one of\nthe files you need for setting up lazy loading for your feature module.\nNavigate into the project by issuing the command `cd customer-app`.", + "translation": "这会创建一个名叫 `customer-app` 的应用,而 `--routing` 标识生成了一个名叫 `app-routing.module.ts` 的文件,它是你建立惰性加载的特性模块时所必须的。\n输入命令 `cd customer-app` 进入该项目。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##CREATEAFEATUREMODULEWITHROUTING", + "original": "## Create a feature module with routing", + "translation": "## 创建一个带路由的特性模块", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "NEXTYOULLNEEDAFEATUREMODULETOROUTETOTOMAKEONEENTERTHEFOLLOWINGCOMMANDATTHETERMINALWINDOWPROMPTWHERECUSTOMERSISTHENAMEOFTHEMODULE:", + "original": "Next, you’ll need a feature module to route to. To make one, enter\nthe following command at the terminal window prompt where `customers` is the name of the module:", + "translation": "接下来,你需要一个要路由到的特性模块。要生成一个,请输入下列命令,其中的 `customers` 是该模块的名字:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THISCREATESACUSTOMERSFOLDERWITHTWOFILESINSIDECUSTOMERSMODULEANDCUSTOMERSROUTINGMODULECUSTOMERSMODULEWILLACTASTHEGATEKEEPERFORANYTHINGTHATCONCERNSCUSTOMERSCUSTOMERSROUTINGMODULEWILLHANDLEANYCUSTOMERRELATEDROUTINGTHISKEEPSTHEAPPSSTRUCTUREORGANIZEDASTHEAPPGROWSANDALLOWSYOUTOREUSETHISMODULEWHILEEASILYKEEPINGITSROUTINGINTACT", + "original": "This creates a customers folder with two files inside; `CustomersModule`\nand `CustomersRoutingModule`. `CustomersModule` will act as the gatekeeper\nfor anything that concerns customers. `CustomersRoutingModule` will handle\nany customer-related routing. This keeps the app’s structure organized as\nthe app grows and allows you to reuse this module while easily keeping its routing intact.", + "translation": "这会创建一个 `customers` 目录,其中有两个文件:`CustomersModule` 和 `CustomersRoutingModule`。\n`CustomersModule` 扮演的是与客户紧密相关的所有事物的管理员。`CustomersRoutingModule` 则会处理任何与客户有关的路由。\n这样就可以在应用不断成长时保持应用的良好结构,并且当复用本模块时,你可以轻松的让其路由保持完好。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THECLIIMPORTSTHECUSTOMERSROUTINGMODULEINTOTHECUSTOMERSMODULEBYADDINGAJAVASCRIPTIMPORTSTATEMENTATTHETOPOFTHEFILEANDADDINGCUSTOMERSROUTINGMODULETOTHENGMODULEIMPORTSARRAY", + "original": "The CLI imports the `CustomersRoutingModule` into the `CustomersModule` by\nadding a JavaScript import statement at the top of the file and adding\n`CustomersRoutingModule` to the `@NgModule` `imports` array.", + "translation": "CLI 会把 `CustomersRoutingModule` 自动导入到 `CustomersModule`。它会在文件的顶部添加一条 JavaScript 的 `import` 语句,并把 `CustomersRoutingModule` 添加到 `@NgModule` 的 `imports` 数组中。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##ADDACOMPONENTTOTHEFEATUREMODULE", + "original": "## Add a component to the feature module", + "translation": "## 向特性模块中添加组件", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "INORDERTOSEETHEMODULEBEINGLAZYLOADEDINTHEBROWSERCREATEACOMPONENTTORENDERSOMEHTMLWHENTHEAPPLOADSCUSTOMERSMODULEATTHECOMMANDLINEENTERTHEFOLLOWING:", + "original": "In order to see the module being lazy loaded in the browser, create a component to render some HTML when the app loads `CustomersModule`. At the command line, enter the following:", + "translation": "要想在浏览器中看出该模块惰性加载成功了,就创建一个组件用来在应用加载 `CustomersModule` 之后渲染出一些 HTML。在命令行中输入如下命令:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THISCREATESAFOLDERINSIDEOFCUSTOMERSCALLEDCUSTOMERLISTWITHTHEFOURFILESTHATMAKEUPTHECOMPONENT", + "original": "This creates a folder inside of `customers` called `customer-list`\nwith the four files that make up the component.", + "translation": "这会在 `customers` 目录中创建一个名叫 `customer-list` 的文件夹,其中包含该组件的四个文件。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "JUSTLIKEWITHTHEROUTINGMODULETHECLIIMPORTSTHECUSTOMERLISTCOMPONENTINTOTHECUSTOMERSMODULE", + "original": "Just like with the routing module, the CLI imports the\n`CustomerListComponent` into the `CustomersModule`.", + "translation": "就像路由模块一样,CLI 也自动把 `CustomerListComponent` 导入了 `CustomersModule`。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##ADDANOTHERFEATUREMODULE", + "original": "## Add another feature module", + "translation": "## 再添加一个特性模块", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "FORANOTHERPLACETOROUTETOCREATEASECONDFEATUREMODULEWITHROUTING:", + "original": "For another place to route to, create a second feature module with routing:", + "translation": "为了提供另一个可路由到的地点,再创建第二个带路由的特性模块:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THISMAKESANEWFOLDERCALLEDORDERSCONTAININGANORDERSMODULEANDANORDERSROUTINGMODULE", + "original": "This makes a new folder called `orders` containing an `OrdersModule` and an `OrdersRoutingModule`.", + "translation": "这会创建一个名叫 `orders` 的新文件夹,其中包含 `OrdersModule` 和 `OrdersRoutingModule`。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "NOWJUSTLIKEWITHTHECUSTOMERSMODULEGIVEITSOMECONTENT:", + "original": "Now, just like with the `CustomersModule`, give it some content:", + "translation": "现在,像 `CustomersModule` 一样,给它添加一些内容:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##SETUPTHEUI", + "original": "## Set up the UI", + "translation": "## 建立 UI", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THOUGHYOUCANTYPETHEURLINTOTHEADDRESSBARANAVISEASIERFORTHEUSERANDMORECOMMONREPLACETHEDEFAULTPLACEHOLDERMARKUPINAPPCOMPONENTHTMLWITHACUSTOMNAVSOYOUCANEASILYNAVIGATETOYOURMODULESINTHEBROWSER:", + "original": "Though you can type the URL into the address bar, a nav\nis easier for the user and more common. Replace the default\nplaceholder markup in `app.component.html` with a custom nav\nso you can easily navigate to your modules in the browser:", + "translation": "虽然你也可以在地址栏中输入 URL,不过导航菜单会更好用,而且更常见。\n把 `app.component.html` 中的占位脚本替换成一个自定义的导航,以便你在浏览器中能轻松地在模块之间导航。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "TOSEEYOURAPPINTHEBROWSERSOFARENTERTHEFOLLOWINGCOMMANDINTHETERMINALWINDOW:", + "original": "To see your app in the browser so far, enter the following command in the terminal window:", + "translation": "要想在浏览器中看到你的应用,就在终端窗口中输入下列命令:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THENGOTOLOCALHOST:4200WHEREYOUSHOULDSEEAPPWORKSANDTHREEBUTTONS", + "original": "Then go to `localhost:4200` where you should see “app works!” and three buttons.", + "translation": "然后,跳转到 `localhost:4200`,这时你应该看到 “app works!” 和三个按钮。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "TOMAKETHEBUTTONSWORKYOUNEEDTOCONFIGURETHEROUTINGMODULES", + "original": "To make the buttons work, you need to configure the routing modules.", + "translation": "要想让这些按钮生效,你需要配置一下这些路由模块。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##CONFIGURETHEROUTES", + "original": "## Configure the routes", + "translation": "## 配置路由", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THETWOFEATUREMODULESORDERSMODULEANDCUSTOMERSMODULEHAVETOBEWIREDUPTOTHEAPPROUTINGMODULESOTHEROUTERKNOWSABOUTTHEMTHESTRUCTUREISASFOLLOWS:", + "original": "The two feature modules, `OrdersModule` and `CustomersModule`, have to be\nwired up to the `AppRoutingModule` so the router knows about them. The structure is as follows:", + "translation": "这两个特性模块(`OrdersModule` 和 `CustomersModule`)应该挂接到 `AppRoutingModule` 中,来让路由器知道它们。其结构如下:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "EACHFEATUREMODULEACTSASADOORWAYVIATHEROUTERINTHEAPPROUTINGMODULEYOUCONFIGURETHEROUTESTOTHEFEATUREMODULESINTHISCASEORDERSMODULEANDCUSTOMERSMODULETHISWAYTHEROUTERKNOWSTOGOTOTHEFEATUREMODULETHEFEATUREMODULETHENCONNECTSTHEAPPROUTINGMODULETOTHECUSTOMERSROUTINGMODULEORTHEORDERSROUTINGMODULETHOSEROUTINGMODULESTELLTHEROUTERWHERETOGOTOLOADRELEVANTCOMPONENTS", + "original": "Each feature module acts as a doorway via the router. In the `AppRoutingModule`, you configure the routes to the feature modules, in this case `OrdersModule` and `CustomersModule`. This way, the router knows to go to the feature module. The feature module then connects the `AppRoutingModule` to the `CustomersRoutingModule` or the `OrdersRoutingModule`. Those routing modules tell the router where to go to load relevant components.", + "translation": "每个特性模块都是路由器中的一个“门口”。在 `AppRoutingModule` 中,你配置了一些路由指向这些特性模块(即 `OrderModule` 和 `CustomersModule`)。\n通过这种方式,路由器就知道了如何跳转到特性模块。然后,特性模块就把 `AppRoutingModule` 和 `CustomersRoutingModule` 或 `OrdersRoutingModule` 连接到一起。这些路由模块会告诉路由器该到哪里去加载相应的组件。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "###ROUTESATTHEAPPLEVEL", + "original": "### Routes at the app level", + "translation": "### 顶层的路由", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "INAPPROUTINGMODULEUPDATETHEROUTESARRAYWITHTHEFOLLOWING:", + "original": "In `AppRoutingModule`, update the `routes` array with the following:", + "translation": "在 `AppRoutingModule` 中,把 `routes` 数组修改成这样:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THEIMPORTSTATEMENTSSTAYTHESAMETHEFIRSTTWOPATHSARETHEROUTESTOTHECUSTOMERSMODULEANDTHEORDERSMODULERESPECTIVELYNOTICETHATTHELAZYLOADINGSYNTAXUSESLOADCHILDRENFOLLOWEDBYASTRINGTHATISTHEPATHTOTHEMODULEAHASHMARKOR#ANDTHEMODULESCLASSNAME", + "original": "The import statements stay the same. The first two paths are the routes to the `CustomersModule` and the `OrdersModule` respectively. Notice that the lazy loading syntax uses `loadChildren` followed by a string that is the path to the module, a hash mark or `#`, and the module’s class name.", + "translation": "这些 `import` 语句没有变化。前两个路径分别路由到了 `CustomersModule` 和 `OrdersModule`。注意看惰性加载的语法:`loadChildren` 后面紧跟着一个字符串,它指向模块路径,然后是一个 `#`,然后是该模块的类名。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "###INSIDETHEFEATUREMODULE", + "original": "### Inside the feature module", + "translation": "### 特性模块内部", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "NEXTTAKEALOOKATCUSTOMERSMODULETSIFYOUREUSINGTHECLIANDFOLLOWINGTHESTEPSOUTLINEDINTHISPAGEYOUDONTHAVETODOANYTHINGHERETHEFEATUREMODULEISLIKEACONNECTORBETWEENTHEAPPROUTINGMODULEANDTHEFEATUREROUTINGMODULETHEAPPROUTINGMODULEIMPORTSTHEFEATUREMODULECUSTOMERSMODULEANDCUSTOMERSMODULEINTURNIMPORTSTHECUSTOMERSROUTINGMODULE", + "original": "Next, take a look at `customers.module.ts`. If you’re using the CLI and following the steps outlined in this page, you don’t have to do anything here. The feature module is like a connector between the `AppRoutingModule` and the feature routing module. The `AppRoutingModule` imports the feature module, `CustomersModule`, and `CustomersModule` in turn imports the `CustomersRoutingModule`.", + "translation": "接下来看看 `customers.module.ts`。如果你使用的是 CLI,并遵循本页面中给出的步骤,那么在这里你不必做任何事。\n特性模块就像是 `AppRoutingModule` 和该特性自己的路由模块之间的连接器。\n`AppRoutingModule` 导入了特性模块 `CustomersModule`,而 `CustomersModule` 又导入了 `CustomersRoutingModule`。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THECUSTOMERSMODULETSFILEIMPORTSTHECUSTOMERSROUTINGMODULEANDCUSTOMERLISTCOMPONENTSOTHECUSTOMERSMODULECLASSCANHAVEACCESSTOTHEMCUSTOMERSROUTINGMODULEISTHENLISTEDINTHENGMODULEIMPORTSARRAYGIVINGCUSTOMERSMODULEACCESSTOITSOWNROUTINGMODULEANDCUSTOMERLISTCOMPONENTISINTHEDECLARATIONSARRAYWHICHMEANSCUSTOMERLISTCOMPONENTBELONGSTOTHECUSTOMERSMODULE", + "original": "The `customers.module.ts` file imports the `CustomersRoutingModule` and `CustomerListComponent` so the `CustomersModule` class can have access to them. `CustomersRoutingModule` is then listed in the `@NgModule` `imports` array giving `CustomersModule` access to its own routing module, and `CustomerListComponent` is in the `declarations` array, which means `CustomerListComponent` belongs to the `CustomersModule`.", + "translation": "`customers.module.ts` 文件导入了 `CustomersRoutingModule` 和 `CustomerListComponent`,所以 `CustomersModule` 类可以访问它们。\n接着 `CustomersRoutingModule` 出现在了 `@NgModule` 的 `imports` 数组中,这让 `CustomersModule` 可以访问它的路由模块。而 `CustomerListComponent` 出现在了 `declarations` 数组中,这表示 `CustomerListComponent` 属于 `CustomersModule`。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "###CONFIGURETHEFEATUREMODULESROUTES", + "original": "### Configure the feature module’s routes", + "translation": "### 配置该特性模块的路由", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THENEXTSTEPISINCUSTOMERSROUTINGMODULETSFIRSTIMPORTTHECOMPONENTATTHETOPOFTHEFILEWITHTHEOTHERJAVASCRIPTIMPORTSTATEMENTSTHENADDTHEROUTETOCUSTOMERLISTCOMPONENT", + "original": "The next step is in `customers-routing.module.ts`. First, import the component at the top of the file with the other JavaScript import statements. Then, add the route to `CustomerListComponent`.", + "translation": "接下来的步骤位于 `customers-routing.module.ts` 中。首先,在文件的顶部使用 JS 的 `import` 语句导入该组件。然后添加指向 `CustomerListComponent` 的路由。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "NOTICETHATTHEPATHISSETTOANEMPTYSTRINGTHISISBECAUSETHEPATHINAPPROUTINGMODULEISALREADYSETTOCUSTOMERSSOTHISROUTEINTHECUSTOMERSROUTINGMODULEISALREADYWITHINTHECUSTOMERSCONTEXTEVERYROUTEINTHISROUTINGMODULEISACHILDROUTE", + "original": "Notice that the `path` is set to an empty string. This is because the path in `AppRoutingModule` is already set to `customers`, so this route in the `CustomersRoutingModule`, is already within the `customers` context. Every route in this routing module is a child route.", + "translation": "注意,`path` 被设置成了空字符串。这是因为 `AppRoutingModule` 中的路径已经设置为了 `customers`,所以 `CustomersRoutingModule` 中的这个路由定义已经位于 `customers` 这个上下文中了。也就是说这个路由模块中的每个路由其实都是子路由。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "REPEATTHISLASTSTEPOFIMPORTINGTHEORDERSLISTCOMPONENTANDCONFIGURINGTHEROUTESARRAYFORTHEORDERSROUTINGMODULETS:", + "original": "Repeat this last step of importing the `OrdersListComponent` and configuring the Routes array for the `orders-routing.module.ts`:", + "translation": "重复这个步骤以导入 `OrdersListComponent`,并为 `orders-routing.module.ts` 配置路由树组:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "NOWIFYOUVIEWTHEAPPINTHEBROWSERTHETHREEBUTTONSTAKEYOUTOEACHMODULE", + "original": "Now, if you view the app in the browser, the three buttons take you to each module.", + "translation": "现在,如果你在浏览器中查看该应用,这三个按钮会把你带到每个模块去。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##CONFIRMITSWORKING", + "original": "## Confirm it’s working", + "translation": "## 确认它工作正常", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "YOUCANCHECKTOSEETHATAMODULEISINDEEDBEINGLAZYLOADEDWITHTHECHROMEDEVELOPERTOOLSINCHROMEOPENTHEDEVTOOLSBYPRESSINGCMDOPTIONIONAMACORCTRLALTIONAPCANDGOTOTHENETWORKTAB", + "original": "You can check to see that a module is indeed being lazy loaded with the Chrome developer tools. In Chrome, open the dev tools by pressing `Cmd+Option+i` on a Mac or `Ctrl+Alt+i` on a PC and go to the Network Tab.", + "translation": "你可以使用 Chrome 开发者工具来确认一下这些模块真的是惰性加载的。\n在 Chrome 中,按 `Cmd+Option+i`(Mac)或 `Ctrl+Alt+i`(PC),并选中 `Network` 页标签。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "CLICKONTHEORDERSORCUSTOMERSBUTTONIFYOUSEEACHUNKAPPEARYOUVEWIREDEVERYTHINGUPPROPERLYANDTHEFEATUREMODULEISBEINGLAZYLOADEDACHUNKSHOULDAPPEARFORORDERSANDFORCUSTOMERSBUTWILLONLYAPPEARONCEFOREACH", + "original": "Click on the Orders or Customers button. If you see a chunk appear, you’ve wired everything up properly and the feature module is being lazy loaded. A chunk should appear for Orders and for Customers but will only appear once for each.", + "translation": "点击 Orders 或 Customers 按钮。如果你看到某个 chunk 文件出现了,就表示你已经惰性加载并接入了这个特性模块。Orders 和 Customers 都应该出现一次 chunk,并且它们各自只应该出现一次。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "TOSEEITAGAINORTOTESTAFTERWORKINGINTHEPROJECTCLEAREVERYTHINGOUTBYCLICKINGTHECIRCLEWITHALINETHROUGHITINTHEUPPERLEFTOFTHENETWORKTAB:", + "original": "To see it again, or to test after working in the project, clear everything out by clicking the circle with a line through it in the upper left of the Network Tab:", + "translation": "要想再次查看它或测试本项目后面的行为,只要点击 Network 页左上放的“清除”图标即可。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THENRELOADWITHCMDRORCTRLRDEPENDINGONYOURPLATFORM", + "original": "Then reload with `Cmd+r` or `Ctrl+r`, depending on your platform.", + "translation": "然后,使用 `Cmd+r`(Mac) 或 `Ctrl+r`(PC) 重新加载页面。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##FORROOTANDFORCHILD", + "original": "## `forRoot()` and `forChild()`", + "translation": "## `forRoot()` 与 `forChild()`", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "YOUMIGHTHAVENOTICEDTHATTHECLIADDSROUTERMODULEFORROOTROUTESTOTHEAPPROUTINGMODULETSIMPORTSARRAYTHISLETSANGULARKNOWTHATTHISMODULEAPPROUTINGMODULEISAROUTINGMODULEANDFORROOTSPECIFIESTHATTHISISTHEROOTROUTINGMODULEITCONFIGURESALLTHEROUTESYOUPASSTOITGIVESYOUACCESSTOTHEROUTERDIRECTIVESANDREGISTERSTHEROUTERSERVICEUSEFORROOTINTHEAPPROUTINGMODULEMDASHTHATISONETIMEINTHEAPPATTHEROOTLEVEL", + "original": "You might have noticed that the CLI adds `RouterModule.forRoot(routes)` to the `app-routing.module.ts` `imports` array. This lets Angular know that this module,\n`AppRoutingModule`, is a routing module and `forRoot()` specifies that this is the root\nrouting module. It configures all the\nroutes you pass to it, gives you access to the router directives, and registers the `RouterService`.\nUse `forRoot()` in the `AppRoutingModule`—that is, one time in the app at the root level.", + "translation": "你可能已经注意到了,CLI 会把 `RouterModule.forRoot(routes)` 添加到 `app-routing.module.ts` 的 `imports` 数组中。\n这会让 Angular 知道 `AppRoutingModule` 是一个路由模块,而 `forRoot()` 表示这是一个根路由模块。\n它会配置你传入的所有路由、让你能访问路由器指令并注册 `RouterService`。\n在 `AppRoutingModule` 中使用 `forRoot()`,在本应用中这只会在顶层模块中写一次。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "THECLIALSOADDSROUTERMODULEFORCHILDROUTESTOFEATUREROUTINGMODULESTHISWAYANGULARKNOWSTHATTHEROUTELISTISONLYRESPONSIBLEFORPROVIDINGADDITIONALROUTESANDISINTENDEDFORFEATUREMODULESYOUCANUSEFORCHILDINMULTIPLEMODULES", + "original": "The CLI also adds `RouterModule.forChild(routes)` to feature routing modules. This way, Angular\nknows that the route list is only responsible for providing additional routes and is intended for feature modules. You can use `forChild()` in multiple modules.", + "translation": "CLI 还会把 `RouterModule.forChild(routes)` 添加到各个特性模块中。这种方式下 Angular 就会知道这个路由列表只负责提供额外的路由并且其设计意图是作为特性模块使用。你可以在多个模块中使用 `forChild()`。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "FORROOTCONTAINSINJECTORCONFIGURATIONWHICHISGLOBALSUCHASCONFIGURINGTHEROUTERFORCHILDHASNOINJECTORCONFIGURATIONONLYDIRECTIVESSUCHASROUTEROUTLETANDROUTERLINK", + "original": "`forRoot()` contains injector configuration which is global; such as configuring the Router. `forChild()` has no injector configuration, only directives such as `RouterOutlet` and `RouterLink`.", + "translation": "`forRoot()` 包含的注入器配置是全局性的,比如对路由器的配置。`forChild()` 中没有注入器配置,只有像 `RouterOutlet` 和 `RouterLink` 这样的指令。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "##MOREONNGMODULESANDROUTING", + "original": "## More on NgModules and routing", + "translation": "## 更多关于 NgModule 和路由的知识", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", + "original": "You may also be interested in the following:", + "translation": "你可能还对下列内容感兴趣:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "ROUTINGANDNAVIGATIONGUIDEROUTER", + "original": "* [Routing and Navigation](guide/router).", + "translation": "[路由与导航](guide/router)。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" + }, + { + "key": "PROVIDERSGUIDEPROVIDERS", "original": "* [Providers](guide/providers).", "translation": "[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "TYPESOFFEATUREMODULESGUIDEMODULETYPES", "original": "* [Types of Feature Modules](guide/module-types).", "translation": "[特性模块的分类](guide/module-types)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lazy-loading-ngmodules.md" }, { + "key": "#LIFECYCLEHOOKS", "original": "# Lifecycle Hooks", "translation": "# 生命周期钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ACOMPONENTHASALIFECYCLEMANAGEDBYANGULAR", "original": "A component has a lifecycle managed by Angular.", "translation": "每个组件都有一个被 Angular 管理的生命周期。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANGULARCREATESITRENDERSITCREATESANDRENDERSITSCHILDRENCHECKSITWHENITSDATABOUNDPROPERTIESCHANGEANDDESTROYSITBEFOREREMOVINGITFROMTHEDOM", "original": "Angular creates it, renders it, creates and renders its children,\nchecks it when its data-bound properties change, and destroys it before removing it from the DOM.", "translation": "Angular 创建它,渲染它,创建并渲染它的子组件,在它被绑定的属性发生变化时检查它,并在它从 DOM 中被移除前销毁它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANGULAROFFERSLIFECYCLEHOOKSTHATPROVIDEVISIBILITYINTOTHESEKEYLIFEMOMENTSANDTHEABILITYTOACTWHENTHEYOCCUR", "original": "Angular offers **lifecycle hooks**\nthat provide visibility into these key life moments and the ability to act when they occur.", "translation": "Angular 提供了**生命周期钩子**,把这些关键生命时刻暴露出来,赋予你在它们发生时采取行动的能力。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ADIRECTIVEHASTHESAMESETOFLIFECYCLEHOOKS", "original": "A directive has the same set of lifecycle hooks.", "translation": "除了那些组件内容和视图相关的钩子外,指令有相同生命周期钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##COMPONENTLIFECYCLEHOOKSOVERVIEW", "original": "## Component lifecycle hooks overview", "translation": "## 组件生命周期钩子概览", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "DIRECTIVEANDCOMPONENTINSTANCESHAVEALIFECYCLEASANGULARCREATESUPDATESANDDESTROYSTHEMDEVELOPERSCANTAPINTOKEYMOMENTSINTHATLIFECYCLEBYIMPLEMENTINGONEORMOREOFTHELIFECYCLEHOOKINTERFACESINTHEANGULARCORELIBRARY", "original": "Directive and component instances have a lifecycle\nas Angular creates, updates, and destroys them.\nDevelopers can tap into key moments in that lifecycle by implementing\none or more of the *lifecycle hook* interfaces in the Angular `core` library.", "translation": "指令和组件的实例有一个生命周期:新建、更新和销毁。\n通过实现一个或多个 Angular `core` 库里定义的*生命周期钩子*接口,开发者可以介入该生命周期中的这些关键时刻。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "EACHINTERFACEHASASINGLEHOOKMETHODWHOSENAMEISTHEINTERFACENAMEPREFIXEDWITHNGFOREXAMPLETHEONINITINTERFACEHASAHOOKMETHODNAMEDNGONINITTHATANGULARCALLSSHORTLYAFTERCREATINGTHECOMPONENT:", "original": "Each interface has a single hook method whose name is the interface name prefixed with `ng`.\nFor example, the `OnInit` interface has a hook method named `ngOnInit()`\nthat Angular calls shortly after creating the component:", "translation": "每个接口都有唯一的一个钩子方法,它们的名字是由接口名再加上 `ng` 前缀构成的。比如,`OnInit` 接口的钩子方法叫做 `ngOnInit`,\nAngular 在创建组件后立刻调用它,:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "NODIRECTIVEORCOMPONENTWILLIMPLEMENTALLOFTHELIFECYCLEHOOKSANGULARONLYCALLSADIRECTIVECOMPONENTHOOKMETHODIFITISDEFINED", "original": "No directive or component will implement all of the lifecycle hooks.\nAngular only calls a directive/component hook method *if it is defined*.", "translation": "没有指令或者组件会实现所有这些接口,并且有些钩子只对组件有意义。只有在指令/组件中*定义过的*那些钩子方法才会被 Angular 调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##LIFECYCLESEQUENCE", "original": "## Lifecycle sequence", "translation": "## 生命周期的顺序", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "AFTERCREATINGACOMPONENTDIRECTIVEBYCALLINGITSCONSTRUCTORANGULARCALLSTHELIFECYCLEHOOKMETHODSINTHEFOLLOWINGSEQUENCEATSPECIFICMOMENTS:", "original": "*After* creating a component/directive by calling its constructor, Angular\ncalls the lifecycle hook methods in the following sequence at specific moments:", "translation": "当 Angular 使用构造函数新建一个组件或指令后,就会按下面的顺序在特定时刻调用这些生命周期钩子方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "HOOK", "original": "Hook", "translation": "钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "PURPOSEANDTIMING", "original": "Purpose and Timing", "translation": "用途及时机", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "RESPONDWHENANGULARRESETSDATABOUNDINPUTPROPERTIESTHEMETHODRECEIVESASIMPLECHANGESOBJECTOFCURRENTANDPREVIOUSPROPERTYVALUES", "original": "Respond when Angular (re)sets data-bound input properties.\n The method receives a `SimpleChanges` object of current and previous property values.", "translation": "当 Angular(重新)设置数据绑定输入属性时响应。\n 该方法接受当前和上一属性值的 `SimpleChanges` 对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CALLEDBEFORENGONINITANDWHENEVERONEORMOREDATABOUNDINPUTPROPERTIESCHANGE", "original": "Called before `ngOnInit()` and whenever one or more data-bound input properties change.", "translation": "当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在 `ngOnInit()` 之前。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "INITIALIZETHEDIRECTIVECOMPONENTAFTERANGULARFIRSTDISPLAYSTHEDATABOUNDPROPERTIESANDSETSTHEDIRECTIVECOMPONENTSINPUTPROPERTIES", "original": "Initialize the directive/component after Angular first displays the data-bound properties\n and sets the directive/component's input properties.", "translation": "在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CALLEDONCEAFTERTHEFIRSTNGONCHANGES", "original": "Called _once_, after the _first_ `ngOnChanges()`.", "translation": "在第一轮 `ngOnChanges()` 完成之后调用,只调用**一次**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "DETECTANDACTUPONCHANGESTHATANGULARCANTORWONTDETECTONITSOWN", "original": "Detect and act upon changes that Angular can't or won't detect on its own.", "translation": "检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CALLEDDURINGEVERYCHANGEDETECTIONRUNIMMEDIATELYAFTERNGONCHANGESANDNGONINIT", "original": "Called during every change detection run, immediately after `ngOnChanges()` and `ngOnInit()`.", "translation": "在每个 Angular 变更检测周期中调用,`ngOnChanges()` 和 `ngOnInit()` 之后。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "RESPONDAFTERANGULARPROJECTSEXTERNALCONTENTINTOTHECOMPONENTSVIEWTHEVIEWTHATADIRECTIVEISIN", "original": "Respond after Angular projects external content into the component's view / the view that a directive is in.", "translation": "当把内容投影进组件之后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CALLEDONCEAFTERTHEFIRSTNGDOCHECK", "original": "Called _once_ after the first `ngDoCheck()`.", "translation": "第一次 `ngDoCheck()` 之后调用,只调用一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "RESPONDAFTERANGULARCHECKSTHECONTENTPROJECTEDINTOTHEDIRECTIVECOMPONENT", "original": "Respond after Angular checks the content projected into the directive/component.", "translation": "每次完成被投影组件内容的变更检测之后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CALLEDAFTERTHENGAFTERCONTENTINITANDEVERYSUBSEQUENTNGDOCHECK", "original": "Called after the `ngAfterContentInit()` and every subsequent `ngDoCheck()`.", "translation": "`ngAfterContentInit()` 和每次 `ngDoCheck()` 之后调用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "RESPONDAFTERANGULARINITIALIZESTHECOMPONENTSVIEWSANDCHILDVIEWSTHEVIEWTHATADIRECTIVEISIN", "original": "Respond after Angular initializes the component's views and child views / the view that a directive is in.", "translation": "初始化完组件视图及其子视图之后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CALLEDONCEAFTERTHEFIRSTNGAFTERCONTENTCHECKED", "original": "Called _once_ after the first `ngAfterContentChecked()`.", "translation": "第一次 `ngAfterContentChecked()` 之后调用,只调用一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "RESPONDAFTERANGULARCHECKSTHECOMPONENTSVIEWSANDCHILDVIEWSTHEVIEWTHATADIRECTIVEISIN", "original": "Respond after Angular checks the component's views and child views / the view that a directive is in.", "translation": "每次做完组件视图和子视图的变更检测之后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CALLEDAFTERTHENGAFTERVIEWINITANDEVERYSUBSEQUENTNGAFTERCONTENTCHECKED", "original": "Called after the `ngAfterViewInit` and every subsequent `ngAfterContentChecked()`.", "translation": "`ngAfterViewInit()` 和每次 `ngAfterContentChecked()` 之后调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CLEANUPJUSTBEFOREANGULARDESTROYSTHEDIRECTIVECOMPONENTUNSUBSCRIBEOBSERVABLESANDDETACHEVENTHANDLERSTOAVOIDMEMORYLEAKS", "original": "Cleanup just before Angular destroys the directive/component.\n Unsubscribe Observables and detach event handlers to avoid memory leaks.", "translation": "当 Angular 每次销毁指令/组件之前调用并清扫。\n 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CALLEDJUSTBEFOREANGULARDESTROYSTHEDIRECTIVECOMPONENT", "original": "Called _just before_ Angular destroys the directive/component.", "translation": "在 Angular 销毁指令/组件之前调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##INTERFACESAREOPTIONALTECHNICALLY", "original": "## Interfaces are optional (technically)", "translation": "## 接口是可选的(严格来说)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEINTERFACESAREOPTIONALFORJAVASCRIPTANDTYPESCRIPTDEVELOPERSFROMAPURELYTECHNICALPERSPECTIVETHEJAVASCRIPTLANGUAGEDOESNTHAVEINTERFACESANGULARCANTSEETYPESCRIPTINTERFACESATRUNTIMEBECAUSETHEYDISAPPEARFROMTHETRANSPILEDJAVASCRIPT", "original": "The interfaces are optional for JavaScript and Typescript developers from a purely technical perspective.\nThe JavaScript language doesn't have interfaces.\nAngular can't see TypeScript interfaces at runtime because they disappear from the transpiled JavaScript.", "translation": "从纯技术的角度讲,接口对 JavaScript 和 TypeScript 的开发者都是可选的。JavaScript 语言本身没有接口。\nAngular 在运行时看不到 TypeScript 接口,因为它们在编译为 JavaScript 的时候已经消失了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "FORTUNATELYTHEYARENTNECESSARYYOUDONTHAVETOADDTHELIFECYCLEHOOKINTERFACESTODIRECTIVESANDCOMPONENTSTOBENEFITFROMTHEHOOKSTHEMSELVES", "original": "Fortunately, they aren't necessary.\nYou don't have to add the lifecycle hook interfaces to directives and components to benefit from the hooks themselves.", "translation": "幸运的是,它们并不是必须的。\n你并不需要在指令和组件上添加生命周期钩子接口就能获得钩子带来的好处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANGULARINSTEADINSPECTSDIRECTIVEANDCOMPONENTCLASSESANDCALLSTHEHOOKMETHODSIFTHEYAREDEFINEDANGULARFINDSANDCALLSMETHODSLIKENGONINITWITHORWITHOUTTHEINTERFACES", "original": "Angular instead inspects directive and component classes and calls the hook methods *if they are defined*.\nAngular finds and calls methods like `ngOnInit()`, with or without the interfaces.", "translation": "Angular 会去检测这些指令和组件的类,一旦发现钩子方法被定义了,就调用它们。\nAngular 会找到并调用像 `ngOnInit()` 这样的钩子方法,有没有接口无所谓。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "NONETHELESSITSGOODPRACTICETOADDINTERFACESTOTYPESCRIPTDIRECTIVECLASSESINORDERTOBENEFITFROMSTRONGTYPINGANDEDITORTOOLING", "original": "Nonetheless, it's good practice to add interfaces to TypeScript directive classes\nin order to benefit from strong typing and editor tooling.", "translation": "虽然如此,在 TypeScript 指令类中添加接口是一项最佳实践,它可以获得强类型和 IDE 等编辑器带来的好处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##OTHERANGULARLIFECYCLEHOOKS", "original": "## Other Angular lifecycle hooks", "translation": "## 其它生命周期钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "OTHERANGULARSUBSYSTEMSMAYHAVETHEIROWNLIFECYCLEHOOKSAPARTFROMTHESECOMPONENTHOOKS", "original": "Other Angular sub-systems may have their own lifecycle hooks apart from these component hooks.", "translation": "Angular 的其它子系统除了有这些组件钩子外,还可能有它们自己的生命周期钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "3RDPARTYLIBRARIESMIGHTIMPLEMENTTHEIRHOOKSASWELLINORDERTOGIVEDEVELOPERSMORECONTROLOVERHOWTHESELIBRARIESAREUSED", "original": "3rd party libraries might implement their hooks as well in order to give developers more\ncontrol over how these libraries are used.", "translation": "第三方库也可能会实现它们自己的钩子,以便让这些开发者在使用时能做更多的控制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##LIFECYCLEEXAMPLES", "original": "## Lifecycle examples", "translation": "## 生命周期范例", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THELIVEEXAMPLELIVEEXAMPLEDEMONSTRATESTHELIFECYCLEHOOKSINACTIONTHROUGHASERIESOFEXERCISESPRESENTEDASCOMPONENTSUNDERTHECONTROLOFTHEROOTAPPCOMPONENT", "original": "The <live-example></live-example>\ndemonstrates the lifecycle hooks in action through a series of exercises\npresented as components under the control of the root `AppComponent`.", "translation": "<live-example></live-example>通过在受控于根组件 `AppComponent` 的一些组件上进行的一系列练习,演示了生命周期钩子的运作方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEYFOLLOWACOMMONPATTERN:APARENTCOMPONENTSERVESASATESTRIGFORACHILDCOMPONENTTHATILLUSTRATESONEORMOREOFTHELIFECYCLEHOOKMETHODS", "original": "They follow a common pattern: a *parent* component serves as a test rig for\na *child* component that illustrates one or more of the lifecycle hook methods.", "translation": "它们遵循了一个常用的模式:用*子组件*演示一个或多个生命周期钩子方法,而*父组件*被当作该*子组件*的测试台。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "HERESABRIEFDESCRIPTIONOFEACHEXERCISE:", "original": "Here's a brief description of each exercise:", "translation": "下面是每个练习简短的描述:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "COMPONENT", "original": "Component", "translation": "组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "DEMONSTRATESEVERYLIFECYCLEHOOKEACHHOOKMETHODWRITESTOTHEONSCREENLOG", "original": "Demonstrates every lifecycle hook.\n Each hook method writes to the on-screen log.", "translation": "展示每个生命周期钩子,每个钩子方法都会在屏幕上显示一条日志。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "DIRECTIVESHAVELIFECYCLEHOOKSTOOASPYDIRECTIVECANLOGWHENTHEELEMENTITSPIESUPONISCREATEDORDESTROYEDUSINGTHENGONINITANDNGONDESTROYHOOKS", "original": "Directives have lifecycle hooks too.\n A `SpyDirective` can log when the element it spies upon is\n created or destroyed using the `ngOnInit` and `ngOnDestroy` hooks.", "translation": "指令也同样有生命周期钩子。`SpyDirective` 可以利用 `ngOnInit` 和 `ngOnDestroy` 钩子在它所监视的每个元素被创建或销毁时输出日志。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THISEXAMPLEAPPLIESTHESPYDIRECTIVETOADIVINANNGFORHEROREPEATERMANAGEDBYTHEPARENTSPYCOMPONENT", "original": "This example applies the `SpyDirective` to a `<div>` in an `ngFor` *hero* repeater\n managed by the parent `SpyComponent`.", "translation": "本例把 `SpyDirective` 应用到父组件里的 `ngFor`*英雄*重复器(repeater)的 `<div>` 里面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "SEEHOWANGULARCALLSTHENGONCHANGESHOOKWITHACHANGESOBJECTEVERYTIMEONEOFTHECOMPONENTINPUTPROPERTIESCHANGESSHOWSHOWTOINTERPRETTHECHANGESOBJECT", "original": "See how Angular calls the `ngOnChanges()` hook with a `changes` object\n every time one of the component input properties changes.\n Shows how to interpret the `changes` object.", "translation": "这里将会看到:每当组件的输入属性发生变化时,Angular 会如何以 `changes` 对象作为参数去调用 `ngOnChanges()` 钩子。\n 展示了该如何理解和使用 `changes` 对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "IMPLEMENTSANNGDOCHECKMETHODWITHCUSTOMCHANGEDETECTIONSEEHOWOFTENANGULARCALLSTHISHOOKANDWATCHITPOSTCHANGESTOALOG", "original": "Implements an `ngDoCheck()` method with custom change detection.\n See how often Angular calls this hook and watch it post changes to a log.", "translation": "实现了一个 `ngDoCheck()` 方法,通过它可以自定义变更检测逻辑。\n 这里将会看到:Angular 会用什么频度调用这个钩子,监视它的变化,并把这些变化输出成一条日志。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "SHOWSWHATANGULARMEANSBYAVIEWDEMONSTRATESTHENGAFTERVIEWINITANDNGAFTERVIEWCHECKEDHOOKS", "original": "Shows what Angular means by a *view*.\n Demonstrates the `ngAfterViewInit` and `ngAfterViewChecked` hooks.", "translation": "显示 Angular 中的*视图*所指的是什么。\n 演示了 `ngAfterViewInit` 和 `ngAfterViewChecked` 钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "SHOWSHOWTOPROJECTEXTERNALCONTENTINTOACOMPONENTANDHOWTODISTINGUISHPROJECTEDCONTENTFROMACOMPONENTSVIEWCHILDRENDEMONSTRATESTHENGAFTERCONTENTINITANDNGAFTERCONTENTCHECKEDHOOKS", "original": "Shows how to project external content into a component and\n how to distinguish projected content from a component's view children.\n Demonstrates the `ngAfterContentInit` and `ngAfterContentChecked` hooks.", "translation": "展示如何把外部内容投影进组件中,以及如何区分“投影进来的内容”和“组件的子视图”。\n 演示了 `ngAfterContentInit` 和 `ngAfterContentChecked` 钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "COUNTER", "original": "Counter", "translation": "计数器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "DEMONSTRATESACOMBINATIONOFACOMPONENTANDADIRECTIVEEACHWITHITSOWNHOOKS", "original": "Demonstrates a combination of a component and a directive\n each with its own hooks.", "translation": "演示了组件和指令的组合,它们各自有自己的钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "INTHISEXAMPLEACOUNTERCOMPONENTLOGSACHANGEVIANGONCHANGESEVERYTIMETHEPARENTCOMPONENTINCREMENTSITSINPUTCOUNTERPROPERTYMEANWHILETHESPYDIRECTIVEFROMTHEPREVIOUSEXAMPLEISAPPLIEDTOTHECOUNTERCOMPONENTLOGWHEREITWATCHESLOGENTRIESBEINGCREATEDANDDESTROYED", "original": "In this example, a `CounterComponent` logs a change (via `ngOnChanges`)\n every time the parent component increments its input counter property.\n Meanwhile, the `SpyDirective` from the previous example is applied\n to the `CounterComponent` log where it watches log entries being created and destroyed.", "translation": "在这个例子中,每当父组件递增它的输入属性 `counter` 时,`CounterComponent` 就会通过 `ngOnChanges` 记录一条变更。\n 同时,前一个例子中的 `SpyDirective` 被用于在 `CounterComponent` 上提供日志,它可以同时观察到日志的创建和销毁过程。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEREMAINDEROFTHISPAGEDISCUSSESSELECTEDEXERCISESINFURTHERDETAIL", "original": "The remainder of this page discusses selected exercises in further detail.", "translation": "本文剩下的部分将详细讨论这些练习。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##PEEKABOO:ALLHOOKS", "original": "## Peek-a-boo: all hooks", "translation": "## Peek-a-boo:全部钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEPEEKABOOCOMPONENTDEMONSTRATESALLOFTHEHOOKSINONECOMPONENT", "original": "The `PeekABooComponent` demonstrates all of the hooks in one component.", "translation": "`PeekABooComponent` 组件演示了组件中所有可能存在的钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "YOUWOULDRARELYIFEVERIMPLEMENTALLOFTHEINTERFACESLIKETHISTHEPEEKABOOEXISTSTOSHOWHOWANGULARCALLSTHEHOOKSINTHEEXPECTEDORDER", "original": "You would rarely, if ever, implement all of the interfaces like this.\nThe peek-a-boo exists to show how Angular calls the hooks in the expected order.", "translation": "你可能很少、或者永远不会像这里一样实现所有这些接口。\n之所以在 peek-a-boo 中这么做,是为了演示 Angular 是如何按照期望的顺序调用这些钩子的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THISSNAPSHOTREFLECTSTHESTATEOFTHELOGAFTERTHEUSERCLICKEDTHECREATEBUTTONANDTHENTHEDESTROYBUTTON", "original": "This snapshot reflects the state of the log after the user clicked the *Create...* button and then the *Destroy...* button.", "translation": "用户点击**Create...**按钮,然后点击**Destroy...**按钮后,日志的状态如下图所示:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THESEQUENCEOFLOGMESSAGESFOLLOWSTHEPRESCRIBEDHOOKCALLINGORDER:ONCHANGESONINITDOCHECKNBSP3XAFTERCONTENTINITAFTERCONTENTCHECKEDNBSP3XAFTERVIEWINITAFTERVIEWCHECKEDNBSP3XANDONDESTROY", "original": "The sequence of log messages follows the prescribed hook calling order:\n`OnChanges`, `OnInit`, `DoCheck` (3x), `AfterContentInit`, `AfterContentChecked` (3x),\n`AfterViewInit`, `AfterViewChecked` (3x), and `OnDestroy`.", "translation": "日志信息的日志和所规定的钩子调用顺序是一致的:\n`OnChanges`、`OnInit`、`DoCheck` (3x)、`AfterContentInit`、`AfterContentChecked` (3x)、\n`AfterViewInit`、`AfterViewChecked` (3x)和 `OnDestroy`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THECONSTRUCTORISNTANANGULARHOOKPERSETHELOGCONFIRMSTHATINPUTPROPERTIESTHENAMEPROPERTYINTHISCASEHAVENOASSIGNEDVALUESATCONSTRUCTION", "original": "The constructor isn't an Angular hook *per se*.\n The log confirms that input properties (the `name` property in this case) have no assigned values at construction.", "translation": "构造函数本质上不应该算作 Angular 的钩子。\n记录确认了在创建期间那些输入属性(这里是 `name` 属性)没有被赋值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "HADTHEUSERCLICKEDTHEUPDATEHEROBUTTONTHELOGWOULDSHOWANOTHERONCHANGESANDTWOMORETRIPLETSOFDOCHECKAFTERCONTENTCHECKEDANDAFTERVIEWCHECKEDCLEARLYTHESETHREEHOOKSFIREOFTENKEEPTHELOGICINTHESEHOOKSASLEANASPOSSIBLE", "original": "Had the user clicked the *Update Hero* button, the log would show another `OnChanges` and two more triplets of\n`DoCheck`, `AfterContentChecked` and `AfterViewChecked`.\nClearly these three hooks fire *often*. Keep the logic in these hooks as lean as possible!", "translation": "如果用户点击*Update Hero*按钮,就会看到另一个 `OnChanges` 和至少两组 `DoCheck`、`AfterContentChecked` 和 `AfterViewChecked` 钩子。\n显然,这三种钩子被触发了*很多次*,必须让这三种钩子里的逻辑尽可能的精简!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THENEXTEXAMPLESFOCUSONHOOKDETAILS", "original": "The next examples focus on hook details.", "translation": "下一个例子就聚焦于这些钩子的细节上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##SPYINGONINITANDONDESTROY", "original": "## Spying *OnInit* and *OnDestroy*", "translation": "## 窥探 *OnInit* 和 *OnDestroy*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "GOUNDERCOVERWITHTHESETWOSPYHOOKSTODISCOVERWHENANELEMENTISINITIALIZEDORDESTROYED", "original": "Go undercover with these two spy hooks to discover when an element is initialized or destroyed.", "translation": "潜入这两个 spy 钩子来发现一个元素是什么时候被初始化或者销毁的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THISISTHEPERFECTINFILTRATIONJOBFORADIRECTIVETHEHEROESWILLNEVERKNOWTHEYREBEINGWATCHED", "original": "This is the perfect infiltration job for a directive.\nThe heroes will never know they're being watched.", "translation": "指令是一种完美的渗透方式,这些英雄们永远不会知道该指令的存在。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "KIDDINGASIDEPAYATTENTIONTOTWOKEYPOINTS:", "original": "Kidding aside, pay attention to two key points:", "translation": "不开玩笑了,注意下面两个关键点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "1ANGULARCALLSHOOKMETHODSFORDIRECTIVESASWELLASCOMPONENTSBRBR", "original": "1. Angular calls hook methods for *directives* as well as components.<br><br>", "translation": "就像对组件一样,Angular 也会对*指令*调用这些钩子方法。<br><br>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "2ASPYDIRECTIVECANPROVIDEINSIGHTINTOADOMOBJECTTHATYOUCANNOTCHANGEDIRECTLYOBVIOUSLYYOUCANTTOUCHTHEIMPLEMENTATIONOFANATIVEDIVYOUCANTMODIFYATHIRDPARTYCOMPONENTEITHERBUTYOUCANWATCHBOTHWITHADIRECTIVE", "original": "2. A spy directive can provide insight into a DOM object that you cannot change directly.\n Obviously you can't touch the implementation of a native `<div>`.\n You can't modify a third party component either.\n But you can watch both with a directive.", "translation": "一个侦探(spy)指令可以让你在无法直接修改 DOM 对象实现代码的情况下,透视其内部细节。\n显然,你不能修改一个原生 `<div>` 元素的实现代码。\n你同样不能修改第三方组件。\n但你用一个指令就能监视它们了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THESNEAKYSPYDIRECTIVEISSIMPLECONSISTINGALMOSTENTIRELYOFNGONINITANDNGONDESTROYHOOKSTHATLOGMESSAGESTOTHEPARENTVIAANINJECTEDLOGGERSERVICE", "original": "The sneaky spy directive is simple, consisting almost entirely of `ngOnInit()` and `ngOnDestroy()` hooks\nthat log messages to the parent via an injected `LoggerService`.", "translation": "这个鬼鬼祟祟的侦探指令很简单,几乎完全由 `ngOnInit()` 和 `ngOnDestroy()` 钩子组成,它通过一个注入进来的 `LoggerService` 来把消息记录到父组件中去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "YOUCANAPPLYTHESPYTOANYNATIVEORCOMPONENTELEMENTANDITLLBEINITIALIZEDANDDESTROYEDATTHESAMETIMEASTHATELEMENTHEREITISATTACHEDTOTHEREPEATEDHERODIV:", "original": "You can apply the spy to any native or component element and it'll be initialized and destroyed\nat the same time as that element.\nHere it is attached to the repeated hero `<div>`:", "translation": "你可以把这个侦探指令写到任何原生元素或组件元素上,它将与所在的组件同时初始化和销毁。\n下面是把它附加到用来重复显示英雄数据的这个 `<div>` 上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "EACHSPYSBIRTHANDDEATHMARKSTHEBIRTHANDDEATHOFTHEATTACHEDHERODIVWITHANENTRYINTHEHOOKLOGASSEENHERE:", "original": "Each spy's birth and death marks the birth and death of the attached hero `<div>`\nwith an entry in the *Hook Log* as seen here:", "translation": "每个“侦探”的出生和死亡也同时标记出了存放英雄的那个 `<div>` 的出生和死亡。*钩子记录*中的结构是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ADDINGAHERORESULTSINANEWHERODIVTHESPYSNGONINITLOGSTHATEVENT", "original": "Adding a hero results in a new hero `<div>`. The spy's `ngOnInit()` logs that event.", "translation": "添加一个英雄就会产生一个新的英雄 `<div>`。侦探的 `ngOnInit()` 记录下了这个事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THERESETBUTTONCLEARSTHEHEROESLISTANGULARREMOVESALLHERODIVELEMENTSFROMTHEDOMANDDESTROYSTHEIRSPYDIRECTIVESATTHESAMETIMETHESPYSNGONDESTROYMETHODREPORTSITSLASTMOMENTS", "original": "The *Reset* button clears the `heroes` list.\nAngular removes all hero `<div>` elements from the DOM and destroys their spy directives at the same time.\nThe spy's `ngOnDestroy()` method reports its last moments.", "translation": "*Reset* 按钮清除了这个 `heroes` 列表。\nAngular 从 DOM 中移除了所有英雄的 div,并且同时销毁了附加在这些 div 上的侦探指令。\n侦探的 `ngOnDestroy()` 方法汇报了它自己的临终时刻。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THENGONINITANDNGONDESTROYMETHODSHAVEMOREVITALROLESTOPLAYINREALAPPLICATIONS", "original": "The `ngOnInit()` and `ngOnDestroy()` methods have more vital roles to play in real applications.", "translation": "在真实的应用程序中,`ngOnInit()` 和 `ngOnDestroy()` 方法扮演着更重要的角色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "###ONINIT", "original": "### _OnInit()_", "translation": "### _OnInit()钩子_", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "USENGONINITFORTWOMAINREASONS:", "original": "Use `ngOnInit()` for two main reasons:", "translation": "使用 `ngOnInit()` 有两个原因:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "1TOPERFORMCOMPLEXINITIALIZATIONSSHORTLYAFTERCONSTRUCTION", "original": "1. To perform complex initializations shortly after construction.", "translation": "在构造函数之后马上执行复杂的初始化逻辑", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "1TOSETUPTHECOMPONENTAFTERANGULARSETSTHEINPUTPROPERTIES", "original": "1. To set up the component after Angular sets the input properties.", "translation": "在 Angular 设置完输入属性之后,对该组件进行准备。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "EXPERIENCEDDEVELOPERSAGREETHATCOMPONENTSSHOULDBECHEAPANDSAFETOCONSTRUCT", "original": "Experienced developers agree that components should be cheap and safe to construct.", "translation": "有经验的开发者会认同组件的构建应该很便宜和安全。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "MISKOHEVERYANGULARTEAMLEADEXPLAINSWHYHTTP:MISKOHEVERYCOMCODEREVIEWERSGUIDEFLAWCONSTRUCTORDOESREALWORKYOUSHOULDAVOIDCOMPLEXCONSTRUCTORLOGIC", "original": "Misko Hevery, Angular team lead,\n [explains why](http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/)\n you should avoid complex constructor logic.", "translation": "Misko Hevery,Angular 项目的组长,在[这里解释](http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/)了你为什么应该避免复杂的构造函数逻辑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "DONTFETCHDATAINACOMPONENTCONSTRUCTORYOUSHOULDNTWORRYTHATANEWCOMPONENTWILLTRYTOCONTACTAREMOTESERVERWHENCREATEDUNDERTESTORBEFOREYOUDECIDETODISPLAYITCONSTRUCTORSSHOULDDONOMORETHANSETTHEINITIALLOCALVARIABLESTOSIMPLEVALUES", "original": "Don't fetch data in a component constructor.\nYou shouldn't worry that a new component will try to contact a remote server when\ncreated under test or before you decide to display it.\nConstructors should do no more than set the initial local variables to simple values.", "translation": "不要在组件的构造函数中获取数据?\n在测试环境下新建组件时或在你决定要显示它之前,不应该担心它会尝试联系远程服务器。\n构造函数中除了使用简单的值对局部变量进行初始化之外,什么都不应该做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANNGONINITISAGOODPLACEFORACOMPONENTTOFETCHITSINITIALDATATHETOUROFHEROESTUTORIALTUTORIALTOHPT4#ONINITGUIDESHOWSHOW", "original": "An `ngOnInit()` is a good place for a component to fetch its initial data. The\n[Tour of Heroes Tutorial](tutorial/toh-pt4#oninit) guide shows how.", "translation": "`ngOnInit()` 是组件获取初始数据的好地方。[指南](tutorial/toh-pt4#oninit)中讲解了如何这样做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "REMEMBERALSOTHATADIRECTIVESDATABOUNDINPUTPROPERTIESARENOTSETUNTILAFTERCONSTRUCTIONTHATSAPROBLEMIFYOUNEEDTOINITIALIZETHEDIRECTIVEBASEDONTHOSEPROPERTIESTHEYLLHAVEBEENSETWHENNGONINITRUNS", "original": "Remember also that a directive's data-bound input properties are not set until _after construction_.\nThat's a problem if you need to initialize the directive based on those properties.\nThey'll have been set when `ngOnInit()` runs.", "translation": "另外还要记住,在指令的*构造函数完成之前*,那些被绑定的输入属性还都没有值。\n如果你需要基于这些属性的值来初始化这个指令,这种情况就会出问题。\n而当 `ngOnInit()` 执行的时候,这些属性都已经被正确的赋值过了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THENGONCHANGESMETHODISYOURFIRSTOPPORTUNITYTOACCESSTHOSEPROPERTIESANGULARCALLSNGONCHANGESBEFORENGONINITANDMANYTIMESAFTERTHATITONLYCALLSNGONINITONCE", "original": "The `ngOnChanges()` method is your first opportunity to access those properties.\n Angular calls `ngOnChanges()` before `ngOnInit()` and many times after that.\n It only calls `ngOnInit()` once.", "translation": "`ngOnChanges()` 方法是你访问这些属性的第一次机会,Angular 会在 `ngOnInit()` 之前调用它。\n但是在那之后,Angular 还会调用 `ngOnChanges()` 很多次。而 `ngOnInit()` 只会被调用一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "YOUCANCOUNTONANGULARTOCALLTHENGONINITMETHODSOONAFTERCREATINGTHECOMPONENTTHATSWHERETHEHEAVYINITIALIZATIONLOGICBELONGS", "original": "You can count on Angular to call the `ngOnInit()` method _soon_ after creating the component.\nThat's where the heavy initialization logic belongs.", "translation": "你可以信任 Angular 会在创建组件后立刻调用 `ngOnInit()` 方法。\n 这里是放置复杂初始化逻辑的好地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "###ONDESTROY", "original": "### _OnDestroy()_", "translation": "### _OnDestroy()钩子_", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "PUTCLEANUPLOGICINNGONDESTROYTHELOGICTHATMUSTRUNBEFOREANGULARDESTROYSTHEDIRECTIVE", "original": "Put cleanup logic in `ngOnDestroy()`, the logic that *must* run before Angular destroys the directive.", "translation": "一些清理逻辑*必须*在 Angular 销毁指令之前运行,把它们放在 `ngOnDestroy()` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THISISTHETIMETONOTIFYANOTHERPARTOFTHEAPPLICATIONTHATTHECOMPONENTISGOINGAWAY", "original": "This is the time to notify another part of the application that the component is going away.", "translation": "这是在该组件消失之前,可用来通知应用程序中其它部分的最后一个时间点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THISISTHEPLACETOFREERESOURCESTHATWONTBEGARBAGECOLLECTEDAUTOMATICALLYUNSUBSCRIBEFROMOBSERVABLESANDDOMEVENTSSTOPINTERVALTIMERSUNREGISTERALLCALLBACKSTHATTHISDIRECTIVEREGISTEREDWITHGLOBALORAPPLICATIONSERVICESYOURISKMEMORYLEAKSIFYOUNEGLECTTODOSO", "original": "This is the place to free resources that won't be garbage collected automatically.\nUnsubscribe from Observables and DOM events. Stop interval timers.\nUnregister all callbacks that this directive registered with global or application services.\nYou risk memory leaks if you neglect to do so.", "translation": "这里是用来释放那些不会被垃圾收集器自动回收的各类资源的地方。\n取消那些对可观察对象和 DOM 事件的订阅。停止定时器。注销该指令曾注册到全局服务或应用级服务中的各种回调函数。\n如果不这么做,就会有导致内存泄露的风险。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##ONCHANGES", "original": "## _OnChanges()_", "translation": "## _OnChanges()_ 钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANGULARCALLSITSNGONCHANGESMETHODWHENEVERITDETECTSCHANGESTOINPUTPROPERTIESOFTHECOMPONENTORDIRECTIVETHISEXAMPLEMONITORSTHEONCHANGESHOOK", "original": "Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive).\nThis example monitors the `OnChanges` hook.", "translation": "一旦检测到该组件(或指令)的***输入属性***发生了变化,Angular 就会调用它的 `ngOnChanges()` 方法。\n本例监控 `OnChanges` 钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THENGONCHANGESMETHODTAKESANOBJECTTHATMAPSEACHCHANGEDPROPERTYNAMETOASIMPLECHANGEAPICORESIMPLECHANGEOBJECTHOLDINGTHECURRENTANDPREVIOUSPROPERTYVALUESTHISHOOKITERATESOVERTHECHANGEDPROPERTIESANDLOGSTHEM", "original": "The `ngOnChanges()` method takes an object that maps each changed property name to a\n[SimpleChange](api/core/SimpleChange) object holding the current and previous property values.\nThis hook iterates over the changed properties and logs them.", "translation": "`ngOnChanges()` 方法获取了一个对象,它把每个发生变化的属性名都映射到了一个[SimpleChange](api/core/SimpleChange)对象,\n该对象中有属性的当前值和前一个值。这个钩子会在这些发生了变化的属性上进行迭代,并记录它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEEXAMPLECOMPONENTONCHANGESCOMPONENTHASTWOINPUTPROPERTIES:HEROANDPOWER", "original": "The example component, `OnChangesComponent`, has two input properties: `hero` and `power`.", "translation": "这个例子中的 `OnChangesComponent` 组件有两个输入属性:`hero` 和 `power`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEHOSTONCHANGESPARENTCOMPONENTBINDSTOTHEMLIKETHIS:", "original": "The host `OnChangesParentComponent` binds to them like this:", "translation": "宿主 `OnChangesParentComponent` 绑定了它们,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "HERESTHESAMPLEINACTIONASTHEUSERMAKESCHANGES", "original": "Here's the sample in action as the user makes changes.", "translation": "下面是此例子中的当用户做出更改时的操作演示:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THELOGENTRIESAPPEARASTHESTRINGVALUEOFTHEPOWERPROPERTYCHANGESBUTTHENGONCHANGESDOESNOTCATCHCHANGESTOHERONAMETHATSSURPRISINGATFIRST", "original": "The log entries appear as the string value of the *power* property changes.\nBut the `ngOnChanges` does not catch changes to `hero.name`\nThat's surprising at first.", "translation": "当 *power* 属性的字符串值变化时,相应的日志就出现了。\n但是 `ngOnChanges` 并没有捕捉到 `hero.name` 的变化。\n这是第一个意外。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANGULARONLYCALLSTHEHOOKWHENTHEVALUEOFTHEINPUTPROPERTYCHANGESTHEVALUEOFTHEHEROPROPERTYISTHEREFERENCETOTHEHEROOBJECTANGULARDOESNTCARETHATTHEHEROSOWNNAMEPROPERTYCHANGEDTHEHEROOBJECTREFERENCEDIDNTCHANGESOFROMANGULARSPERSPECTIVETHEREISNOCHANGETOREPORT", "original": "Angular only calls the hook when the value of the input property changes.\nThe value of the `hero` property is the *reference to the hero object*.\nAngular doesn't care that the hero's own `name` property changed.\nThe hero object *reference* didn't change so, from Angular's perspective, there is no change to report!", "translation": "Angular 只会在输入属性的值变化时调用这个钩子。\n而 `hero` 属性的值是一个*到英雄对象的引用*。\nAngular 不会关注这个英雄对象的 `name` 属性的变化。\n这个英雄对象的*引用*没有发生变化,于是从 Angular 的视角看来,也就没有什么需要报告的变化了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##DOCHECK", "original": "## _DoCheck()_", "translation": "## _DoCheck()_ 钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "USETHEDOCHECKHOOKTODETECTANDACTUPONCHANGESTHATANGULARDOESNTCATCHONITSOWN", "original": "Use the `DoCheck` hook to detect and act upon changes that Angular doesn't catch on its own.", "translation": "使用 `DoCheck` 钩子来检测那些 Angular 自身无法捕获的变更并采取行动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "USETHISMETHODTODETECTACHANGETHATANGULAROVERLOOKED", "original": "Use this method to detect a change that Angular overlooked.", "translation": "用这个方法来检测那些被 Angular 忽略的更改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEDOCHECKSAMPLEEXTENDSTHEONCHANGESSAMPLEWITHTHEFOLLOWINGNGDOCHECKHOOK:", "original": "The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck()` hook:", "translation": "*DoCheck* 范例通过下面的 `ngDoCheck()` 实现扩展了 *OnChanges* 范例:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THISCODEINSPECTSCERTAINVALUESOFINTERESTCAPTURINGANDCOMPARINGTHEIRCURRENTSTATEAGAINSTPREVIOUSVALUESITWRITESASPECIALMESSAGETOTHELOGWHENTHEREARENOSUBSTANTIVECHANGESTOTHEHEROORTHEPOWERSOYOUCANSEEHOWOFTENDOCHECKISCALLEDTHERESULTSAREILLUMINATING:", "original": "This code inspects certain _values of interest_, capturing and comparing their current state against previous values.\nIt writes a special message to the log when there are no substantive changes to the `hero` or the `power`\nso you can see how often `DoCheck` is called. The results are illuminating:", "translation": "该代码检测一些**相关的值**,捕获当前值并与以前的值进行比较。\n当英雄或它的超能力发生了非实质性改变时,就会往日志中写一条特殊的消息。\n这样你可以看到 `DoCheck` 被调用的频率。结果非常显眼:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "WHILETHENGDOCHECKHOOKCANDETECTWHENTHEHEROSNAMEHASCHANGEDITHASAFRIGHTFULCOSTTHISHOOKISCALLEDWITHENORMOUSFREQUENCYMDASHAFTEREVERYCHANGEDETECTIONCYCLENOMATTERWHERETHECHANGEOCCURREDITSCALLEDOVERTWENTYTIMESINTHISEXAMPLEBEFORETHEUSERCANDOANYTHING", "original": "While the `ngDoCheck()` hook can detect when the hero's `name` has changed, it has a frightful cost.\nThis hook is called with enormous frequency—after _every_\nchange detection cycle no matter where the change occurred.\nIt's called over twenty times in this example before the user can do anything.", "translation": "虽然 `ngDoCheck()` 钩子可以可以监测到英雄的 `name` 什么时候发生了变化。但其开销很恐怖。\n这个 `ngDoCheck` 钩子被非常频繁的调用 —— 在*每次*变更检测周期之后,发生了变化的每个地方都会调它。\n在这个例子中,用户还没有做任何操作之前,它就被调用了超过二十次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "MOSTOFTHESEINITIALCHECKSARETRIGGEREDBYANGULARSFIRSTRENDERINGOFUNRELATEDDATAELSEWHEREONTHEPAGEMEREMOUSINGINTOANOTHERINPUTTRIGGERSACALLRELATIVELYFEWCALLSREVEALACTUALCHANGESTOPERTINENTDATACLEARLYOURIMPLEMENTATIONMUSTBEVERYLIGHTWEIGHTORTHEUSEREXPERIENCESUFFERS", "original": "Most of these initial checks are triggered by Angular's first rendering of *unrelated data elsewhere on the page*.\nMere mousing into another `<input>` triggers a call.\nRelatively few calls reveal actual changes to pertinent data.\nClearly our implementation must be very lightweight or the user experience suffers.", "translation": "大部分检查的第一次调用都是在 Angular 首次渲染该页面中*其它不相关数据*时触发的。\n仅仅把鼠标移到其它 `<input>` 中就会触发一次调用。\n只有相对较少的调用才是由于对相关数据的修改而触发的。\n显然,我们的实现必须非常轻量级,否则将损害用户体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##AFTERVIEW", "original": "## AfterView", "translation": "## AfterView 钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEAFTERVIEWSAMPLEEXPLORESTHEAFTERVIEWINITANDAFTERVIEWCHECKEDHOOKSTHATANGULARCALLSAFTERITCREATESACOMPONENTSCHILDVIEWS", "original": "The *AfterView* sample explores the `AfterViewInit()` and `AfterViewChecked()` hooks that Angular calls\n*after* it creates a component's child views.", "translation": "*AfterView* 例子展示了 `AfterViewInit()` 和 `AfterViewChecked()` 钩子,Angular 会在每次创建了组件的子视图后调用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "HERESACHILDVIEWTHATDISPLAYSAHEROSNAMEINANINPUT:", "original": "Here's a child view that displays a hero's name in an `<input>`:", "translation": "下面是一个子视图,它用来把英雄的名字显示在一个 `<input>` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEAFTERVIEWCOMPONENTDISPLAYSTHISCHILDVIEWWITHINITSTEMPLATE:", "original": "The `AfterViewComponent` displays this child view *within its template*:", "translation": "`AfterViewComponent` 把这个子视图显示*在它的模板中*:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEFOLLOWINGHOOKSTAKEACTIONBASEDONCHANGINGVALUESWITHINTHECHILDVIEWWHICHCANONLYBEREACHEDBYQUERYINGFORTHECHILDVIEWVIATHEPROPERTYDECORATEDWITHVIEWCHILDAPICOREVIEWCHILD", "original": "The following hooks take action based on changing values *within the child view*,\nwhich can only be reached by querying for the child view via the property decorated with\n[@ViewChild](api/core/ViewChild).", "translation": "下列钩子基于*子视图中*的每一次数据变更采取行动,它只能通过带[@ViewChild](api/core/ViewChild)装饰器的属性来访问子视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "###ABIDEBYTHEUNIDIRECTIONALDATAFLOWRULE", "original": "### Abide by the unidirectional data flow rule", "translation": "### 遵循单向数据流规则", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEDOSOMETHINGMETHODUPDATESTHESCREENWHENTHEHERONAMEEXCEEDS10CHARACTERS", "original": "The `doSomething()` method updates the screen when the hero name exceeds 10 characters.", "translation": "当英雄的名字超过 10 个字符时,`doSomething()` 方法就会更新屏幕。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "WHYDOESTHEDOSOMETHINGMETHODWAITATICKBEFOREUPDATINGCOMMENT", "original": "Why does the `doSomething()` method wait a tick before updating `comment`?", "translation": "为什么在更新 `comment` 属性之前,`doSomething()` 方法要等上一拍(tick)?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANGULARSUNIDIRECTIONALDATAFLOWRULEFORBIDSUPDATESTOTHEVIEWAFTERITHASBEENCOMPOSEDBOTHOFTHESEHOOKSFIREAFTERTHECOMPONENTSVIEWHASBEENCOMPOSED", "original": "Angular's unidirectional data flow rule forbids updates to the view *after* it has been composed.\nBoth of these hooks fire _after_ the component's view has been composed.", "translation": "Angular 的“单向数据流”规则禁止在一个视图已经被组合好*之后*再更新视图。\n而这两个钩子都是在组件的视图已经被组合好之后触发的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANGULARTHROWSANERRORIFTHEHOOKUPDATESTHECOMPONENTSDATABOUNDCOMMENTPROPERTYIMMEDIATELYTRYITTHELOGGERSERVICETICKTHENPOSTPONESTHELOGUPDATEFORONETURNOFTHEBROWSERSJAVASCRIPTCYCLEANDTHATSJUSTLONGENOUGH", "original": "Angular throws an error if the hook updates the component's data-bound `comment` property immediately (try it!).\nThe `LoggerService.tick_then()` postpones the log update\nfor one turn of the browser's JavaScript cycle and that's just long enough.", "translation": "如果立即更新组件中被绑定的 `comment` 属性,Angular 就会抛出一个错误(试试!)。\n`LoggerService.tick_then()` 方法延迟更新日志一个回合(浏览器 JavaScript 周期回合),这样就够了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "HERESAFTERVIEWINACTION:", "original": "Here's *AfterView* in action:", "translation": "这里是 *AfterView* 的操作演示:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "NOTICETHATANGULARFREQUENTLYCALLSAFTERVIEWCHECKEDOFTENWHENTHEREARENOCHANGESOFINTERESTWRITELEANHOOKMETHODSTOAVOIDPERFORMANCEPROBLEMS", "original": "Notice that Angular frequently calls `AfterViewChecked()`, often when there are no changes of interest.\nWrite lean hook methods to avoid performance problems.", "translation": "注意,Angular 会频繁的调用 `AfterViewChecked()`,甚至在并没有需要关注的更改时也会触发。\n所以务必把这个钩子方法写得尽可能精简,以免出现性能问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "##AFTERCONTENT", "original": "## AfterContent", "translation": "## AfterContent 钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEAFTERCONTENTSAMPLEEXPLORESTHEAFTERCONTENTINITANDAFTERCONTENTCHECKEDHOOKSTHATANGULARCALLSAFTERANGULARPROJECTSEXTERNALCONTENTINTOTHECOMPONENT", "original": "The *AfterContent* sample explores the `AfterContentInit()` and `AfterContentChecked()` hooks that Angular calls\n*after* Angular projects external content into the component.", "translation": "*AfterContent* 例子展示了 `AfterContentInit()` 和 `AfterContentChecked()` 钩子,Angular 会在外来内容被投影到组件中*之后*调用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "###CONTENTPROJECTION", "original": "### Content projection", "translation": "### 内容投影", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CONTENTPROJECTIONISAWAYTOIMPORTHTMLCONTENTFROMOUTSIDETHECOMPONENTANDINSERTTHATCONTENTINTOTHECOMPONENTSTEMPLATEINADESIGNATEDSPOT", "original": "*Content projection* is a way to import HTML content from outside the component and insert that content\ninto the component's template in a designated spot.", "translation": "*内容投影*是从组件外部导入 HTML 内容,并把它插入在组件模板中指定位置上的一种途径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "ANGULARJSDEVELOPERSKNOWTHISTECHNIQUEASTRANSCLUSION", "original": "AngularJS developers know this technique as *transclusion*.", "translation": "AngularJS 的开发者大概知道一项叫做 *transclusion* 的技术,对,这就是它的马甲。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "CONSIDERTHISVARIATIONONTHEPREVIOUSAFTERVIEWGUIDELIFECYCLEHOOKS#AFTERVIEWEXAMPLETHISTIMEINSTEADOFINCLUDINGTHECHILDVIEWWITHINTHETEMPLATEITIMPORTSTHECONTENTFROMTHEAFTERCONTENTCOMPONENTSPARENTHERESTHEPARENTSTEMPLATE:", "original": "Consider this variation on the [previous _AfterView_](guide/lifecycle-hooks#afterview) example.\nThis time, instead of including the child view within the template, it imports the content from\nthe `AfterContentComponent`'s parent. Here's the parent's template:", "translation": "对比[前一个](guide/lifecycle-hooks#afterview)例子考虑这个变化。\n这次不再通过模板来把子视图包含进来,而是改为从 `AfterContentComponent` 的父组件中导入它。下面是父组件的模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "NOTICETHATTHEMYCHILDTAGISTUCKEDBETWEENTHEAFTERCONTENTTAGSNEVERPUTCONTENTBETWEENACOMPONENTSELEMENTTAGSUNLESSYOUINTENDTOPROJECTTHATCONTENTINTOTHECOMPONENT", "original": "Notice that the `<my-child>` tag is tucked between the `<after-content>` tags.\nNever put content between a component's element tags *unless you intend to project that content\ninto the component*.", "translation": "注意,`<my-child>` 标签被包含在 `<after-content>` 标签中。\n永远不要在组件标签的内部放任何内容 —— *除非你想把这些内容投影进这个组件中*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "NOWLOOKATTHECOMPONENTSTEMPLATE:", "original": "Now look at the component's template:", "translation": "现在来看下 `<after-content>` 组件的模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THENGCONTENTTAGISAPLACEHOLDERFORTHEEXTERNALCONTENTITTELLSANGULARWHERETOINSERTTHATCONTENTINTHISCASETHEPROJECTEDCONTENTISTHEMYCHILDFROMTHEPARENT", "original": "The `<ng-content>` tag is a *placeholder* for the external content.\nIt tells Angular where to insert that content.\nIn this case, the projected content is the `<my-child>` from the parent.", "translation": "`<ng-content>` 标签是外来内容的*占位符*。\n它告诉 Angular 在哪里插入这些外来内容。\n在这里,被投影进去的内容就是来自父组件的 `<my-child>` 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THETELLTALESIGNSOFCONTENTPROJECTIONARETWOFOLD:", "original": "The telltale signs of *content projection* are twofold:", "translation": "下列迹象表明存在着*内容投影*:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "HTMLBETWEENCOMPONENTELEMENTTAGS", "original": "* HTML between component element tags.", "translation": "在组件的元素标签中有 HTML", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEPRESENCEOFNGCONTENTTAGSINTHECOMPONENTSTEMPLATE", "original": "* The presence of `<ng-content>` tags in the component's template.", "translation": "组件的模板中出现了 `<ng-content>` 标签", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "###AFTERCONTENTHOOKS", "original": "### AfterContent hooks", "translation": "### AfterContent 钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "AFTERCONTENTHOOKSARESIMILARTOTHEAFTERVIEWHOOKSTHEKEYDIFFERENCEISINTHECHILDCOMPONENT", "original": "*AfterContent* hooks are similar to the *AfterView* hooks.\nThe key difference is in the child component.", "translation": "*AfterContent* 钩子和 *AfterView* 相似。关键的不同点是子组件的类型不同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEAFTERVIEWHOOKSCONCERNVIEWCHILDRENTHECHILDCOMPONENTSWHOSEELEMENTTAGSAPPEARWITHINTHECOMPONENTSTEMPLATE", "original": "* The *AfterView* hooks concern `ViewChildren`, the child components whose element tags\nappear *within* the component's template.", "translation": "*AfterView* 钩子所关心的是 `ViewChildren`,这些子组件的元素标签会出现在该组件的模板*里面*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEAFTERCONTENTHOOKSCONCERNCONTENTCHILDRENTHECHILDCOMPONENTSTHATANGULARPROJECTEDINTOTHECOMPONENT", "original": "* The *AfterContent* hooks concern `ContentChildren`, the child components that Angular\nprojected into the component.", "translation": "*AfterContent* 钩子所关心的是 `ContentChildren`,这些子组件被 Angular 投影进该组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THEFOLLOWINGAFTERCONTENTHOOKSTAKEACTIONBASEDONCHANGINGVALUESINACONTENTCHILDWHICHCANONLYBEREACHEDBYQUERYINGFORTHEMVIATHEPROPERTYDECORATEDWITHCONTENTCHILDAPICORECONTENTCHILD", "original": "The following *AfterContent* hooks take action based on changing values in a *content child*,\nwhich can only be reached by querying for them via the property decorated with\n[@ContentChild](api/core/ContentChild).", "translation": "下列 *AfterContent* 钩子基于*子级内容*中值的变化而采取相应的行动,它只能通过带有[@ContentChild](api/core/ContentChild)装饰器的属性来查询到“子级内容”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "###NOUNIDIRECTIONALFLOWWORRIESWITHAFTERCONTENT", "original": "### No unidirectional flow worries with _AfterContent_", "translation": "### 使用 **AfterContent** 时,无需担心单向数据流规则", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "THISCOMPONENTSDOSOMETHINGMETHODUPDATESTHECOMPONENTSDATABOUNDCOMMENTPROPERTYIMMEDIATELYTHERESNONEEDTOWAITGUIDELIFECYCLEHOOKS#WAITATICK", "original": "This component's `doSomething()` method update's the component's data-bound `comment` property immediately.\nThere's no [need to wait](guide/lifecycle-hooks#wait-a-tick).", "translation": "该组件的 `doSomething()` 方法立即更新了组件被绑定的 `comment` 属性。\n它[不用等](guide/lifecycle-hooks#wait-a-tick)下一回合。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "RECALLTHATANGULARCALLSBOTHAFTERCONTENTHOOKSBEFORECALLINGEITHEROFTHEAFTERVIEWHOOKSANGULARCOMPLETESCOMPOSITIONOFTHEPROJECTEDCONTENTBEFOREFINISHINGTHECOMPOSITIONOFTHISCOMPONENTSVIEWTHEREISASMALLWINDOWBETWEENTHEAFTERCONTENTANDAFTERVIEWHOOKSTOMODIFYTHEHOSTVIEW", "original": "Recall that Angular calls both *AfterContent* hooks before calling either of the *AfterView* hooks.\nAngular completes composition of the projected content *before* finishing the composition of this component's view.\nThere is a small window between the `AfterContent...` and `AfterView...` hooks to modify the host view.", "translation": "回忆一下,Angular 在每次调用 *AfterView* 钩子之前也会同时调用 *AfterContent*。\nAngular 在完成当前组件的视图合成之前,就已经完成了被投影内容的合成。\n所以你仍然有机会去修改那个视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/lifecycle-hooks.md" }, { + "key": "#TYPESOFFEATUREMODULES", "original": "# Types of Feature Modules", "translation": "# 特性模块的分类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWINGCONCEPTS:", "original": "A basic understanding of the following concepts:", "translation": "对下列概念有基本的理解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "FEATUREMODULESGUIDEFEATUREMODULES", "original": "* [Feature Modules](guide/feature-modules).", - "translation": "[特性模块](guide/feature-modules)。", + "translation": "[特性模块](guide/feature-modules)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "JAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "FREQUENTLYUSEDMODULESGUIDEFREQUENTNGMODULES", "original": "* [Frequently Used Modules](guide/frequent-ngmodules).", "translation": "[常用模块](guide/frequent-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "THEREAREFIVEGENERALCATEGORIESOFFEATUREMODULESWHICHTENDTOFALLINTOTHEFOLLOWINGGROUPS:", "original": "There are five general categories of feature modules which\ntend to fall into the following groups:", "translation": "下面是特性模块的五个常用分类,包括五组:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DOMAINFEATUREMODULES", "original": "* Domain feature modules.", "translation": "领域特性模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTEDFEATUREMODULES", "original": "* Routed feature modules.", "translation": "带路由的特性模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTINGMODULES", "original": "* Routing modules.", "translation": "路由模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "SERVICEFEATUREMODULES", "original": "* Service feature modules.", "translation": "服务特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "WIDGETFEATUREMODULES", "original": "* Widget feature modules.", "translation": "可视部件特性模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "WHILETHEFOLLOWINGGUIDELINESDESCRIBETHEUSEOFEACHTYPEANDTHEIRTYPICALCHARACTERISTICSINREALWORLDAPPSYOUMAYSEEHYBRIDS", "original": "While the following guidelines describe the use of each type and their\ntypical characteristics, in real world apps, you may see hybrids.", "translation": "虽然下面的指南中描述了每种类型的使用及其典型特征,但在实际的应用中,你还可能看到它们的混合体。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "FEATUREMODULE", "original": "Feature Module", "translation": "特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "GUIDELINES", "original": "Guidelines", "translation": "指导原则", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DOMAIN", "original": "Domain", "translation": "领域", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DOMAINFEATUREMODULESDELIVERAUSEREXPERIENCEDEDICATEDTOAPARTICULARAPPLICATIONDOMAINLIKEEDITINGACUSTOMERORPLACINGANORDER", "original": "Domain feature modules deliver a user experience dedicated to a particular application domain like editing a customer or placing an order.", "translation": "领域特性模块用来给用户提供应用程序领域中特有的用户体验,比如编辑客户信息或下订单等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "THEYTYPICALLYHAVEATOPCOMPONENTTHATACTSASTHEFEATUREROOTANDPRIVATESUPPORTINGSUBCOMPONENTSDESCENDFROMIT", "original": "They typically have a top component that acts as the feature root and private, supporting sub-components descend from it.", "translation": "它们通常会有一个顶级组件来充当该特性的根组件,并且通常是私有的。用来支持它的各级子组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DOMAINFEATUREMODULESCONSISTMOSTLYOFDECLARATIONSONLYTHETOPCOMPONENTISEXPORTED", "original": "Domain feature modules consist mostly of declarations. Only the top component is exported.", "translation": "领域特性模块大部分由 `declarations` 组成,只有顶级组件会被导出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DOMAINFEATUREMODULESRARELYHAVEPROVIDERSWHENTHEYDOTHELIFETIMEOFTHEPROVIDEDSERVICESSHOULDBETHESAMEASTHELIFETIMEOFTHEMODULE", "original": "Domain feature modules rarely have providers. When they do, the lifetime of the provided services should be the same as the lifetime of the module.", "translation": "领域特性模块很少会有服务提供商。如果有,那么这些服务的生命周期必须和该模块的生命周期完全相同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DOMAINFEATUREMODULESARETYPICALLYIMPORTEDEXACTLYONCEBYALARGERFEATUREMODULE", "original": "Domain feature modules are typically imported exactly once by a larger feature module.", "translation": "领域特性模块通常会由更高一级的特性模块导出且只导出一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "THEYMIGHTBEIMPORTEDBYTHEROOTAPPMODULEOFASMALLAPPLICATIONTHATLACKSROUTING", "original": "They might be imported by the root `AppModule` of a small application that lacks routing.", "translation": "对于缺少路由的小型应用,它们可能只会被根模块 `AppModule` 导入一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTED", "original": "Routed", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTEDFEATUREMODULESAREDOMAINFEATUREMODULESWHOSETOPCOMPONENTSARETHETARGETSOFROUTERNAVIGATIONROUTES", "original": "Routed feature modules are domain feature modules whose top components are the targets of router navigation routes.", "translation": "带路由的特性模块是一种特殊的领域特性模块,但它的顶层组件会作为路由导航时的目标组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ALLLAZYLOADEDMODULESAREROUTEDFEATUREMODULESBYDEFINITION", "original": "All lazy-loaded modules are routed feature modules by definition.", "translation": "根据这个定义,所有惰性加载的模块都是路由特性模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTEDFEATUREMODULESDONTEXPORTANYTHINGBECAUSETHEIRCOMPONENTSNEVERAPPEARINTHETEMPLATEOFANEXTERNALCOMPONENT", "original": "Routed feature modules don’t export anything because their components never appear in the template of an external component.", "translation": "带路由的特性模块不会导出任何东西,因为它们的组件永远不会出现在外部组件的模板中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ALAZYLOADEDROUTEDFEATUREMODULESHOULDNOTBEIMPORTEDBYANYMODULEDOINGSOWOULDTRIGGERANEAGERLOADDEFEATINGTHEPURPOSEOFLAZYLOADINGTHATMEANSYOUWONTSEETHEMMENTIONEDAMONGTHEAPPMODULEIMPORTSANEAGERLOADEDROUTEDFEATUREMODULEMUSTBEIMPORTEDBYANOTHERMODULESOTHATTHECOMPILERLEARNSABOUTITSCOMPONENTS", "original": "A lazy-loaded routed feature module should not be imported by any module. Doing so would trigger an eager load, defeating the purpose of lazy loading.That means you won’t see them mentioned among the `AppModule` imports. An eager loaded routed feature module must be imported by another module so that the compiler learns about its components.", "translation": "惰性加载的路由特性模块不应该被任何模块导入。如果那样做就会导致它被立即加载,破坏了惰性加载的设计用途。\n 也就是说你应该永远不会看到它们在 `AppModule` 的 `imports` 中被引用。\n 立即加载的路由特性模块必须被其它模块导入,以便编译器能了解它所包含的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTEDFEATUREMODULESRARELYHAVEPROVIDERSFORREASONSEXPLAINEDINLAZYLOADINGFEATUREMODULESGUIDELAZYLOADINGNGMODULESWHENTHEYDOTHELIFETIMEOFTHEPROVIDEDSERVICESSHOULDBETHESAMEASTHELIFETIMEOFTHEMODULEDONTPROVIDEAPPLICATIONWIDESINGLETONSERVICESINAROUTEDFEATUREMODULEORINAMODULETHATTHEROUTEDMODULEIMPORTS", "original": "Routed feature modules rarely have providers for reasons explained in [Lazy Loading Feature Modules](/guide/lazy-loading-ngmodules). When they do, the lifetime of the provided services should be the same as the lifetime of the module. Don't provide application-wide singleton services in a routed feature module or in a module that the routed module imports.", "translation": "路由特性模块很少会有服务提供商,原因参见[惰性加载的特性模块](/guide/lazy-loading-ngmodules)中的解释。如果那样做,那么它所提供的服务的生命周期必须与该模块的生命周期完全相同。不要在路由特性模块或被路由特性模块所导入的模块中提供全应用级的单例服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTING", "original": "Routing", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "AROUTINGMODULEPROVIDESROUTINGCONFIGURATIONFORANOTHERMODULEANDSEPARATESROUTINGCONCERNSFROMITSCOMPANIONMODULE", "original": "A routing module provides routing configuration for another module and separates routing concerns from its companion module.", "translation": "路由模块为其它模块提供路由配置,并且把路由这个关注点从它的伴随模块中分离出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "AROUTINGMODULETYPICALLYDOESTHEFOLLOWING:", "original": "A routing module typically does the following:", "translation": "路由模块通常会做这些:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DEFINESROUTES", "original": "Defines routes.", "translation": "定义路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ADDSROUTERCONFIGURATIONTOTHEMODULESIMPORTS", "original": "Adds router configuration to the module's imports.", "translation": "把路由配置添加到该模块的 `imports` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ADDSGUARDANDRESOLVERSERVICEPROVIDERSTOTHEMODULESPROVIDERS", "original": "Adds guard and resolver service providers to the module's providers.", "translation": "把路由守卫和解析器的服务提供商添加到该模块的 `providers` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "THENAMEOFTHEROUTINGMODULESHOULDPARALLELTHENAMEOFITSCOMPANIONMODULEUSINGTHESUFFIXROUTINGFOREXAMPLECODEFOOMODULECODEINCODEFOOMODULETSCODEHASAROUTINGMODULENAMEDCODEFOOROUTINGMODULECODEINCODEFOOROUTINGMODULETSCODEIFTHECOMPANIONMODULEISTHEROOTCODEAPPMODULECODETHECODEAPPROUTINGMODULECODEADDSROUTERCONFIGURATIONTOITSIMPORTSWITHCODEROUTERMODULEFORROOTROUTESCODEALLOTHERROUTINGMODULESARECHILDRENTHATIMPORTCODEROUTERMODULEFORCHILDROUTESCODE", "original": "The name of the routing module should parallel the name of its companion module, using the suffix \"Routing\". For example, <code>FooModule</code> in <code>foo.module.ts</code> has a routing module named <code>FooRoutingModule</code> in <code>foo-routing.module.ts</code>. If the companion module is the root <code>AppModule</code>, the <code>AppRoutingModule</code> adds router configuration to its imports with <code>RouterModule.forRoot(routes)</code>. All other routing modules are children that import <code>RouterModule.forChild(routes)</code>.", "translation": "路由模块应该与其伴随模块同名,但是加上“Routing”后缀。比如,<code>foo.module.ts</code> 中的 <code>FooModule</code> 就有一个位于 <code>foo-routing.module.ts</code> 文件中的 <code>FooRoutingModule</code> 路由模块。\n 如果其伴随模块是根模块 `AppModule`,`AppRoutingModule` 就要使用 `RouterModule.forRoot(routes)` 来把路由器配置添加到它的 `imports` 中。\n 所有其它路由模块都是子模块,要使用 `RouterModule.forChild(routes)`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "AROUTINGMODULEREEXPORTSTHECODEROUTERMODULECODEASACONVENIENCESOTHATCOMPONENTSOFTHECOMPANIONMODULEHAVEACCESSTOROUTERDIRECTIVESSUCHASCODEROUTERLINKCODEANDCODEROUTEROUTLETCODE", "original": "A routing module re-exports the <code>RouterModule</code> as a convenience so that components of the companion module have access to router directives such as <code>RouterLink</code> and <code>RouterOutlet</code>.", "translation": "按照惯例,路由模块会重新导出这个 <code>RouterModule</code>,以便伴随模块中的组件可以访问路由器指令,比如 `RouterLink` 和 `RouterOutlet`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "AROUTINGMODULEDOESNOTHAVEITSOWNDECLARATIONSCOMPONENTSDIRECTIVESANDPIPESARETHERESPONSIBILITYOFTHEFEATUREMODULENOTTHEROUTINGMODULE", "original": "A routing module does not have its own declarations. Components, directives, and pipes are the responsibility of the feature module, not the routing module.", "translation": "路由模块没有自己的可声明对象。组件、指令和管道都是特性模块的职责,而不是路由模块的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "AROUTINGMODULESHOULDONLYBEIMPORTEDBYITSCOMPANIONMODULE", "original": "A routing module should only be imported by its companion module.", "translation": "路由模块应该只被它的伴随模块导入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "SERVICE", "original": "Service", "translation": "服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "SERVICEMODULESPROVIDEUTILITYSERVICESSUCHASDATAACCESSANDMESSAGINGIDEALLYTHEYCONSISTENTIRELYOFPROVIDERSANDHAVENODECLARATIONSANGULARSHTTPCLIENTMODULEISAGOODEXAMPLEOFASERVICEMODULE", "original": "Service modules provide utility services such as data access and messaging. Ideally, they consist entirely of providers and have no declarations. Angular's `HttpClientModule` is a good example of a service module.", "translation": "服务模块提供了一些工具服务,比如数据访问和消息。理论上,它们应该是完全由服务提供商组成的,不应该有可声明对象。Angular 的 `HttpClientModule` 就是一个服务模块的好例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "THEROOTAPPMODULEISTHEONLYMODULETHATSHOULDIMPORTSERVICEMODULES", "original": "The root `AppModule` is the only module that should import service modules.", "translation": "根模块 `AppModule` 是唯一的可以导入服务模块的模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "WIDGET", "original": "Widget", "translation": "窗口部件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "AWIDGETMODULEMAKESCOMPONENTSDIRECTIVESANDPIPESAVAILABLETOEXTERNALMODULESMANYTHIRDPARTYUICOMPONENTLIBRARIESAREWIDGETMODULES", "original": "A widget module makes components, directives, and pipes available to external modules. Many third-party UI component libraries are widget modules.", "translation": "窗口部件模块为外部模块提供组件、指令和管道。很多第三方 UI 组件库都是窗口部件模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "AWIDGETMODULESHOULDCONSISTENTIRELYOFDECLARATIONSMOSTOFTHEMEXPORTED", "original": "A widget module should consist entirely of declarations, most of them exported.", "translation": "窗口部件模块应该完全由可声明对象组成,它们中的大部分都应该被导出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "AWIDGETMODULESHOULDRARELYHAVEPROVIDERS", "original": "A widget module should rarely have providers.", "translation": "窗口部件模块很少会有服务提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "IMPORTWIDGETMODULESINANYMODULEWHOSECOMPONENTTEMPLATESNEEDTHEWIDGETS", "original": "Import widget modules in any module whose component templates need the widgets.", "translation": "如果任何模块的组件模板中需要用到这些窗口部件,就请导入相应的窗口部件模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "THEFOLLOWINGTABLESUMMARIZESTHEKEYCHARACTERISTICSOFEACHFEATUREMODULEGROUP", "original": "The following table summarizes the key characteristics of each feature module group.", "translation": "下表中汇总了各种特性模块类型的关键特征。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "FEATUREMODULE", "original": "Feature Module", "translation": "特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DECLARATIONS", "original": "Declarations", "translation": "声明 `declarations`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "PROVIDERS", "original": "Providers", "translation": "提供商 `providers`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "EXPORTS", "original": "Exports", "translation": "导出什么", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "IMPORTEDBY", "original": "Imported by", "translation": "被谁导入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "DOMAIN", "original": "Domain", "translation": "领域", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "YES", "original": "Yes", "translation": "有", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "RARE", "original": "Rare", "translation": "罕见", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "TOPCOMPONENT", "original": "Top component", "translation": "顶级组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "FEATUREAPPMODULE", "original": "Feature, AppModule", "translation": "特性模块,AppModule", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTED", "original": "Routed", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "YES", "original": "Yes", "translation": "有", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "RARE", "original": "Rare", "translation": "罕见", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "NO", "original": "No", "translation": "无", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "NONE", "original": "None", "translation": "无", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "ROUTING", "original": "Routing", "translation": "路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "NO", "original": "No", "translation": "无", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "YESGUARDS", "original": "Yes (Guards)", "translation": "是(守卫)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "FEATUREFORROUTING", "original": "Feature (for routing)", "translation": "特性(供路由使用)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "SERVICE", "original": "Service", "translation": "服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "NO", "original": "No", "translation": "无", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "YES", "original": "Yes", "translation": "有", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "NO", "original": "No", "translation": "无", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "WIDGET", "original": "Widget", "translation": "窗口部件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "YES", "original": "Yes", "translation": "有", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "RARE", "original": "Rare", "translation": "罕见", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "YES", "original": "Yes", "translation": "有", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "FEATURE", "original": "Feature", "translation": "特性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "LAZYLOADINGMODULESWITHTHEANGULARROUTERGUIDELAZYLOADINGNGMODULES", "original": "* [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules).", "translation": "[使用 Angular 路由器惰性加载模块](guide/lazy-loading-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "PROVIDERSGUIDEPROVIDERS", "original": "* [Providers](guide/providers).", "translation": "[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/module-types.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWINGCONCEPTS:", "original": "A basic understanding of the following concepts:", "translation": "对下列概念有基本的理解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "BOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "* [Bootstrapping](guide/bootstrapping).", - "translation": "[引导](guide/bootstrapping)。", + "translation": "[引导启动](guide/bootstrapping)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "JAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "##PURPOSEOFNGMODULE", "original": "## Purpose of `@NgModule`", "translation": "## `@NgModule` 的设计意图", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ATAHIGHLEVELNGMODULESAREAWAYTOORGANIZEANGULARAPPSANDTHEYACCOMPLISHTHISTHROUGHTHEMETADATAINTHENGMODULEDECORATORTHEMETADATAFALLSINTOTHREECATEGORIES:", "original": "At a high level, NgModules are a way to organize Angular apps\nand they accomplish this through the metadata in the `@NgModule`\ndecorator. The metadata falls\ninto three categories:", "translation": "宏观来讲,NgModule 是组织 Angular 应用的一种方式,它们通过 `@NgModule` 装饰器中的元数据来实现这一点。\n这些元数据可以分成三类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "STATIC:COMPILERCONFIGURATIONWHICHTELLSTHECOMPILERABOUTDIRECTIVESELECTORSANDWHEREINTEMPLATESTHEDIRECTIVESSHOULDBEAPPLIEDTHROUGHSELECTORMATCHINGTHISISCONFIGUREDVIATHEDECLARATIONSARRAY", "original": "* **Static:** Compiler configuration which tells the compiler about directive selectors and where in templates the directives should be applied through selector matching. This is configured via the `declarations` array.", "translation": "**静态的:**编译器配置,用于告诉编译器指令的选择器并通过选择器匹配的方式决定要把该指令应用到模板中的什么位置。它是通过 `declarations` 数组来配置的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "RUNTIME:INJECTORCONFIGURATIONVIATHEPROVIDERSARRAY", "original": "* **Runtime:** Injector configuration via the `providers` array.", "translation": "**运行时:**通过 `providers` 数组提供给注入器的配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "COMPOSABILITYGROUPING:BRINGINGNGMODULESTOGETHERANDMAKINGTHEMAVAILABLEVIATHEIMPORTSANDEXPORTSARRAYS", "original": "* **Composability/Grouping:** Bringing NgModules together and making them available via the `imports` and `exports` arrays.", "translation": "**组合/分组:**通过 `imports` 和 `exports` 数组来把多个 NgModule 放在一起,并彼此可用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "##NGMODULEMETADATA", "original": "## `@NgModule` metadata", "translation": "## `@NgModule` 元数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "THEFOLLOWINGTABLESUMMARIZESTHENGMODULEMETADATAPROPERTIES", "original": "The following table summarizes the `@NgModule` metadata properties.", "translation": "下面是 `@NgModule` 元数据中属性的汇总表:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "PROPERTY", "original": "Property", "translation": "属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALISTOFDECLARABLEGUIDENGMODULEFAQ#QDECLARABLECLASSESCOMPONENTSDIRECTIVESANDPIPESTHATBELONGTOTHISMODULE", "original": "A list of [declarable](guide/ngmodule-faq#q-declarable) classes,\n (*components*, *directives*, and *pipes*) that _belong to this module_.", "translation": "*属于该模块*的[可声明对象](guide/ngmodule-faq#q-declarable)(*组件*、*指令*和*管道*)的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "WHENCOMPILINGATEMPLATEYOUNEEDTODETERMINEASETOFSELECTORSWHICHSHOULDBEUSEDFORTRIGGERINGTHEIRCORRESPONDINGDIRECTIVES", "original": "When compiling a template, you need to determine a set of selectors which should be used for triggering their corresponding directives.", "translation": "当编译模板时,你需要确定一组选择器,它们将用于触发相应的指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "THETEMPLATEISCOMPILEDWITHINTHECONTEXTOFANNGMODULEMDASHTHENGMODULEWITHINWHICHTHETEMPLATESCOMPONENTISDECLAREDMDASHWHICHDETERMINESTHESETOFSELECTORSUSINGTHEFOLLOWINGRULES:", "original": "The template is compiled within the context of an NgModule—the NgModule within which the template's component is declared—which determines the set of selectors using the following rules:", "translation": "该模板在 NgModule 环境中编译 —— 模板的组件是在该 NgModule 内部声明的,它会使用如下规则来确定这组选择器:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALLSELECTORSOFDIRECTIVESLISTEDINDECLARATIONS", "original": "All selectors of directives listed in `declarations`.", "translation": "列在 `declarations` 中的所有指令选择器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALLSELECTORSOFDIRECTIVESEXPORTEDFROMIMPORTEDNGMODULES", "original": "All selectors of directives exported from imported NgModules.", "translation": "从所导入的 NgModule 中导出的那些指令的选择器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "COMPONENTSDIRECTIVESANDPIPESMUSTBELONGTOEXACTLYONEMODULETHECOMPILEREMITSANERRORIFYOUTRYTODECLARETHESAMECLASSINMORETHANONEMODULE", "original": "Components, directives, and pipes must belong to _exactly_ one module.\n The compiler emits an error if you try to declare the same class in more than one module.", "translation": "组件、指令和管道*只能*属于一个模块。\n 如果尝试把同一个类声明在多个模块中,编译器就会报告一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "DONTREDECLAREACLASSIMPORTEDFROMANOTHERMODULE", "original": "Don't re-declare a class imported from another module.", "translation": "不要重复声明从其它模块中导入的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALISTOFDEPENDENCYINJECTIONPROVIDERS", "original": "A list of dependency-injection providers.", "translation": "依赖注入提供商的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ANGULARREGISTERSTHESEPROVIDERSWITHTHENGMODULESINJECTORIFITISTHENGMODULEUSEDFORBOOTSTRAPPINGTHENITISTHEROOTINJECTOR", "original": "Angular registers these providers with the NgModule's injector.\n If it is the NgModule used for bootstrapping then it is the root injector.", "translation": "Angular 会使用该模块的注入器注册这些提供商。\n 如果该模块是启动模块,那就会使用根注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "THESESERVICESBECOMEAVAILABLEFORINJECTIONINTOANYCOMPONENTDIRECTIVEPIPEORSERVICEWHICHISACHILDOFTHISINJECTOR", "original": "These services become available for injection into any component, directive, pipe or service which is a child of this injector.", "translation": "当需要注入到任何组件、指令、管道或服务时,这些服务对于本注入器的子注入器都是可用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALAZYLOADEDMODULEHASITSOWNINJECTORWHICHISTYPICALLYACHILDOFTHEAPPLICATIONROOTINJECTOR", "original": "A lazy-loaded module has its own injector which\n is typically a child of the application root injector.", "translation": "惰性加载模块有自己的注入器,它通常是应用的根注入器的子注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "LAZYLOADEDSERVICESARESCOPEDTOTHELAZYMODULESINJECTORIFALAZYLOADEDMODULEALSOPROVIDESTHEUSERSERVICEANYCOMPONENTCREATEDWITHINTHATMODULESCONTEXTSUCHASBYROUTERNAVIGATIONGETSTHELOCALINSTANCEOFTHESERVICENOTTHEINSTANCEINTHEROOTAPPLICATIONINJECTOR", "original": "Lazy-loaded services are scoped to the lazy module's injector.\n If a lazy-loaded module also provides the `UserService`,\n any component created within that module's context (such as by router navigation)\n gets the local instance of the service, not the instance in the root application injector.", "translation": "惰性加载的服务是局限于这个惰性加载模块的注入器中的。\n 如果惰性加载模块也提供了 `UserService`,那么在这个模块的上下文中创建的任何组件(比如在路由器导航时),都会获得这个服务的本模块内实例,而不是来自应用的根注入器的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "COMPONENTSINEXTERNALMODULESCONTINUETORECEIVETHEINSTANCEPROVIDEDBYTHEIRINJECTORS", "original": "Components in external modules continue to receive the instance provided by their injectors.", "translation": "其它外部模块中的组件也会使用它们自己的注入器提供的服务实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "FORMOREINFORMATIONONINJECTORHIERARCHYANDSCOPINGSEEPROVIDERSGUIDEPROVIDERS", "original": "For more information on injector hierarchy and scoping, see [Providers](guide/providers).", "translation": "要深入了解关于多级注入器及其作用域,参见[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALISTOFMODULESWHICHSHOULDBEFOLDEDINTOTHISMODULEFOLDEDMEANSITISASIFALLTHEIMPORTEDNGMODULESEXPORTEDPROPERTIESWEREDECLAREDHERE", "original": "A list of modules which should be folded into this module. Folded means it is\n as if all the imported NgModule's exported properties were declared here.", "translation": "要折叠(Folded)进本模块中的其它模块。折叠的意思是从被导入的模块中导出的那些软件资产同样会被声明在这里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "SPECIFICALLYITISASIFTHELISTOFMODULESWHOSEEXPORTEDCOMPONENTSDIRECTIVESORPIPESAREREFERENCEDBYTHECOMPONENTTEMPLATESWEREDECLAREDINTHISMODULE", "original": "Specifically, it is as if the list of modules whose exported components, directives, or pipes\n are referenced by the component templates were declared in this module.", "translation": "特别是,这里列出的模块,其导出的组件、指令或管道,当在组件模板中被引用时,和本模块自己声明的那些是等价的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ACOMPONENTTEMPLATECANREFERENCEGUIDENGMODULEFAQ#QTEMPLATEREFERENCEANOTHERCOMPONENTDIRECTIVEORPIPEWHENTHEREFERENCEISDECLAREDINTHISMODULEORIFTHEIMPORTEDMODULEHASEXPORTEDITFOREXAMPLEACOMPONENTCANUSETHENGIFANDNGFORDIRECTIVESONLYIFTHEMODULEHASIMPORTEDTHEANGULARCOMMONMODULEPERHAPSINDIRECTLYBYIMPORTINGBROWSERMODULE", "original": "A component template can [reference](guide/ngmodule-faq#q-template-reference) another component, directive, or pipe\n when the reference is declared in this module or if the imported module has exported it.\n For example, a component can use the `NgIf` and `NgFor` directives only if the\n module has imported the Angular `CommonModule` (perhaps indirectly by importing `BrowserModule`).", "translation": "组件模板可以[引用](guide/ngmodule-faq#q-template-reference)其它组件、指令或管道,不管它们是在本模块中声明的,还是从导入的模块中导出的。\n 比如,只有当该模块导入了 Angular 的 `CommonModule(也可能从 `BrowserModule` 中间接导入)时,组件才能使用 `NgIf` 和 `NgFor` 指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "YOUCANIMPORTMANYSTANDARDDIRECTIVESFROMTHECOMMONMODULEBUTSOMEFAMILIARDIRECTIVESBELONGTOOTHERMODULESFOREXAMPLEYOUCANUSENGMODELONLYAFTERIMPORTINGTHEANGULARFORMSMODULE", "original": "You can import many standard directives from the `CommonModule`\n but some familiar directives belong to other modules.\n For example, you can use `[(ngModel)]` only\n after importing the Angular `FormsModule`.", "translation": "你可以从 `CommonModule` 中导入很多标准指令,不过也有些常用的指令属于其它模块。\n 比如,你只有导入了 Angular 的 `FormsModule` 时才能使用 `[(ngModel)]`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALISTOFDECLARATIONSMDASHCOMPONENTDIRECTIVEANDPIPECLASSESMDASHTHATANIMPORTINGMODULECANUSE", "original": "A list of declarations—*component*, *directive*, and *pipe* classes—that\n an importing module can use.", "translation": "可供导入了自己的模块使用的可声明对象(**组件**、**指令**、**管道类**)的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "EXPORTEDDECLARATIONSARETHEMODULESPUBLICAPIACOMPONENTINANOTHERMODULECANUSEGUIDENGMODULEFAQ#QTEMPLATEREFERENCETHISMODULESUSERCOMPONENTIFITIMPORTSTHISMODULEANDTHISMODULEEXPORTSUSERCOMPONENT", "original": "Exported declarations are the module's _public API_.\n A component in another module can [use](guide/ngmodule-faq#q-template-reference) _this_\n module's `UserComponent` if it imports this module and this module exports `UserComponent`.", "translation": "导出的可声明对象就是本模块的*公共 API*。\n 只有当其它模块导入了本模块,并且本模块导出了 `UserComponent` 时,其它模块中的组件才能[使用](guide/ngmodule-faq#q-template-reference)*本*模块中的 `UserComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "DECLARATIONSAREPRIVATEBYDEFAULTIFTHISMODULEDOESNOTEXPORTUSERCOMPONENTTHENONLYTHECOMPONENTSWITHINTHISMODULECANUSEUSERCOMPONENT", "original": "Declarations are private by default.\n If this module does _not_ export `UserComponent`, then only the components within _this_\n module can use `UserComponent`.", "translation": "默认情况下这些可声明对象都是私有的。\n 如果本模块*没有*导出 `UserComponent`,那么就只有*本*模块中的组件才能使用 `UserComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "IMPORTINGAMODULEDOESNOTAUTOMATICALLYREEXPORTTHEIMPORTEDMODULESIMPORTSMODULEBCANTUSENGIFJUSTBECAUSEITIMPORTEDMODULEAWHICHIMPORTEDCOMMONMODULEMODULEBMUSTIMPORTCOMMONMODULEITSELF", "original": "Importing a module does _not_ automatically re-export the imported module's imports.\n Module 'B' can't use `ngIf` just because it imported module 'A' which imported `CommonModule`.\n Module 'B' must import `CommonModule` itself.", "translation": "导入某个模块*并不会*自动重新导出被导入模块的那些导入。\n 模块 B 不会因为它导入了模块 A,而模块 A 导入了 `CommonModule` 而能够使用 `ngIf`。\n 模块 B 必须自己导入 `CommonModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "AMODULECANLISTANOTHERMODULEAMONGITSEXPORTSINWHICHCASEALLOFTHATMODULESPUBLICCOMPONENTSDIRECTIVESANDPIPESAREEXPORTED", "original": "A module can list another module among its `exports`, in which case\n all of that module's public components, directives, and pipes are exported.", "translation": "一个模块可以把另一个模块加入自己的 `exports` 列表中,这时,另一个模块的所有公共组件、指令和管道都会被导出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "REEXPORTGUIDENGMODULEFAQ#QREEXPORTMAKESMODULETRANSITIVITYEXPLICITIFMODULEAREEXPORTSCOMMONMODULEANDMODULEBIMPORTSMODULEAMODULEBCOMPONENTSCANUSENGIFEVENTHOUGHBITSELFDIDNTIMPORTCOMMONMODULE", "original": "[Re-export](guide/ngmodule-faq#q-reexport) makes module transitivity explicit.\n If Module 'A' re-exports `CommonModule` and Module 'B' imports Module 'A',\n Module 'B' components can use `ngIf` even though 'B' itself didn't import `CommonModule`.", "translation": "[重新导出](guide/ngmodule-faq#q-reexport)可以让模块被显式传递。\n 如果模块 A 重新导出了 `CommonModule`,而模块 B 导入了模块 A,那么模块 B 就可以使用 `ngIf` 了 —— 即使它自己没有导入 `CommonModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALISTOFCOMPONENTSTHATAREAUTOMATICALLYBOOTSTRAPPED", "original": "A list of components that are automatically bootstrapped.", "translation": "要自动启动的组件列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "USUALLYTHERESONLYONECOMPONENTINTHISLISTTHEROOTCOMPONENTOFTHEAPPLICATION", "original": "Usually there's only one component in this list, the _root component_ of the application.", "translation": "通常,在这个列表中只有一个组件,也就是应用的*根组件*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ANGULARCANLAUNCHWITHMULTIPLEBOOTSTRAPCOMPONENTSEACHWITHITSOWNLOCATIONINTHEHOSTWEBPAGE", "original": "Angular can launch with multiple bootstrap components,\n each with its own location in the host web page.", "translation": "Angular 也可以引导多个引导组件,它们每一个都在宿主页面中有自己的位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ABOOTSTRAPCOMPONENTISAUTOMATICALLYADDEDTOENTRYCOMPONENTS", "original": "A bootstrap component is automatically added to `entryComponents`.", "translation": "启动组件会自动添加到 `entryComponents` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ALISTOFCOMPONENTSTHATCANBEDYNAMICALLYLOADEDINTOTHEVIEW", "original": "A list of components that can be dynamically loaded into the view.", "translation": "那些可以动态加载进视图的组件列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "BYDEFAULTANANGULARAPPALWAYSHASATLEASTONEENTRYCOMPONENTTHEROOTCOMPONENTAPPCOMPONENTITSPURPOSEISTOSERVEASAPOINTOFENTRYINTOTHEAPPTHATISYOUBOOTSTRAPITTOLAUNCHTHEAPP", "original": "By default, an Angular app always has at least one entry component, the root component, `AppComponent`. Its purpose is to serve as a point of entry into the app, that is, you bootstrap it to launch the app.", "translation": "默认情况下,Angular 应用至少有一个入口组件,也就是根组件 `AppComponent`。\n 它用作进入该应用的入口点,也就是说你通过引导它来启动本应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ROUTEDCOMPONENTSAREALSOENTRYCOMPONENTSBECAUSETHEYNEEDTOBELOADEDDYNAMICALLYTHEROUTERCREATESTHEMANDDROPSTHEMINTOTHEDOMNEARAROUTEROUTLET", "original": "Routed components are also _entry components_ because they need to be loaded dynamically.\n The router creates them and drops them into the DOM near a `<router-outlet>`.", "translation": "路由组件也是*入口组件*,因为你需要动态加载它们。\n 路由器创建它们,并把它们扔到 DOM 中的 `<router-outlet>` 附近。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "WHILETHEBOOTSTRAPPEDANDROUTEDCOMPONENTSAREENTRYCOMPONENTSYOUDONTHAVETOADDTHEMTOAMODULESENTRYCOMPONENTSLISTASTHEYAREADDEDIMPLICITLY", "original": "While the bootstrapped and routed components are _entry components_,\n you don't have to add them to a module's `entryComponents` list,\n as they are added implicitly.", "translation": "虽然引导组件和路由组件都是*入口组件*,不过你不用自己把它们加到模块的 `entryComponents` 列表中,因为它们会被隐式添加进去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ANGULARAUTOMATICALLYADDSCOMPONENTSINTHEMODULESBOOTSTRAPANDROUTEDEFINITIONSINTOTHEENTRYCOMPONENTSLIST", "original": "Angular automatically adds components in the module's `bootstrap` and route definitions into the `entryComponents` list.", "translation": "Angular 会自动把模块的 `bootstrap` 中的组件和路由定义中的组件添加到 `entryComponents` 列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "THATLEAVESONLYCOMPONENTSBOOTSTRAPPEDUSINGONEOFTHEIMPERATIVETECHNIQUESSUCHASVIEWCOMPONENTREFCREATECOMPONENTHTTPS:ANGULARIOAPICOREVIEWCONTAINERREF#CREATECOMPONENTASUNDISCOVERABLE", "original": "That leaves only components bootstrapped using one of the imperative techniques, such as [`ViewComponentRef.createComponent()`](https://angular.io/api/core/ViewContainerRef#createComponent) as undiscoverable.", "translation": "而那些使用不易察觉的[`ViewComponentRef.createComponent()`](https://angular.io/api/core/ViewContainerRef#createComponent)的方式进行命令式引导的组件仍然需要添加。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "DYNAMICCOMPONENTLOADINGISNOTCOMMONINMOSTAPPSBEYONDTHEROUTERIFYOUNEEDTODYNAMICALLYLOADCOMPONENTSYOUMUSTADDTHESECOMPONENTSTOTHEENTRYCOMPONENTSLISTYOURSELF", "original": "Dynamic component loading is not common in most apps beyond the router. If you need to dynamically load components, you must add these components to the `entryComponents` list yourself.", "translation": "动态组件加载在除路由器之外的大多数应用中都不太常见。如果你需要动态加载组件,就必须自己把那些组件添加到 `entryComponents` 列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "FORMOREINFORMATIONSEEENTRYCOMPONENTSGUIDEENTRYCOMPONENTS", "original": "For more information, see [Entry Components](guide/entry-components).", "translation": "要了解更多,参见[入口组件](guide/entry-components)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "FEATUREMODULESGUIDEFEATUREMODULES", "original": "* [Feature Modules](guide/feature-modules).", - "translation": "[特性模块](guide/feature-modules)。", + "translation": "[特性模块](guide/feature-modules)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "ENTRYCOMPONENTSGUIDEENTRYCOMPONENTS", "original": "* [Entry Components](guide/entry-components).", - "translation": "[入口组件](guide/entry-components)。", + "translation": "[入口组件](guide/entry-components)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "PROVIDERSGUIDEPROVIDERS", "original": "* [Providers](guide/providers).", - "translation": "[提供商](guide/providers)。", + "translation": "[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "TYPESOFFEATUREMODULESGUIDEMODULETYPES", "original": "* [Types of Feature Modules](guide/module-types).", "translation": "[特性模块的分类](guide/module-types)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-api.md" }, { + "key": "#NGMODULEFAQS", "original": "# NgModule FAQs", "translation": "# Angular 模块常见问题", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "####PREREQUISITES:", "original": "#### Prerequisites:", "translation": "#### 前提条件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWINGCONCEPTS:", "original": "A basic understanding of the following concepts:", "translation": "对下列概念有基本的理解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "NGMODULESGUIDENGMODULES", + "original": "* [NgModules](guide/ngmodules).", + "translation": "[Angular 模块](guide/ngmodules).", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" + }, + { + "key": "NGMODULESHELPORGANIZEANAPPLICATIONINTOCOHESIVEBLOCKSOFFUNCTIONALITY", "original": "NgModules help organize an application into cohesive blocks of functionality.", "translation": "NgModules 可以帮你把应用组织成一些紧密相关的代码块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THISPAGEANSWERSTHEQUESTIONSMANYDEVELOPERSASKABOUTNGMODULEDESIGNANDIMPLEMENTATION", "original": "This page answers the questions many developers ask about NgModule design and implementation.", "translation": "这里回答的是开发者常问起的关于 Angular 模块的设计与实现问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATCLASSESSHOULDIADDTOTHEDECLARATIONSARRAY", "original": "## What classes should I add to the `declarations` array?", "translation": "## 我应该把哪些类加到 *declarations* 中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ADDDECLARABLEGUIDEBOOTSTRAPPING#THEDECLARATIONSARRAYCLASSESMDASHCOMPONENTSDIRECTIVESANDPIPESMDASHTOADECLARATIONSLIST", "original": "Add [declarable](guide/bootstrapping#the-declarations-array) classes—components, directives, and pipes—to a `declarations` list.", "translation": "把[可声明](guide/bootstrapping#the-declarations-array)的类(组件、指令和管道)添加到 `declarations` 列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "DECLARETHESECLASSESINEXACTLYONEMODULEOFTHEAPPLICATIONDECLARETHEMINAMODULEIFTHEYBELONGTOTHATPARTICULARMODULE", "original": "Declare these classes in _exactly one_ module of the application.\nDeclare them in a module if they belong to that particular module.", "translation": "这些类只能在应用程序的*一个并且只有一个*模块中声明。\n只有当它们*从属于*某个模块时,才能把在*此*模块中声明它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATISADECLARABLE", "original": "## What is a _declarable_?", "translation": "## 什么是*可声明的*?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "DECLARABLESARETHECLASSTYPESMDASHCOMPONENTSDIRECTIVESANDPIPESMDASHTHATYOUCANADDTOAMODULESDECLARATIONSLISTTHEYRETHEONLYCLASSESTHATYOUCANADDTODECLARATIONS", "original": "Declarables are the class types—components, directives, and pipes—that\nyou can add to a module's `declarations` list.\nThey're the only classes that you can add to `declarations`.", "translation": "*可声明的*就是组件、指令和管道等可以被加到模块的 `declarations` 列表中的类。它们也是*所有*能被加到 `declarations` 中的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATCLASSESSHOULDINOTADDTODECLARATIONS", "original": "## What classes should I _not_ add to `declarations`?", "translation": "## 哪些类*不*应该加到 `declarations` 中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ADDONLYDECLARABLEGUIDEBOOTSTRAPPING#THEDECLARATIONSARRAYCLASSESTOANNGMODULESDECLARATIONSLIST", "original": "Add only [declarable](guide/bootstrapping#the-declarations-array) classes to an NgModule's `declarations` list.", "translation": "只有[可声明的](guide/ngmodule-faq#q-declarable)类才能加到模块的 `declarations` 列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "DONOTDECLARETHEFOLLOWING:", "original": "Do *not* declare the following:", "translation": "*不要*声明:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ACLASSTHATSALREADYDECLAREDINANOTHERMODULEWHETHERANAPPMODULENGMODULEORTHIRDPARTYMODULE", "original": "* A class that's already declared in another module, whether an app module, @NgModule, or third-party module.", "translation": "已经在其它模块中声明过的类。无论它来自应用自己的模块(@NgModule)还是第三方模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANARRAYOFDIRECTIVESIMPORTEDFROMANOTHERMODULEFOREXAMPLEDONTDECLAREFORMSDIRECTIVESFROMANGULARFORMSBECAUSETHEFORMSMODULEALREADYDECLARESIT", "original": "* An array of directives imported from another module.\nFor example, don't declare `FORMS_DIRECTIVES` from `@angular/forms` because the `FormsModule` already declares it.", "translation": "从其它模块中导入的指令。例如,不要声明来自 `@angular/forms` 的 FORMS_DIRECTIVES,因为 `FormsModule` 已经声明过它们了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "MODULECLASSES", "original": "* Module classes.", "translation": "模块类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "SERVICECLASSES", "original": "* Service classes.", "translation": "服务类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "NONANGULARCLASSESANDOBJECTSSUCHASSTRINGSNUMBERSFUNCTIONSENTITYMODELSCONFIGURATIONSBUSINESSLOGICANDHELPERCLASSES", "original": "* Non-Angular classes and objects, such as\nstrings, numbers, functions, entity models, configurations, business logic, and helper classes.", "translation": "非 Angular 的类和对象,比如:字符串、数字、函数、实体模型、配置、业务逻辑和辅助类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHYLISTTHESAMECOMPONENTINMULTIPLENGMODULEPROPERTIES", "original": "## Why list the same component in multiple `NgModule` properties?", "translation": "## 为什么要把同一个组件声明在不同的 *NgModule* 属性中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "APPCOMPONENTISOFTENLISTEDINBOTHDECLARATIONSANDBOOTSTRAPYOUMIGHTSEETHESAMECOMPONENTLISTEDINDECLARATIONSEXPORTSANDENTRYCOMPONENTS", "original": "`AppComponent` is often listed in both `declarations` and `bootstrap`.\nYou might see the same component listed in `declarations`, `exports`, and `entryComponents`.", "translation": "`AppComponent` 经常被同时列在 `declarations` 和 `bootstrap` 中。\n另外你还可能看到 `HeroComponent` 被同时列在 `declarations`、`exports` 和 `entryComponent` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHILETHATSEEMSREDUNDANTTHESEPROPERTIESHAVEDIFFERENTFUNCTIONSMEMBERSHIPINONELISTDOESNTIMPLYMEMBERSHIPINANOTHERLIST", "original": "While that seems redundant, these properties have different functions.\nMembership in one list doesn't imply membership in another list.", "translation": "这*看起来*是多余的,不过这些函数具有不同的功能,从它出现在一个列表中无法推断出它也应该在另一个列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "APPCOMPONENTCOULDBEDECLAREDINTHISMODULEBUTNOTBOOTSTRAPPED", "original": "* `AppComponent` could be declared in this module but not bootstrapped.", "translation": "`AppComponent` 可能被声明在此模块中,但可能不是引导组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "APPCOMPONENTCOULDBEBOOTSTRAPPEDINTHISMODULEBUTDECLAREDINADIFFERENTFEATUREMODULE", "original": "* `AppComponent` could be bootstrapped in this module but declared in a different feature module.", "translation": "`AppComponent` 可能在此模块中引导,但可能是由另一个特性模块声明的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ACOMPONENTCOULDBEIMPORTEDFROMANOTHERAPPMODULESOYOUCANTDECLAREITANDREEXPORTEDBYTHISMODULE", "original": "* A component could be imported from another app module (so you can't declare it) and re-exported by this module.", "translation": "`HeroComponent` 可能是从另一个应用模块中导入的(所以你没法声明它)并且被当前模块重新导出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ACOMPONENTCOULDBEEXPORTEDFORINCLUSIONINANEXTERNALCOMPONENTSTEMPLATEASWELLASDYNAMICALLYLOADEDINAPOPUPDIALOG", "original": "* A component could be exported for inclusion in an external component's template\nas well as dynamically loaded in a pop-up dialog.", "translation": "`HeroComponent` 可能被导入,以便用在外部组件的模板中,但也可能同时被一个弹出式对话框加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATDOESCANTBINDTOXSINCEITISNTAKNOWNPROPERTYOFYMEAN", "original": "## What does \"Can't bind to 'x' since it isn't a known property of 'y'\" mean?", "translation": "## \"_Can't bind to 'x' since it isn't a known property of 'y'_\"是什么意思?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THISERROROFTENMEANSTHATYOUHAVENTDECLAREDTHEDIRECTIVEXORHAVENTIMPORTEDTHENGMODULETOWHICHXBELONGS", "original": "This error often means that you haven't declared the directive \"x\"\nor haven't imported the NgModule to which \"x\" belongs.", "translation": "这个错误通常意味着你或者忘了声明指令“x”,或者你没有导入“x”所属的模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "PERHAPSYOUDECLAREDXINANAPPLICATIONSUBMODULEBUTFORGOTTOEXPORTITTHEXCLASSISNTVISIBLETOOTHERMODULESUNTILYOUADDITTOTHEEXPORTSLIST", "original": "Perhaps you declared \"x\" in an application sub-module but forgot to export it.\nThe \"x\" class isn't visible to other modules until you add it to the `exports` list.", "translation": "如果“x”其实不是属性,或者是组件的私有属性(比如它不带 `@Input` 或 `@Output` 装饰器),那么你也同样会遇到这个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATSHOULDIIMPORT", "original": "## What should I import?", "translation": "## 我应该导入什么?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IMPORTNGMODULESWHOSEPUBLICEXPORTEDDECLARABLECLASSESGUIDEBOOTSTRAPPING#THEDECLARATIONSARRAYYOUNEEDTOREFERENCEINTHISMODULESCOMPONENTTEMPLATES", "original": "Import NgModules whose public (exported) [declarable classes](guide/bootstrapping#the-declarations-array)\nyou need to reference in this module's component templates.", "translation": "导入你需要在当前模块的组件模板中使用的那些公开的(被导出的)[可声明类](guide/ngmodule-faq#q-declarable)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THISALWAYSMEANSIMPORTINGCOMMONMODULEFROMANGULARCOMMONFORACCESSTOTHEANGULARDIRECTIVESSUCHASNGIFANDNGFORYOUCANIMPORTITDIRECTLYORFROMANOTHERNGMODULETHATREEXPORTSGUIDENGMODULEFAQ#QREEXPORTIT", "original": "This always means importing `CommonModule` from `@angular/common` for access to\nthe Angular directives such as `NgIf` and `NgFor`.\nYou can import it directly or from another NgModule that [re-exports](guide/ngmodule-faq#q-reexport) it.", "translation": "这意味着要从 `@angular/common` 中导入 `CommonModule` 才能访问 Angular 的内置指令,比如 `NgIf` 和 `NgFor`。\n你可以直接导入它或者从[重新导出](guide/ngmodule-faq#q-reexport)过该模块的其它模块中导入它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IMPORTFORMSMODULEFROMANGULARFORMSIFYOURCOMPONENTSHAVENGMODELTWOWAYBINDINGEXPRESSIONS", "original": "Import `FormsModule` from `@angular/forms`\nif your components have `[(ngModel)]` two-way binding expressions.", "translation": "如果你的组件有 `[(ngModel)]` 双向绑定表达式,就要从 `@angular/forms` 中导入 `FormsModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IMPORTSHAREDANDFEATUREMODULESWHENTHISMODULESCOMPONENTSINCORPORATETHEIRCOMPONENTSDIRECTIVESANDPIPES", "original": "Import _shared_ and _feature_ modules when this module's components incorporate their\ncomponents, directives, and pipes.", "translation": "如果当前模块中的组件包含了*共享*模块和*特性*模块中的组件、指令和管道,就导入这些模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IMPORTONLYBROWSERMODULEGUIDENGMODULEFAQ#QBROWSERVSCOMMONMODULEINTHEROOTAPPMODULE", "original": "Import only [BrowserModule](guide/ngmodule-faq#q-browser-vs-common-module) in the root `AppModule`.", "translation": "只能在根模块 `AppModule` 中[导入_BrowserModule_](guide/ngmodule-faq#q-browser-vs-common-module)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##SHOULDIIMPORTBROWSERMODULEORCOMMONMODULE", "original": "## Should I import `BrowserModule` or `CommonModule`?", "translation": "## 我应该导入 *BrowserModule* 还是 *CommonModule*?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEROOTAPPLICATIONMODULEAPPMODULEOFALMOSTEVERYBROWSERAPPLICATIONSHOULDIMPORTBROWSERMODULEFROMANGULARPLATFORMBROWSER", "original": "The root application module, `AppModule`, of almost every browser application\nshould import `BrowserModule` from `@angular/platform-browser`.", "translation": "几乎所有要在浏览器中使用的应用的**根模块**(`AppModule`)都应该从 `@angular/platform-browser` 中导入 `BrowserModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "BROWSERMODULEPROVIDESSERVICESTHATAREESSENTIALTOLAUNCHANDRUNABROWSERAPP", "original": "`BrowserModule` provides services that are essential to launch and run a browser app.", "translation": "`BrowserModule` 提供了启动和运行浏览器应用的那些基本的服务提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "BROWSERMODULEALSOREEXPORTSCOMMONMODULEFROMANGULARCOMMONWHICHMEANSTHATCOMPONENTSINTHEAPPMODULEMODULEALSOHAVEACCESSTOTHEANGULARDIRECTIVESEVERYAPPNEEDSSUCHASNGIFANDNGFOR", "original": "`BrowserModule` also re-exports `CommonModule` from `@angular/common`,\nwhich means that components in the `AppModule` module also have access to\nthe Angular directives every app needs, such as `NgIf` and `NgFor`.", "translation": "`BrowserModule` 还从 `@angular/common` 中重新导出了 `CommonModule`,这意味着 `AppModule` 中的组件也同样可以访问那些每个应用都需要的 Angular 指令,如 `NgIf` 和 `NgFor`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "DONOTIMPORTBROWSERMODULEINANYOTHERMODULEFEATUREMODULESANDLAZYLOADEDMODULESSHOULDIMPORTCOMMONMODULEINSTEADTHEYNEEDTHECOMMONDIRECTIVESTHEYDONTNEEDTOREINSTALLTHEAPPWIDEPROVIDERS", "original": "Do not import `BrowserModule` in any other module.\n*Feature modules* and *lazy-loaded modules* should import `CommonModule` instead.\nThey need the common directives. They don't need to re-install the app-wide providers.", "translation": "在其它任何模块中都*不要导入*`BrowserModule`。\n*特性模块*和*惰性加载模块*应该改成导入 `CommonModule`。\n它们需要通用的指令。它们不需要重新初始化全应用级的提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IMPORTINGCOMMONMODULEALSOFREESFEATUREMODULESFORUSEONANYTARGETPLATFORMNOTJUSTBROWSERS", "original": "Importing `CommonModule` also frees feature modules for use on _any_ target platform, not just browsers.", "translation": "特性模块中导入 `CommonModule` 可以让它能用在任何目标平台上,不仅是浏览器。那些跨平台库的作者应该喜欢这种方式的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATIFIIMPORTTHESAMEMODULETWICE", "original": "## What if I import the same module twice?", "translation": "## 如果我两次导入同一个模块会怎么样?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THATSNOTAPROBLEMWHENTHREEMODULESALLIMPORTMODULEAANGULAREVALUATESMODULEAONCETHEFIRSTTIMEITENCOUNTERSITANDDOESNTDOSOAGAIN", "original": "That's not a problem. When three modules all import Module 'A',\nAngular evaluates Module 'A' once, the first time it encounters it, and doesn't do so again.", "translation": "没有任何问题。当三个模块全都导入模块'A'时,Angular 只会首次遇到时加载一次模块'A',之后就不会这么做了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THATSTRUEATWHATEVERLEVELAAPPEARSINAHIERARCHYOFIMPORTEDNGMODULESWHENMODULEBIMPORTSMODULEAMODULECIMPORTSBANDMODULEDIMPORTSCBATHENDTRIGGERSTHEEVALUATIONOFCWHICHTRIGGERSTHEEVALUATIONOFBWHICHEVALUATESAWHENANGULARGETSTOTHEBANDAINDTHEYREALREADYCACHEDANDREADYTOGO", "original": "That's true at whatever level `A` appears in a hierarchy of imported NgModules.\nWhen Module 'B' imports Module 'A', Module 'C' imports 'B', and Module 'D' imports `[C, B, A]`,\nthen 'D' triggers the evaluation of 'C', which triggers the evaluation of 'B', which evaluates 'A'.\nWhen Angular gets to the 'B' and 'A' in 'D', they're already cached and ready to go.", "translation": "无论 `A` 出现在所导入模块的哪个层级,都会如此。\n如果模块'B'导入模块'A'、模块'C'导入模块'B',模块'D'导入 `[C, B, A]`,那么'D'会触发模块'C'的加载,'C'会触发'B'的加载,而'B'会加载'A'。\n当 Angular 在'D'中想要获取'B'和'A'时,这两个模块已经被缓存过了,可以立即使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANGULARDOESNTLIKENGMODULESWITHCIRCULARREFERENCESSODONTLETMODULEAIMPORTMODULEBWHICHIMPORTSMODULEA", "original": "Angular doesn't like NgModules with circular references, so don't let Module 'A' import Module 'B', which imports Module 'A'.", "translation": "Angular 不允许模块之间出现循环依赖,所以不要让模块'A'导入模块'B',而模块'B'又导入模块'A'。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATSHOULDIEXPORT", "original": "## What should I export?", "translation": "## 我应该导出什么?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "EXPORTDECLARABLEGUIDEBOOTSTRAPPING#THEDECLARATIONSARRAYCLASSESTHATCOMPONENTSINOTHERNGMODULESAREABLETOREFERENCEINTHEIRTEMPLATESTHESEAREYOURPUBLICCLASSESIFYOUDONTEXPORTADECLARABLECLASSITSTAYSPRIVATEVISIBLEONLYTOOTHERCOMPONENTSDECLAREDINTHISNGMODULE", "original": "Export [declarable](guide/bootstrapping#the-declarations-array) classes that components in _other_ NgModules\nare able to reference in their templates. These are your _public_ classes.\nIf you don't export a declarable class, it stays _private_, visible only to other components\ndeclared in this NgModule.", "translation": "导出那些*其它模块*希望在自己的模板中引用的[可声明类](guide/ngmodule-faq#q-declarable)。这些也是你的*公共*类。\n如果你不导出某个类,它就是*私有的*,只对当前模块中声明的其它组件可见。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "YOUCANEXPORTANYDECLARABLECLASSMDASHCOMPONENTSDIRECTIVESANDPIPESMDASHWHETHERITSDECLAREDINTHISNGMODULEORINANIMPORTEDNGMODULE", "original": "You _can_ export any declarable class—components, directives, and pipes—whether\nit's declared in this NgModule or in an imported NgModule.", "translation": "你*可以*导出任何可声明类(组件、指令和管道),而不用管它是声明在当前模块中还是某个导入的模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "YOUCANREEXPORTENTIREIMPORTEDNGMODULESWHICHEFFECTIVELYREEXPORTSALLOFTHEIREXPORTEDCLASSESANNGMODULECANEVENEXPORTAMODULETHATITDOESNTIMPORT", "original": "You _can_ re-export entire imported NgModules, which effectively re-exports all of their exported classes.\nAn NgModule can even export a module that it doesn't import.", "translation": "你*可以*重新导出整个导入过的模块,这将导致重新导出它们导出的所有类。重新导出的模块甚至不用先导入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATSHOULDINOTEXPORT", "original": "## What should I *not* export?", "translation": "## 我*不应该*导出什么?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "DONTEXPORTTHEFOLLOWING:", "original": "Don't export the following:", "translation": "*不要*导出:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "PRIVATECOMPONENTSDIRECTIVESANDPIPESTHATYOUNEEDONLYWITHINCOMPONENTSDECLAREDINTHISNGMODULEIFYOUDONTWANTANOTHERNGMODULETOSEEITDONTEXPORTIT", "original": "* Private components, directives, and pipes that you need only within components declared in this NgModule.\nIf you don't want another NgModule to see it, don't export it.", "translation": "那些你只想在当前模块中声明的那些组件中使用的私有组件、指令和管道。如果你不希望任何模块看到它,就不要导出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "NONDECLARABLEOBJECTSSUCHASSERVICESFUNCTIONSCONFIGURATIONSANDENTITYMODELS", "original": "* Non-declarable objects such as services, functions, configurations, and entity models.", "translation": "不可声明的对象,比如服务、函数、配置、实体模型等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "COMPONENTSTHATAREONLYLOADEDDYNAMICALLYBYTHEROUTERORBYBOOTSTRAPPINGSUCHENTRYCOMPONENTSGUIDENGMODULEFAQ#QENTRYCOMPONENTDEFINEDCANNEVERBESELECTEDINANOTHERCOMPONENTSTEMPLATEWHILETHERESNOHARMINEXPORTINGTHEMTHERESALSONOBENEFIT", "original": "* Components that are only loaded dynamically by the router or by bootstrapping.\nSuch [entry components](guide/ngmodule-faq#q-entry-component-defined) can never be selected in another component's template.\nWhile there's no harm in exporting them, there's also no benefit.", "translation": "那些只被路由器或引导函数动态加载的组件。\n 比如[入口组件](guide/ngmodule-faq#q-entry-component-defined)可能从来不会在其它组件的模板中出现。\n 导出它们没有坏处,但也没有好处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "PURESERVICEMODULESTHATDONTHAVEPUBLICEXPORTEDDECLARATIONSFOREXAMPLETHERESNOPOINTINREEXPORTINGHTTPCLIENTMODULEBECAUSEITDOESNTEXPORTANYTHINGITSONLYPURPOSEISTOADDHTTPSERVICEPROVIDERSTOTHEAPPLICATIONASAWHOLE", "original": "* Pure service modules that don't have public (exported) declarations.\nFor example, there's no point in re-exporting `HttpClientModule` because it doesn't export anything.\nIts only purpose is to add http service providers to the application as a whole.", "translation": "纯服务模块没有公开(导出)的声明。\n 例如,没必要重新导出 `HttpClientModule`,因为它不导出任何东西。\n 它唯一的用途是一起把 http 的那些服务提供商添加到应用中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##CANIREEXPORTCLASSESANDMODULES", "original": "## Can I re-export classes and modules?", "translation": "## 我可以重新导出类和模块吗?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ABSOLUTELY", "original": "Absolutely.", "translation": "毫无疑问!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "NGMODULESAREAGREATWAYTOSELECTIVELYAGGREGATECLASSESFROMOTHERNGMODULESANDREEXPORTTHEMINACONSOLIDATEDCONVENIENCEMODULE", "original": "NgModules are a great way to selectively aggregate classes from other NgModules and\nre-export them in a consolidated, convenience module.", "translation": "模块是从其它模块中选取类并把它们重新导出成统一、便利的新模块的最佳方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANNGMODULECANREEXPORTENTIRENGMODULESWHICHEFFECTIVELYREEXPORTSALLOFTHEIREXPORTEDCLASSESANGULARSOWNBROWSERMODULEEXPORTSACOUPLEOFNGMODULESLIKETHIS:", "original": "An NgModule can re-export entire NgModules, which effectively re-exports all of their exported classes.\nAngular's own `BrowserModule` exports a couple of NgModules like this:", "translation": "模块可以重新导出其它模块,这会导致重新导出它们导出的所有类。\nAngular 自己的 `BrowserModule` 就重新导出了一组模块,例如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANNGMODULECANEXPORTACOMBINATIONOFITSOWNDECLARATIONSSELECTEDIMPORTEDCLASSESANDIMPORTEDNGMODULES", "original": "An NgModule can export a combination of its own declarations, selected imported classes, and imported NgModules.", "translation": "模块还能导出一个组合,它可以包含自己的声明、某些导入的类以及导入的模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "DONTBOTHERREEXPORTINGPURESERVICEMODULESPURESERVICEMODULESDONTEXPORTDECLARABLEGUIDEBOOTSTRAPPING#THEDECLARATIONSARRAYCLASSESTHATANOTHERNGMODULECOULDUSEFOREXAMPLETHERESNOPOINTINREEXPORTINGHTTPCLIENTMODULEBECAUSEITDOESNTEXPORTANYTHINGITSONLYPURPOSEISTOADDHTTPSERVICEPROVIDERSTOTHEAPPLICATIONASAWHOLE", "original": "Don't bother re-exporting pure service modules.\nPure service modules don't export [declarable](guide/bootstrapping#the-declarations-array) classes that another NgModule could use.\nFor example, there's no point in re-exporting `HttpClientModule` because it doesn't export anything.\nIts only purpose is to add http service providers to the application as a whole.", "translation": "不要费心去导出纯服务类。\n纯服务类的模块不会导出任何可供其它模块使用的[可声明类](guide/ngmodule-faq#q-declarable)。\n例如,不用重新导出 `HttpClientModule`,因为它没有导出任何东西。\n它唯一的用途是把那些 http 服务提供商一起添加到应用中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATISTHEFORROOTMETHOD", "original": "## What is the `forRoot()` method?", "translation": "## *forRoot()*方法是什么?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEFORROOTSTATICMETHODISACONVENTIONTHATMAKESITEASYFORDEVELOPERSTOCONFIGURETHEMODULESPROVIDERS", "original": "The `forRoot()` static method is a convention that makes it easy for developers to configure the module's providers.", "translation": "静态方法 `forRoot()` 是一个约定,它可以让开发人员更轻松的配置模块的提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEROUTERMODULEFORROOTMETHODISAGOODEXAMPLEAPPSPASSAROUTESOBJECTTOROUTERMODULEFORROOTINORDERTOCONFIGURETHEAPPWIDEROUTERSERVICEWITHROUTESROUTERMODULEFORROOTRETURNSAMODULEWITHPROVIDERSAPICOREMODULEWITHPROVIDERSYOUADDTHATRESULTTOTHEIMPORTSLISTOFTHEROOTAPPMODULE", "original": "The `RouterModule.forRoot()` method is a good example.\nApps pass a `Routes` object to `RouterModule.forRoot()` in order to configure the app-wide `Router` service with routes.\n`RouterModule.forRoot()` returns a [ModuleWithProviders](api/core/ModuleWithProviders).\nYou add that result to the `imports` list of the root `AppModule`.", "translation": "`RouterModule.forRoot()` 就是一个很好的例子。\n应用把一个 `Routes` 对象传给 `RouterModule.forRoot()`,为的就是使用路由配置全应用级的 `Router` 服务。\n`RouterModule.forRoot()` 返回一个[ModuleWithProviders](api/core/ModuleWithProviders)对象。\n你把这个结果添加到根模块 `AppModule` 的 `imports` 列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ONLYCALLANDIMPORTAFORROOTRESULTINTHEROOTAPPLICATIONMODULEAPPMODULEIMPORTINGITINANYOTHERMODULEPARTICULARLYINALAZYLOADEDMODULEISCONTRARYTOTHEINTENTANDWILLLIKELYPRODUCEARUNTIMEERRORFORMOREINFORMATIONSEESINGLETONSERVICESGUIDESINGLETONSERVICES", "original": "Only call and import a `.forRoot()` result in the root application module, `AppModule`.\nImporting it in any other module, particularly in a lazy-loaded module,\nis contrary to the intent and will likely produce a runtime error.\nFor more information, see [Singleton Services](guide/singleton-services).", "translation": "只能在应用的根模块 `AppModule` 中调用并导入 `.forRoot()` 的结果。\n在其它模块中导入它,特别是惰性加载模块中,是违反设计目标的并会导致一个运行时错误。\n要了解更多,参见[单例服务](guide/singleton-services)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ROUTERMODULEALSOOFFERSAFORCHILDSTATICMETHODFORCONFIGURINGTHEROUTESOFLAZYLOADEDMODULES", "original": "`RouterModule` also offers a `forChild` static method for configuring the routes of lazy-loaded modules.", "translation": "`RouterModule` 也提供了静态方法 `forChild`,用于配置惰性加载模块的路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FORROOTANDFORCHILDARECONVENTIONALNAMESFORMETHODSTHATCONFIGURESERVICESINROOTANDFEATUREMODULESRESPECTIVELY", "original": "`forRoot()` and `forChild()` are conventional names for methods that\nconfigure services in root and feature modules respectively.", "translation": "`forRoot()` 和 `forChild()` 都是约定俗成的方法名,它们分别用于在根模块和特性模块中配置服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANGULARDOESNTRECOGNIZETHESENAMESBUTANGULARDEVELOPERSDOFOLLOWTHISCONVENTIONWHENYOUWRITESIMILARMODULESWITHCONFIGURABLESERVICEPROVIDERS", "original": "Angular doesn't recognize these names but Angular developers do.\nFollow this convention when you write similar modules with configurable service providers.", "translation": "Angular 并不识别这些名字,但是 Angular 的开发人员可以。\n当你写类似的需要可配置的服务提供商时,请遵循这个约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHYISASERVICEPROVIDEDINAFEATUREMODULEVISIBLEEVERYWHERE", "original": "## Why is a service provided in a feature module visible everywhere?", "translation": "## 为什么服务提供商在特性模块中的任何地方都是可见的?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "PROVIDERSLISTEDINTHENGMODULEPROVIDERSOFABOOTSTRAPPEDMODULEHAVEAPPLICATIONSCOPEADDINGASERVICEPROVIDERTONGMODULEPROVIDERSEFFECTIVELYPUBLISHESTHESERVICETOTHEENTIREAPPLICATION", "original": "Providers listed in the `@NgModule.providers` of a bootstrapped module have application scope.\nAdding a service provider to `@NgModule.providers` effectively publishes the service to the entire application.", "translation": "列在引导模块的 `@NgModule.providers` 中的服务提供商具有**全应用级作用域**。\n往 `NgModule.providers` 中添加服务提供商将导致该服务被发布到整个应用中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENYOUIMPORTANNGMODULEANGULARADDSTHEMODULESSERVICEPROVIDERSTHECONTENTSOFITSPROVIDERSLISTTOTHEAPPLICATIONROOTINJECTOR", "original": "When you import an NgModule,\nAngular adds the module's service providers (the contents of its `providers` list)\nto the application root injector.", "translation": "当你导入一个模块时,Angular 就会把该模块的服务提供商(也就是它的 `providers` 列表中的内容)加入该应用的*根注入器*中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THISMAKESTHEPROVIDERVISIBLETOEVERYCLASSINTHEAPPLICATIONTHATKNOWSTHEPROVIDERSLOOKUPTOKENORKNOWSITSNAME", "original": "This makes the provider visible to every class in the application that knows the provider's lookup token, or knows its name.", "translation": "这会让该提供商对应用中所有知道该提供商令牌(token)的类都可见。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THISISBYDESIGNEXTENSIBILITYTHROUGHNGMODULEIMPORTSISAPRIMARYGOALOFTHENGMODULESYSTEMMERGINGNGMODULEPROVIDERSINTOTHEAPPLICATIONINJECTORMAKESITEASYFORAMODULELIBRARYTOENRICHTHEENTIREAPPLICATIONWITHNEWSERVICESBYADDINGTHEHTTPCLIENTMODULEONCEEVERYAPPLICATIONCOMPONENTCANMAKEHTTPREQUESTS", "original": "This is by design.\nExtensibility through NgModule imports is a primary goal of the NgModule system.\nMerging NgModule providers into the application injector\nmakes it easy for a module library to enrich the entire application with new services.\nBy adding the `HttpClientModule` once, every application component can make HTTP requests.", "translation": "Angular 就是如此设计的。\n通过模块导入来实现可扩展性是 Angular 模块系统的主要设计目标。\n把模块的提供商并入应用程序的注入器可以让库模块使用新的服务来强化应用程序变得更容易。\n只要添加一次 `HttpClientModule`,那么应用中的每个组件就都可以发起 Http 请求了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "HOWEVERTHISMIGHTFEELLIKEANUNWELCOMESURPRISEIFYOUEXPECTTHEMODULESSERVICESTOBEVISIBLEONLYTOTHECOMPONENTSDECLAREDBYTHATFEATUREMODULEIFTHEHEROMODULEPROVIDESTHEHEROSERVICEANDTHEROOTAPPMODULEIMPORTSHEROMODULEANYCLASSTHATKNOWSTHEHEROSERVICETYPECANINJECTTHATSERVICENOTJUSTTHECLASSESDECLAREDINTHEHEROMODULE", "original": "However, this might feel like an unwelcome surprise if you expect the module's services\nto be visible only to the components declared by that feature module.\nIf the `HeroModule` provides the `HeroService` and the root `AppModule` imports `HeroModule`,\nany class that knows the `HeroService` _type_ can inject that service,\nnot just the classes declared in the `HeroModule`.", "translation": "不过,如果你期望模块的服务只对那个特性模块内部声明的组件可见,那么这可能会带来一些不受欢迎的意外。\n如果 `HeroModule` 提供了一个 `HeroService`,并且根模块 `AppModule` 导入了 `HeroModule`,那么任何知道 `HeroService`*类型*的类都可能注入该服务,而不仅是在 `HeroModule` 中声明的那些类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHYISASERVICEPROVIDEDINALAZYLOADEDMODULEVISIBLEONLYTOTHATMODULE", "original": "## Why is a service provided in a lazy-loaded module visible only to that module?", "translation": "## 为什么在惰性加载模块中声明的服务提供商只对该模块自身可见?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "UNLIKEPROVIDERSOFTHEMODULESLOADEDATLAUNCHPROVIDERSOFLAZYLOADEDMODULESAREMODULESCOPED", "original": "Unlike providers of the modules loaded at launch,\nproviders of lazy-loaded modules are *module-scoped*.", "translation": "和启动时就加载的模块中的提供商不同,惰性加载模块中的提供商是*局限于模块*的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENTHEANGULARROUTERLAZYLOADSAMODULEITCREATESANEWEXECUTIONCONTEXTTHATCONTEXTHASITSOWNINJECTORGUIDENGMODULEFAQ#QWHYCHILDINJECTORWHYANGULARCREATESACHILDINJECTORWHICHISADIRECTCHILDOFTHEAPPLICATIONINJECTOR", "original": "When the Angular router lazy-loads a module, it creates a new execution context.\nThat [context has its own injector](guide/ngmodule-faq#q-why-child-injector \"Why Angular creates a child injector\"),\nwhich is a direct child of the application injector.", "translation": "当 Angular 路由器惰性加载一个模块时,它创建了一个新的运行环境。\n那个环境[拥有自己的注入器](guide/ngmodule-faq#q-why-child-injector \"为什么 Angular 会创建子注入器\"),它是应用注入器的直属子级。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEROUTERADDSTHELAZYMODULESPROVIDERSANDTHEPROVIDERSOFITSIMPORTEDNGMODULESTOTHISCHILDINJECTOR", "original": "The router adds the lazy module's providers and the providers of its imported NgModules to this child injector.", "translation": "路由器把该惰性加载模块的提供商和它导入的模块的提供商添加到这个子注入器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THESEPROVIDERSAREINSULATEDFROMCHANGESTOAPPLICATIONPROVIDERSWITHTHESAMELOOKUPTOKENWHENTHEROUTERCREATESACOMPONENTWITHINTHELAZYLOADEDCONTEXTANGULARPREFERSSERVICEINSTANCESCREATEDFROMTHESEPROVIDERSTOTHESERVICEINSTANCESOFTHEAPPLICATIONROOTINJECTOR", "original": "These providers are insulated from changes to application providers with the same lookup token.\nWhen the router creates a component within the lazy-loaded context,\nAngular prefers service instances created from these providers to the service instances of the application root injector.", "translation": "这些提供商不会被拥有相同令牌的应用级别提供商的变化所影响。\n当路由器在惰性加载环境中创建组件时,Angular 优先使用惰性加载模块中的服务实例,而不是来自应用的根注入器的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATIFTWOMODULESPROVIDETHESAMESERVICE", "original": "## What if two modules provide the same service?", "translation": "## 如果两个模块提供了*同一个*服务会怎么样?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENTWOIMPORTEDMODULESLOADEDATTHESAMETIMELISTAPROVIDERWITHTHESAMETOKENTHESECONDMODULESPROVIDERWINSTHATSBECAUSEBOTHPROVIDERSAREADDEDTOTHESAMEINJECTOR", "original": "When two imported modules, loaded at the same time, list a provider with the same token,\nthe second module's provider \"wins\". That's because both providers are added to the same injector.", "translation": "当同时加载了两个导入的模块,它们都列出了使用同一个令牌的提供商时,后导入的模块会“获胜”,这是因为这两个提供商都被添加到了同一个注入器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENANGULARLOOKSTOINJECTASERVICEFORTHATTOKENITCREATESANDDELIVERSTHEINSTANCECREATEDBYTHESECONDPROVIDER", "original": "When Angular looks to inject a service for that token,\nit creates and delivers the instance created by the second provider.", "translation": "当 Angular 尝试根据令牌注入服务时,它使用第二个提供商来创建并交付服务实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "EVERYCLASSTHATINJECTSTHISSERVICEGETSTHEINSTANCECREATEDBYTHESECONDPROVIDEREVENCLASSESDECLAREDWITHINTHEFIRSTMODULEGETTHEINSTANCECREATEDBYTHESECONDPROVIDER", "original": "_Every_ class that injects this service gets the instance created by the second provider.\nEven classes declared within the first module get the instance created by the second provider.", "translation": "*每个*注入了该服务的类获得的都是由第二个提供商创建的实例。\n即使是声明在第一个模块中的类,它取得的实例也是来自第二个提供商的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IFNGMODULEAPROVIDESASERVICEFORTOKENXANDIMPORTSANNGMODULEBTHATALSOPROVIDESASERVICEFORTOKENXTHENNGMODULEASSERVICEDEFINITIONWINS", "original": "If NgModule A provides a service for token 'X' and imports an NgModule B\nthat also provides a service for token 'X', then NgModule A's service definition \"wins\".", "translation": "如果模块 A 提供了一个使用令牌'X'的服务,并且导入的模块 B 也用令牌'X'提供了一个服务,那么模块 A 中定义的服务“获胜”了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THESERVICEPROVIDEDBYTHEROOTAPPMODULETAKESPRECEDENCEOVERSERVICESPROVIDEDBYIMPORTEDNGMODULESTHEAPPMODULEALWAYSWINS", "original": "The service provided by the root `AppModule` takes precedence over services provided by imported NgModules.\nThe `AppModule` always wins.", "translation": "由根 `AppModule` 提供的服务相对于所导入模块中提供的服务有优先权。换句话说:`AppModule` 总会获胜。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##HOWDOIRESTRICTSERVICESCOPETOAMODULE", "original": "## How do I restrict service scope to a module?", "translation": "## 我应该如何把服务的范围限制到模块中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENAMODULEISLOADEDATAPPLICATIONLAUNCHITSNGMODULEPROVIDERSHAVEAPPLICATIONWIDESCOPETHATISTHEYAREAVAILABLEFORINJECTIONTHROUGHOUTTHEAPPLICATION", "original": "When a module is loaded at application launch,\nits `@NgModule.providers` have *application-wide scope*;\nthat is, they are available for injection throughout the application.", "translation": "如果一个模块在应用程序启动时就加载,它的 `@NgModule.providers` 具有***全应用级作用域***。\n它们也可用于整个应用的注入中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IMPORTEDPROVIDERSAREEASILYREPLACEDBYPROVIDERSFROMANOTHERIMPORTEDNGMODULESUCHREPLACEMENTMIGHTBEBYDESIGNITCOULDBEUNINTENTIONALANDHAVEADVERSECONSEQUENCES", "original": "Imported providers are easily replaced by providers from another imported NgModule.\nSuch replacement might be by design. It could be unintentional and have adverse consequences.", "translation": "导入的提供商很容易被由其它导入模块中的提供商替换掉。\n这虽然是故意这样设计的,但是也可能引起意料之外的结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ASAGENERALRULEIMPORTMODULESWITHPROVIDERSEXACTLYONCEPREFERABLYINTHEAPPLICATIONSROOTMODULETHATSALSOUSUALLYTHEBESTPLACETOCONFIGUREWRAPANDOVERRIDETHEM", "original": "As a general rule, import modules with providers _exactly once_, preferably in the application's _root module_.\nThat's also usually the best place to configure, wrap, and override them.", "translation": "作为一个通用的规则,应该*只导入一次*带提供商的模块,最好在应用的*根模块*中。\n那里也是配置、包装和改写这些服务的最佳位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "SUPPOSEAMODULEREQUIRESACUSTOMIZEDHTTPBACKENDTHATADDSASPECIALHEADERFORALLHTTPREQUESTSIFANOTHERMODULEELSEWHEREINTHEAPPLICATIONALSOCUSTOMIZESHTTPBACKENDORMERELYIMPORTSTHEHTTPCLIENTMODULEITCOULDOVERRIDETHISMODULESHTTPBACKENDPROVIDERLOSINGTHESPECIALHEADERTHESERVERWILLREJECTHTTPREQUESTSFROMTHISMODULE", "original": "Suppose a module requires a customized `HttpBackend` that adds a special header for all Http requests.\nIf another module elsewhere in the application also customizes `HttpBackend`\nor merely imports the `HttpClientModule`, it could override this module's `HttpBackend` provider,\nlosing the special header. The server will reject http requests from this module.", "translation": "假设模块需要一个定制过的 `HttpBackend`,它为所有的 Http 请求添加一个特别的请求头。\n 如果应用中其它地方的另一个模块也定制了 `HttpBackend` 或仅仅导入了 `HttpClientModule`,它就会改写当前模块的 `HttpBackend` 提供商,丢掉了这个特别的请求头。\n 这样服务器就会拒绝来自该模块的请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "TOAVOIDTHISPROBLEMIMPORTTHEHTTPCLIENTMODULEONLYINTHEAPPMODULETHEAPPLICATIONROOTMODULE", "original": "To avoid this problem, import the `HttpClientModule` only in the `AppModule`, the application _root module_.", "translation": "要消除这个问题,就只能在应用的根模块 `AppModule` 中导入 `HttpClientModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IFYOUMUSTGUARDAGAINSTTHISKINDOFPROVIDERCORRUPTIONDONTRELYONALAUNCHTIMEMODULESPROVIDERS", "original": "If you must guard against this kind of \"provider corruption\", *don't rely on a launch-time module's `providers`.*", "translation": "如果你必须防范这种“提供商腐化”现象,那就*不要依赖于“启动时加载”模块的 `providers`*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "LOADTHEMODULELAZILYIFYOUCANANGULARGIVESALAZYLOADEDMODULEGUIDENGMODULEFAQ#QLAZYLOADEDMODULEPROVIDERVISIBILITYITSOWNCHILDINJECTORTHEMODULESPROVIDERSAREVISIBLEONLYWITHINTHECOMPONENTTREECREATEDWITHTHISINJECTOR", "original": "Load the module lazily if you can.\nAngular gives a [lazy-loaded module](guide/ngmodule-faq#q-lazy-loaded-module-provider-visibility) its own child injector.\nThe module's providers are visible only within the component tree created with this injector.", "translation": "只要可能,就让模块惰性加载。\nAngular 给了[惰性加载模块](guide/ngmodule-faq#q-lazy-loaded-module-provider-visibility)自己的子注入器。\n该模块中的提供商只对由该注入器创建的组件树可见。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IFYOUMUSTLOADTHEMODULEEAGERLYWHENTHEAPPLICATIONSTARTSPROVIDETHESERVICEINACOMPONENTINSTEAD", "original": "If you must load the module eagerly, when the application starts,\n*provide the service in a component instead.*", "translation": "如果你必须在应用程序启动时主动加载该模块,***就改成在组件中提供该服务***。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "CONTINUINGWITHTHESAMEEXAMPLESUPPOSETHECOMPONENTSOFAMODULETRULYREQUIREAPRIVATECUSTOMHTTPBACKEND", "original": "Continuing with the same example, suppose the components of a module truly require a private, custom `HttpBackend`.", "translation": "继续看这个例子,假设某个模块的组件真的需要一个私有的、自定义的 `HttpBackend`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "CREATEATOPCOMPONENTTHATACTSASTHEROOTFORALLOFTHEMODULESCOMPONENTSADDTHECUSTOMHTTPBACKENDPROVIDERTOTHETOPCOMPONENTSPROVIDERSLISTRATHERTHANTHEMODULESPROVIDERSRECALLTHATANGULARCREATESACHILDINJECTORFOREACHCOMPONENTINSTANCEANDPOPULATESTHEINJECTORWITHTHECOMPONENTSOWNPROVIDERS", "original": "Create a \"top component\" that acts as the root for all of the module's components.\nAdd the custom `HttpBackend` provider to the top component's `providers` list rather than the module's `providers`.\nRecall that Angular creates a child injector for each component instance and populates the injector\nwith the component's own providers.", "translation": "那就创建一个“顶级组件”来扮演该模块中所有组件的根。\n把这个自定义的 `HttpBackend` 提供商添加到这个顶级组件的 `providers` 列表中,而不是该模块的 `providers` 中。\n回忆一下,Angular 会为每个组件实例创建一个子注入器,并使用组件自己的 `providers` 来配置这个注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENACHILDOFTHISCOMPONENTASKSFORTHEHTTPBACKENDSERVICEANGULARPROVIDESTHELOCALHTTPBACKENDSERVICENOTTHEVERSIONPROVIDEDINTHEAPPLICATIONROOTINJECTORCHILDCOMPONENTSMAKEPROPERHTTPREQUESTSNOMATTERWHATOTHERMODULESDOTOHTTPBACKEND", "original": "When a child of this component asks for the `HttpBackend` service,\nAngular provides the local `HttpBackend` service,\nnot the version provided in the application root injector.\nChild components make proper HTTP requests no matter what other modules do to `HttpBackend`.", "translation": "当该组件的子组件*想要*一个 `HttpBackend` 服务时,Angular 会提供一个局部的 `HttpBackend` 服务,而不是应用的根注入器创建的那个。\n子组件将正确发起 http 请求,而不管其它模块对 `HttpBackend` 做了什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "BESURETOCREATEMODULECOMPONENTSASCHILDRENOFTHISMODULESTOPCOMPONENT", "original": "Be sure to create module components as children of this module's top component.", "translation": "确保把模块中的组件都创建成这个顶级组件的子组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "YOUCANEMBEDTHECHILDCOMPONENTSINTHETOPCOMPONENTSTEMPLATEALTERNATIVELYMAKETHETOPCOMPONENTAROUTINGHOSTBYGIVINGITAROUTEROUTLETDEFINECHILDROUTESANDLETTHEROUTERLOADMODULECOMPONENTSINTOTHATOUTLET", "original": "You can embed the child components in the top component's template.\nAlternatively, make the top component a routing host by giving it a `<router-outlet>`.\nDefine child routes and let the router load module components into that outlet.", "translation": "你可以把这些子组件都嵌在顶级组件的模板中。或者,给顶级组件一个 `<router-outlet>`,让它作为路由的宿主。\n定义子路由,并让路由器把模块中的组件加载进该路由出口(outlet)中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##SHOULDIADDAPPLICATIONWIDEPROVIDERSTOTHEROOTAPPMODULEORTHEROOTAPPCOMPONENT", "original": "## Should I add application-wide providers to the root `AppModule` or the root `AppComponent`?", "translation": "## 我应该把全应用级提供商添加到根模块 `AppModule` 中还是根组件 `AppComponent` 中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "REGISTERAPPLICATIONWIDEPROVIDERSINTHEROOTAPPMODULENOTINTHEAPPCOMPONENT", "original": "Register application-wide providers in the root `AppModule`, not in the `AppComponent`.", "translation": "在根模块 `AppModule` 中注册全应用级提供商,而不是 `AppComponent` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "LAZYLOADEDMODULESANDTHEIRCOMPONENTSCANINJECTAPPMODULESERVICESTHEYCANTINJECTAPPCOMPONENTSERVICES", "original": "Lazy-loaded modules and their components can inject `AppModule` services;\nthey can't inject `AppComponent` services.", "translation": "惰性加载模块及其组件可以注入 `AppModule` 中的服务,却不能注入 `AppComponent` 中的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "REGISTERASERVICEINAPPCOMPONENTPROVIDERSONLYIFTHESERVICEMUSTBEHIDDENFROMCOMPONENTSOUTSIDETHEAPPCOMPONENTTREETHISISARAREUSECASE", "original": "Register a service in `AppComponent` providers _only_ if the service must be hidden\nfrom components outside the `AppComponent` tree. This is a rare use case.", "translation": "*只有*当该服务必须对 `AppComponent` 组件树之外的组件不可见时,才应该把服务注册进 `AppComponent` 的 `providers` 中。\n这是一个非常罕见的异常用法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "MOREGENERALLYPREFERREGISTERINGPROVIDERSINNGMODULESGUIDENGMODULEFAQ#QCOMPONENTORMODULETOREGISTERINGINCOMPONENTS", "original": "More generally, [prefer registering providers in NgModules](guide/ngmodule-faq#q-component-or-module) to registering in components.", "translation": "更一般地说,[优先把提供商注册进模块中](guide/ngmodule-faq#q-component-or-module),而不是组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "H3CLASSNOTOCDISCUSSIONH3", "original": "<h3 class=\"no-toc\">Discussion</h3>", "translation": "<h3 class=\"no-toc\">讨论</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANGULARREGISTERSALLSTARTUPMODULEPROVIDERSWITHTHEAPPLICATIONROOTINJECTORTHESERVICESTHATROOTINJECTORPROVIDERSCREATEHAVEAPPLICATIONSCOPEWHICHMEANSTHEYAREAVAILABLETOTHEENTIREAPPLICATION", "original": "Angular registers all startup module providers with the application root injector.\nThe services that root injector providers create have application scope, which\nmeans they are available to the entire application.", "translation": "Angular 把所有启动期模块的提供商都注册进了应用的根注入器中。\n这些服务是由根注入器中的提供商创建的,并且在整个应用中都可用。\n它们具有*应用级作用域*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "CERTAINSERVICESSUCHASTHEROUTERONLYWORKWHENYOUREGISTERTHEMINTHEAPPLICATIONROOTINJECTOR", "original": "Certain services, such as the `Router`, only work when you register them in the application root injector.", "translation": "某些服务(比如 `Router`)只有当注册进应用的根注入器时才能正常工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "BYCONTRASTANGULARREGISTERSAPPCOMPONENTPROVIDERSWITHTHEAPPCOMPONENTSOWNINJECTORAPPCOMPONENTSERVICESAREAVAILABLEONLYTOTHATCOMPONENTANDITSCOMPONENTTREETHEYHAVECOMPONENTSCOPE", "original": "By contrast, Angular registers `AppComponent` providers with the `AppComponent`'s own injector.\n`AppComponent` services are available only to that component and its component tree.\nThey have component scope.", "translation": "相反,Angular 使用 `AppComponent` 自己的注入器注册了 `AppComponent` 的提供商。\n`AppComponent` 服务只在该组件及其子组件树中才能使用。\n它们具有*组件级作用域*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEAPPCOMPONENTSINJECTORISACHILDOFTHEROOTINJECTORONEDOWNINTHEINJECTORHIERARCHYFORAPPLICATIONSTHATDONTUSETHEROUTERTHATSALMOSTTHEENTIREAPPLICATIONBUTINROUTEDAPPLICATIONSROUTINGOPERATESATTHEROOTLEVELWHEREAPPCOMPONENTSERVICESDONTEXISTTHISMEANSTHATLAZYLOADEDMODULESCANTREACHTHEM", "original": "The `AppComponent`'s injector is a child of the root injector, one down in the injector hierarchy.\nFor applications that don't use the router, that's almost the entire application.\nBut in routed applications, routing operates at the root level\nwhere `AppComponent` services don't exist.\nThis means that lazy-loaded modules can't reach them.", "translation": "`AppComponent` 的注入器是根注入器的*子级*,注入器层次中的下一级。\n这对于没有路由器的应用来说*几乎是*整个应用了。\n但对那些带路由的应用,路由操作位于顶层,那里不存在 `AppComponent` 服务。这意味着惰性加载模块不能使用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##SHOULDIADDOTHERPROVIDERSTOAMODULEORACOMPONENT", "original": "## Should I add other providers to a module or a component?", "translation": "## 我应该把其它提供商注册到模块中还是组件中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "INGENERALPREFERREGISTERINGFEATURESPECIFICPROVIDERSINMODULESNGMODULEPROVIDERSTOREGISTERINGINCOMPONENTSCOMPONENTPROVIDERS", "original": "In general, prefer registering feature-specific providers in modules (`@NgModule.providers`)\nto registering in components (`@Component.providers`).", "translation": "通常,优先把模块中具体特性的提供商注册到模块中(`@NgModule.providers`),而不是组件中(`@Component.providers`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "REGISTERAPROVIDERWITHACOMPONENTWHENYOUMUSTLIMITTHESCOPEOFASERVICEINSTANCETOTHATCOMPONENTANDITSCOMPONENTTREEAPPLYTHESAMEREASONINGTOREGISTERINGAPROVIDERWITHADIRECTIVE", "original": "Register a provider with a component when you _must_ limit the scope of a service instance\nto that component and its component tree.\nApply the same reasoning to registering a provider with a directive.", "translation": "当你*必须*把服务实例的范围限制到某个组件及其子组件树时,就把提供商注册到该组件中。\n指令的提供商也同样照此处理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FOREXAMPLEANEDITINGCOMPONENTTHATNEEDSAPRIVATECOPYOFACACHINGSERVICESHOULDREGISTERTHESERVICEWITHTHECOMPONENTTHENEACHNEWINSTANCEOFTHECOMPONENTGETSITSOWNCACHEDSERVICEINSTANCETHECHANGESTHATEDITORMAKESINITSSERVICEDONTTOUCHTHEINSTANCESELSEWHEREINTHEAPPLICATION", "original": "For example, an editing component that needs a private copy of a caching service should register\nthe service with the component.\nThen each new instance of the component gets its own cached service instance.\nThe changes that editor makes in its service don't touch the instances elsewhere in the application.", "translation": "例如,如果英雄编辑组件需要自己私有的缓存英雄服务实例,那就应该把 `HeroService` 注册进 `HeroEditorComponent` 中。\n这样,每个新的 `HeroEditorComponent` 的实例都会得到一份自己的缓存服务实例。\n编辑器的改动只会作用于它自己的服务,而不会影响到应用中其它地方的英雄实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ALWAYSREGISTERAPPLICATIONWIDESERVICESWITHTHEROOTAPPMODULEGUIDENGMODULEFAQ#QROOTCOMPONENTORMODULENOTTHEROOTAPPCOMPONENT", "original": "[Always register _application-wide_ services with the root `AppModule`](guide/ngmodule-faq#q-root-component-or-module),\nnot the root `AppComponent`.", "translation": "[总是在根模块 `AppModule` 中注册*全应用级*服务](guide/ngmodule-faq#q-root-component-or-module),而不要在根组件 `AppComponent` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHYISITBADIFASHAREDMODULEPROVIDESASERVICETOALAZYLOADEDMODULE", "original": "## Why is it bad if a shared module provides a service to a lazy-loaded module?", "translation": "## 为什么在共享模块中为惰性加载模块提供服务是个馊主意?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "###THEEAGERLYLOADEDSCENARIO", "original": "### The eagerly loaded scenario", "translation": "### 立即加载的场景", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENANEAGERLYLOADEDMODULEPROVIDESASERVICEFOREXAMPLEAUSERSERVICETHATSERVICEISAVAILABLEAPPLICATIONWIDEIFTHEROOTMODULEPROVIDESUSERSERVICEANDIMPORTSANOTHERMODULETHATPROVIDESTHESAMEUSERSERVICEANGULARREGISTERSONEOFTHEMINTHEROOTAPPINJECTORSEEWHATIFIIMPORTTHESAMEMODULETWICEGUIDENGMODULEFAQ#QREIMPORT", "original": "When an eagerly loaded module provides a service, for example a `UserService`, that service is available application-wide. If the root module provides `UserService` and\nimports another module that provides the same `UserService`, Angular registers one of\nthem in the root app injector (see [What if I import the same module twice?](guide/ngmodule-faq#q-reimport)).", "translation": "当立即加载的模块提供了服务时,比如 `UserService`,该服务是在全应用级可用的。如果根模块提供了 `UserService`,并导入了另一个也提供了同一个 `UserService` 的模块,Angular 就会把它们中的一个注册进应用的根注入器中(参见[如果两次导入了同一个模块会怎样?](guide/ngmodule-faq#q-reimport))。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THENWHENSOMECOMPONENTINJECTSUSERSERVICEANGULARFINDSITINTHEAPPROOTINJECTORANDDELIVERSTHEAPPWIDESINGLETONSERVICENOPROBLEM", "original": "Then, when some component injects `UserService`, Angular finds it in the app root injector,\nand delivers the app-wide singleton service. No problem.", "translation": "然后,当某些组件注入 `UserService` 时,Angular 就会发现它已经在应用的根注入器中了,并交付这个全应用级的单例服务。这样不会出现问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "###THELAZYLOADEDSCENARIO", "original": "### The lazy loaded scenario", "translation": "### 惰性加载场景", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "NOWCONSIDERALAZYLOADEDMODULETHATALSOPROVIDESASERVICECALLEDUSERSERVICE", "original": "Now consider a lazy loaded module that also provides a service called `UserService`.", "translation": "现在,该考虑 `HeroModule` 了,*它是惰性加载的!*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENTHEROUTERLAZYLOADSAMODULEITCREATESACHILDINJECTORANDREGISTERSTHEUSERSERVICEPROVIDERWITHTHATCHILDINJECTORTHECHILDINJECTORISNOTTHEROOTINJECTOR", "original": "When the router lazy loads a module, it creates a child injector and registers the `UserService`\nprovider with that child injector. The child injector is _not_ the root injector.", "translation": "当路由器准备惰性加载 `HeroModule` 的时候,它会创建一个子注入器,并且把 `UserService` 的提供商注册到那个子注入器中。子注入器和根注入器是*不同*的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENANGULARCREATESALAZYCOMPONENTFORTHATMODULEANDINJECTSUSERSERVICEITFINDSAUSERSERVICEPROVIDERINTHELAZYMODULESCHILDINJECTORANDCREATESANEWINSTANCEOFTHEUSERSERVICETHISISANENTIRELYDIFFERENTUSERSERVICEINSTANCETHANTHEAPPWIDESINGLETONVERSIONTHATANGULARINJECTEDINONEOFTHEEAGERLYLOADEDCOMPONENTS", "original": "When Angular creates a lazy component for that module and injects `UserService`,\nit finds a `UserService` provider in the lazy module's _child injector_\nand creates a _new_ instance of the `UserService`.\nThis is an entirely different `UserService` instance\nthan the app-wide singleton version that Angular injected in one of the eagerly loaded components.", "translation": "当 Angular 创建一个惰性加载的 `HeroComponent` 时,它必须注入一个 `UserService`。\n这次,它会从惰性加载模块的*子注入器*中查找 `UserService` 的提供商,并用它创建一个 `UserService` 的新实例。\n这个 `UserService` 实例与 Angular 在主动加载的组件中注入的那个全应用级单例对象截然不同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THISSCENARIOCAUSESYOURAPPTOCREATEANEWINSTANCEEVERYTIMEINSTEADOFUSINGTHESINGLETON", "original": "This scenario causes your app to create a new instance every time, instead of using the singleton.", "translation": "这个场景导致你的应用每次都创建一个新的服务实例,而不是使用单例的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHYDOESLAZYLOADINGCREATEACHILDINJECTOR", "original": "## Why does lazy loading create a child injector?", "translation": "## 为什么惰性加载模块会创建一个子注入器?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANGULARADDSNGMODULEPROVIDERSTOTHEAPPLICATIONROOTINJECTORUNLESSTHENGMODULEISLAZYLOADEDFORALAZYLOADEDNGMODULEANGULARCREATESACHILDINJECTORANDADDSTHEMODULESPROVIDERSTOTHECHILDINJECTOR", "original": "Angular adds `@NgModule.providers` to the application root injector, unless the NgModule is lazy-loaded.\nFor a lazy-loaded NgModule, Angular creates a _child injector_ and adds the module's providers to the child injector.", "translation": "Angular 会把 `@NgModule.providers` 中的提供商添加到应用的根注入器中……\n除非该模块是惰性加载的,这种情况下,它会创建一*子注入器*,并且把该模块的提供商添加到这个子注入器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THISMEANSTHATANNGMODULEBEHAVESDIFFERENTLYDEPENDINGONWHETHERITSLOADEDDURINGAPPLICATIONSTARTORLAZYLOADEDLATERNEGLECTINGTHATDIFFERENCECANLEADTOADVERSECONSEQUENCESGUIDENGMODULEFAQ#QWHYBAD", "original": "This means that an NgModule behaves differently depending on whether it's loaded during application start\nor lazy-loaded later. Neglecting that difference can lead to [adverse consequences](guide/ngmodule-faq#q-why-bad).", "translation": "这意味着模块的行为将取决于它是在应用启动期间加载的还是后来惰性加载的。如果疏忽了这一点,可能导致[严重后果](guide/ngmodule-faq#q-why-bad)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHYDOESNTANGULARADDLAZYLOADEDPROVIDERSTOTHEAPPROOTINJECTORASITDOESFOREAGERLYLOADEDNGMODULES", "original": "Why doesn't Angular add lazy-loaded providers to the app root injector as it does for eagerly loaded NgModules?", "translation": "为什么 Angular 不能像主动加载模块那样把惰性加载模块的提供商也添加到应用程序的根注入器中呢?为什么会出现这种不一致?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEANSWERISGROUNDEDINAFUNDAMENTALCHARACTERISTICOFTHEANGULARDEPENDENCYINJECTIONSYSTEMANINJECTORCANADDPROVIDERSUNTILITSFIRSTUSEDONCEANINJECTORSTARTSCREATINGANDDELIVERINGSERVICESITSPROVIDERLISTISFROZENNONEWPROVIDERSAREALLOWED", "original": "The answer is grounded in a fundamental characteristic of the Angular dependency-injection system.\nAn injector can add providers _until it's first used_.\nOnce an injector starts creating and delivering services, its provider list is frozen; no new providers are allowed.", "translation": "归根结底,这来自于 Angular 依赖注入系统的一个基本特征:\n在注入器还没有被第一次使用之前,可以不断为其添加提供商。\n一旦注入器已经创建和开始交付服务,它的提供商列表就被冻结了,不再接受新的提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "WHENANAPPLICATIONSSTARTSANGULARFIRSTCONFIGURESTHEROOTINJECTORWITHTHEPROVIDERSOFALLEAGERLYLOADEDNGMODULESBEFORECREATINGITSFIRSTCOMPONENTANDINJECTINGANYOFTHEPROVIDEDSERVICESONCETHEAPPLICATIONBEGINSTHEAPPROOTINJECTORISCLOSEDTONEWPROVIDERS", "original": "When an applications starts, Angular first configures the root injector with the providers of all eagerly loaded NgModules\n_before_ creating its first component and injecting any of the provided services.\nOnce the application begins, the app root injector is closed to new providers.", "translation": "当应用启动时,Angular 会首先使用所有主动加载模块中的提供商来配置根注入器,这发生在它创建第一个组件以及注入任何服务之前。\n一旦应用开始工作,应用的根注入器就不再接受新的提供商了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "TIMEPASSESANDAPPLICATIONLOGICTRIGGERSLAZYLOADINGOFANNGMODULEANGULARMUSTADDTHELAZYLOADEDMODULESPROVIDERSTOANINJECTORSOMEWHEREITCANTADDTHEMTOTHEAPPROOTINJECTORBECAUSETHATINJECTORISCLOSEDTONEWPROVIDERSSOANGULARCREATESANEWCHILDINJECTORFORTHELAZYLOADEDMODULECONTEXT", "original": "Time passes and application logic triggers lazy loading of an NgModule.\nAngular must add the lazy-loaded module's providers to an injector somewhere.\nIt can't add them to the app root injector because that injector is closed to new providers.\nSo Angular creates a new child injector for the lazy-loaded module context.", "translation": "之后,应用逻辑开始惰性加载某个模块。\nAngular 必须把这个惰性加载模块中的提供商添加到*某个*注入器中。\n但是它无法将它们添加到应用的根注入器中,因为根注入器已经不再接受新的提供商了。\n于是,Angular 在惰性加载模块的上下文中创建了一个新的子注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##HOWCANITELLIFANNGMODULEORSERVICEWASPREVIOUSLYLOADED", "original": "## How can I tell if an NgModule or service was previously loaded?", "translation": "## 我要如何知道一个模块或服务是否已经加载过了?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "SOMENGMODULESANDTHEIRSERVICESSHOULDBELOADEDONLYONCEBYTHEROOTAPPMODULEIMPORTINGTHEMODULEASECONDTIMEBYLAZYLOADINGAMODULECOULDPRODUCEERRANTBEHAVIORGUIDENGMODULEFAQ#QWHYBADTHATMAYBEDIFFICULTTODETECTANDDIAGNOSE", "original": "Some NgModules and their services should be loaded only once by the root `AppModule`.\nImporting the module a second time by lazy loading a module could [produce errant behavior](guide/ngmodule-faq#q-why-bad)\nthat may be difficult to detect and diagnose.", "translation": "某些模块及其服务只能被根模块 `AppModule` 加载一次。\n 在惰性加载模块中再次导入这个模块会[导致错误的行为](guide/ngmodule-faq#q-why-bad),这个错误可能非常难于检测和诊断。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "TOPREVENTTHISISSUEWRITEACONSTRUCTORTHATATTEMPTSTOINJECTTHEMODULEORSERVICEFROMTHEROOTAPPINJECTORIFTHEINJECTIONSUCCEEDSTHECLASSHASBEENLOADEDASECONDTIMEYOUCANTHROWANERRORORTAKEOTHERREMEDIALACTION", "original": "To prevent this issue, write a constructor that attempts to inject the module or service\nfrom the root app injector. If the injection succeeds, the class has been loaded a second time.\nYou can throw an error or take other remedial action.", "translation": "为了防范这种风险,可以写一个构造函数,它会尝试从应用的根注入器中注入该模块或服务。如果这种注入成功了,那就说明这个类是被第二次加载的,你就可以抛出一个错误,或者采取其它挽救措施。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "CERTAINNGMODULESSUCHASBROWSERMODULEIMPLEMENTSUCHAGUARDHEREISACUSTOMCONSTRUCTORFORANNGMODULECALLEDCOREMODULE", "original": "Certain NgModules, such as `BrowserModule`, implement such a guard.\nHere is a custom constructor for an NgModule called `CoreModule`.", "translation": "某些 Angular 模块(例如 `BrowserModule`)就实现了一个像 Angular 模块那一章的 `CoreModule` 构造函数那样的守卫。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATISANENTRYCOMPONENT", "original": "## What is an `entry component`?", "translation": "## 什么是*入口组件*?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANENTRYCOMPONENTISANYCOMPONENTTHATANGULARLOADSIMPERATIVELYBYTYPE", "original": "An entry component is any component that Angular loads _imperatively_ by type.", "translation": "Angular 根据其类型*不可避免地*加载的组件是*入口组件*,", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ACOMPONENTLOADEDDECLARATIVELYVIAITSSELECTORISNOTANENTRYCOMPONENT", "original": "A component loaded _declaratively_ via its selector is _not_ an entry component.", "translation": "而通过组件选择器*声明式*加载的组件则*不是*入口组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANGULARLOADSACOMPONENTDECLARATIVELYWHENUSINGTHECOMPONENTSSELECTORTOLOCATETHEELEMENTINTHETEMPLATEANGULARTHENCREATESTHEHTMLREPRESENTATIONOFTHECOMPONENTANDINSERTSITINTOTHEDOMATTHESELECTEDELEMENTTHESEARENTENTRYCOMPONENTS", "original": "Angular loads a component declaratively when\nusing the component's selector to locate the element in the template.\nAngular then creates the HTML representation of the component and inserts it into the DOM at the selected element. These aren't entry components.", "translation": "大多数应用组件都是声明式加载的。\nAngular 使用该组件的选择器在模板中定位元素,然后创建表现该组件的 HTML,并把它插入 DOM 中所选元素的内部。它们不是入口组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEBOOTSTRAPPEDROOTAPPCOMPONENTISANENTRYCOMPONENTTRUEITSSELECTORMATCHESANELEMENTTAGININDEXHTMLBUTINDEXHTMLISNTACOMPONENTTEMPLATEANDTHEAPPCOMPONENTSELECTORDOESNTMATCHANELEMENTINANYCOMPONENTTEMPLATE", "original": "The bootstrapped root `AppComponent` is an _entry component_.\nTrue, its selector matches an element tag in `index.html`.\nBut `index.html` isn't a component template and the `AppComponent`\nselector doesn't match an element in any component template.", "translation": "而用于引导的根 `AppComponent` 则是一个*入口组件*。\n虽然它的选择器匹配了 `index.html` 中的一个元素,但是 `index.html` 并不是组件模板,而且 `AppComponent` 选择器也不会在任何组件模板中出现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "COMPONENTSINROUTEDEFINITIONSAREALSOENTRYCOMPONENTSAROUTEDEFINITIONREFERSTOACOMPONENTBYITSTYPETHEROUTERIGNORESAROUTEDCOMPONENTSSELECTORIFITEVENHASONEANDLOADSTHECOMPONENTDYNAMICALLYINTOAROUTEROUTLET", "original": "Components in route definitions are also _entry components_.\nA route definition refers to a component by its _type_.\nThe router ignores a routed component's selector, if it even has one, and\nloads the component dynamically into a `RouterOutlet`.", "translation": "在路由定义中用到的组件也同样是*入口组件*。\n路由定义根据*类型*来引用组件。\n路由器会忽略路由组件的选择器(即使它有选择器),并且把该组件动态加载到 `RouterOutlet` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FORMOREINFORMATIONSEEENTRYCOMPONENTSGUIDEENTRYCOMPONENTS", "original": "For more information, see [Entry Components](guide/entry-components).", "translation": "要了解更多,参见[入口组件](guide/entry-components)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATSTHEDIFFERENCEBETWEENABOOTSTRAPCOMPONENTANDANENTRYCOMPONENT", "original": "## What's the difference between a _bootstrap_ component and an _entry component_?", "translation": "## *引导组件*和*入口组件*有什么不同?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ABOOTSTRAPPEDCOMPONENTISANENTRYCOMPONENTGUIDENGMODULEFAQ#QENTRYCOMPONENTDEFINEDTHATANGULARLOADSINTOTHEDOMDURINGTHEBOOTSTRAPPROCESSAPPLICATIONLAUNCHOTHERENTRYCOMPONENTSARELOADEDDYNAMICALLYBYOTHERMEANSSUCHASWITHTHEROUTER", "original": "A bootstrapped component _is_ an [entry component](guide/ngmodule-faq#q-entry-component-defined)\nthat Angular loads into the DOM during the bootstrap process (application launch).\nOther entry components are loaded dynamically by other means, such as with the router.", "translation": "引导组件是[入口组件](guide/ngmodule-faq#q-entry-component-defined)的一种。\n它是被 Angular 的引导(应用启动)过程加载到 DOM 中的入口组件。\n其它入口组件则是被其它方式动态加载的,比如被路由器加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THENGMODULEBOOTSTRAPPROPERTYTELLSTHECOMPILERTHATTHISISANENTRYCOMPONENTANDITSHOULDGENERATECODETOBOOTSTRAPTHEAPPLICATIONWITHTHISCOMPONENT", "original": "The `@NgModule.bootstrap` property tells the compiler that this is an entry component _and_\nit should generate code to bootstrap the application with this component.", "translation": "`@NgModule.bootstrap` 属性告诉编译器这是一个入口组件,同时它应该生成一些代码来用该组件引导此应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THERESNONEEDTOLISTACOMPONENTINBOTHTHEBOOTSTRAPANDENTRYCOMPONENTSLISTSALTHOUGHDOINGSOISHARMLESS", "original": "There's no need to list a component in both the `bootstrap` and `entryComponents` lists,\nalthough doing so is harmless.", "translation": "不需要把组件同时列在 `bootstrap` 和 `entryComponent` 列表中 —— 虽然这样做也没坏处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FORMOREINFORMATIONSEEENTRYCOMPONENTSGUIDEENTRYCOMPONENTS", "original": "For more information, see [Entry Components](guide/entry-components).", "translation": "要了解更多,参见[入口组件](guide/entry-components)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHENDOIADDCOMPONENTSTOENTRYCOMPONENTS", "original": "## When do I add components to _entryComponents_?", "translation": "## 什么时候我应该把组件加到 `entryComponents` 中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "MOSTAPPLICATIONDEVELOPERSWONTNEEDTOADDCOMPONENTSTOTHEENTRYCOMPONENTS", "original": "Most application developers won't need to add components to the `entryComponents`.", "translation": "大多数应用开发者都不需要把组件添加到 `entryComponents` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANGULARADDSCERTAINCOMPONENTSTOENTRYCOMPONENTSAUTOMATICALLYCOMPONENTSLISTEDINNGMODULEBOOTSTRAPAREADDEDAUTOMATICALLYCOMPONENTSREFERENCEDINROUTERCONFIGURATIONAREADDEDAUTOMATICALLYTHESETWOMECHANISMSACCOUNTFORALMOSTALLENTRYCOMPONENTS", "original": "Angular adds certain components to _entry components_ automatically.\nComponents listed in `@NgModule.bootstrap` are added automatically.\nComponents referenced in router configuration are added automatically.\nThese two mechanisms account for almost all entry components.", "translation": "Angular 会自动把恰当的组件添加到*入口组件*中。\n列在 `@NgModule.bootstrap` 中的组件会自动加入。\n由路由配置引用到的组件会被自动加入。\n用这两种机制添加的组件在入口组件中占了绝大多数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IFYOURAPPHAPPENSTOBOOTSTRAPORDYNAMICALLYLOADACOMPONENTBYTYPEINSOMEOTHERMANNERYOUMUSTADDITTOENTRYCOMPONENTSEXPLICITLY", "original": "If your app happens to bootstrap or dynamically load a component _by type_ in some other manner,\nyou must add it to `entryComponents` explicitly.", "translation": "如果你的应用要用其它手段来*根据类型*引导或动态加载组件,那就得把它显式添加到 `entryComponents` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ALTHOUGHITSHARMLESSTOADDCOMPONENTSTOTHISLISTITSBESTTOADDONLYTHECOMPONENTSTHATARETRULYENTRYCOMPONENTSDONTINCLUDECOMPONENTSTHATAREREFERENCEDGUIDENGMODULEFAQ#QTEMPLATEREFERENCEINTHETEMPLATESOFOTHERCOMPONENTS", "original": "Although it's harmless to add components to this list,\nit's best to add only the components that are truly _entry components_.\nDon't include components that [are referenced](guide/ngmodule-faq#q-template-reference)\nin the templates of other components.", "translation": "虽然把组件加到这个列表中也没什么坏处,不过最好还是只添加真正的*入口组件*。\n不要添加那些被其它组件的模板[引用过](guide/ngmodule-faq#q-template-reference)的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FORMOREINFORMATIONSEEENTRYCOMPONENTSGUIDEENTRYCOMPONENTS", "original": "For more information, see [Entry Components](guide/entry-components).", "translation": "要了解更多,参见[入口组件](guide/entry-components)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHYDOESANGULARNEEDENTRYCOMPONENTS", "original": "## Why does Angular need _entryComponents_?", "translation": "## 为什么 Angular 需要*入口组件*?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEREASONISTREESHAKINGFORPRODUCTIONAPPSYOUWANTTOLOADTHESMALLESTFASTESTCODEPOSSIBLETHECODESHOULDCONTAINONLYTHECLASSESTHATYOUACTUALLYNEEDITSHOULDEXCLUDEACOMPONENTTHATSNEVERUSEDWHETHERORNOTTHATCOMPONENTISDECLARED", "original": "The reason is _tree shaking_. For production apps you want to load the smallest, fastest code possible. The code should contain only the classes that you actually need.\nIt should exclude a component that's never used, whether or not that component is declared.", "translation": "原因在于*摇树优化*。对于产品化应用,你会希望加载尽可能小而快的代码。\n代码中应该仅仅包括那些实际用到的类。\n它应该排除那些从未用过的组件,无论该组件是否被声明过。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "INFACTMANYLIBRARIESDECLAREANDEXPORTCOMPONENTSYOULLNEVERUSEIFYOUDONTREFERENCETHEMTHETREESHAKERDROPSTHESECOMPONENTSFROMTHEFINALCODEPACKAGE", "original": "In fact, many libraries declare and export components you'll never use.\nIf you don't reference them, the tree shaker drops these components from the final code package.", "translation": "事实上,大多数库中声明和导出的组件你都用不到。\n如果你从未引用它们,那么*摇树优化器*就会从最终的代码包中把这些组件砍掉。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IFTHEANGULARCOMPILERGUIDENGMODULEFAQ#QANGULARCOMPILERGENERATEDCODEFOREVERYDECLAREDCOMPONENTITWOULDDEFEATTHEPURPOSEOFTHETREESHAKER", "original": "If the [Angular compiler](guide/ngmodule-faq#q-angular-compiler) generated code for every declared component, it would defeat the purpose of the tree shaker.", "translation": "如果[Angular 编译器](guide/ngmodule-faq#q-angular-compiler)为每个声明的组件都生成了代码,那么摇树优化器的作用就没有了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "INSTEADTHECOMPILERADOPTSARECURSIVESTRATEGYTHATGENERATESCODEONLYFORTHECOMPONENTSYOUUSE", "original": "Instead, the compiler adopts a recursive strategy that generates code only for the components you use.", "translation": "所以,编译器转而采用一种递归策略,它只为你用到的那些组件生成代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THECOMPILERSTARTSWITHTHEENTRYCOMPONENTSTHENITGENERATESCODEFORTHEDECLAREDCOMPONENTSITFINDSGUIDENGMODULEFAQ#QTEMPLATEREFERENCEINANENTRYCOMPONENTSTEMPLATETHENFORTHEDECLAREDCOMPONENTSITDISCOVERSINTHETEMPLATESOFPREVIOUSLYCOMPILEDCOMPONENTSANDSOONATTHEENDOFTHEPROCESSTHECOMPILERHASGENERATEDCODEFOREVERYENTRYCOMPONENTANDEVERYCOMPONENTREACHABLEFROMANENTRYCOMPONENT", "original": "The compiler starts with the entry components,\nthen it generates code for the declared components it [finds](guide/ngmodule-faq#q-template-reference) in an entry component's template,\nthen for the declared components it discovers in the templates of previously compiled components,\nand so on. At the end of the process, the compiler has generated code for every entry component\nand every component reachable from an entry component.", "translation": "编译器从入口组件开始工作,为它在入口组件的模板中[找到的](guide/ngmodule-faq#q-template-reference)那些组件生成代码,然后又为在这些组件中的模板中发现的组件生成代码,以此类推。\n当这个过程结束时,它就已经为每个入口组件以及从入口组件可以抵达的每个组件生成了代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IFACOMPONENTISNTANENTRYCOMPONENTORWASNTFOUNDINATEMPLATETHECOMPILEROMITSIT", "original": "If a component isn't an _entry component_ or wasn't found in a template,\nthe compiler omits it.", "translation": "如果该组件不是*入口组件*或者没有在任何模板中发现过,编译器就会忽略它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATKINDSOFMODULESSHOULDIHAVEANDHOWSHOULDIUSETHEM", "original": "## What kinds of modules should I have and how should I use them?", "translation": "## 有哪些类型的模块?我应该如何使用它们?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "EVERYAPPISDIFFERENTDEVELOPERSHAVEVARIOUSLEVELSOFEXPERIENCEANDCOMFORTWITHTHEAVAILABLECHOICESSOMESUGGESTIONSANDGUIDELINESAPPEARTOHAVEWIDEAPPEAL", "original": "Every app is different. Developers have various levels of experience and comfort with the available choices.\nSome suggestions and guidelines appear to have wide appeal.", "translation": "每个应用都不一样。根据不同程度的经验,开发者会做出不同的选择。下列建议和指导原则广受欢迎。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "SHAREDMODULEISACONVENTIONALNAMEFORANNGMODULEWITHTHECOMPONENTSDIRECTIVESANDPIPESTHATYOUUSEEVERYWHEREINYOURAPPTHISMODULESHOULDCONSISTENTIRELYOFDECLARATIONSMOSTOFTHEMEXPORTED", "original": "`SharedModule` is a conventional name for an `NgModule` with the components, directives, and pipes that you use\neverywhere in your app. This module should consist entirely of `declarations`,\nmost of them exported.", "translation": "为那些可能会在应用中到处使用的组件、指令和管道创建 `SharedModule`。\n 这种模块应该只包含 `declarations`,并且应该导出几乎所有 `declarations` 里面的声明。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THESHAREDMODULEMAYREEXPORTOTHERWIDGETMODULESSUCHASCOMMONMODULEFORMSMODULEANDNGMODULESWITHTHEUICONTROLSTHATYOUUSEMOSTWIDELY", "original": "The `SharedModule` may re-export other widget modules, such as `CommonModule`,\n`FormsModule`, and NgModules with the UI controls that you use most widely.", "translation": "`SharedModule` 可以重新导出其它小部件模块,比如 `CommonModule`、`FormsModule` 和提供你广泛使用的 UI 控件的那些模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THESHAREDMODULESHOULDNOTHAVEPROVIDERSFORREASONSEXPLAINEDPREVIOUSLYGUIDENGMODULEFAQ#QWHYBADNORSHOULDANYOFITSIMPORTEDORREEXPORTEDMODULESHAVEPROVIDERS", "original": "The `SharedModule` should not have `providers` for reasons [explained previously](guide/ngmodule-faq#q-why-bad).\nNor should any of its imported or re-exported modules have `providers`.", "translation": "`SharedModule`***不应该***带有 `providers`,原因[在前面解释过了](guide/ngmodule-faq#q-why-bad)。\n它的导入或重新导出的模块中也不应该有 `providers`。\n如果你要违背这条指导原则,请务必想清楚你在做什么,并要有充分的理由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IMPORTTHESHAREDMODULEINYOURFEATUREMODULESBOTHTHOSELOADEDWHENTHEAPPSTARTSANDTHOSEYOULAZYLOADLATER", "original": "Import the `SharedModule` in your _feature_ modules,\nboth those loaded when the app starts and those you lazy load later.", "translation": "在任何特性模块中(无论是你在应用启动时主动加载的模块还是之后惰性加载的模块),你都可以随意导入这个 `SharedModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "COREMODULEISACONVENTIONALNAMEFORANNGMODULEWITHPROVIDERSFORTHESINGLETONSERVICESYOULOADWHENTHEAPPLICATIONSTARTS", "original": "`CoreModule` is a conventional name for an `NgModule` with `providers` for\nthe singleton services you load when the application starts.", "translation": "为你要在应用启动时加载的那些服务创建一个带 `providers` 的 `CoreModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "IMPORTCOREMODULEINTHEROOTAPPMODULEONLYNEVERIMPORTCOREMODULEINANYOTHERMODULE", "original": "Import `CoreModule` in the root `AppModule` only.\nNever import `CoreModule` in any other module.", "translation": "只能在根模块 `AppModule` 中导入 `CoreModule`。\n永远不要在除根模块 `AppModule` 之外的任何模块中导入 `CoreModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "CONSIDERMAKINGCOREMODULEAPURESERVICESMODULEWITHNODECLARATIONS", "original": "Consider making `CoreModule` a pure services module\nwith no `declarations`.", "translation": "考虑把 `CoreModule` 做成一个没有 `declarations` 的纯服务模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FORMOREINFORMATIONSEESHARINGNGMODULESGUIDESHARINGNGMODULESANDSINGLETONSERVICESGUIDESINGLETONSERVICES", "original": "For more information, see [Sharing NgModules](guide/sharing-ngmodules)\nand [Singleton Services](guide/singleton-services).", "translation": "要了解更多,参见[共享模块](guide/sharing-ngmodules)和[单例服务](guide/singleton-services)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "###FEATUREMODULES", "original": "### Feature Modules", "translation": "### 特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FEATUREMODULESAREMODULESYOUCREATEAROUNDSPECIFICAPPLICATIONBUSINESSDOMAINSUSERWORKFLOWSANDUTILITYCOLLECTIONSTHEYSUPPORTYOURAPPBYCONTAININGAPARTICULARFEATURESUCHASROUTESSERVICESWIDGETSETCTOCONCEPTUALIZEWHATAFEATUREMODULEMIGHTBEINYOURAPPCONSIDERTHATIFYOUWOULDPUTTHEFILESRELATEDTOACERTAINFUNCTIONALITYLIKEASEARCHINONEFOLDERTHATTHECONTENTSOFTHATFOLDERWOULDBEAFEATUREMODULETHATYOUMIGHTCALLYOURSEARCHMODULEITWOULDCONTAINALLOFTHECOMPONENTSROUTINGANDTEMPLATESTHATWOULDMAKEUPTHESEARCHFUNCTIONALITY", "original": "Feature modules are modules you create around specific application business domains, user workflows, and utility collections. They support your app by containing a particular feature,\nsuch as routes, services, widgets, etc. To conceptualize what a feature module might be in your\napp, consider that if you would put the files related to a certain functionality, like a search,\nin one folder, that the contents of that folder would be a feature module that you might call\nyour `SearchModule`. It would contain all of the components, routing, and templates that\nwould make up the search functionality.", "translation": "特性模块是你围绕特定的应用业务领域创建的模块,比如用户工作流、小工具集等。它们包含指定的特性,并为你的应用提供支持,比如路由、服务、窗口部件等。\n要对你的应用中可能会有哪些特性模块有个概念,考虑如果你要把与特定功能(比如搜索)有关的文件放进一个目录下,该目录的内容就可能是一个名叫 `SearchModule` 的特性模块。\n它将会包含构成搜索功能的全部组件、路由和模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FORMOREINFORMATIONSEEFEATUREMODULESGUIDEFEATUREMODULESANDMODULETYPESGUIDEMODULETYPES", "original": "For more information, see [Feature Modules](guide/feature-modules) and\n[Module Types](guide/module-types)", "translation": "要了解更多,参见[特性模块](guide/feature-modules)和[模块的分类](guide/module-types)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATSTHEDIFFERENCEBETWEENNGMODULESANDJAVASCRIPTMODULES", "original": "## What's the difference between NgModules and JavaScript Modules?", "translation": "## 在 NgModule 和 JavaScript 模块之间有什么不同?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "INANANGULARAPPNGMODULESANDJAVASCRIPTMODULESWORKTOGETHER", "original": "In an Angular app, NgModules and JavaScript modules work together.", "translation": "在 Angular 应用中,NgModule 会和 JavaScript 的模块一起工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "INMODERNJAVASCRIPTEVERYFILEISAMODULESEETHEMODULESHTTP:EXPLORINGJSCOMES6CHMODULESHTMLPAGEOFTHEEXPLORINGES6WEBSITEWITHINEACHFILEYOUWRITEANEXPORTSTATEMENTTOMAKEPARTSOFTHEMODULEPUBLIC", "original": "In modern JavaScript, every file is a module\n(see the [Modules](http://exploringjs.com/es6/ch_modules.html) page of the Exploring ES6 website).\nWithin each file you write an `export` statement to make parts of the module public.", "translation": "在现代 JavaScript 中,每个文件都是模块(参见[模块](http://exploringjs.com/es6/ch_modules.html))。\n在每个文件中,你要写一个 `export` 语句将模块的一部分公开。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANANGULARNGMODULEISACLASSWITHTHENGMODULEDECORATORMDASHJAVASCRIPTMODULESDONTHAVETOHAVETHENGMODULEDECORATORANGULARSNGMODULEHASIMPORTSANDEXPORTSANDTHEYSERVEASIMILARPURPOSE", "original": "An Angular NgModule is a class with the `@NgModule` decorator—JavaScript modules\ndon't have to have the `@NgModule` decorator. Angular's `NgModule` has `imports` and `exports` and they serve a similar purpose.", "translation": "Angular 模块是一个带有 `@NgModule` 装饰器的类,而 JavaScript 模块则没有。\nAngular 的 `NgModule` 有自己的 `imports` 和 `exports` 来达到类似的目的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "YOUIMPORTOTHERNGMODULESSOYOUCANUSETHEIREXPORTEDCLASSESINCOMPONENTTEMPLATESYOUEXPORTTHISNGMODULESCLASSESSOTHEYCANBEIMPORTEDANDUSEDBYCOMPONENTSOFOTHERNGMODULES", "original": "You _import_ other NgModules so you can use their exported classes in component templates.\nYou _export_ this NgModule's classes so they can be imported and used by components of _other_ NgModules.", "translation": "你可以*导入*其它 Angular 模块,以便在当前模块的组件模板中使用它们导出的类。\n你可以*导出*当前 Angular 模块中的类,以便其它模块可以导入它们,并用在自己的组件模板中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "FORMOREINFORMATIONSEEJAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "For more information, see [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", "translation": "要了解更多,参见 [JavaScript 模块 vs. NgModules](guide/ngmodule-vs-jsmodule) 一章", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##HOWDOESANGULARFINDCOMPONENTSDIRECTIVESANDPIPESINATEMPLATEBRWHATISAIBTEMPLATEREFERENCEBI", "original": "## How does Angular find components, directives, and pipes in a template?<br>What is a <i><b>template reference</b></i>?", "translation": "## Angular 如何查找模板中的组件、指令和管道?什么是 ***模板引用*** ?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEANGULARCOMPILERGUIDENGMODULEFAQ#QANGULARCOMPILERLOOKSINSIDECOMPONENTTEMPLATESFOROTHERCOMPONENTSDIRECTIVESANDPIPESWHENITFINDSONETHATSATEMPLATEREFERENCE", "original": "The [Angular compiler](guide/ngmodule-faq#q-angular-compiler) looks inside component templates\nfor other components, directives, and pipes. When it finds one, that's a template reference.", "translation": "[Angular 编译器](guide/ngmodule-faq#q-angular-compiler)在组件模板内查找其它组件、指令和管道。一旦找到了,那就是一个“模板引用”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEANGULARCOMPILERFINDSACOMPONENTORDIRECTIVEINATEMPLATEWHENITCANMATCHTHESELECTOROFTHATCOMPONENTORDIRECTIVETOSOMEHTMLINTHATTEMPLATE", "original": "The Angular compiler finds a component or directive in a template when it can match the *selector* of that component or directive to some HTML in that template.", "translation": "Angular 编译器通过在一个模板的 HTML 中匹配组件或指令的**选择器(selector)**,来查找组件或指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THECOMPILERFINDSAPIPEIFTHEPIPESNAMEAPPEARSWITHINTHEPIPESYNTAXOFTHETEMPLATEHTML", "original": "The compiler finds a pipe if the pipe's *name* appears within the pipe syntax of the template HTML.", "translation": "编译器通过分析模板 HTML 中的管道语法中是否出现了特定的管道名来查找对应的管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ANGULARONLYMATCHESSELECTORSANDPIPENAMESFORCLASSESTHATAREDECLAREDBYTHISMODULEOREXPORTEDBYAMODULETHATTHISMODULEIMPORTS", "original": "Angular only matches selectors and pipe names for classes that are declared by this module\nor exported by a module that this module imports.", "translation": "Angular 只查询两种组件、指令或管道:1)那些在当前模块中声明过的,以及 2)那些被当前模块导入的模块所导出的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "##WHATISTHEANGULARCOMPILER", "original": "## What is the Angular compiler?", "translation": "## 什么是 Angular 编译器?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEANGULARCOMPILERCONVERTSTHEAPPLICATIONCODEYOUWRITEINTOHIGHLYPERFORMANTJAVASCRIPTCODETHENGMODULEMETADATAPLAYSANIMPORTANTROLEINGUIDINGTHECOMPILATIONPROCESS", "original": "The Angular compiler converts the application code you write into highly performant JavaScript code.\nThe `@NgModule` metadata plays an important role in guiding the compilation process.", "translation": "*Angular 编译器*会把你所编写的应用代码转换成高性能的 JavaScript 代码。\n在编译过程中,`@NgModule` 的元数据扮演了很重要的角色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THECODEYOUWRITEISNTIMMEDIATELYEXECUTABLEFOREXAMPLECOMPONENTSHAVETEMPLATESTHATCONTAINCUSTOMELEMENTSATTRIBUTEDIRECTIVESANGULARBINDINGDECLARATIONSANDSOMEPECULIARSYNTAXTHATCLEARLYISNTNATIVEHTML", "original": "The code you write isn't immediately executable. For example, components have templates that contain custom elements, attribute directives, Angular binding declarations,\nand some peculiar syntax that clearly isn't native HTML.", "translation": "你写的代码是无法直接执行的。\n比如**组件**。\n组件有一个模板,其中包含了自定义元素、属性型指令、Angular 绑定声明和一些显然不属于原生 HTML 的古怪语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "THEANGULARCOMPILERREADSTHETEMPLATEMARKUPCOMBINESITWITHTHECORRESPONDINGCOMPONENTCLASSCODEANDEMITSCOMPONENTFACTORIES", "original": "The Angular compiler reads the template markup,\ncombines it with the corresponding component class code, and emits _component factories_.", "translation": "*Angular 编译器*读取模板的 HTML,把它和相应的组件类代码组合在一起,并产出*组件工厂*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "ACOMPONENTFACTORYCREATESAPURE100JAVASCRIPTREPRESENTATIONOFTHECOMPONENTTHATINCORPORATESEVERYTHINGDESCRIBEDINITSCOMPONENTMETADATA:THEHTMLTHEBINDINGINSTRUCTIONSTHEATTACHEDSTYLES", "original": "A component factory creates a pure, 100% JavaScript representation\nof the component that incorporates everything described in its `@Component` metadata:\nthe HTML, the binding instructions, the attached styles.", "translation": "组件工厂为组件创建纯粹的、100% JavaScript 的表示形式,它包含了 `@Component` 元数据中描述的一切:HTML、绑定指令、附属的样式等……", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "BECAUSEDIRECTIVESANDPIPESAPPEARINCOMPONENTTEMPLATESTHEANGULARCOMPILERINCORPORATESTHEMINTOCOMPILEDCOMPONENTCODETOO", "original": "Because directives and pipes appear in component templates,\nthe Angular compiler incorporates them into compiled component code too.", "translation": "由于**指令**和**管道**都出现在组件模板中,*Angular 编译器**也同样会把它们组合到编译成的组件代码中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "NGMODULEMETADATATELLSTHEANGULARCOMPILERWHATCOMPONENTSTOCOMPILEFORTHISMODULEANDHOWTOLINKTHISMODULEWITHOTHERMODULES", "original": "`@NgModule` metadata tells the Angular compiler what components to compile for this module and\nhow to link this module with other modules.", "translation": "`@NgModule` 元数据告诉*Angular 编译器*要为当前模块编译哪些组件,以及如何把当前模块和其它模块链接起来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-faq.md" }, { + "key": "#JAVASCRIPTMODULESVSNGMODULES", "original": "# JavaScript Modules vs. NgModules", "translation": "# JavaScript 模块 vs. NgModule", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "ABASICUNDERSTANDINGOFJAVASCRIPTECMASCRIPTMODULESHTTPS:HACKSMOZILLAORG201508ES6INDEPTHMODULES", "original": "A basic understanding of [JavaScript/ECMAScript modules](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/).", "translation": "对 [JavaScript/ECMAScript 模块](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/) 有基本的了解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "JAVASCRIPTANDANGULARUSEMODULESTOORGANIZECODEANDTHOUGHTHEYORGANIZEITDIFFERENTLYANGULARAPPSRELYONBOTH", "original": "JavaScript and Angular use modules to organize code, and\nthough they organize it differently, Angular apps rely on both.", "translation": "JavaScript 和 Angular 都使用模块来组织代码,虽然它们的组织形式不同,但 Angular 的应用会同时依赖两者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "##JAVASCRIPTMODULES", "original": "## JavaScript modules", "translation": "## JavaScript 模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "INJAVASCRIPTMODULESAREINDIVIDUALFILESWITHJAVASCRIPTCODEINTHEMTOMAKEWHATSINTHEMAVAILABLEYOUWRITEANEXPORTSTATEMENTUSUALLYAFTERTHERELEVANTCODELIKETHIS:", "original": "In JavaScript, modules are individual files with JavaScript code in them. To make what’s in them available, you write an export statement, usually after the relevant code, like this:", "translation": "在 JavaScript 中,模块是内含 JavaScript 代码的独立文件。要让其中的东西可用,你要写一个导出语句,通常会放在相应的代码之后,类似这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "THENWHENYOUNEEDTHATFILESCODEINANOTHERFILEYOUIMPORTITLIKETHIS:", "original": "Then, when you need that file’s code in another file, you import it like this:", "translation": "然后,当你在其它文件中需要这个文件的代码时,要像这样导入它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "JAVASCRIPTMODULESHELPYOUNAMESPACEPREVENTINGACCIDENTALGLOBALVARIABLES", "original": "JavaScript modules help you namespace, preventing accidental global variables.", "translation": "JavaScript 模块让你能为代码加上命名空间,防止因为全局变量而引起意外。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "NGMODULESARECLASSESDECORATEDWITHNGMODULETHENGMODULEDECORATORSIMPORTSARRAYTELLSANGULARWHATOTHERNGMODULESTHECURRENTMODULENEEDSTHEMODULESINTHEIMPORTSARRAYAREDIFFERENTTHANJAVASCRIPTMODULESBECAUSETHEYARENGMODULESRATHERTHANREGULARJAVASCRIPTMODULESCLASSESWITHANNGMODULEDECORATORAREBYCONVENTIONKEPTINTHEIROWNFILESBUTWHATMAKESTHEMANNGMODULEISNTBEINGINTHEIROWNFILELIKEJAVASCRIPTMODULESITSTHEPRESENCEOFNGMODULEANDITSMETADATA", "original": "NgModules are classes decorated with `@NgModule`. The `@NgModule` decorator’s `imports` array tells Angular what other NgModules the current module needs. The modules in the `imports` array are different than JavaScript modules because they are NgModules rather than regular JavaScript modules. Classes with an `@NgModule` decorator are by convention kept in their own files, but what makes them an `NgModule` isn’t being in their own file, like JavaScript modules; it’s the presence of `@NgModule` and its metadata.", "translation": "NgModule 是一些带有 `@NgModule` 装饰器的类。`@NgModule` 装饰器的 `imports` 数组会告诉 Angular 哪些其它的 NgModule 是当前模块所需的。\n`imports` 数组中的这些模块与 JavaScript 模块不同,它们都是 NgModule 而不是常规的 JavaScript 模块。\n带有 `@NgModule` 装饰器的类通常会习惯性地放在单独的文件中,但单独的文件并不像 JavaScript 模块那样作为必要条件,而是因为它带有 `@NgModule` 装饰器及其元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "THEAPPMODULEGENERATEDFROMTHEANGULARCLIDEMONSTRATESBOTHKINDSOFMODULESINACTION:", "original": "The `AppModule` generated from the Angular CLI demonstrates both kinds of modules in action:", "translation": "Angular CLI 生成的 `AppModule` 实际演示了这两种模块:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "THENGMODULECLASSESDIFFERFROMJAVASCRIPTMODULEINTHEFOLLOWINGKEYWAYS:", "original": "The NgModule classes differ from JavaScript module in the following key ways:", "translation": "NgModule 类与 JavaScript 模块有下列关键性的不同:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "ANNGMODULEBOUNDSDECLARABLECLASSESGUIDENGMODULEFAQ#QDECLARABLEONLYDECLARABLESARETHEONLYCLASSESTHATMATTERTOTHEANGULARCOMPILERGUIDENGMODULEFAQ#QANGULARCOMPILER", "original": "* An NgModule bounds [declarable classes](guide/ngmodule-faq#q-declarable) only.\nDeclarables are the only classes that matter to the [Angular compiler](guide/ngmodule-faq#q-angular-compiler).", "translation": "Angular 模块只绑定了[*可声明的类*](guide/ngmodule-faq#q-declarable),这些可声明的类只是供[Angular 编译器](guide/ngmodule-faq#q-angular-compiler)用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "INSTEADOFDEFININGALLMEMBERCLASSESINONEGIANTFILEASINAJAVASCRIPTMODULEYOULISTTHEMODULESCLASSESINTHENGMODULEDECLARATIONSLIST", "original": "* Instead of defining all member classes in one giant file as in a JavaScript module,\nyou list the module's classes in the `@NgModule.declarations` list.", "translation": "与 JavaScript 类把它所有的成员类都放在一个巨型文件中不同,你要把该模块的类列在它的 `@NgModule.declarations` 列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "ANNGMODULECANONLYEXPORTTHEDECLARABLECLASSESGUIDENGMODULEFAQ#QDECLARABLEITOWNSORIMPORTSFROMOTHERMODULESITDOESNTDECLAREOREXPORTANYOTHERKINDOFCLASS", "original": "* An NgModule can only export the [declarable classes](guide/ngmodule-faq#q-declarable)\nit owns or imports from other modules. It doesn't declare or export any other kind of class.", "translation": "Angular 模块只能导出[*可声明的类*](guide/ngmodule-faq#q-declarable)。这可能是它自己拥有的也可能是从其它模块中导入的。它不会声明或导出任何其它类型的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "UNLIKEJAVASCRIPTMODULESANNGMODULECANEXTENDTHEENTIREAPPLICATIONWITHSERVICESBYADDINGPROVIDERSTOTHENGMODULEPROVIDERSLIST", "original": "* Unlike JavaScript modules, an NgModule can extend the _entire_ application with services\nby adding providers to the `@NgModule.providers` list.", "translation": "与 JavaScript 模块不同,NgModule 可以通过把服务提供商加到 `@NgModule.providers` 列表中,来用服务扩展*整个*应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "FORMOREINFORMATIONONNGMODULESSEE:", "original": "For more information on NgModules, see:", "translation": "要了解关于 NgModule 的更多知识,参见", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "BOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "* [Bootstrapping](guide/bootstrapping).", - "translation": "[引导](guide/bootstrapping).", + "translation": "[引导启动](guide/bootstrapping)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "FREQUENTLYUSEDMODULESGUIDEFREQUENTNGMODULES", "original": "* [Frequently used modules](guide/frequent-ngmodules).", - "translation": "[常用模块](guide/frequent-ngmodules).", + "translation": "[常用模块](guide/frequent-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "PROVIDERSGUIDEPROVIDERS", "original": "* [Providers](guide/providers).", - "translation": "[服务提供商](guide/providers).", + "translation": "[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodule-vs-jsmodule.md" }, { + "key": "#NGMODULES", "original": "# NgModules", "translation": "# Angular 模块 (NgModule)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWINGCONCEPTS:", "original": "A basic understanding of the following concepts:", "translation": "对下列概念有基本的理解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "BOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "* [Bootstrapping](guide/bootstrapping).", "translation": "[引导启动](guide/bootstrapping)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "JAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "NGMODULESCONFIGURETHEINJECTORANDTHECOMPILERANDHELPORGANIZERELATEDTHINGSTOGETHER", "original": "**NgModules** configure the injector and the compiler and help organize related things together.", "translation": "**NgModules** 用于配置注入器和编译器,并帮你把那些相关的东西组织在一起。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "ANNGMODULEISACLASSMARKEDBYTHENGMODULEDECORATORNGMODULETAKESAMETADATAOBJECTTHATDESCRIBESHOWTOCOMPILEACOMPONENTSTEMPLATEANDHOWTOCREATEANINJECTORATRUNTIMEITIDENTIFIESTHEMODULESOWNCOMPONENTSDIRECTIVESANDPIPESMAKINGSOMEOFTHEMPUBLICTHROUGHTHEEXPORTSPROPERTYSOTHATEXTERNALCOMPONENTSCANUSETHEMNGMODULECANALSOADDSERVICEPROVIDERSTOTHEAPPLICATIONDEPENDENCYINJECTORS", "original": "An NgModule is a class marked by the `@NgModule` decorator.\n`@NgModule` takes a metadata object that describes how to compile a component's template and how to create an injector at runtime.\nIt identifies the module's own components, directives, and pipes,\nmaking some of them public, through the `exports` property, so that external components can use them.\n`@NgModule` can also add service providers to the application dependency injectors.", "translation": "NgModule 是一个带有 `@NgModule` 装饰器的类。\n`@NgModule` 的参数是一个元数据对象,用于描述如何编译组件的模板,以及如何在运行时创建注入器。\n它会标出该模块自己的组件、指令和管道,通过 `exports` 属性公开其中的一部分,以便外部组件使用它们。\n`NgModule` 还能把一些服务提供商添加到应用的依赖注入器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "FORANEXAMPLEAPPSHOWCASINGALLTHETECHNIQUESTHATNGMODULESRELATEDPAGESCOVERSEETHELIVEEXAMPLELIVEEXAMPLEFOREXPLANATIONSONTHEINDIVIDUALTECHNIQUESVISITTHERELEVANTNGMODULEPAGESUNDERTHENGMODULESSECTION", "original": "For an example app showcasing all the techniques that NgModules related pages\ncover, see the <live-example></live-example>. For explanations on the individual techniques, visit the relevant NgModule pages under the NgModules\nsection.", "translation": "要想找一个涉及本章所讲的全部技术的范例,参见 <live-example></live-example>。\n要想得到针对单项技术的一些讲解,参见本目录下的相关页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "##ANGULARMODULARITY", "original": "## Angular modularity", "translation": "## Angular 模块化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "MODULESAREAGREATWAYTOORGANIZEANAPPLICATIONANDEXTENDITWITHCAPABILITIESFROMEXTERNALLIBRARIES", "original": "Modules are a great way to organize an application and extend it with capabilities from external libraries.", "translation": "模块是组织应用和使用外部库扩展应用的最佳途径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "ANGULARLIBRARIESARENGMODULESSUCHASFORMSMODULEHTTPCLIENTMODULEANDROUTERMODULEMANYTHIRDPARTYLIBRARIESAREAVAILABLEASNGMODULESSUCHASAHREFHTTPS:MATERIALANGULARIOMATERIALDESIGNAAHREFHTTP:IONICFRAMEWORKCOMIONICAANDAHREFHTTPS:GITHUBCOMANGULARANGULARFIRE2ANGULARFIRE2A", "original": "Angular libraries are NgModules, such as `FormsModule`, `HttpClientModule`, and `RouterModule`.\nMany third-party libraries are available as NgModules such as\n<a href=\"https://material.angular.io/\">Material Design</a>,\n<a href=\"http://ionicframework.com/\">Ionic</a>, and\n<a href=\"https://github.com/angular/angularfire2\">AngularFire2</a>.", "translation": "Angular 自己的库都是 NgModule,比如 `FormsModule`、`HttpClientModule` 和 `RouterModule`。\n很多第三方库也是 NgModule,比如 <a href=\"https://material.angular.io/\">Material Design</a>、\n<a href=\"http://ionicframework.com/\">Ionic</a> 和\n<a href=\"https://github.com/angular/angularfire2\">AngularFire2</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "NGMODULESCONSOLIDATECOMPONENTSDIRECTIVESANDPIPESINTOCOHESIVEBLOCKSOFFUNCTIONALITYEACHFOCUSEDONAFEATUREAREAAPPLICATIONBUSINESSDOMAINWORKFLOWORCOMMONCOLLECTIONOFUTILITIES", "original": "NgModules consolidate components, directives, and pipes into\ncohesive blocks of functionality, each focused on a\nfeature area, application business domain, workflow, or common collection of utilities.", "translation": "Angular 模块把组件、指令和管道打包成内聚的功能块,每个模块聚焦于一个特性区域、业务领域、工作流或通用工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "MODULESCANALSOADDSERVICESTOTHEAPPLICATIONSUCHSERVICESMIGHTBEINTERNALLYDEVELOPEDLIKESOMETHINGYOUDDEVELOPYOURSELFORCOMEFROMOUTSIDESOURCESSUCHASTHEANGULARROUTERANDHTTPCLIENT", "original": "Modules can also add services to the application.\nSuch services might be internally developed, like something you'd develop yourself or come from outside sources, such as the Angular router and HTTP client.", "translation": "模块还可以把服务加到应用中。\n这些服务可能是内部开发的(比如你自己写的),或者来自外部的(比如 Angular 的路由和 HTTP 客户端)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "MODULESCANBELOADEDEAGERLYWHENTHEAPPLICATIONSTARTSORLAZYLOADEDASYNCHRONOUSLYBYTHEROUTER", "original": "Modules can be loaded eagerly when the application starts or lazy loaded asynchronously by the router.", "translation": "模块可以在应用启动时立即加载,也可以由路由器进行异步的惰性加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "NGMODULEMETADATADOESTHEFOLLOWING:", "original": "NgModule metadata does the following:", "translation": "NgModule 的元数据会做这些:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "DECLARESWHICHCOMPONENTSDIRECTIVESANDPIPESBELONGTOTHEMODULE", "original": "* Declares which components, directives, and pipes belong to the module.", "translation": "声明某些组件、指令和管道属于这个模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "MAKESSOMEOFTHOSECOMPONENTSDIRECTIVESANDPIPESPUBLICSOTHATOTHERMODULESCOMPONENTTEMPLATESCANUSETHEM", "original": "* Makes some of those components, directives, and pipes public so that other module's component templates can use them.", "translation": "公开其中的部分组件、指令和管道,以便其它模块中的组件模板中可以使用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "IMPORTSOTHERMODULESWITHTHECOMPONENTSDIRECTIVESANDPIPESTHATCOMPONENTSINTHECURRENTMODULENEED", "original": "* Imports other modules with the components, directives, and pipes that components in the current module need.", "translation": "导入其它带有组件、指令和管道的模块,这些模块中的元件都是本模块所需的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "PROVIDESSERVICESTHATTHEOTHERAPPLICATIONCOMPONENTSCANUSE", "original": "* Provides services that the other application components can use.", "translation": "提供一些供应用中的其它组件使用的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "EVERYANGULARAPPHASATLEASTONEMODULETHEROOTMODULEYOUBOOTSTRAPGUIDEBOOTSTRAPPINGTHATMODULETOLAUNCHTHEAPPLICATION", "original": "Every Angular app has at least one module, the root module.\nYou [bootstrap](guide/bootstrapping) that module to launch the application.", "translation": "每个 Angular 应用都至少有一个模块,也就是根模块。\n你可以[引导](guide/bootstrapping)那个模块,以启动该应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "THEROOTMODULEISALLYOUNEEDINASIMPLEAPPLICATIONWITHAFEWCOMPONENTSASTHEAPPGROWSYOUREFACTORTHEROOTMODULEINTOFEATUREMODULESGUIDEFEATUREMODULESTHATREPRESENTCOLLECTIONSOFRELATEDFUNCTIONALITYYOUTHENIMPORTTHESEMODULESINTOTHEROOTMODULE", "original": "The root module is all you need in a simple application with a few components.\nAs the app grows, you refactor the root module into [feature modules](guide/feature-modules)\nthat represent collections of related functionality.\nYou then import these modules into the root module.", "translation": "对于那些只有少量组件的简单应用,根模块就是你所需的一切。\n随着应用的成长,你要把这个根模块重构成一些[特性模块](guide/feature-modules),它们代表一组密切相关的功能集。\n然后你再把这些模块导入到根模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "##THEBASICNGMODULE", "original": "## The basic NgModule", "translation": "## 基本的模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "THECLIGENERATESTHEFOLLOWINGBASICAPPMODULEWHENCREATINGANEWAPP", "original": "The CLI generates the following basic app module when creating a new app.", "translation": "CLI 在创建新应用时会生成下列基本的应用模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "ATTHETOPARETHEIMPORTSTATEMENTSTHENEXTSECTIONISWHEREYOUCONFIGURETHENGMODULEBYSTATINGWHATCOMPONENTSANDDIRECTIVESBELONGTOITDECLARATIONSASWELLASWHICHOTHERMODULESITUSESIMPORTSTHISPAGEBUILDSONBOOTSTRAPPINGGUIDEBOOTSTRAPPINGWHICHCOVERSTHESTRUCTUREOFANNGMODULEINDETAILIFYOUNEEDMOREINFORMATIONONTHESTRUCTUREOFANNGMODULEBESURETOREADBOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "At the top are the import statements. The next section is where you configure the `@NgModule` by stating what components and directives belong to it (`declarations`) as well as which other modules it uses (`imports`). This page builds on [Bootstrapping](guide/bootstrapping), which covers the structure of an NgModule in detail. If you need more information on the structure of an `@NgModule`, be sure to read [Bootstrapping](guide/bootstrapping).", "translation": "文件的顶部是一些导入语句。接下来是你配置 `NgModule` 的地方,用于规定哪些组件和指令属于它(`declarations`),以及它使用了哪些其它模块(`imports`)。\n本章是基于[引导](guide/bootstrapping)一章的,那里详细讲了 NgModule 的结构。如果要进一步了解 `@NgModule` 的结构,参见[引导](guide/bootstrapping)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "FEATUREMODULESGUIDEFEATUREMODULES", "original": "* [Feature Modules](guide/feature-modules).", "translation": "[特性模块](guide/feature-modules)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "ENTRYCOMPONENTSGUIDEENTRYCOMPONENTS", "original": "* [Entry Components](guide/entry-components).", "translation": "[入口组件](guide/entry-components)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "PROVIDERSGUIDEPROVIDERS", "original": "* [Providers](guide/providers).", - "translation": "[服务提供商](guide/providers).", + "translation": "[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "TYPESOFNGMODULESGUIDEMODULETYPES", "original": "* [Types of NgModules](guide/module-types).", "translation": "[NgModule 的分类](guide/module-types).", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/ngmodules.md" }, { + "key": "#NPMPACKAGES", "original": "# Npm Packages", "translation": "# Npm 包", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THEANGULARCLIHTTPS:CLIANGULARIOANGULARAPPLICATIONSANDANGULARITSELFDEPENDUPONFEATURESANDFUNCTIONALITYPROVIDEDBYLIBRARIESTHATAREAVAILABLEASNPMHTTPS:DOCSNPMJSCOMPACKAGES", "original": "The [**Angular CLI**](https://cli.angular.io/), Angular applications, and Angular itself depend upon features and functionality provided by libraries that are available as [**npm**](https://docs.npmjs.com/) packages.", "translation": "[**Angular CLI**](https://cli.angular.io/)、Angular 应用程序以及 Angular 本身都依赖于很多第三方包(包括 Angular 自己)提供的特性和功能。这些都是 [**npm**](https://docs.npmjs.com/) 包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "YOUCANDOWNLOADANDINSTALLTHESENPMPACKAGESWITHTHENPMCLIENTHTTPS:DOCSNPMJSCOMCLIINSTALLWHICHRUNSASANODEJSAPPLICATION", "original": "You can download and install these npm packages with the [**npm client**](https://docs.npmjs.com/cli/install), which runs as a node.js application.", "translation": "你可以使用 [**npm**](https://docs.npmjs.com/cli/install) 来安装这些 npm 包,npm 命令也是一个 node.js 应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THEYARNCLIENTHTTPS:YARNPKGCOMENISAPOPULARALTERNATIVEFORDOWNLOADINGANDINSTALLINGNPMPACKAGESTHEANGULARCLIUSESYARNBYDEFAULTTOINSTALLNPMPACKAGESWHENYOUCREATEANEWPROJECT", "original": "The [**yarn client**](https://yarnpkg.com/en/) is a popular alternative for downloading and installing npm packages.\nThe Angular CLI uses `yarn` by default to install npm packages when you create a new project.", "translation": "[**yarn**](https://yarnpkg.com/en/) 是另一个下载和安装 npm 包的工具。\n当创建新项目时,Angular CLI 默认使用 `yarn` 来安装 npm 包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "NODEJSANDNPMAREESSENTIALTOANGULARDEVELOPMENT", "original": "Node.js and npm are essential to Angular development.", "translation": "Node.js 和 npm 是做 Angular 开发的基础。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "GETTHEMNOWHTTPS:DOCSNPMJSCOMGETTINGSTARTEDINSTALLINGNODEINSTALLINGNODEJSANDUPDATINGNPMIFTHEYRENOTALREADYINSTALLEDONYOURMACHINE", "original": "[Get them now](https://docs.npmjs.com/getting-started/installing-node \"Installing Node.js and updating npm\")\nif they're not already installed on your machine.", "translation": "如果你的电脑上还没有装过,请 [立即获取它们](https://docs.npmjs.com/getting-started/installing-node \"Installing Node.js and updating npm\")!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "VERIFYTHATYOUARERUNNINGNODEV4XXORHIGHERANDNPM3XXORHIGHERBYRUNNINGTHECOMMANDSNODEVANDNPMVINATERMINALCONSOLEWINDOWOLDERVERSIONSPRODUCEERRORS", "original": "**Verify that you are running node `v4.x.x` or higher and npm `3.x.x` or higher**\nby running the commands `node -v` and `npm -v` in a terminal/console window.\nOlder versions produce errors.", "translation": "在终端/控制器窗口运行命令 `node -v` 和 `npm -v`,来**确认你运行的 node 是 `v4.x.x` 或更高,npm 为 `3.x.x` 或更高。**\n老版本会产生错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "CONSIDERUSINGNVMHTTPS:GITHUBCOMCREATIONIXNVMFORMANAGINGMULTIPLEVERSIONSOFNODEANDNPMYOUMAYNEEDNVMHTTPS:GITHUBCOMCREATIONIXNVMIFYOUALREADYHAVEPROJECTSRUNNINGONYOURMACHINETHATUSEOTHERVERSIONSOFNODEANDNPM", "original": "Consider using [nvm](https://github.com/creationix/nvm) for managing multiple\nversions of node and npm. You may need [nvm](https://github.com/creationix/nvm) if\nyou already have projects running on your machine that use other versions of node and npm.", "translation": "建议使用[nvm](https://github.com/creationix/nvm)来管理 node 和 npm 的多个版本。如果你机器上已经有某些项目运行了 node 和 npm 的其它版本,你就会需要[nvm](https://github.com/creationix/nvm)了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "BOTHNPMANDYARNINSTALLPACKAGESIDENTIFIEDINAPACKAGEJSONHTTPS:DOCSNPMJSCOMFILESPACKAGEJSONFILE", "original": "Both `npm` and `yarn` install packages identified in a [**package.json**](https://docs.npmjs.com/files/package.json) file.", "translation": "无论是 `npm` 还是 `yarn`,所安装的包都记录在 [**package.json**](https://docs.npmjs.com/files/package.json) 文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THECLINGNEWCOMMANDCREATESADEFAULTPACKAGEJSONFILEFORYOURPROJECTTHISPACKAGEJSONSPECIFIESASTARTERSETOFPACKAGESTHATWORKWELLTOGETHERANDJOINTLYSUPPORTMANYCOMMONAPPLICATIONSCENARIOS", "original": "The CLI `ng new` command creates a default `package.json` file for your project.\nThis `package.json` specifies _a starter set of packages_ that work well together and \njointly support many common application scenarios.", "translation": "CLI 的 `ng new` 命令会给项目创建一个默认的 `package.json` 文件。\n这个 `package.json` 中带有一些起步包,这些包可以很好地协同,并可用于大量常见的应用场景。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "YOUWILLADDPACKAGESTOPACKAGEJSONASYOURAPPLICATIONEVOLVESYOUMAYEVENREMOVESOME", "original": "You will add packages to `package.json` as your application evolves.\nYou may even remove some.", "translation": "随着应用的成长,你还会往 `package.json` 中添加更多包,甚至可能会移除一些。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THISGUIDEFOCUSESONTHEMOSTIMPORTANTPACKAGESINTHESTARTERSET", "original": "This guide focuses on the most important packages in the starter set.", "translation": "本指南中会集中讲解这些初始包中的重点部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "####DEPENDENCIESANDDEVDEPENDENCIES", "original": "#### *dependencies* and *devDependencies*", "translation": "#### *dependencies* 和 *devDependencies*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THEPACKAGEJSONINCLUDESTWOSETSOFPACKAGESDEPENDENCIESGUIDENPMPACKAGES#DEPENDENCIESANDDEVDEPENDENCIESGUIDENPMPACKAGES#DEVDEPENDENCIES", "original": "The `package.json` includes two sets of packages,\n[dependencies](guide/npm-packages#dependencies) and [devDependencies](guide/npm-packages#dev-dependencies).", "translation": "`package.json` 包括两组包:[dependencies](guide/npm-packages#dependencies) 和 [devDependencies](guide/npm-packages#dev-dependencies)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THEDEPENDENCIESAREESSENTIALTORUNNINGTHEAPPLICATIONTHEDEVDEPENDENCIESAREONLYNECESSARYTODEVELOPTHEAPPLICATION", "original": "The *dependencies* are essential to *running* the application.\nThe *devDependencies* are only necessary to *develop* the application.", "translation": "**dependencies** 是**运行**应用的基础,而 **devDependencies** 只有在**开发**应用时才会用到。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THEDEPENDENCIESSECTIONOFPACKAGEJSONCONTAINS:", "original": "The `dependencies` section of `package.json` contains:", "translation": "应用程序的 `package.json` 文件中,`dependencies` 下包括:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARPACKAGES:ANGULARCOREANDOPTIONALMODULESTHEIRPACKAGENAMESBEGINANGULAR", "original": "* **Angular packages**: Angular core and optional modules; their package names begin `@angular/`.", "translation": "**Angular 包**:Angular 的核心和可选模块,它们的包名以 `@angular/` 开头。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "SUPPORTPACKAGES:3RDPARTYLIBRARIESTHATMUSTBEPRESENTFORANGULARAPPSTORUN", "original": "* **Support packages**: 3rd party libraries that must be present for Angular apps to run.", "translation": "**支持包**:那些 Angular 应用运行时必需的第三方库。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "POLYFILLPACKAGES:POLYFILLSPLUGGAPSINABROWSERSJAVASCRIPTIMPLEMENTATION", "original": "* **Polyfill packages**: Polyfills plug gaps in a browser's JavaScript implementation.", "translation": "**腻子脚本**:腻子脚本负责抹平不同浏览器的 JavaScript 实现之间的差异。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "###ANGULARPACKAGES", "original": "### Angular Packages", "translation": "### Angular 包", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARANIMATIONS:ANGULARSANIMATIONSLIBRARYMAKESITEASYTODEFINEANDAPPLYANIMATIONEFFECTSSUCHASPAGEANDLISTTRANSITIONSREADABOUTITINTHEANIMATIONSGUIDEGUIDEANIMATIONS", "original": "**@angular/animations**: Angular's animations library makes it easy to define and apply animation effects such as page and list transitions.\nRead about it in the [Animations guide](guide/animations).", "translation": "**@angular/animations**:Angular 的动画库,它能让你更容易定义和使用动画效果,比如页面和列表的转场动画。要了解更多,请参见 [动画指南](guide/animations)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARCOMMON:THECOMMONLYNEEDEDSERVICESPIPESANDDIRECTIVESPROVIDEDBYTHEANGULARTEAMTHEHTTPCLIENTMODULEGUIDEHTTPISALSOHEREINTHEANGULARCOMMONHTTPSUBFOLDER", "original": "**@angular/common**: The commonly needed services, pipes, and directives provided by the Angular team.\nThe [`HttpClientModule`](guide/http) is also here, in the '@angular/common/http' subfolder.", "translation": "**@angular/common**:由 Angular 开发组提供的常用服务、管道和指令。\n[`HttpClientModule`](guide/http)也在这里,位于'@angular/common/http'子目录下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARCORE:CRITICALRUNTIMEPARTSOFTHEFRAMEWORKNEEDEDBYEVERYAPPLICATIONINCLUDESALLMETADATADECORATORSCOMPONENTDIRECTIVEDEPENDENCYINJECTIONANDTHECOMPONENTLIFECYCLEHOOKS", "original": "**@angular/core**: Critical runtime parts of the framework needed by every application.\nIncludes all metadata decorators, `Component`, `Directive`, dependency injection, and the component lifecycle hooks.", "translation": "**@angular/core**:本框架的每个应用都需要的关键运行部件。包括元数据装饰器,如 `Component` 和 `Directive`、依赖注入以及组件生命周期钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARCOMPILER:ANGULARSTEMPLATECOMPILERITUNDERSTANDSTEMPLATESANDCANCONVERTTHEMTOCODETHATMAKESTHEAPPLICATIONRUNANDRENDERTYPICALLYYOUDONTINTERACTWITHTHECOMPILERDIRECTLYRATHERYOUUSEITINDIRECTLYVIAPLATFORMBROWSERDYNAMICWHENJITCOMPILINGGUIDEAOTCOMPILERINTHEBROWSER", "original": "**@angular/compiler**: Angular's *Template Compiler*.\nIt understands templates and can convert them to code that makes the application run and render.\nTypically you don’t interact with the compiler directly; rather, you use it indirectly via `platform-browser-dynamic` when [JIT compiling](guide/aot-compiler) in the browser.", "translation": "**@angular/compiler**:Angular 的*模板编译器*。\n它会理解模板,并且把模板转化成代码,以供应用程序运行和渲染。\n开发人员通常不会直接跟这个编译器打交道,而是当在浏览器中使用 [JIT 编译](guide/aot-compiler) 时通过 `platform-browser-dynamic` 间接使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARFORMS:SUPPORTFORBOTHTEMPLATEDRIVENGUIDEFORMSANDREACTIVEFORMSGUIDEREACTIVEFORMS", "original": "**@angular/forms**: support for both [template-driven](guide/forms) and [reactive forms](guide/reactive-forms).", "translation": "**@angular/forms**:支持 [template-driven](guide/forms) 和 [reactive forms](guide/reactive-forms)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARHTTP:ANGULARSOLDSOONTOBEDEPRECATEDHTTPCLIENT", "original": "**@angular/http**: Angular's old, soon-to-be-deprecated, HTTP client.", "translation": "**@angular/http**:Angular 的老的、很快就会废弃的 HTTP 客户端库。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARPLATFORMBROWSER:EVERYTHINGDOMANDBROWSERRELATEDESPECIALLYTHEPIECESTHATHELPRENDERINTOTHEDOMTHISPACKAGEALSOINCLUDESTHEBOOTSTRAPSTATICMETHODFORBOOTSTRAPPINGAPPLICATIONSFORPRODUCTIONBUILDSTHATPRECOMPILEWITHAOTGUIDEAOTCOMPILER", "original": "**@angular/platform-browser**: Everything DOM and browser related, especially\nthe pieces that help render into the DOM.\nThis package also includes the `bootstrapStatic()` method\nfor bootstrapping applications for production builds that pre-compile with [AOT](guide/aot-compiler).", "translation": "**@angular/platform-browser**:与 DOM 和浏览器相关的每样东西,特别是帮助往 DOM 中渲染的那部分。\n这个包还包含 bootstrapStatic 方法,用来引导那些在产品构建时要用 [AOT](guide/aot-compiler) 进行编译的应用程序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARPLATFORMBROWSERDYNAMIC:INCLUDESPROVIDERSAPICOREPROVIDERANDMETHODSTOCOMPILEANDRUNTHEAPPONTHECLIENTUSINGTHEJITCOMPILERGUIDEAOTCOMPILER", "original": "**@angular/platform-browser-dynamic**: Includes [Providers](api/core/Provider)\nand methods to compile and run the app on the client \nusing the [JIT compiler](guide/aot-compiler).", "translation": "**@angular/platform-browser-dynamic**: 为应用程序提供一些[提供商](api/core/Provider)和方法,以便在客户端使用 [JIT 编译器](guide/aot-compiler)运行本应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARROUTER:THEROUTERMODULEGUIDEROUTERNAVIGATESAMONGYOURAPPPAGESWHENTHEBROWSERURLCHANGES", "original": "**@angular/router**: The [router module](/guide/router) navigates among your app pages when the browser URL changes.", "translation": "**@angular/router**: [router 模块](/guide/router) 可以在浏览器的 URL 变化时在应用的页面之间导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARUPGRADE:SETOFUTILITIESFORUPGRADINGANGULARJSAPPLICATIONSTOANGULAR", "original": "**@angular/upgrade**: Set of utilities for upgrading AngularJS applications to Angular.", "translation": "**@angular/upgrade**: 一组用来把 AngularJS 应用升级到 Angular 的工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "###POLYFILLPACKAGES", "original": "### Polyfill packages", "translation": "### 腻子脚本包", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "MANYBROWSERSLACKNATIVESUPPORTFORSOMEFEATURESINTHELATESTHTMLSTANDARDSFEATURESTHATANGULARREQUIRESPOLYFILLSHTTPS:ENWIKIPEDIAORGWIKIPOLYFILLCANEMULATETHEMISSINGFEATURESTHEBROWSERSUPPORTGUIDEBROWSERSUPPORTGUIDEEXPLAINSWHICHBROWSERSNEEDPOLYFILLSANDHOWYOUCANADDTHEM", "original": "Many browsers lack native support for some features in the latest HTML standards,\nfeatures that Angular requires.\n\"[Polyfills](https://en.wikipedia.org/wiki/Polyfill)\" can emulate the missing features.\nThe [Browser Support](guide/browser-support) guide explains which browsers need polyfills and \nhow you can add them.", "translation": "很多浏览器欠缺对 Angular 所需的某些最新 HTML 标准、特性的原生支持。\n[腻子脚本](https://en.wikipedia.org/wiki/Polyfill) 可以模拟这些缺失的特性。\n[浏览器支持](guide/browser-support)一章中解释了哪些浏览器分别需要哪些腻子脚本,以及如何添加它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THEDEFAULTPACKAGEJSONINSTALLSTHECOREJSHTTPS:GITHUBCOMZLOIROCKCOREJSPACKAGEWHICHPOLYFILLSMISSINGFEATURESFORSEVERALPOPULARBROWSER", "original": "The default `package.json` installs the **[core-js](https://github.com/zloirock/core-js)** package\nwhich polyfills missing features for several popular browser.", "translation": "默认的 `package.json` 会安装 **[core-js](https://github.com/zloirock/core-js)** 包,它会弥补很多常用浏览器缺失的特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "###SUPPORTPACKAGES", "original": "### Support packages", "translation": "### 支持包", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "RXJSHTTPS:GITHUBCOMBENLESHRXJS:MANYANGULARAPISRETURNOBSERVABLESRXJSISANIMPLEMENTATIONOFTHEPROPOSEDOBSERVABLESSPECIFICATIONHTTPS:GITHUBCOMZENPARSINGESOBSERVABLECURRENTLYBEFORETHETC39HTTP:WWWECMAINTERNATIONALORGMEMENTOTC39HTMCOMMITTEETHATDETERMINESSTANDARDSFORTHEJAVASCRIPTLANGUAGE", "original": "**[rxjs](https://github.com/benlesh/RxJS)**: Many Angular APIs return _observables_. RxJS is an implementation of the proposed [Observables specification](https://github.com/zenparsing/es-observable) currently before the\n[TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.", "translation": "**[rxjs](https://github.com/benlesh/RxJS)**:很多 Angular API 都会返回**可观察对象(Observable)**。RxJS 是个对[Observables 规范](https://github.com/zenparsing/es-observable)的当前实现。[TC39](http://www.ecma-international.org/memento/TC39.htm)委员会将来会决定它是否成为 JavaScript 语言标准的一部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ZONEJSHTTPS:GITHUBCOMANGULARZONEJS:ANGULARRELIESONZONEJSTORUNANGULARSCHANGEDETECTIONPROCESSESWHENNATIVEJAVASCRIPTOPERATIONSRAISEEVENTSZONEJSISANIMPLEMENTATIONOFASPECIFICATIONHTTPS:GISTGITHUBCOMMHEVERY63FDCDF7C65886051D55CURRENTLYBEFORETHETC39HTTP:WWWECMAINTERNATIONALORGMEMENTOTC39HTMCOMMITTEETHATDETERMINESSTANDARDSFORTHEJAVASCRIPTLANGUAGE", "original": "**[zone.js](https://github.com/angular/zone.js)**: Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events. Zone.js is an implementation of a [specification](https://gist.github.com/mhevery/63fdcdf7c65886051d55) currently before the\n[TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.", "translation": "**[zone.js](https://github.com/angular/zone.js)**:Angular 依赖 zone.js,以便在原生 JavaScript 操作触发事件时运行 Angular 的变更检测过程。Zone.js 是对 [这个规范](https://gist.github.com/mhevery/63fdcdf7c65886051d55) 的当前实现。[TC39](http://www.ecma-international.org/memento/TC39.htm)委员会将来会决定它是否成为 JavaScript 语言标准的一部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THEPACKAGESLISTEDINTHEDEVDEPENDENCIESSECTIONOFTHEPACKAGEJSONHELPYOUDEVELOPTHEAPPLICATIONONYOURLOCALMACHINE", "original": "The packages listed in the *devDependencies* section of the `package.json` help you develop the application on your local machine.", "translation": "`package.json` 的 *devDependencies* 区列出的这些包可以帮助你在本机开发应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "YOUDONTDEPLOYTHEMWITHTHEPRODUCTIONAPPLICATIONALTHOUGHTHEREISNOHARMINDOINGSO", "original": "You don't deploy them with the production application although there is no harm in doing so.", "translation": "你不必在生产环境的应用中部署它们,当然,就算部署了也没什么坏处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARCLIHTTPS:GITHUBCOMANGULARANGULARCLI:THEANGULARCLITOOLS", "original": "**[@angular/cli](https://github.com/angular/angular-cli/)**: The Angular CLI tools.", "translation": "**[@angular/cli](https://github.com/angular/angular-cli/)**:Angular 的命令行工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARCOMPILERCLIHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERPACKAGESCOMPILERCLIREADMEMD:THEANGULARCOMPILERWHICHISINVOKEDBYTHEANGULARCLISBUILDANDSERVECOMMANDS", "original": "**[@angular/compiler-cli](https://github.com/angular/angular/blob/master/packages/compiler-cli/README.md)**: The Angular compiler, which is invoked by the Angular CLI's `build` and `serve` commands.", "translation": "**[@angular/compiler-cli](https://github.com/angular/angular/blob/master/packages/compiler-cli/README.md)**:Angular 的编译器,它会被 Angular CLI 的 `build` 和 `serve` 命令调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "ANGULARLANGUAGESERVICEHTTPS:GITHUBCOMANGULARANGULARCLI:THEANGULARLANGUAGESERVICEANALYZESCOMPONENTTEMPLATESANDPROVIDESTYPEANDERRORINFORMATIONTHATTYPESCRIPTAWAREEDITORSCANUSETOIMPROVETHEDEVELOPERSEXPERIENCEFOREXAMPLESEETHEANGULARLANGUAGESERVICEEXTENSIONFORVSCODEHTTPS:MARKETPLACEVISUALSTUDIOCOMITEMSITEMNAMEANGULARNGTEMPLATE", "original": "**[@angular/language-service](https://github.com/angular/angular-cli/)**: The Angular language service analyzes component templates and provides type and error information that TypeScript-aware editors can use to improve the developer's experience.\nFor example, see the [Angular language service extension for VS Code](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template)", "translation": "**[@angular/language-service](https://github.com/angular/angular-cli/)**:Angular 的语言服务会分析组件模板,并且提供类型信息和错误信息,那些支持 TypeScript 的编辑机器可以使用它们来提升开发体验。比如这个:[VS Code 的 Angular 语言服务扩展包](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "TYPES:TYPESCRIPTDEFINITIONFILESFOR3RDPARTYLIBRARIESSUCHASJASMINEANDNODE", "original": "**@types/... **: TypeScript definition files for 3rd party libraries such as Jasmine and node.", "translation": "**@types/... **:第三方库(比如 Jasmine 和 node)的 TypeScript 类型定义文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "CODELYZERHTTPS:WWWNPMJSCOMPACKAGECODELYZER:ALINTERFORANGULARAPPSWHOSERULESCONFORMTOTHEANGULARSTYLEGUIDEGUIDESTYLEGUIDE", "original": "**[codelyzer](https://www.npmjs.com/package/codelyzer)**: A linter for Angular apps whose rules conform to the Angular [style guide](guide/styleguide).", "translation": "**[codelyzer](https://www.npmjs.com/package/codelyzer)**:专用于 Angular 应用的 linter,它的规则适用于 Angular 的[风格指南](guide/styleguide)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "JASMINE:PACKAGESTOSUPPORTTHEJASMINEHTTPS:JASMINEGITHUBIOTESTLIBRARY", "original": "**jasmine/... **: packages to support the [Jasmine](https://jasmine.github.io/) test library.", "translation": "**jasmine/... **:[Jasmine](https://jasmine.github.io/) 测试库的支持包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "KARMA:PACKAGESTOSUPPORTTHEKARMAHTTPS:WWWNPMJSCOMPACKAGEKARMATESTRUNNER", "original": "**karma/... **: packages to support the [karma](https://www.npmjs.com/package/karma) test runner.", "translation": "**karma/... **:[karma](https://www.npmjs.com/package/karma) 测试运行器的支持包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "PROTRACTORHTTPS:WWWNPMJSCOMPACKAGEPROTRACTOR:ANENDTOENDE2EFRAMEWORKFORANGULARAPPSBUILTONTOPOFWEBDRIVERJSHTTPS:GITHUBCOMSELENIUMHQSELENIUMWIKIWEBDRIVERJS", "original": "**[protractor](https://www.npmjs.com/package/protractor)**: an end-to-end (e2e) framework for Angular apps. \nBuilt on top of [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs).", "translation": "**[protractor](https://www.npmjs.com/package/protractor)**:适用于 Angular 应用的端到端(e2e)框架。基于 [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs) 构建。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "TSNODEHTTPS:WWWNPMJSCOMPACKAGETSNODE:TYPESCRIPTEXECUTIONENVIRONMENTANDREPLFORNODE", "original": "**[ts-node](https://www.npmjs.com/package/ts-node)**: TypeScript execution environment and REPL for node.", "translation": "**[ts-node](https://www.npmjs.com/package/ts-node)**:TypeScript 的运行环境以及在 node 环境下用的 REPL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "TSLINTHTTPS:WWWNPMJSCOMPACKAGETSLINT:ASTATICANALYSISTOOLTHATCHECKSTYPESCRIPTCODEFORREADABILITYMAINTAINABILITYANDFUNCTIONALITYERRORS", "original": "**[tslint](https://www.npmjs.com/package/tslint)**: a static analysis tool that checks TypeScript code for readability, maintainability, and functionality errors.", "translation": "**[tslint](https://www.npmjs.com/package/tslint)**:一个静态分析器,用来检查 TypeScript 代码的可读性、可维护性和功能方面的错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "TYPESCRIPTHTTPS:WWWNPMJSCOMPACKAGETYPESCRIPT:THETYPESCRIPTLANGUAGESERVERINCLUDINGTHETSCTYPESCRIPTCOMPILER", "original": "**[typescript](https://www.npmjs.com/package/typescript)**:\nthe TypeScript language server, including the *tsc* TypeScript compiler.", "translation": "**[typescript](https://www.npmjs.com/package/typescript)**:TypeScript 语言服务,包括 TypeScript 编译器 *tsc*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "##SOMANYPACKAGESSOMANYFILES", "original": "## So many packages! So many files!", "translation": "## 那么多包!那么多文件!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "THEDEFAULTPACKAGEJSONINSTALLSMOREPACKAGESTHANYOULLNEEDFORYOURPROJECT", "original": "The default `package.json` installs more packages than you'll need for your project.", "translation": "默认的 `package.json` 所安装的包比项目实际需要的多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "AGIVENPACKAGEMAYCONTAINTENSHUNDREDSEVENTHOUSANDSOFFILESALLOFTHEMINYOURLOCALMACHINESNODEMODULESDIRECTORYTHESHEERVOLUMEOFFILESISINTIMIDATING", "original": "A given package may contain tens, hundreds, even thousands of files,\nall of them in your local machine's `node_modules` directory.\nThe sheer volume of files is intimidating,", "translation": "某个指定的包可能包含十个、上百个甚至上千个文件,它们都位于本机的 `node_modules` 目录下。简直令人生畏。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "YOUCANREMOVEPACKAGESTHATYOUDONTNEEDBUTHOWCANYOUBESURETHATYOUWONTNEEDITASAPRACTICALMATTERITSBETTERTOINSTALLAPACKAGEYOUDONTNEEDTHANWORRYABOUTITEXTRAPACKAGESANDPACKAGEFILESONYOURLOCALDEVELOPMENTMACHINEAREHARMLESS", "original": "You can remove packages that you don't need but how can you be sure that you won't need it?\nAs a practical matter, it's better to install a package you don't need than worry about it.\nExtra packages and package files on your local development machine are harmless.", "translation": "你可以移除这些不需要的包,不过你怎么知道哪些是不需要的呢?\n实际上,安装不需要的包好过担心缺少某个包。\n在你本机开发环境下存在无用的包和文件并没有害处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "BYDEFAULTTHEANGULARCLIBUILDPROCESSBUNDLESINTOASINGLEFILEJUSTTHEFEWVENDORLIBRARYFILESTHATYOURAPPLICATIONACTUALLYNEEDSTHEBROWSERDOWNLOADSTHISBUNDLENOTTHEORIGINALPACKAGEFILES", "original": "By default the Angular CLI build process bundles into a single file just the few \"vendor\" library files that your application actually needs.\nThe browser downloads this bundle, not the original package files.", "translation": "默认情况下,Angular CLI 的构建过程只会把应用程序中实际用到的那些第三方库文件打包到结果中。\n浏览器要下载的是这个包,而不是原始的包文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "SEETHEDEPLOYMENTGUIDEDEPLOYMENTTOLEARNMORE", "original": "See the [Deployment](guide/deployment) to learn more.", "translation": "参见[部署](guide/deployment)一章了解详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/npm-packages.md" }, { + "key": "#OBSERVABLESINANGULAR", "original": "# Observables in Angular", "translation": "# Angular 中的可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "ANGULARMAKESUSEOFOBSERVABLESASANINTERFACETOHANDLEAVARIETYOFCOMMONASYNCHRONOUSOPERATIONSFOREXAMPLE:", "original": "Angular makes use of observables as an interface to handle a variety of common asynchronous operations. For example:", "translation": "Angular 使用可观察对象作为处理各种常用异步操作的接口。比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "THEEVENTEMITTERCLASSEXTENDSOBSERVABLE", "original": "* The `EventEmitter` class extends `Observable`.", "translation": "`EventEmitter` 类派生自 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "THEHTTPMODULEUSESOBSERVABLESTOHANDLEAJAXREQUESTSANDRESPONSES", "original": "* The HTTP module uses observables to handle AJAX requests and responses.", "translation": "HTTP 模块使用可观察对象来处理 AJAX 请求和响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "THEROUTERANDFORMSMODULESUSEOBSERVABLESTOLISTENFORANDRESPONDTOUSERINPUTEVENTS", "original": "* The Router and Forms modules use observables to listen for and respond to user-input events.", "translation": "路由器和表单模块使用可观察对象来监听对用户输入事件的响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "##EVENTEMITTER", "original": "## Event emitter", "translation": "## 事件发送器 `EventEmitter`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "ANGULARPROVIDESANEVENTEMITTERCLASSTHATISUSEDWHENPUBLISHINGVALUESFROMACOMPONENTTHROUGHTHEOUTPUTDECORATOREVENTEMITTEREXTENDSOBSERVABLEADDINGANEMITMETHODSOITCANSENDARBITRARYVALUESWHENYOUCALLEMITITPASSESTHEEMITTEDVALUETOTHENEXTMETHODOFANYSUBSCRIBEDOBSERVER", "original": "Angular provides an `EventEmitter` class that is used when publishing values from a component through the `@Output()` decorator. `EventEmitter` extends `Observable`, adding an `emit()` method so it can send arbitrary values. When you call `emit()`, it passes the emitted value to the `next()` method of any subscribed observer.", "translation": "Angular 提供了一个 `EventEmitter` 类,它用来从组件的 `@Output()` 属性中发布一些值。`EventEmitter` 扩展了 `Observable`,并添加了一个 `emit()` 方法,这样它就可以发送任意值了。当你调用 `emit()` 时,就会把所发送的值传给订阅上来的观察者的 `next()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "AGOODEXAMPLEOFUSAGECANBEFOUNDONTHEEVENTEMITTERHTTPS:ANGULARIOAPICOREEVENTEMITTERDOCUMENTATIONHEREISTHEEXAMPLECOMPONENTTHATLISTENSFOROPENANDCLOSEEVENTS:", "original": "A good example of usage can be found on the [EventEmitter](https://angular.io/api/core/EventEmitter) documentation. Here is the example component that listens for open and close events:", "translation": "这种用法的例子参见 [EventEmitter](https://angular.cn/api/core/EventEmitter) 文档。下面这个范例组件监听了 `open` 和 `close` 事件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "HEREISTHECOMPONENTDEFINITION:", "original": "Here is the component definition:", "translation": "组件的定义如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "ANGULARSHTTPCLIENTRETURNSOBSERVABLESFROMHTTPMETHODCALLSFORINSTANCEHTTPGETAPIRETURNSANOBSERVABLETHISPROVIDESSEVERALADVANTAGESOVERPROMISEBASEDHTTPAPIS:", "original": "Angular’s `HttpClient` returns observables from HTTP method calls. For instance, `http.get(‘/api’)` returns an observable. This provides several advantages over promise-based HTTP APIs:", "translation": "Angular 的 `HttpClient` 从 HTTP 方法调用中返回了可观察对象。例如,`http.get(‘/api’)` 就会返回可观察对象。相对于基于承诺(Promise)的 HTTP API,它有一系列优点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "OBSERVABLESDONOTMUTATETHESERVERRESPONSEASCANOCCURTHROUGHCHAINEDTHENCALLSONPROMISESINSTEADYOUCANUSEASERIESOFOPERATORSTOTRANSFORMVALUESASNEEDED", "original": "* Observables do not mutate the server response (as can occur through chained `.then()` calls on promises). Instead, you can use a series of operators to transform values as needed.", "translation": "可观察对象不会修改服务器的响应(和在承诺上串联起来的 `.then()` 调用一样)。反之,你可以使用一系列操作符来按需转换这些值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "HTTPREQUESTSARECANCELLABLETHROUGHTHEUNSUBSCRIBEMETHOD", "original": "* HTTP requests are cancellable through the `unsubscribe()` method.", "translation": "HTTP 请求是可以通过 `unsubscribe()` 方法来取消的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "REQUESTSCANBECONFIGUREDTOGETPROGRESSEVENTUPDATES", "original": "* Requests can be configured to get progress event updates.", "translation": "请求可以进行配置,以获取进度事件的变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "FAILEDREQUESTSCANBERETRIEDEASILY", "original": "* Failed requests can be retried easily.", "translation": "失败的请求很容易重试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "##ASYNCPIPE", "original": "## Async pipe", "translation": "## Async 管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "THEASYNCPIPEHTTPS:ANGULARIOAPICOMMONASYNCPIPESUBSCRIBESTOANOBSERVABLEORPROMISEANDRETURNSTHELATESTVALUEITHASEMITTEDWHENANEWVALUEISEMITTEDTHEPIPEMARKSTHECOMPONENTTOBECHECKEDFORCHANGES", "original": "The [AsyncPipe](https://angular.io/api/common/AsyncPipe) subscribes to an observable or promise and returns the latest value it has emitted. When a new value is emitted, the pipe marks the component to be checked for changes.", "translation": "[AsyncPipe](https://angular.io/api/common/AsyncPipe) 会订阅一个可观察对象或承诺,并返回其发出的最后一个值。当发出新值时,该管道就会把这个组件标记为需要进行变更检查的(译注:因此可能导致刷新界面)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "THEFOLLOWINGEXAMPLEBINDSTHETIMEOBSERVABLETOTHECOMPONENTSVIEWTHEOBSERVABLECONTINUOUSLYUPDATESTHEVIEWWITHTHECURRENTTIME", "original": "The following example binds the `time` observable to the component's view. The observable continuously updates the view with the current time.", "translation": "下面的例子把 `time` 这个可观察对象绑定到了组件的视图中。这个可观察对象会不断使用当前时间更新组件的视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "##ROUTER", "original": "## Router", "translation": "## 路由器 (router)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "ROUTEREVENTSHTTPS:ANGULARIOAPIROUTERROUTER#EVENTSPROVIDESEVENTSASOBSERVABLESYOUCANUSETHEFILTEROPERATORFROMRXJSTOLOOKFOREVENTSOFINTERESTANDSUBSCRIBETOTHEMINORDERTOMAKEDECISIONSBASEDONTHESEQUENCEOFEVENTSINTHENAVIGATIONPROCESSHERESANEXAMPLE:", "original": "[`Router.events`](https://angular.io/api/router/Router#events) provides events as observables. You can use the `filter()` operator from RxJS to look for events of interest, and subscribe to them in order to make decisions based on the sequence of events in the navigation process. Here's an example:", "translation": "[`Router.events`](https://angular.io/api/router/Router#events) 以可观察对象的形式提供了其事件。\n你可以使用 RxJS 中的 `filter()` 操作符来找到感兴趣的事件,并且订阅它们,以便根据浏览过程中产生的事件序列作出决定。\n例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "THEACTIVATEDROUTEHTTPS:ANGULARIOAPIROUTERACTIVATEDROUTEISANINJECTEDROUTERSERVICETHATMAKESUSEOFOBSERVABLESTOGETINFORMATIONABOUTAROUTEPATHANDPARAMETERSFOREXAMPLEACTIVATEROUTEURLCONTAINSANOBSERVABLETHATREPORTSTHEROUTEPATHORPATHSHERESANEXAMPLE:", "original": "The [ActivatedRoute](https://angular.io/api/router/ActivatedRoute) is an injected router service that makes use of observables to get information about a route path and parameters. For example, `ActivateRoute.url` contains an observable that reports the route path or paths. Here's an example:", "translation": "[ActivatedRoute](https://angular.io/api/router/ActivatedRoute) 是一个可注入的路由器服务,它使用可观察对象来获取关于路由路径和路由参数的信息。比如,`ActivateRoute.url` 包含一个用于汇报路由路径的可观察对象。例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "##REACTIVEFORMS", "original": "## Reactive forms", "translation": "## 响应式表单 (reactive forms)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "REACTIVEFORMSHAVEPROPERTIESTHATUSEOBSERVABLESTOMONITORFORMCONTROLVALUESTHEFORMCONTROLHTTPS:ANGULARIOAPIFORMSFORMCONTROLPROPERTIESVALUECHANGESANDSTATUSCHANGESCONTAINOBSERVABLESTHATRAISECHANGEEVENTSSUBSCRIBINGTOANOBSERVABLEFORMCONTROLPROPERTYISAWAYOFTRIGGERINGAPPLICATIONLOGICWITHINTHECOMPONENTCLASSFOREXAMPLE:", "original": "Reactive forms have properties that use observables to monitor form control values. The [`FormControl`](https://angular.io/api/forms/FormControl) properties `valueChanges` and `statusChanges` contain observables that raise change events. Subscribing to an observable form-control property is a way of triggering application logic within the component class. For example:", "translation": "响应式表单具有一些属性,它们使用可观察对象来监听表单控件的值。\n[`FormControl`](https://angular.io/api/forms/FormControl) 的 `valueChanges` 属性和 `statusChanges` 属性包含了会发出变更事件的可观察对象。订阅可观察的表单控件属性是在组件类中触发应用逻辑的途径之一。比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables-in-angular.md" }, { + "key": "#OBSERVABLES", "original": "# Observables", "translation": "# 可观察对象(Observable)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "OBSERVABLESPROVIDESUPPORTFORPASSINGMESSAGESBETWEENPUBLISHERSANDSUBSCRIBERSINYOURAPPLICATIONOBSERVABLESOFFERSIGNIFICANTBENEFITSOVEROTHERTECHNIQUESFOREVENTHANDLINGASYNCHRONOUSPROGRAMMINGANDHANDLINGMULTIPLEVALUES", "original": "Observables provide support for passing messages between publishers and subscribers in your application. Observables offer significant benefits over other techniques for event handling, asynchronous programming, and handling multiple values.", "translation": "可观察对象支持在应用中的发布者和订阅者之间传递消息。\n在需要进行事件处理、异步编程和处理多个值的时候,可观察对象相对其它技术有着显著的优点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "OBSERVABLESAREDECLARATIVEMDASHTHATISYOUDEFINEAFUNCTIONFORPUBLISHINGVALUESBUTITISNOTEXECUTEDUNTILACONSUMERSUBSCRIBESTOITTHESUBSCRIBEDCONSUMERTHENRECEIVESNOTIFICATIONSUNTILTHEFUNCTIONCOMPLETESORUNTILTHEYUNSUBSCRIBE", "original": "Observables are declarative—that is, you define a function for publishing values, but it is not executed until a consumer subscribes to it. The subscribed consumer then receives notifications until the function completes, or until they unsubscribe.", "translation": "可观察对象是声明式的 —— 也就是说,虽然你定义了一个用于发布值的函数,但是在有消费者订阅它之前,这个函数并不会实际执行。\n订阅之后,当这个函数执行完或取消订阅时,订阅者就会收到通知。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "ANOBSERVABLECANDELIVERMULTIPLEVALUESOFANYTYPEMDASHLITERALSMESSAGESOREVENTSDEPENDINGONTHECONTEXTTHEAPIFORRECEIVINGVALUESISTHESAMEWHETHERTHEVALUESAREDELIVEREDSYNCHRONOUSLYORASYNCHRONOUSLYBECAUSESETUPANDTEARDOWNLOGICAREBOTHHANDLEDBYTHEOBSERVABLEYOURAPPLICATIONCODEONLYNEEDSTOWORRYABOUTSUBSCRIBINGTOCONSUMEVALUESANDWHENDONEUNSUBSCRIBINGWHETHERTHESTREAMWASKEYSTROKESANHTTPRESPONSEORANINTERVALTIMERTHEINTERFACEFORLISTENINGTOVALUESANDSTOPPINGLISTENINGISTHESAME", "original": "An observable can deliver multiple values of any type—literals, messages, or events, depending on the context. The API for receiving values is the same whether the values are delivered synchronously or asynchronously. Because setup and teardown logic are both handled by the observable, your application code only needs to worry about subscribing to consume values, and when done, unsubscribing. Whether the stream was keystrokes, an HTTP response, or an interval timer, the interface for listening to values and stopping listening is the same.", "translation": "可观察对象可以发送多个任意类型的值 —— 字面量、消息、事件。无论这些值是同步发送的还是异步发送的,接收这些值的 API 都是一样的。\n由于准备(setup)和清场(teardown)的逻辑都是由可观察对象自己处理的,因此你的应用代码只管订阅并消费这些值就可以了,做完之后,取消订阅。无论这个流是击键流、HTTP 响应流还是定时器,对这些值进行监听和停止监听的接口都是一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "BECAUSEOFTHESEADVANTAGESOBSERVABLESAREUSEDEXTENSIVELYWITHINANGULARANDARERECOMMENDEDFORAPPDEVELOPMENTASWELL", "original": "Because of these advantages, observables are used extensively within Angular, and are recommended for app development as well.", "translation": "由于这些优点,可观察对象在 Angular 中得到广泛使用,也同样建议应用开发者好好使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "##BASICUSAGEANDTERMS", "original": "## Basic usage and terms", "translation": "## 基本用法和词汇", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "ASAPUBLISHERYOUCREATEANOBSERVABLEINSTANCETHATDEFINESASUBSCRIBERFUNCTIONTHISISTHEFUNCTIONTHATISEXECUTEDWHENACONSUMERCALLSTHESUBSCRIBEMETHODTHESUBSCRIBERFUNCTIONDEFINESHOWTOOBTAINORGENERATEVALUESORMESSAGESTOBEPUBLISHED", "original": "As a publisher, you create an `Observable` instance that defines a *subscriber* function. This is the function that is executed when a consumer calls the `subscribe()` method. The subscriber function defines how to obtain or generate values or messages to be published.", "translation": "作为发布者,你创建一个 `Observable` 的实例,其中定义了一个*订阅者(subscriber)*函数。\n当有消费者调用 `subscribe()` 方法时,这个函数就会执行。\n订阅者函数用于定义“如何获取或生成那些要发布的值或消息”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "TOEXECUTETHEOBSERVABLEYOUHAVECREATEDANDBEGINRECEIVINGNOTIFICATIONSYOUCALLITSSUBSCRIBEMETHODPASSINGANOBSERVERTHISISAJAVASCRIPTOBJECTTHATDEFINESTHEHANDLERSFORTHENOTIFICATIONSYOURECEIVETHESUBSCRIBECALLRETURNSASUBSCRIPTIONOBJECTTHATHASANUNSUBSCRIBEMETHODWHICHYOUCALLTOSTOPRECEIVINGNOTIFICATIONS", "original": "To execute the observable you have created and begin receiving notifications, you call its `subscribe()` method, passing an *observer*. This is a JavaScript object that defines the handlers for the notifications you receive. The `subscribe()` call returns a `Subscription` object that has an `unsubscribe()` method, which you call to stop receiving notifications.", "translation": "要执行所创建的可观察对象,并开始从中接收通知,你就要调用它的 `subscribe()` 方法,并传入一个*观察者(observer)*。\n这是一个 JavaScript 对象,它定义了你收到的这些消息的处理器(handler)。\n`subscribe()` 调用会返回一个 `Subscription` 对象,该对象具有一个 `unsubscribe()` 方法。\n当调用该方法时,你就会停止接收通知。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "HERESANEXAMPLETHATDEMONSTRATESTHEBASICUSAGEMODELBYSHOWINGHOWANOBSERVABLECOULDBEUSEDTOPROVIDEGEOLOCATIONUPDATES", "original": "Here's an example that demonstrates the basic usage model by showing how an observable could be used to provide geolocation updates.", "translation": "下面这个例子中示范了这种基本用法,它展示了如何使用可观察对象来对当前地理位置进行更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "##DEFININGOBSERVERS", "original": "## Defining observers", "translation": "## 定义观察者", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "AHANDLERFORRECEIVINGOBSERVABLENOTIFICATIONSIMPLEMENTSTHEOBSERVERINTERFACEITISANOBJECTTHATDEFINESCALLBACKMETHODSTOHANDLETHETHREETYPESOFNOTIFICATIONSTHATANOBSERVABLECANSEND:", "original": "A handler for receiving observable notifications implements the `Observer` interface. It is an object that defines callback methods to handle the three types of notifications that an observable can send:", "translation": "用于接收可观察对象通知的处理器要实现 `Observer` 接口。这个对象定义了一些回调函数来处理可观察对象可能会发来的三种通知:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "NOTIFICATIONTYPEDESCRIPTION::NEXTREQUIREDAHANDLERFOREACHDELIVEREDVALUECALLEDZEROORMORETIMESAFTEREXECUTIONSTARTSERROROPTIONALAHANDLERFORANERRORNOTIFICATIONANERRORHALTSEXECUTIONOFTHEOBSERVABLEINSTANCECOMPLETEOPTIONALAHANDLERFORTHEEXECUTIONCOMPLETENOTIFICATIONDELAYEDVALUESCANCONTINUETOBEDELIVEREDTOTHENEXTHANDLERAFTEREXECUTIONISCOMPLETE", + "original": "| Notification type | Description |\n|:---------|:-------------------------------------------|\n| `next` | Required. A handler for each delivered value. Called zero or more times after execution starts.|\n| `error` | Optional. A handler for an error notification. An error halts execution of the observable instance.|\n| `complete` | Optional. A handler for the execution-complete notification. Delayed values can continue to be delivered to the next handler after execution is complete.|", + "translation": "| <t>Notification type</t><t>通知类型</t> | <t>Description</t><t>说明</t> |\n|:---------|:-------------------------------------------|\n| `next` | <t>Required. A handler for each delivered value. Called zero or more times after execution starts.</t><t>必要。用来处理每个送达值。在开始执行后可能执行零次或多次。</t>|\n| `error` | <t>Optional. A handler for an error notification. An error halts execution of the observable instance.</t><t> 可选。用来处理错误通知。错误会中断这个可观察对象实例的执行过程。 </t>|\n| `complete` | <t>Optional. A handler for the execution-complete notification. Delayed values can continue to be delivered to the next handler after execution is complete.</t><t> 可选。用来处理执行完毕(complete)通知。当执行完毕后,这些值就会继续传给下一个处理器。 </t>|", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" + }, + { + "key": "ANOBSERVEROBJECTCANDEFINEANYCOMBINATIONOFTHESEHANDLERSIFYOUDONTSUPPLYAHANDLERFORANOTIFICATIONTYPETHEOBSERVERIGNORESNOTIFICATIONSOFTHATTYPE", "original": "An observer object can define any combination of these handlers. If you don't supply a handler for a notification type, the observer ignores notifications of that type.", "translation": "观察者对象可以定义这三种处理器的任意组合。如果你不为某种通知类型提供处理器,这个观察者就会忽略相应类型的通知。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "##SUBSCRIBING", "original": "## Subscribing", "translation": "## 订阅", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "ANOBSERVABLEINSTANCEBEGINSPUBLISHINGVALUESONLYWHENSOMEONESUBSCRIBESTOITYOUSUBSCRIBEBYCALLINGTHESUBSCRIBEMETHODOFTHEINSTANCEPASSINGANOBSERVEROBJECTTORECEIVETHENOTIFICATIONS", "original": "An `Observable` instance begins publishing values only when someone subscribes to it. You subscribe by calling the `subscribe()` method of the instance, passing an observer object to receive the notifications.", "translation": "只有当有人订阅 `Observable` 的实例时,它才会开始发布值。\n订阅时要先调用该实例的 `subscribe()` 方法,并把一个观察者对象传给它,用来接收通知。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "INORDERTOSHOWHOWSUBSCRIBINGWORKSWENEEDTOCREATEANEWOBSERVABLETHEREISACONSTRUCTORTHATYOUUSETOCREATENEWINSTANCESBUTFORILLUSTRATIONWECANUSESOMESTATICMETHODSONTHEOBSERVABLECLASSTHATCREATESIMPLEOBSERVABLESOFFREQUENTLYUSEDTYPES:", "original": "In order to show how subscribing works, we need to create a new observable. There is a constructor that you use to create new instances, but for illustration, we can use some static methods on the `Observable` class that create simple observables of frequently used types:", "translation": "为了展示订阅的原理,我们需要创建新的可观察对象。它有一个构造函数可以用来创建新实例,但是为了更简明,也可以使用 `Observable` 上定义的一些静态方法来创建一些常用的简单可观察对象:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "OBSERVABLEOFITEMSMDASHRETURNSANOBSERVABLEINSTANCETHATSYNCHRONOUSLYDELIVERSTHEVALUESPROVIDEDASARGUMENTS", "original": "* `Observable.of(...items)`—Returns an `Observable` instance that synchronously delivers the values provided as arguments.", "translation": "`Observable.of(...items)` —— 返回一个 `Observable` 实例,它用同步的方式把参数中提供的这些值发送出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "OBSERVABLEFROMITERABLEMDASHCONVERTSITSARGUMENTTOANOBSERVABLEINSTANCETHISMETHODISCOMMONLYUSEDTOCONVERTANARRAYTOANOBSERVABLE", "original": "* `Observable.from(iterable)`—Converts its argument to an `Observable` instance. This method is commonly used to convert an array to an observable.", "translation": "`Observable.from(iterable)` —— 把它的参数转换成一个 `Observable` 实例。\n 该方法通常用于把一个数组转换成一个(发送多个值的)可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "HERESANEXAMPLEOFCREATINGANDSUBSCRIBINGTOASIMPLEOBSERVABLEWITHANOBSERVERTHATLOGSTHERECEIVEDMESSAGETOTHECONSOLE:", "original": "Here's an example of creating and subscribing to a simple observable, with an observer that logs the received message to the console:", "translation": "下面的例子会创建并订阅一个简单的可观察对象,它的观察者会把接收到的消息记录到控制台中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "ALTERNATIVELYTHESUBSCRIBEMETHODCANACCEPTCALLBACKFUNCTIONDEFINITIONSINLINEFORNEXTERRORANDCOMPLETEHANDLERSFOREXAMPLETHEFOLLOWINGSUBSCRIBECALLISTHESAMEASTHEONETHATSPECIFIESTHEPREDEFINEDOBSERVER:", "original": "Alternatively, the `subscribe()` method can accept callback function definitions in line, for `next`, `error`, and `complete` handlers. For example, the following `subscribe()` call is the same as the one that specifies the predefined observer:", "translation": "另外,`subscribe()` 方法还可以接收定义在同一行中的回调函数,无论 `next`、`error` 还是 `complete` 处理器。比如,下面的 `subscribe()` 调用和前面指定预定义观察者的例子是等价的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "INEITHERCASEANEXTHANDLERISREQUIREDTHEERRORANDCOMPLETEHANDLERSAREOPTIONAL", "original": "In either case, a `next` handler is required. The `error` and `complete` handlers are optional.", "translation": "无论哪种情况,`next` 处理器都是必要的,而 `error` 和 `complete` 处理器是可选的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { - "original": "Note that a `next()` function could receive, for instance, message strings, or event objects, numeric values, or structures, depending on context. As a general term, we refer to data published by an observable as a *stream*. Any type of value can be represented with an observable, and the values are published as a stream.", + "key": "NOTETHATANEXTFUNCTIONCOULDRECEIVEFORINSTANCEMESSAGESTRINGSOREVENTOBJECTSNUMERICVALUESORSTUCTURESDEPENDINGONCONTEXTASAGENERALTERMWEREFERTODATAPUBLISHEDBYANOBSERVABLEASASTREAMANYTYPEOFVALUECANBEREPRESENTEDWITHANOBSERVABLEANDTHEVALUESAREPUBLISHEDASASTREAM", + "original": "Note that a `next()` function could receive, for instance, message strings, or event objects, numeric values, or stuctures, depending on context. As a general term, we refer to data published by an observable as a *stream*. Any type of value can be represented with an observable, and the values are published as a stream.", "translation": "注意,`next()` 函数可以接受消息字符串、事件对象、数字值或各种结构,具体类型取决于上下文。\n为了更通用一点,我们把由可观察对象发布出来的数据统称为*流*。任何类型的值都可以表示为可观察对象,而这些值会被发布为一个流。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "##CREATINGOBSERVABLES", "original": "## Creating observables", "translation": "## 创建可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "USETHEOBSERVABLECONSTRUCTORTOCREATEANOBSERVABLESTREAMOFANYTYPETHECONSTRUCTORTAKESASITSARGUMENTTHESUBSCRIBERFUNCTIONTORUNWHENTHEOBSERVABLESSUBSCRIBEMETHODEXECUTESASUBSCRIBERFUNCTIONRECEIVESANOBSERVEROBJECTANDCANPUBLISHVALUESTOTHEOBSERVERSNEXTMETHOD", "original": "Use the `Observable` constructor to create an observable stream of any type. The constructor takes as its argument the subscriber function to run when the observable’s `subscribe()` method executes. A subscriber function receives an `Observer` object, and can publish values to the observer's `next()` method.", "translation": "使用 `Observable` 构造函数可以创建任何类型的可观察流。\n当执行可观察对象的 `subscribe()` 方法时,这个构造函数就会把它接收到的参数作为订阅函数来运行。\n订阅函数会接收一个 `Observer` 对象,并把值发布给观察者的 `next()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "FOREXAMPLETOCREATEANOBSERVABLEEQUIVALENTTOTHEOBSERVABLEOF123ABOVEYOUCOULDDOSOMETHINGLIKETHIS:", "original": "For example, to create an observable equivalent to the `Observable.of(1, 2, 3)` above, you could do something like this:", "translation": "比如,要创建一个与前面的 `Observable.of(1, 2, 3)` 等价的可观察对象,你可以这样做:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "TOTAKETHISEXAMPLEALITTLEFURTHERWECANCREATEANOBSERVABLETHATPUBLISHESEVENTSINTHISEXAMPLETHESUBSCRIBERFUNCTIONISDEFINEDINLINE", "original": "To take this example a little further, we can create an observable that publishes events. In this example, the subscriber function is defined inline.", "translation": "如果要略微加强这个例子,我们可以创建一个用来发布事件的可观察对象。在这个例子中,订阅函数是用内联方式定义的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "NOWYOUCANUSETHISFUNCTIONTOCREATEANOBSERVABLETHATPUBLISHESKEYDOWNEVENTS:", "original": "Now you can use this function to create an observable that publishes keydown events:", "translation": "现在,你就可以使用这个函数来创建可发布 `keydown` 事件的可观察对象了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "##MULTICASTING", "original": "## Multicasting", "translation": "## 多播", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "ATYPICALOBSERVABLECREATESANEWINDEPENDENTEXECUTIONFOREACHSUBSCRIBEDOBSERVERWHENANOBSERVERSUBSCRIBESTHEOBSERVABLEWIRESUPANEVENTHANDLERANDDELIVERSVALUESTOTHATOBSERVERWHENASECONDOBSERVERSUBSCRIBESTHEOBSERVABLETHENWIRESUPANEWEVENTHANDLERANDDELIVERSVALUESTOTHATSECONDOBSERVERINASEPARATEEXECUTION", "original": "A typical observable creates a new, independent execution for each subscribed observer. When an observer subscribes, the observable wires up an event handler and delivers values to that observer. When a second observer subscribes, the observable then wires up a new event handler and delivers values to that second observer in a separate execution.", "translation": "典型的可观察对象会为每一个观察者创建一次新的、独立的执行。\n当观察者进行订阅时,该可观察对象会连上一个事件处理器,并且向那个观察者发送一些值。当第二个观察者订阅时,这个可观察对象就会连上一个新的事件处理器,并独立执行一次,把这些值发送给第二个可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "SOMETIMESINSTEADOFSTARTINGANINDEPENDENTEXECUTIONFOREACHSUBSCRIBERYOUWANTEACHSUBSCRIPTIONTOGETTHESAMEVALUESMDASHEVENIFVALUESHAVEALREADYSTARTEDEMITTINGTHISMIGHTBETHECASEWITHSOMETHINGLIKEANOBSERVABLEOFCLICKSONTHEDOCUMENTOBJECT", "original": "Sometimes, instead of starting an independent execution for each subscriber, you want each subscription to get the same values—even if values have already started emitting. This might be the case with something like an observable of clicks on the document object.", "translation": "有时候,不应该对每一个订阅者都独立执行一次,你可能会希望每次订阅都得到同一批值 —— 即使是那些你已经发送过的。这在某些情况下有用,比如用来发送 `document` 上的点击事件的可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "MULTICASTINGISTHEPRACTICEOFBROADCASTINGTOALISTOFMULTIPLESUBSCRIBERSINASINGLEEXECUTIONWITHAMULTICASTINGOBSERVABLEYOUDONTREGISTERMULTIPLELISTENERSONTHEDOCUMENTBUTINSTEADREUSETHEFIRSTLISTENERANDSENDVALUESOUTTOEACHSUBSCRIBER", "original": "*Multicasting* is the practice of broadcasting to a list of multiple subscribers in a single execution. With a multicasting observable, you don't register multiple listeners on the document, but instead re-use the first listener and send values out to each subscriber.", "translation": "*多播*用来让可观察对象在一次执行中同时广播给多个订阅者。借助支持多播的可观察对象,你不必注册多个监听器,而是复用第一个(`next`)监听器,并且把值发送给各个订阅者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "WHENCREATINGANOBSERVABLEYOUSHOULDDETERMINEHOWYOUWANTTHATOBSERVABLETOBEUSEDANDWHETHERORNOTYOUWANTTOMULTICASTITSVALUES", "original": "When creating an observable you should determine how you want that observable to be used and whether or not you want to multicast its values.", "translation": "当创建可观察对象时,你要决定你希望别人怎么用这个对象以及是否对它的值进行多播。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "LETSLOOKATANEXAMPLETHATCOUNTSFROM1TO3WITHAONESECONDDELAYAFTEREACHNUMBEREMITTED", "original": "Let’s look at an example that counts from 1 to 3, with a one-second delay after each number emitted.", "translation": "来看一个从 1 到 3 进行计数的例子,它每发出一个数字就会等待 1 秒。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "NOTICETHATIFYOUSUBSCRIBETWICETHEREWILLBETWOSEPARATESTREAMSEACHEMITTINGVALUESEVERYSECONDITLOOKSSOMETHINGLIKETHIS:", "original": "Notice that if you subscribe twice, there will be two separate streams, each emitting values every second. It looks something like this:", "translation": "注意,如果你订阅了两次,就会有两个独立的流,每个流都会每秒发出一个数字。代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "CHANGINGTHEOBSERVABLETOBEMULTICASTINGCOULDLOOKSOMETHINGLIKETHIS:", "original": "Changing the observable to be multicasting could look something like this:", "translation": "修改这个可观察对象以支持多播,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "MULTICASTINGOBSERVABLESTAKEABITMORESETUPBUTTHEYCANBEUSEFULFORCERTAINAPPLICATIONSLATERWEWILLLOOKATTOOLSTHATSIMPLIFYTHEPROCESSOFMULTICASTINGALLOWINGYOUTOTAKEANYOBSERVABLEANDMAKEITMULTICASTING", "original": "Multicasting observables take a bit more setup, but they can be useful for certain applications. Later we will look at tools that simplify the process of multicasting, allowing you to take any observable and make it multicasting.", "translation": "虽然支持多播的可观察对象需要做更多的准备工作,但对某些应用来说,这非常有用。稍后我们会介绍一些简化多播的工具,它们让你能接收任何可观察对象,并把它变成支持多播的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "##ERRORHANDLING", "original": "## Error handling", "translation": "## 错误处理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "BECAUSEOBSERVABLESPRODUCEVALUESASYNCHRONOUSLYTRYCATCHWILLNOTEFFECTIVELYCATCHERRORSINSTEADYOUHANDLEERRORSBYSPECIFYINGANERRORCALLBACKONTHEOBSERVERPRODUCINGANERRORALSOCAUSESTHEOBSERVABLETOCLEANUPSUBSCRIPTIONSANDSTOPPRODUCINGVALUESANOBSERVABLECANEITHERPRODUCEVALUESCALLINGTHENEXTCALLBACKORITCANCOMPLETECALLINGEITHERTHECOMPLETEORERRORCALLBACK", "original": "Because observables produce values asynchronously, try/catch will not effectively catch errors. Instead, you handle errors by specifying an `error` callback on the observer. Producing an error also causes the observable to clean up subscriptions and stop producing values. An observable can either produce values (calling the `next` callback), or it can complete, calling either the `complete` or `error` callback.", "translation": "由于可观察对象会异步生成值,所以用 `try/catch` 是无法捕获错误的。你应该在观察者中指定一个 `error` 回调来处理错误。发生错误时还会导致可观察对象清理现有的订阅,并且停止生成值。可观察对象可以生成值(调用 `next` 回调),也可以调用 `complete` 或 `error` 回调来主动结束。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "ERRORHANDLINGANDSPECIFICALLYRECOVERINGFROMANERRORISCOVEREDINMOREDETAILINALATERSECTION", "original": "Error handling (and specifically recovering from an error) is covered in more detail in a later section.", "translation": "在稍后的小节中会对错误处理(特别是从错误中的恢复)做更详细的讲解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/observables.md" }, { + "key": "#PIPES", "original": "# Pipes", "translation": "# 管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "EVERYAPPLICATIONSTARTSOUTWITHWHATSEEMSLIKEASIMPLETASK:GETDATATRANSFORMTHEMANDSHOWTHEMTOUSERSGETTINGDATACOULDBEASSIMPLEASCREATINGALOCALVARIABLEORASCOMPLEXASSTREAMINGDATAOVERAWEBSOCKET", "original": "Every application starts out with what seems like a simple task: get data, transform them, and show them to users.\nGetting data could be as simple as creating a local variable or as complex as streaming data over a WebSocket.", "translation": "每个应用开始的时候差不多都是一些简单任务:获取数据、转换它们,然后把它们显示给用户。\n获取数据可能简单到创建一个局部变量就行,也可能复杂到从 WebSocket 中获取数据流。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ONCEDATAARRIVEYOUCOULDPUSHTHEIRRAWTOSTRINGVALUESDIRECTLYTOTHEVIEWBUTTHATRARELYMAKESFORAGOODUSEREXPERIENCEFOREXAMPLEINMOSTUSECASESUSERSPREFERTOSEEADATEINASIMPLEFORMATLIKESAMPAPRIL151988SAMPRATHERTHANTHERAWSTRINGFORMATSAMPFRIAPR15198800:00:00GMT0700PACIFICDAYLIGHTTIMESAMP", "original": "Once data arrive, you could push their raw `toString` values directly to the view,\nbut that rarely makes for a good user experience.\nFor example, in most use cases, users prefer to see a date in a simple format like\n<samp>April 15, 1988</samp> rather than the raw string format\n<samp>Fri Apr 15 1988 00:00:00 GMT-0700 (Pacific Daylight Time)</samp>.", "translation": "一旦取到数据,你就可以把它们原始值的 `toString` 结果直接推入视图中。\n但这种做法很少能具备良好的用户体验。\n比如,几乎每个人都更喜欢简单的日期格式,例如<samp>1988-04-15</samp>,而不是服务端传过来的原始字符串格式 —— <samp>Fri Apr 15 1988 00:00:00 GMT-0700 (Pacific Daylight Time)</samp>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "CLEARLYSOMEVALUESBENEFITFROMABITOFEDITINGYOUMAYNOTICETHATYOUDESIREMANYOFTHESAMETRANSFORMATIONSREPEATEDLYBOTHWITHINANDACROSSMANYAPPLICATIONSYOUCANALMOSTTHINKOFTHEMASSTYLESINFACTYOUMIGHTLIKETOAPPLYTHEMINYOURHTMLTEMPLATESASYOUDOSTYLES", "original": "Clearly, some values benefit from a bit of editing. You may notice that you\ndesire many of the same transformations repeatedly, both within and across many applications.\nYou can almost think of them as styles.\nIn fact, you might like to apply them in your HTML templates as you do styles.", "translation": "显然,有些值最好显示成用户友好的格式。你很快就会发现,在很多不同的应用中,都在重复做出某些相同的变换。\n你几乎会把它们看做某种 CSS 样式,事实上,你也确实更喜欢在 HTML 模板中应用它们 —— 就像 CSS 样式一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "INTRODUCINGANGULARPIPESAWAYTOWRITEDISPLAYVALUETRANSFORMATIONSTHATYOUCANDECLAREINYOURHTML", "original": "Introducing Angular pipes, a way to write display-value transformations that you can declare in your HTML.", "translation": "通过引入 Angular 管道,你可以把这种简单的“显示-值”转换器声明在 HTML 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUCANRUNTHELIVEEXAMPLELIVEEXAMPLEINSTACKBLITZANDDOWNLOADTHECODEFROMTHERE", "original": "You can run the <live-example></live-example> in Stackblitz and download the code from there.", - "translation": "运行<live-example></live-example>来试用本页的代码。", + "translation": "你可以运行<live-example></live-example>,在 Stackblitz 中试用并下载本页的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##USINGPIPES", "original": "## Using pipes", "translation": "## 使用管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "APIPETAKESINDATAASINPUTANDTRANSFORMSITTOADESIREDOUTPUTINTHISPAGEYOULLUSEPIPESTOTRANSFORMACOMPONENTSBIRTHDAYPROPERTYINTOAHUMANFRIENDLYDATE", "original": "A pipe takes in data as input and transforms it to a desired output.\nIn this page, you'll use pipes to transform a component's birthday property into\na human-friendly date.", "translation": "管道把数据作为输入,然后转换它,给出期望的输出。\n你要把组件的 `birthday` 属性转换成对人类更友好的日期格式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "FOCUSONTHECOMPONENTSTEMPLATE", "original": "Focus on the component's template.", "translation": "重点看下组件的模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "INSIDETHEINTERPOLATIONEXPRESSIONYOUFLOWTHECOMPONENTSBIRTHDAYVALUETHROUGHTHEPIPEOPERATORGUIDETEMPLATESYNTAX#PIPETOTHEDATEPIPEAPICOMMONDATEPIPEFUNCTIONONTHERIGHTALLPIPESWORKTHISWAY", "original": "Inside the interpolation expression, you flow the component's `birthday` value through the\n[pipe operator](guide/template-syntax#pipe) ( | ) to the [Date pipe](api/common/DatePipe)\nfunction on the right. All pipes work this way.", "translation": "在这个插值表达式中,你让组件的 `birthday` 值通过[管道操作符](guide/template-syntax#pipe)( | )流动到\n右侧的[Date 管道](api/common/DatePipe)函数中。所有管道都会用这种方式工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##BUILTINPIPES", "original": "## Built-in pipes", "translation": "## 内置的管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ANGULARCOMESWITHASTOCKOFPIPESSUCHASDATEPIPEUPPERCASEPIPELOWERCASEPIPECURRENCYPIPEANDPERCENTPIPETHEYAREALLAVAILABLEFORUSEINANYTEMPLATE", "original": "Angular comes with a stock of pipes such as\n`DatePipe`, `UpperCasePipe`, `LowerCasePipe`, `CurrencyPipe`, and `PercentPipe`.\nThey are all available for use in any template.", "translation": "Angular 内置了一些管道,比如 `DatePipe`、`UpperCasePipe`、`LowerCasePipe`、`CurrencyPipe` 和 `PercentPipe`。\n它们全都可以直接用在任何模板中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "READMOREABOUTTHESEANDMANYOTHERBUILTINPIPESINTHEPIPESTOPICSAPITYPEPIPEOFTHEAPIREFERENCEAPIFILTERFORENTRIESTHATINCLUDETHEWORDPIPE", "original": "Read more about these and many other built-in pipes in the [pipes topics](api?type=pipe) of the\n[API Reference](api); filter for entries that include the word \"pipe\".", "translation": "要学习更多内置管道的知识,参见[API 参考手册](api?type=pipe),并用“pipe”为关键词对结果进行过滤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ANGULARDOESNTHAVEAFILTERPIPEORANORDERBYPIPEFORREASONSEXPLAINEDINTHEAPPENDIXGUIDEPIPES#NOFILTERPIPEOFTHISPAGE", "original": "Angular doesn't have a `FilterPipe` or an `OrderByPipe` for reasons explained in the [Appendix](guide/pipes#no-filter-pipe) of this page.", "translation": "Angular 没有 `FilterPipe` 或 `OrderByPipe` 管道,原因在[后面的附录中](guide/pipes#no-filter-pipe)有解释。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##PARAMETERIZINGAPIPE", "original": "## Parameterizing a pipe", "translation": "## 对管道进行参数化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "APIPECANACCEPTANYNUMBEROFOPTIONALPARAMETERSTOFINETUNEITSOUTPUTTOADDPARAMETERSTOAPIPEFOLLOWTHEPIPENAMEWITHACOLON:ANDTHENTHEPARAMETERVALUESUCHASCURRENCY:EURIFTHEPIPEACCEPTSMULTIPLEPARAMETERSSEPARATETHEVALUESWITHCOLONSSUCHASSLICE:1:5", "original": "A pipe can accept any number of optional parameters to fine-tune its output.\nTo add parameters to a pipe, follow the pipe name with a colon ( : ) and then the parameter value\n(such as `currency:'EUR'`). If the pipe accepts multiple parameters, separate the values with colons (such as `slice:1:5`)", "translation": "管道可能接受任何数量的可选参数来对它的输出进行微调。\n可以在管道名后面添加一个冒号( : )再跟一个参数值,来为管道添加参数(比如 `currency:'EUR'`)。\n如果这个管道可以接受多个参数,那么就用冒号来分隔这些参数值(比如 `slice:1:5`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "MODIFYTHEBIRTHDAYTEMPLATETOGIVETHEDATEPIPEAFORMATPARAMETERAFTERFORMATTINGTHEHEROSAPRIL15THBIRTHDAYITRENDERSASSAMP041588SAMP:", "original": "Modify the birthday template to give the date pipe a format parameter.\nAfter formatting the hero's April 15th birthday, it renders as **<samp>04/15/88</samp>**:", "translation": "修改生日模板,来为这个日期管道提供一个格式化参数。\n当格式化完该英雄的 4 月 15 日生日之后,它应该被渲染成**<samp>04/15/88</samp>**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEPARAMETERVALUECANBEANYVALIDTEMPLATEEXPRESSIONSEETHETEMPLATEEXPRESSIONSGUIDETEMPLATESYNTAX#TEMPLATEEXPRESSIONSSECTIONOFTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXPAGESUCHASASTRINGLITERALORACOMPONENTPROPERTYINOTHERWORDSYOUCANCONTROLTHEFORMATTHROUGHABINDINGTHESAMEWAYYOUCONTROLTHEBIRTHDAYVALUETHROUGHABINDING", "original": "The parameter value can be any valid template expression,\n(see the [Template expressions](guide/template-syntax#template-expressions) section of the\n[Template Syntax](guide/template-syntax) page)\nsuch as a string literal or a component property.\nIn other words, you can control the format through a binding the same way you control the birthday value through a binding.", "translation": "参数值可以是任何有效的模板表达式(参见[模板语法](guide/template-syntax)中的[模板表达式](guide/template-syntax#template-expressions)部分),比如字符串字面量或组件的属性。\n换句话说,借助属性绑定,你也可以像用绑定来控制生日的值一样,控制生日的显示格式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "WRITEASECONDCOMPONENTTHATBINDSTHEPIPESFORMATPARAMETERTOTHECOMPONENTSFORMATPROPERTYHERESTHETEMPLATEFORTHATCOMPONENT:", "original": "Write a second component that *binds* the pipe's format parameter\nto the component's `format` property. Here's the template for that component:", "translation": "来写第二个组件,它把管道的格式参数*绑定*到该组件的 `format` 属性。这里是新组件的模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUALSOADDEDABUTTONTOTHETEMPLATEANDBOUNDITSCLICKEVENTTOTHECOMPONENTSTOGGLEFORMATMETHODTHATMETHODTOGGLESTHECOMPONENTSFORMATPROPERTYBETWEENASHORTFORMSHORTDATEANDALONGERFORMFULLDATE", "original": "You also added a button to the template and bound its click event to the component's `toggleFormat()` method.\nThat method toggles the component's `format` property between a short form\n(`'shortDate'`) and a longer form (`'fullDate'`).", "translation": "你还能在模板中添加一个按钮,并把它的点击事件绑定到组件的 `toggleFormat()` 方法。\n此方法会在短日期格式(`'shortDate'`)和长日期格式(`'fullDate'`)之间切换组件的 `format` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ASYOUCLICKTHEBUTTONTHEDISPLAYEDDATEALTERNATESBETWEENSAMP04151988SAMPANDSAMPFRIDAYAPRIL151988SAMP", "original": "As you click the button, the displayed date alternates between\n\"**<samp>04/15/1988</samp>**\" and\n\"**<samp>Friday, April 15, 1988</samp>**\".", "translation": "当你点击按钮的时候,显示的日志会在“**<samp>04/15/1988</samp>**”和“**<samp>Friday, April 15, 1988</samp>**”之间切换。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "READMOREABOUTTHEDATEPIPEFORMATOPTIONSINTHEDATEPIPEAPICOMMONDATEPIPEAPIREFERENCEPAGE", "original": "Read more about the `DatePipe` format options in the [Date Pipe](api/common/DatePipe)\nAPI Reference page.", "translation": "要了解更多 `DatePipes` 的格式选项,请参阅[API 文档](api/common/DatePipe)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##CHAININGPIPES", "original": "## Chaining pipes", "translation": "## 链式管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUCANCHAINPIPESTOGETHERINPOTENTIALLYUSEFULCOMBINATIONSINTHEFOLLOWINGEXAMPLETODISPLAYTHEBIRTHDAYINUPPERCASETHEBIRTHDAYISCHAINEDTOTHEDATEPIPEANDONTOTHEUPPERCASEPIPETHEBIRTHDAYDISPLAYSASSAMPAPR151988SAMP", "original": "You can chain pipes together in potentially useful combinations.\nIn the following example, to display the birthday in uppercase,\nthe birthday is chained to the `DatePipe` and on to the `UpperCasePipe`.\nThe birthday displays as **<samp>APR 15, 1988</samp>**.", "translation": "你可以把管道串联在一起,以组合出一些潜在的有用功能。\n下面这个例子中,要把 `birthday` 串联到 `DatePipe` 管道,然后又串联到 `UpperCasePipe`,这样就可以把生日显示成大写形式了。\n生日被显示成了**<samp>APR 15, 1988</samp>**:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THISEXAMPLEMDASHWHICHDISPLAYSSAMPFRIDAYAPRIL151988SAMPMDASHCHAINSTHESAMEPIPESASABOVEBUTPASSESINAPARAMETERTODATEASWELL", "original": "This example—which displays **<samp>FRIDAY, APRIL 15, 1988</samp>**—chains\nthe same pipes as above, but passes in a parameter to `date` as well.", "translation": "下面这个显示**<samp>FRIDAY, APRIL 15, 1988</samp>**的例子用同样的方式链接了这两个管道,而且同时还给 `date` 管道传进去一个参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##CUSTOMPIPES", "original": "## Custom pipes", "translation": "## 自定义管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUCANWRITEYOUROWNCUSTOMPIPESHERESACUSTOMPIPENAMEDEXPONENTIALSTRENGTHPIPETHATCANBOOSTAHEROSPOWERS:", "original": "You can write your own custom pipes.\nHere's a custom pipe named `ExponentialStrengthPipe` that can boost a hero's powers:", "translation": "你还可以写自己的自定义管道。\n下面就是一个名叫 `ExponentialStrengthPipe` 的管道,它可以放大英雄的能力:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THISPIPEDEFINITIONREVEALSTHEFOLLOWINGKEYPOINTS:", "original": "This pipe definition reveals the following key points:", "translation": "在这个管道的定义中体现了几个关键点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "APIPEISACLASSDECORATEDWITHPIPEMETADATA", "original": "* A pipe is a class decorated with pipe metadata.", "translation": "管道是一个带有“管道元数据(pipe metadata)”装饰器的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEPIPECLASSIMPLEMENTSTHEPIPETRANSFORMINTERFACESTRANSFORMMETHODTHATACCEPTSANINPUTVALUEFOLLOWEDBYOPTIONALPARAMETERSANDRETURNSTHETRANSFORMEDVALUE", "original": "* The pipe class implements the `PipeTransform` interface's `transform` method that\naccepts an input value followed by optional parameters and returns the transformed value.", "translation": "这个管道类实现了 `PipeTransform` 接口的 `transform` 方法,该方法接受一个输入值和一些可选参数,并返回转换后的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEREWILLBEONEADDITIONALARGUMENTTOTHETRANSFORMMETHODFOREACHPARAMETERPASSEDTOTHEPIPEYOURPIPEHASONESUCHPARAMETER:THEEXPONENT", "original": "* There will be one additional argument to the `transform` method for each parameter passed to the pipe.\nYour pipe has one such parameter: the `exponent`.", "translation": "当每个输入值被传给 `transform` 方法时,还会带上另一个参数,比如你这个管道就有一个 `exponent`(放大指数) 参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "TOTELLANGULARTHATTHISISAPIPEYOUAPPLYTHEPIPEDECORATORWHICHYOUIMPORTFROMTHECOREANGULARLIBRARY", "original": "* To tell Angular that this is a pipe, you apply the\n`@Pipe` decorator, which you import from the core Angular library.", "translation": "可以通过 `@Pipe` 装饰器来告诉 Angular:这是一个管道。该装饰器是从 Angular 的 `core` 库中引入的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEPIPEDECORATORALLOWSYOUTODEFINETHEPIPENAMETHATYOULLUSEWITHINTEMPLATEEXPRESSIONSITMUSTBEAVALIDJAVASCRIPTIDENTIFIERYOURPIPESNAMEISEXPONENTIALSTRENGTH", "original": "* The `@Pipe` decorator allows you to define the\n pipe name that you'll use within template expressions. It must be a valid JavaScript identifier.\n Your pipe's name is `exponentialStrength`.", "translation": "这个 `@Pipe` 装饰器允许你定义管道的名字,这个名字会被用在模板表达式中。它必须是一个有效的 JavaScript 标识符。\n 比如,你这个管道的名字是 `exponentialStrength`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##THEPIPETRANSFORMINTERFACE", "original": "## The *PipeTransform* interface", "translation": "## *PipeTransform* 接口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THETRANSFORMMETHODISESSENTIALTOAPIPETHEPIPETRANSFORMINTERFACEDEFINESTHATMETHODANDGUIDESBOTHTOOLINGANDTHECOMPILERTECHNICALLYITSOPTIONALANGULARLOOKSFORANDEXECUTESTHETRANSFORMMETHODREGARDLESS", "original": "The `transform` method is essential to a pipe.\nThe `PipeTransform` *interface* defines that method and guides both tooling and the compiler.\nTechnically, it's optional; Angular looks for and executes the `transform` method regardless.", "translation": "`transform` 方法是管道的基本要素。\n`PipeTransform`*接口*中定义了它,并用它指导各种工具和编译器。\n理论上说,它是可选的。Angular 不会管它,而是直接查找并执行 `transform` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "NOWYOUNEEDACOMPONENTTODEMONSTRATETHEPIPE", "original": "Now you need a component to demonstrate the pipe.", "translation": "现在,你需要一个组件来演示这个管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "NOTETHEFOLLOWING:", "original": "Note the following:", "translation": "请注意以下几点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUUSEYOURCUSTOMPIPETHESAMEWAYYOUUSEBUILTINPIPES", "original": "* You use your custom pipe the same way you use built-in pipes.", "translation": "你使用自定义管道的方式和内置管道完全相同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUMUSTINCLUDEYOURPIPEINTHEDECLARATIONSARRAYOFTHEAPPMODULE", "original": "* You must include your pipe in the `declarations` array of the `AppModule`.", "translation": "你必须在 `AppModule` 的 `declarations` 数组中包含这个管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "HEADERREMEMBERTHEDECLARATIONSARRAYHEADER", "original": "<header>Remember the declarations array</header>", "translation": "<header>别忘了 `declarations` 数组</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUMUSTREGISTERCUSTOMPIPESIFYOUDONTANGULARREPORTSANERRORANGULARCLISGENERATORREGISTERSTHEPIPEAUTOMATICALLY", "original": "You must register custom pipes.\nIf you don't, Angular reports an error.\nAngular CLI's generator registers the pipe automatically.", "translation": "你必须手动注册自定义管道。如果忘了,Angular 就会报告一个错误。\n在前一个例子中你没有把 `DatePipe` 列进去,这是因为 Angular 所有的内置管道都已经预注册过了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "TOPROBETHEBEHAVIORINTHELIVEEXAMPLELIVEEXAMPLECHANGETHEVALUEANDOPTIONALEXPONENTINTHETEMPLATE", "original": "To probe the behavior in the <live-example></live-example>,\nchange the value and optional exponent in the template.", "translation": "试一下这个<live-example></live-example>,并通过修改值和模板中的可选部分来体会其行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##POWERBOOSTCALCULATOR", "original": "## Power Boost Calculator", "translation": "## 能力倍增计算器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ITSNOTMUCHFUNUPDATINGTHETEMPLATETOTESTTHECUSTOMPIPEUPGRADETHEEXAMPLETOAPOWERBOOSTCALCULATORTHATCOMBINESYOURPIPEANDTWOWAYDATABINDINGWITHNGMODEL", "original": "It's not much fun updating the template to test the custom pipe.\nUpgrade the example to a \"Power Boost Calculator\" that combines\nyour pipe and two-way data binding with `ngModel`.", "translation": "仅仅升级模板来测试这个自定义管道其实没多大意思。\n干脆把这个例子升级为“能力提升计算器”,它可以把该管道和使用 `ngModel` 的双向数据绑定组合起来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##PIPESANDCHANGEDETECTION", "original": "## Pipes and change detection", "translation": "## 管道与变更检测", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ANGULARLOOKSFORCHANGESTODATABOUNDVALUESTHROUGHACHANGEDETECTIONPROCESSTHATRUNSAFTEREVERYDOMEVENT:EVERYKEYSTROKEMOUSEMOVETIMERTICKANDSERVERRESPONSETHISCOULDBEEXPENSIVEANGULARSTRIVESTOLOWERTHECOSTWHENEVERPOSSIBLEANDAPPROPRIATE", "original": "Angular looks for changes to data-bound values through a *change detection* process that runs after every DOM event:\nevery keystroke, mouse move, timer tick, and server response. This could be expensive.\nAngular strives to lower the cost whenever possible and appropriate.", "translation": "Angular 通过*变更检测*过程来查找绑定值的更改,并在每一次 JavaScript 事件之后运行:每次按键、鼠标移动、定时器以及服务器的响应。\n这可能会让变更检测显得很昂贵,但是 Angular 会尽可能降低变更检测的成本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ANGULARPICKSASIMPLERFASTERCHANGEDETECTIONALGORITHMWHENYOUUSEAPIPE", "original": "Angular picks a simpler, faster change detection algorithm when you use a pipe.", "translation": "当使用管道时,Angular 会选用一种更简单、更快速的变更检测算法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "H3CLASSNOTOCNOPIPEH3", "original": "<h3 class=\"no-toc\">No pipe</h3>", "translation": "<h3 class=\"no-toc\">无管道</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "INTHENEXTEXAMPLETHECOMPONENTUSESTHEDEFAULTAGGRESSIVECHANGEDETECTIONSTRATEGYTOMONITORANDUPDATEITSDISPLAYOFEVERYHEROINTHEHEROESARRAYHERESTHETEMPLATE:", "original": "In the next example, the component uses the default, aggressive change detection strategy to monitor and update\nits display of every hero in the `heroes` array. Here's the template:", "translation": "在下一个例子中,组件使用默认的、激进(昂贵)的变更检测策略来检测和更新 `heroes` 数组中的每个英雄。下面是它的模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THECOMPANIONCOMPONENTCLASSPROVIDESHEROESADDSHEROESINTOTHEARRAYANDCANRESETTHEARRAY", "original": "The companion component class provides heroes, adds heroes into the array, and can reset the array.", "translation": "和模板相伴的组件类可以提供英雄数组,能把新的英雄添加到数组中,还能重置英雄数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUCANADDHEROESANDANGULARUPDATESTHEDISPLAYWHENYOUDOIFYOUCLICKTHERESETBUTTONANGULARREPLACESHEROESWITHANEWARRAYOFTHEORIGINALHEROESANDUPDATESTHEDISPLAYIFYOUADDEDTHEABILITYTOREMOVEORCHANGEAHEROANGULARWOULDDETECTTHOSECHANGESANDUPDATETHEDISPLAYASWELL", "original": "You can add heroes and Angular updates the display when you do.\nIf you click the `reset` button, Angular replaces `heroes` with a new array of the original heroes and updates the display.\nIf you added the ability to remove or change a hero, Angular would detect those changes and update the display as well.", "translation": "你可以添加新的英雄,加完之后,Angular 就会更新显示。\n`reset` 按钮会把 `heroes` 替换成一个由原来的英雄组成的新数组,重置完之后,Angular 就会更新显示。\n如果你提供了删除或修改英雄的能力,Angular 也会检测到那些更改,并更新显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "H3CLASSNOTOCIFLYINGHEROESPIPEIH3", "original": "<h3 class=\"no-toc\"><i>FlyingHeroesPipe</i></h3>", "translation": "<h3 class=\"no-toc\"><i>“会飞的英雄”管道(FlyingHeroesPipe)</i></h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ADDAFLYINGHEROESPIPETOTHENGFORREPEATERTHATFILTERSTHELISTOFHEROESTOJUSTTHOSEHEROESWHOCANFLY", "original": "Add a `FlyingHeroesPipe` to the `*ngFor` repeater that filters the list of heroes to just those heroes who can fly.", "translation": "往 `*ngFor` 重复器中添加一个 `FlyingHeroesPipe` 管道,这个管道能过滤出所有会飞的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "HERESTHEFLYINGHEROESPIPEIMPLEMENTATIONWHICHFOLLOWSTHEPATTERNFORCUSTOMPIPESDESCRIBEDEARLIER", "original": "Here's the `FlyingHeroesPipe` implementation, which follows the pattern for custom pipes described earlier.", "translation": "下面是 `FlyingHeroesPipe` 的实现,它遵循了以前讲过的那些写自定义管道的模式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "NOTICETHEODDBEHAVIORINTHELIVEEXAMPLELIVEEXAMPLE:WHENYOUADDFLYINGHEROESNONEOFTHEMAREDISPLAYEDUNDERHEROESWHOFLY", "original": "Notice the odd behavior in the <live-example></live-example>:\nwhen you add flying heroes, none of them are displayed under \"Heroes who fly.\"", "translation": "当运行<live-example></live-example>时,你看到一种奇怪的行为。添加的每个英雄都是会飞行的英雄,但是没有一个被显示出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ALTHOUGHYOURENOTGETTINGTHEBEHAVIORYOUWANTANGULARISNTBROKENITSJUSTUSINGADIFFERENTCHANGEDETECTIONALGORITHMTHATIGNORESCHANGESTOTHELISTORANYOFITSITEMS", "original": "Although you're not getting the behavior you want, Angular isn't broken.\nIt's just using a different change-detection algorithm that ignores changes to the list or any of its items.", "translation": "虽然你没有得到期望的行为,但 Angular 也没有出错。\n这里只是用了另一种变更检测算法 —— 它会忽略对列表及其子项所做的任何更改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "NOTICEHOWAHEROISADDED:", "original": "Notice how a hero is added:", "translation": "注意这里是如何添加新英雄的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUADDTHEHEROINTOTHEHEROESARRAYTHEREFERENCETOTHEARRAYHASNTCHANGEDITSTHESAMEARRAYTHATSALLANGULARCARESABOUTFROMITSPERSPECTIVESAMEARRAYNOCHANGENODISPLAYUPDATE", "original": "You add the hero into the `heroes` array. The reference to the array hasn't changed.\nIt's the same array. That's all Angular cares about. From its perspective, *same array, no change, no display update*.", "translation": "当你往 `heroes` 数组中添加一个新的英雄时,这个数组的引用并没有改变。它还是那个数组。而引用却是 Angular 所关心的一切。\n 从 Angular 的角度来看,*这是同一个数组,没有变化,也就不需要更新显示*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "TOFIXTHATCREATEANARRAYWITHTHENEWHEROAPPENDEDANDASSIGNTHATTOHEROESTHISTIMEANGULARDETECTSTHATTHEARRAYREFERENCEHASCHANGEDITEXECUTESTHEPIPEANDUPDATESTHEDISPLAYWITHTHENEWARRAYWHICHINCLUDESTHENEWFLYINGHERO", "original": "To fix that, create an array with the new hero appended and assign that to `heroes`.\nThis time Angular detects that the array reference has changed.\nIt executes the pipe and updates the display with the new array, which includes the new flying hero.", "translation": "要修复它,就要创建一个新数组,把这个英雄追加进去,并把它赋给 `heroes`。\n 这次,Angular 检测到数组的引用变化了。它执行了这个管道,并使用这个新数组更新显示,这次它就包括新的飞行英雄了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "IFYOUMUTATETHEARRAYNOPIPEISINVOKEDANDTHEDISPLAYISNTUPDATEDIFYOUREPLACETHEARRAYTHEPIPEEXECUTESANDTHEDISPLAYISUPDATEDTHEFLYINGHEROESAPPLICATIONEXTENDSTHECODEWITHCHECKBOXSWITCHESANDADDITIONALDISPLAYSTOHELPYOUEXPERIENCETHESEEFFECTS", "original": "If you *mutate* the array, no pipe is invoked and the display isn't updated;\nif you *replace* the array, the pipe executes and the display is updated.\nThe Flying Heroes application extends the\ncode with checkbox switches and additional displays to help you experience these effects.", "translation": "如果你**修改了**这个数组,没有管道被执行,也没有显示被更新。\n如果你**替换了**这个数组,管道就会被执行,显示也更新了。\n这个*飞行英雄*的例子用检查框和其它显示内容扩展了原有代码,来帮你体验这些效果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "REPLACINGTHEARRAYISANEFFICIENTWAYTOSIGNALANGULARTOUPDATETHEDISPLAYWHENDOYOUREPLACETHEARRAYWHENTHEDATACHANGETHATSANEASYRULETOFOLLOWINTHISEXAMPLEWHERETHEONLYWAYTOCHANGETHEDATAISBYADDINGAHERO", "original": "Replacing the array is an efficient way to signal Angular to update the display.\nWhen do you replace the array? When the data change.\nThat's an easy rule to follow in *this* example\nwhere the only way to change the data is by adding a hero.", "translation": "直接替换这个数组是通知 Angular 更新显示的一种高效方式。\n你该什么时候替换这个数组呢?当数据变化的时候。\n在这个*玩具级*例子中,这是一个简单的规则,因为这里修改数据的唯一途径就是添加新英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "MOREOFTENYOUDONTKNOWWHENTHEDATAHAVECHANGEDESPECIALLYINAPPLICATIONSTHATMUTATEDATAINMANYWAYSPERHAPSINAPPLICATIONLOCATIONSFARAWAYACOMPONENTINSUCHANAPPLICATIONUSUALLYCANTKNOWABOUTTHOSECHANGESMOREOVERITSUNWISETODISTORTTHECOMPONENTDESIGNTOACCOMMODATEAPIPESTRIVETOKEEPTHECOMPONENTCLASSINDEPENDENTOFTHEHTMLTHECOMPONENTSHOULDBEUNAWAREOFPIPES", "original": "More often, you don't know when the data have changed,\nespecially in applications that mutate data in many ways,\nperhaps in application locations far away.\nA component in such an application usually can't know about those changes.\nMoreover, it's unwise to distort the component design to accommodate a pipe.\nStrive to keep the component class independent of the HTML.\nThe component should be unaware of pipes.", "translation": "更多情况下,你不知道什么时候数据变化了,尤其是在那些有很多种途径改动数据的程序中 —— 可能在程序中很远的地方。\n组件就是一个通常无法知道那些改动的例子。此外,它会导致削足适履 —— 扭曲组件的设计来适应管道。\n要尽可能保持组件类独立于 HTML。组件不应该关心管道的存在。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "FORFILTERINGFLYINGHEROESCONSIDERANIMPUREPIPE", "original": "For filtering flying heroes, consider an *impure pipe*.", "translation": "为了过滤出会飞的英雄,考虑使用*非纯(impure)管道*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##PUREANDIMPUREPIPES", "original": "## Pure and impure pipes", "translation": "## 纯(pure)管道与非纯(impure)管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEREARETWOCATEGORIESOFPIPES:PUREANDIMPUREPIPESAREPUREBYDEFAULTEVERYPIPEYOUVESEENSOFARHASBEENPUREYOUMAKEAPIPEIMPUREBYSETTINGITSPUREFLAGTOFALSEYOUCOULDMAKETHEFLYINGHEROESPIPEIMPURELIKETHIS:", "original": "There are two categories of pipes: *pure* and *impure*.\nPipes are pure by default. Every pipe you've seen so far has been pure.\nYou make a pipe impure by setting its pure flag to false. You could make the `FlyingHeroesPipe`\nimpure like this:", "translation": "有两类管道:**纯**的与**非纯**的。\n默认情况下,管道都是纯的。以前见到的每个管道都是纯的。\n通过把它的 `pure` 标志设置为 `false`,你可以制作一个非纯管道。你可以像这样让 `FlyingHeroesPipe` 变成非纯的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "BEFOREDOINGTHATUNDERSTANDTHEDIFFERENCEBETWEENPUREANDIMPURESTARTINGWITHAPUREPIPE", "original": "Before doing that, understand the difference between pure and impure, starting with a pure pipe.", "translation": "在继续往下走之前,先理解一下*纯*和*非纯*之间的区别,从*纯*管道开始。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "H3CLASSNOTOCPUREPIPESH3", "original": "<h3 class=\"no-toc\">Pure pipes</h3>", "translation": "<h3 class=\"no-toc\">纯管道</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ANGULAREXECUTESAPUREPIPEONLYWHENITDETECTSAPURECHANGETOTHEINPUTVALUEAPURECHANGEISEITHERACHANGETOAPRIMITIVEINPUTVALUESTRINGNUMBERBOOLEANSYMBOLORACHANGEDOBJECTREFERENCEDATEARRAYFUNCTIONOBJECT", "original": "Angular executes a *pure pipe* only when it detects a *pure change* to the input value.\nA pure change is either a change to a primitive input value (`String`, `Number`, `Boolean`, `Symbol`)\nor a changed object reference (`Date`, `Array`, `Function`, `Object`).", "translation": "Angular 只有在它检测到输入值发生了*纯变更*时才会执行*纯管道*。\n ***纯变更***是指对原始类型值(`String`、`Number`、`Boolean`、`Symbol`)的更改,\n 或者对对象引用(`Date`、`Array`、`Function`、`Object`)的更改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ANGULARIGNORESCHANGESWITHINCOMPOSITEOBJECTSITWONTCALLAPUREPIPEIFYOUCHANGEANINPUTMONTHADDTOANINPUTARRAYORUPDATEANINPUTOBJECTPROPERTY", "original": "Angular ignores changes within (composite) objects.\nIt won't call a pure pipe if you change an input month, add to an input array, or update an input object property.", "translation": "Angular 会忽略(复合)对象*内部*的更改。\n如果你更改了输入日期(`Date`)中的月份、往一个输入数组(`Array`)中添加新值或者更新了一个输入对象(`Object`)的属性,Angular 都不会调用纯管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THISMAYSEEMRESTRICTIVEBUTITSALSOFASTANOBJECTREFERENCECHECKISFASTMDASHMUCHFASTERTHANADEEPCHECKFORDIFFERENCESMDASHSOANGULARCANQUICKLYDETERMINEIFITCANSKIPBOTHTHEPIPEEXECUTIONANDAVIEWUPDATE", "original": "This may seem restrictive but it's also fast.\nAn object reference check is fast—much faster than a deep check for\ndifferences—so Angular can quickly determine if it can skip both the\npipe execution and a view update.", "translation": "这可能看起来是一种限制,但它保证了速度。\n对象引用的检查是非常快的(比递归的深检查要快得多),所以 Angular 可以快速的决定是否应该跳过管道执行和视图更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "FORTHISREASONAPUREPIPEISPREFERABLEWHENYOUCANLIVEWITHTHECHANGEDETECTIONSTRATEGYWHENYOUCANTYOUCANUSETHEIMPUREPIPE", "original": "For this reason, a pure pipe is preferable when you can live with the change detection strategy.\nWhen you can't, you *can* use the impure pipe.", "translation": "因此,如果要和变更检测策略打交道,就会更喜欢用纯管道。\n如果不能,你就*可以*转回到非纯管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ORYOUMIGHTNOTUSEAPIPEATALLITMAYBEBETTERTOPURSUETHEPIPESPURPOSEWITHAPROPERTYOFTHECOMPONENTAPOINTTHATSDISCUSSEDLATERINTHISPAGE", "original": "Or you might not use a pipe at all.\nIt may be better to pursue the pipe's purpose with a property of the component,\na point that's discussed later in this page.", "translation": "或者你也可以完全不用管道。\n有时候,使用组件的属性能比用管道更好的达到目的,后面会再讨论这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "H3CLASSNOTOCIMPUREPIPESH3", "original": "<h3 class=\"no-toc\">Impure pipes</h3>", "translation": "<h3 class=\"no-toc\">非纯管道</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ANGULAREXECUTESANIMPUREPIPEDURINGEVERYCOMPONENTCHANGEDETECTIONCYCLEANIMPUREPIPEISCALLEDOFTENASOFTENASEVERYKEYSTROKEORMOUSEMOVE", "original": "Angular executes an *impure pipe* during every component change detection cycle.\nAn impure pipe is called often, as often as every keystroke or mouse-move.", "translation": "Angular 会在每个组件的变更检测周期中执行*非纯管道*。\n非纯管道可能会被调用很多次,和每个按键或每次鼠标移动一样频繁。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "WITHTHATCONCERNINMINDIMPLEMENTANIMPUREPIPEWITHGREATCAREANEXPENSIVELONGRUNNINGPIPECOULDDESTROYTHEUSEREXPERIENCE", "original": "With that concern in mind, implement an impure pipe with great care.\nAn expensive, long-running pipe could destroy the user experience.", "translation": "要在脑子里绷着这根弦,必须小心翼翼的实现非纯管道。\n一个昂贵、迟钝的管道将摧毁用户体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "H3CLASSNOTOCANIMPUREIFLYINGHEROESPIPEIH3", "original": "<h3 class=\"no-toc\">An impure <i>FlyingHeroesPipe</i></h3>", "translation": "<h3 class=\"no-toc\">非纯管道 <i>FlyingHeroesPipe</i></h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "AFLIPOFTHESWITCHTURNSTHEFLYINGHEROESPIPEINTOAFLYINGHEROESIMPUREPIPETHECOMPLETEIMPLEMENTATIONISASFOLLOWS:", "original": "A flip of the switch turns the `FlyingHeroesPipe` into a `FlyingHeroesImpurePipe`.\nThe complete implementation is as follows:", "translation": "把 `FlyingHeroesPipe` 换成了 `FlyingHeroesImpurePipe`。\n下面是完整的实现:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUINHERITFROMFLYINGHEROESPIPETOPROVETHEPOINTTHATNOTHINGCHANGEDINTERNALLYTHEONLYDIFFERENCEISTHEPUREFLAGINTHEPIPEMETADATA", "original": "You inherit from `FlyingHeroesPipe` to prove the point that nothing changed internally.\nThe only difference is the `pure` flag in the pipe metadata.", "translation": "你把它从 `FlyingHeroesPipe` 中继承下来,以证明无需改动内部代码。\n唯一的区别是管道元数据中的 `pure` 标志。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THISISAGOODCANDIDATEFORANIMPUREPIPEBECAUSETHETRANSFORMFUNCTIONISTRIVIALANDFAST", "original": "This is a good candidate for an impure pipe because the `transform` function is trivial and fast.", "translation": "这是一个很好地非纯管道候选者,因为它的 `transform` 函数又小又快。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUCANDERIVEAFLYINGHEROESIMPURECOMPONENTFROMFLYINGHEROESCOMPONENT", "original": "You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`.", "translation": "你可以从 `FlyingHeroesComponent` 派生出一个 `FlyingHeroesImpureComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEONLYSUBSTANTIVECHANGEISTHEPIPEINTHETEMPLATEYOUCANCONFIRMINTHELIVEEXAMPLELIVEEXAMPLETHATTHEFLYINGHEROESDISPLAYUPDATESASYOUADDHEROESEVENWHENYOUMUTATETHEHEROESARRAY", "original": "The only substantive change is the pipe in the template.\nYou can confirm in the <live-example></live-example> that the _flying heroes_\ndisplay updates as you add heroes, even when you mutate the `heroes` array.", "translation": "唯一的重大改动就是管道。\n 你可以在<live-example></live-example>中确认,当你添加新的英雄甚至修改 `heroes` 数组时,这个*会飞的英雄*的显示也跟着更新了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "H3CLASSNOTOCTHEIMPUREIASYNCPIPEIH3", "original": "<h3 class=\"no-toc\">The impure <i>AsyncPipe</i></h3>", "translation": "<h3 id='async-pipe'>非纯 <i>AsyncPipe</i></h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEANGULARASYNCPIPEISANINTERESTINGEXAMPLEOFANIMPUREPIPETHEASYNCPIPEACCEPTSAPROMISEOROBSERVABLEASINPUTANDSUBSCRIBESTOTHEINPUTAUTOMATICALLYEVENTUALLYRETURNINGTHEEMITTEDVALUES", "original": "The Angular `AsyncPipe` is an interesting example of an impure pipe.\nThe `AsyncPipe` accepts a `Promise` or `Observable` as input\nand subscribes to the input automatically, eventually returning the emitted values.", "translation": "Angular 的 `AsyncPipe` 是一个有趣的非纯管道的例子。\n `AsyncPipe` 接受一个 `Promise` 或 `Observable` 作为输入,并且自动订阅这个输入,最终返回它们给出的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEASYNCPIPEISALSOSTATEFULTHEPIPEMAINTAINSASUBSCRIPTIONTOTHEINPUTOBSERVABLEANDKEEPSDELIVERINGVALUESFROMTHATOBSERVABLEASTHEYARRIVE", "original": "The `AsyncPipe` is also stateful.\nThe pipe maintains a subscription to the input `Observable` and\nkeeps delivering values from that `Observable` as they arrive.", "translation": "`AsyncPipe` 管道是有状态的。\n 该管道维护着一个所输入的 `Observable` 的订阅,并且持续从那个 `Observable` 中发出新到的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THISNEXTEXAMPLEBINDSANOBSERVABLEOFMESSAGESTRINGSMESSAGETOAVIEWWITHTHEASYNCPIPE", "original": "This next example binds an `Observable` of message strings\n(`message$`) to a view with the `async` pipe.", "translation": "下面例子使用该 `async` 管道把一个消息字符串(`message$`)的 `Observable` 绑定到视图中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEASYNCPIPESAVESBOILERPLATEINTHECOMPONENTCODETHECOMPONENTDOESNTHAVETOSUBSCRIBETOTHEASYNCDATASOURCEEXTRACTTHERESOLVEDVALUESANDEXPOSETHEMFORBINDINGANDHAVETOUNSUBSCRIBEWHENITSDESTROYEDAPOTENTSOURCEOFMEMORYLEAKS", "original": "The Async pipe saves boilerplate in the component code.\nThe component doesn't have to subscribe to the async data source,\nextract the resolved values and expose them for binding,\nand have to unsubscribe when it's destroyed\n(a potent source of memory leaks).", "translation": "这个 Async 管道节省了组件的样板代码。\n组件不用订阅这个异步数据源,而且不用在被销毁时取消订阅(如果订阅了而忘了反订阅容易导致隐晦的内存泄露)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "H3CLASSNOTOCANIMPURECACHINGPIPEH3", "original": "<h3 class=\"no-toc\">An impure caching pipe</h3>", "translation": "<h3 class=\"no-toc\">一个非纯而且带缓存的管道</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "WRITEONEMOREIMPUREPIPEAPIPETHATMAKESANHTTPREQUEST", "original": "Write one more impure pipe, a pipe that makes an HTTP request.", "translation": "来写更多的非纯管道:一个向服务器发起 HTTP 请求的管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "REMEMBERTHATIMPUREPIPESARECALLEDEVERYFEWMILLISECONDSIFYOURENOTCAREFULTHISPIPEWILLPUNISHTHESERVERWITHREQUESTS", "original": "Remember that impure pipes are called every few milliseconds.\nIf you're not careful, this pipe will punish the server with requests.", "translation": "时刻记住,非纯管道可能每隔几微秒就会被调用一次。\n如果你不小心点,这个管道就会发起一大堆请求“攻击”服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "INTHEFOLLOWINGCODETHEPIPEONLYCALLSTHESERVERWHENTHEREQUESTURLCHANGESANDITCACHESTHESERVERRESPONSETHECODEUSESTHEANGULARHTTPGUIDEHTTPCLIENTTORETRIEVEDATA:", "original": "In the following code, the pipe only calls the server when the request URL changes and it caches the server response.\nThe code uses the [Angular http](guide/http) client to retrieve data:", "translation": "下面这个管道只有当所请求的 URL 发生变化时才会向服务器发起请求。它会缓存服务器的响应。\n代码如下,它使用[Angular http](guide/http)客户端来接收数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "NOWDEMONSTRATEITINAHARNESSCOMPONENTWHOSETEMPLATEDEFINESTWOBINDINGSTOTHISPIPEBOTHREQUESTINGTHEHEROESFROMTHEHEROESJSONFILE", "original": "Now demonstrate it in a harness component whose template defines two bindings to this pipe,\nboth requesting the heroes from the `heroes.json` file.", "translation": "接下来在一个测试挽具组件中演示一下它,该组件的模板中定义了两个使用到此管道的绑定,它们都从 `heroes.json` 文件中取得英雄数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THECOMPONENTRENDERSASTHEFOLLOWING:", "original": "The component renders as the following:", "translation": "组件渲染起来是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ABREAKPOINTONTHEPIPESREQUESTFORDATASHOWSTHEFOLLOWING:", "original": "A breakpoint on the pipe's request for data shows the following:", "translation": "这个管道上的断点请求数据的过程显示:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "EACHBINDINGGETSITSOWNPIPEINSTANCE", "original": "* Each binding gets its own pipe instance.", "translation": "每个绑定都有它自己的管道实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "EACHPIPEINSTANCECACHESITSOWNURLANDDATA", "original": "* Each pipe instance caches its own URL and data.", "translation": "每个管道实例都缓存了它自己的 URL 和数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "EACHPIPEINSTANCEONLYCALLSTHESERVERONCE", "original": "* Each pipe instance only calls the server once.", "translation": "每个管道实例都只调用一次服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "INTHEPREVIOUSCODESAMPLETHESECONDFETCHPIPEBINDINGDEMONSTRATESMOREPIPECHAININGITDISPLAYSTHESAMEHERODATAINJSONFORMATBYCHAININGTHROUGHTOTHEBUILTINJSONPIPE", "original": "In the previous code sample, the second `fetch` pipe binding demonstrates more pipe chaining.\nIt displays the same hero data in JSON format by chaining through to the built-in `JsonPipe`.", "translation": "第二个绑定除了用到 `FetchPipe` 之外还链接了更多管道。\n它通过串联上内置管道 `JsonPipe` 来把英雄数据显示成了 JSON 格式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "HEADERDEBUGGINGWITHTHEJSONPIPEHEADER", "original": "<header>Debugging with the json pipe</header>", "translation": "<header>借助 json 管道进行调试</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEJSONPIPEAPICOMMONJSONPIPEPROVIDESANEASYWAYTODIAGNOSISAMYSTERIOUSLYFAILINGDATABINDINGORINSPECTANOBJECTFORFUTUREBINDING", "original": "The [JsonPipe](api/common/JsonPipe)\nprovides an easy way to diagnosis a mysteriously failing data binding or\ninspect an object for future binding.", "translation": "[JsonPipe](api/common/JsonPipe)为你诊断数据绑定的某些神秘错误或为做进一步绑定而探查数据时,提供了一个简单途径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "H3CLASSNOTOCPUREPIPESANDPUREFUNCTIONSH3", "original": "<h3 class=\"no-toc\">Pure pipes and pure functions</h3>", "translation": "<h3 class=\"no-toc\">纯管道与纯函数</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "APUREPIPEUSESPUREFUNCTIONSPUREFUNCTIONSPROCESSINPUTSANDRETURNVALUESWITHOUTDETECTABLESIDEEFFECTSGIVENTHESAMEINPUTTHEYSHOULDALWAYSRETURNTHESAMEOUTPUT", "original": "A pure pipe uses pure functions.\nPure functions process inputs and return values without detectable side effects.\nGiven the same input, they should always return the same output.", "translation": "纯管道使用纯函数。\n纯函数是指在处理输入并返回结果时,不会产生任何副作用的函数。\n给定相同的输入,它们总是返回相同的输出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEPIPESDISCUSSEDEARLIERINTHISPAGEAREIMPLEMENTEDWITHPUREFUNCTIONSTHEBUILTINDATEPIPEISAPUREPIPEWITHAPUREFUNCTIONIMPLEMENTATIONSOARETHEEXPONENTIALSTRENGTHPIPEANDFLYINGHEROESPIPEAFEWSTEPSBACKYOUREVIEWEDTHEFLYINGHEROESIMPUREPIPEMDASHANIMPUREPIPEWITHAPUREFUNCTION", "original": "The pipes discussed earlier in this page are implemented with pure functions.\nThe built-in `DatePipe` is a pure pipe with a pure function implementation.\nSo are the `ExponentialStrengthPipe` and `FlyingHeroesPipe`.\nA few steps back, you reviewed the `FlyingHeroesImpurePipe`—an impure pipe with a pure function.", "translation": "在本章前面讨论的管道都是用纯函数实现的。\n内置的 `DatePipe` 就是一个用纯函数实现的纯管道。\n`ExponentialStrengthPipe` 是如此,\n`FlyingHeroesComponent` 也是如此。\n不久前你刚看过的 `FlyingHeroesImpurePipe` 就是一个*用纯函数实现的非纯管道*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "BUTALWAYSIMPLEMENTAPUREPIPEWITHAPUREFUNCTIONOTHERWISEYOULLSEEMANYCONSOLEERRORSREGARDINGEXPRESSIONSTHATCHANGEDAFTERTHEYWERECHECKED", "original": "But always implement a *pure pipe* with a *pure function*.\nOtherwise, you'll see many console errors regarding expressions that changed after they were checked.", "translation": "但是一个*纯管道*必须总是用*纯函数*实现。忽略这个警告将导致失败并带来一大堆这样的控制台错误:表达式在被检查后被变更。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##NEXTSTEPS", "original": "## Next steps", "translation": "## 下一步", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "PIPESAREAGREATWAYTOENCAPSULATEANDSHARECOMMONDISPLAYVALUETRANSFORMATIONSUSETHEMLIKESTYLESDROPPINGTHEMINTOYOURTEMPLATESEXPRESSIONSTOENRICHTHEAPPEALANDUSABILITYOFYOURVIEWS", "original": "Pipes are a great way to encapsulate and share common display-value\ntransformations. Use them like styles, dropping them\ninto your template's expressions to enrich the appeal and usability\nof your views.", "translation": "管道能很好的封装和共享的通用“值-显示”转换逻辑。可以像样式一样使用它们,把它们扔到模板表达式中,以提升视图的表现力和可用性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "EXPLOREANGULARSINVENTORYOFBUILTINPIPESINTHEAPIREFERENCEAPITYPEPIPETRYWRITINGACUSTOMPIPEANDPERHAPSCONTRIBUTINGITTOTHECOMMUNITY", "original": "Explore Angular's inventory of built-in pipes in the [API Reference](api?type=pipe).\nTry writing a custom pipe and perhaps contributing it to the community.", "translation": "要浏览 Angular 的所有内置管道,请到[API 参考手册](api?type=pipe)。\n学着写写自定义管道,并贡献给开发社区。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "##APPENDIX:NOFILTERPIPEORORDERBYPIPE", "original": "## Appendix: No *FilterPipe* or *OrderByPipe*", "translation": "## 附录:没有 *FilterPipe* 或者 *OrderByPipe*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "ANGULARDOESNTPROVIDEPIPESFORFILTERINGORSORTINGLISTSDEVELOPERSFAMILIARWITHANGULARJSKNOWTHESEASFILTERANDORDERBYTHEREARENOEQUIVALENTSINANGULAR", "original": "Angular doesn't provide pipes for filtering or sorting lists.\nDevelopers familiar with AngularJS know these as `filter` and `orderBy`.\nThere are no equivalents in Angular.", "translation": "Angular 没有随身发布过滤或列表排序的管道。\n熟悉 AngularJS 的开发人员应该知道 `filter` 和 `orderBy` 过滤器,但在 Angular 中它们没有等价物。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THISISNTANOVERSIGHTANGULARDOESNTOFFERSUCHPIPESBECAUSETHEYPERFORMPOORLYANDPREVENTAGGRESSIVEMINIFICATIONBOTHFILTERANDORDERBYREQUIREPARAMETERSTHATREFERENCEOBJECTPROPERTIESEARLIERINTHISPAGEYOULEARNEDTHATSUCHPIPESMUSTBEIMPUREGUIDEPIPES#PUREANDIMPUREPIPESANDTHATANGULARCALLSIMPUREPIPESINALMOSTEVERYCHANGEDETECTIONCYCLE", "original": "This isn't an oversight. Angular doesn't offer such pipes because\nthey perform poorly and prevent aggressive minification.\nBoth `filter` and `orderBy` require parameters that reference object properties.\nEarlier in this page, you learned that such pipes must be [impure](guide/pipes#pure-and-impure-pipes) and that\nAngular calls impure pipes in almost every change-detection cycle.", "translation": "这并不是疏忽。Angular 不想提供这些管道,因为 (a) 它们性能堪忧,以及 (b) 它们会阻止比较激进的代码最小化(minification)。\n无论是 `filter` 还是 `orderBy` 都需要它的参数引用对象型属性。\n你在前面学过,这样的管道必然是[*非纯管道*](guide/pipes#pure-and-impure-pipes),并且 Angular 会在几乎每一次变更检测周期中调用非纯管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "FILTERINGANDESPECIALLYSORTINGAREEXPENSIVEOPERATIONSTHEUSEREXPERIENCECANDEGRADESEVERELYFOREVENMODERATESIZEDLISTSWHENANGULARCALLSTHESEPIPEMETHODSMANYTIMESPERSECONDFILTERANDORDERBYHAVEOFTENBEENABUSEDINANGULARJSAPPSLEADINGTOCOMPLAINTSTHATANGULARITSELFISSLOWTHATCHARGEISFAIRINTHEINDIRECTSENSETHATANGULARJSPREPAREDTHISPERFORMANCETRAPBYOFFERINGFILTERANDORDERBYINTHEFIRSTPLACE", "original": "Filtering and especially sorting are expensive operations.\nThe user experience can degrade severely for even moderate-sized lists when Angular calls these pipe methods many times per second.\n`filter` and `orderBy` have often been abused in AngularJS apps, leading to complaints that Angular itself is slow.\nThat charge is fair in the indirect sense that AngularJS prepared this performance trap\nby offering `filter` and `orderBy` in the first place.", "translation": "过滤、 特别是排序是昂贵的操作。\n当 Angular 每秒调用很多次这类管道函数时,即使是中等规模的列表都可能严重降低用户体验。\n在 AngularJS 程序中,`filter` 和 `orderBy` 经常被误用,结果连累到 Angular 自身,人们抱怨说它太慢。\n从某种意义上,这也不冤:谁叫 AngularJS 把 `filter` 和 `orderBy` 作为首发队员呢?是它自己准备了这个性能陷阱。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEMINIFICATIONHAZARDISALSOCOMPELLINGIFLESSOBVIOUSIMAGINEASORTINGPIPEAPPLIEDTOALISTOFHEROESTHELISTMIGHTBESORTEDBYHERONAMEANDPLANETOFORIGINPROPERTIESINTHEFOLLOWINGWAY:", "original": "The minification hazard is also compelling, if less obvious. Imagine a sorting pipe applied to a list of heroes.\nThe list might be sorted by hero `name` and `planet` of origin properties in the following way:", "translation": "虽然不是很明显,但代码最小化方面也存在风险。想象一个用于英雄列表的排序管道。该列表可能根据英雄原始属性中的 `name` 和 `planet` 进行排序,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "YOUIDENTIFYTHESORTFIELDSBYTEXTSTRINGSEXPECTINGTHEPIPETOREFERENCEAPROPERTYVALUEBYINDEXINGSUCHASHERONAMEUNFORTUNATELYAGGRESSIVEMINIFICATIONMANIPULATESTHEHEROPROPERTYNAMESSOTHATHERONAMEANDHEROPLANETBECOMESOMETHINGLIKEHEROAANDHEROBCLEARLYHERONAMEDOESNTWORK", "original": "You identify the sort fields by text strings, expecting the pipe to reference a property value by indexing\n(such as `hero['name']`).\nUnfortunately, aggressive minification manipulates the `Hero` property names so that `Hero.name` and `Hero.planet`\nbecome something like `Hero.a` and `Hero.b`. Clearly `hero['name']` doesn't work.", "translation": "你使用文本字符串来标记出排序字段,期望管道通过索引形式(如 `hero['name']`)引用属性的值。\n 不幸的是,激进的代码最小化策略会*改变*`Hero` 类的属性名,所以 `Hero.name` 和 `Hero.planet` 可能会被变成 `Hero.a` 和 `Hero.b`。\n 显然,`hero['name']` 是无法正常工作的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "WHILESOMEMAYNOTCARETOMINIFYTHISAGGRESSIVELYTHEANGULARPRODUCTSHOULDNTPREVENTANYONEFROMMINIFYINGAGGRESSIVELYTHEREFORETHEANGULARTEAMDECIDEDTHATEVERYTHINGANGULARPROVIDESWILLMINIFYSAFELY", "original": "While some may not care to minify this aggressively,\nthe Angular product shouldn't prevent anyone from minifying aggressively.\nTherefore, the Angular team decided that everything Angular provides will minify safely.", "translation": "然而有些人可能不想做那么激进的最小化,\nAngular 作为一个产品不应该拒绝那些想做激进的最小化的人。\n所以,Angular 开发组决定随 Angular 一起发布的每样东西,都应该能被安全的最小化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "THEANGULARTEAMANDMANYEXPERIENCEDANGULARDEVELOPERSSTRONGLYRECOMMENDMOVINGFILTERINGANDSORTINGLOGICINTOTHECOMPONENTITSELFTHECOMPONENTCANEXPOSEAFILTEREDHEROESORSORTEDHEROESPROPERTYANDTAKECONTROLOVERWHENANDHOWOFTENTOEXECUTETHESUPPORTINGLOGICANYCAPABILITIESTHATYOUWOULDHAVEPUTINAPIPEANDSHAREDACROSSTHEAPPCANBEWRITTENINAFILTERINGSORTINGSERVICEANDINJECTEDINTOTHECOMPONENT", "original": "The Angular team and many experienced Angular developers strongly recommend moving\nfiltering and sorting logic into the component itself.\nThe component can expose a `filteredHeroes` or `sortedHeroes` property and take control\nover when and how often to execute the supporting logic.\nAny capabilities that you would have put in a pipe and shared across the app can be\nwritten in a filtering/sorting service and injected into the component.", "translation": "Angular 开发组和一些有经验的 Angular 开发者强烈建议你:把你的过滤和排序逻辑挪进组件本身。\n组件可以对外暴露一个 `filteredHeroes` 或 `sortedHeroes` 属性,这样它就获得控制权,以决定要用什么频度去执行其它辅助逻辑。\n你原本准备实现为管道,并在整个应用中共享的那些功能,都能被改写为一个过滤/排序的服务,并注入到组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "IFTHESEPERFORMANCEANDMINIFICATIONCONSIDERATIONSDONTAPPLYTOYOUYOUCANALWAYSCREATEYOUROWNSUCHPIPESSIMILARTOTHEFLYINGHEROESPIPEGUIDEPIPES#IMPUREFLYINGHEROESORFINDTHEMINTHECOMMUNITY", "original": "If these performance and minification considerations don't apply to you, you can always create your own such pipes\n(similar to the [FlyingHeroesPipe](guide/pipes#impure-flying-heroes)) or find them in the community.", "translation": "如果你不需要顾虑这些性能和最小化问题,也可以创建自己的管道来实现这些功能(参考[FlyingHeroesPipe](guide/pipes#impure-flying-heroes)中的写法)或到社区中去找找。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/pipes.md" }, { + "key": "#PRACTICALOBSERVABLEUSAGE", "original": "# Practical observable usage", "translation": "# 可观察对象用法实战", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "HEREARESOMEEXAMPLESOFDOMAINSINWHICHOBSERVABLESAREPARTICULARLYUSEFUL", "original": "Here are some examples of domains in which observables are particularly useful.", "translation": "这里示范了一些在某种领域中可观察对象会特别有用的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "##TYPEAHEADSUGGESTIONS", "original": "## Type-ahead suggestions", "translation": "## 输入提示(type-ahead)建议", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "OBSERVABLESCANSIMPLIFYTHEIMPLEMENTATIONOFTYPEAHEADSUGGESTIONSTYPICALLYATYPEAHEADHASTODOASERIESOFSEPARATETASKS:", "original": "Observables can simplify the implementation of type-ahead suggestions. Typically, a type-ahead has to do a series of separate tasks:", "translation": "可观察对象可以简化输入提示建议的实现方式。典型的输入提示要完成一系列独立的任务:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "LISTENFORDATAFROMANINPUT", "original": "* Listen for data from an input.", "translation": "从输入中监听数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "TRIMTHEVALUEREMOVEWHITESPACEANDMAKESUREITSAMINIMUMLENGTH", "original": "* Trim the value (remove whitespace) and make sure it’s a minimum length.", "translation": "移除输入值前后的空白字符,并确认它达到了最小长度。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "DEBOUNCESOASNOTTOSENDOFFAPIREQUESTSFOREVERYKEYSTROKEBUTINSTEADWAITFORABREAKINKEYSTROKES", "original": "* Debounce (so as not to send off API requests for every keystroke, but instead wait for a break in keystrokes).", "translation": "防抖(这样才能防止连续按键时每次按键都发起 API 请求,而应该等到按键出现停顿时才发起)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "DONTSENDAREQUESTIFTHEVALUESTAYSTHESAMERAPIDLYHITACHARACTERTHENBACKSPACEFORINSTANCE", "original": "* Don’t send a request if the value stays the same (rapidly hit a character, then backspace, for instance).", "translation": "如果输入值没有变化,则不要发起请求(比如按某个字符,然后快速按退格)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "CANCELONGOINGAJAXREQUESTSIFTHEIRRESULTSWILLBEINVALIDATEDBYTHEUPDATEDRESULTS", "original": "* Cancel ongoing AJAX requests if their results will be invalidated by the updated results.", "translation": "如果已发出的 AJAX 请求的结果会因为后续的修改而变得无效,那就取消它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "WRITINGTHISINFULLJAVASCRIPTCANBEQUITEINVOLVEDWITHOBSERVABLESYOUCANUSEASIMPLESERIESOFRXJSOPERATORS:", "original": "Writing this in full JavaScript can be quite involved. With observables, you can use a simple series of RxJS operators:", "translation": "完全用 JavaScript 的传统写法实现这个功能可能需要大量的工作。使用可观察对象,你可以使用这样一个 RxJS 操作符的简单序列:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "##EXPONENTIALBACKOFF", "original": "## Exponential backoff", "translation": "## 指数化退避", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "EXPONENTIALBACKOFFISATECHNIQUEINWHICHYOURETRYANAPIAFTERFAILUREMAKINGTHETIMEINBETWEENRETRIESLONGERAFTEREACHCONSECUTIVEFAILUREWITHAMAXIMUMNUMBEROFRETRIESAFTERWHICHTHEREQUESTISCONSIDEREDTOHAVEFAILEDTHISCANBEQUITECOMPLEXTOIMPLEMENTWITHPROMISESANDOTHERMETHODSOFTRACKINGAJAXCALLSWITHOBSERVABLESITISVERYEASY:", "original": "Exponential backoff is a technique in which you retry an API after failure, making the time in between retries longer after each consecutive failure, with a maximum number of retries after which the request is considered to have failed. This can be quite complex to implement with promises and other methods of tracking AJAX calls. With observables, it is very easy:", "translation": "指数化退避是一种失败后重试 API 的技巧,它会在每次连续的失败之后让重试时间逐渐变长,超过最大重试次数之后就会彻底放弃。\n如果使用承诺和其它跟踪 AJAX 调用的方法会非常复杂,而使用可观察对象,这非常简单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/practical-observable-usage.md" }, { + "key": "#PROVIDERS", "original": "# Providers", "translation": "# 服务提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "####PREREQUISITES:", "original": "#### Prerequisites:", "translation": "#### 前提条件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "ABASICUNDERSTANDINGOFBOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "* A basic understanding of [Bootstrapping](guide/bootstrapping).", "translation": "对[引导](guide/bootstrapping)有基本的了解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "FAMILIARITYWITHFREQUENTLYUSEDMODULESGUIDEFREQUENTNGMODULES", "original": "* Familiarity with [Frequently Used Modules](guide/frequent-ngmodules).", - "translation": "熟悉[常用模块](guide/frequent-ngmodules).", + "translation": "熟悉[常用模块](guide/frequent-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "FORTHEFINALSAMPLEAPPUSINGTHEPROVIDERTHATTHISPAGEDESCRIBESSEETHELIVEEXAMPLELIVEEXAMPLE", "original": "For the final sample app using the provider that this page describes,\nsee the <live-example></live-example>.", "translation": "要想查看本页提到的这个带有特性模块的范例应用,参见 <live-example></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "##CREATEASERVICE", "original": "## Create a service", "translation": "## 创建服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "YOUCANPROVIDESERVICESTOYOURAPPBYUSINGTHEPROVIDERSARRAYINANNGMODULECONSIDERTHEDEFAULTAPPGENERATEDBYTHECLIINORDERTOADDAUSERSERVICETOITYOUCANGENERATEONEBYENTERINGTHEFOLLOWINGCOMMANDINTHETERMINALWINDOW:", "original": "You can provide services to your app by using the `providers` array in an NgModule.\nConsider the default app generated by the CLI. In order to add a user service to it,\nyou can generate one by entering the following command in the terminal window:", "translation": "你可以使用 NgModule 中的 `providers` 数组来为你的应用提供服务。\n对于用 CLI 生成的默认应用,要想为它添加一个 `user` 服务,你可以在终端窗口中输入如下命令来生成一个:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "THISCREATESASERVICECALLEDUSERSERVICEYOUNOWNEEDTOMAKETHESERVICEAVAILABLEINYOURAPPSINJECTORUPDATEAPPMODULETSBYIMPORTINGITWITHYOUROTHERIMPORTSTATEMENTSATTHETOPOFTHEFILEANDADDINGITTOTHEPROVIDERSARRAY:", "original": "This creates a service called `UserService`. You now need to make the service available in your\napp's injector. Update `app.module.ts` by importing it with your other import statements at the top\nof the file and adding it to the `providers` array:", "translation": "这将会创建一个名叫 `UserService` 的服务。你现在要让该服务在你的应用注入器中可用,就要修改 `app.module.ts` 文件。先在文件的顶部导入它,然后把它加入 `providers` 数组中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "##PROVIDERSCOPE", "original": "## Provider scope", "translation": "## 提供商的作用域", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "WHENYOUADDASERVICEPROVIDERTOTHEPROVIDERSARRAYOFTHEROOTMODULEITSAVAILABLETHROUGHOUTTHEAPPADDITIONALLYWHENYOUIMPORTAMODULETHATHASPROVIDERSTHOSEPROVIDERSAREALSOAVAILABLETOALLTHECLASSESINTHEAPPASLONGTHEYHAVETHELOOKUPTOKENFOREXAMPLEIFYOUIMPORTTHEHTTPCLIENTMODULEINTOYOURAPPMODULEITSPROVIDERSARETHENAVAILABLETOTHEENTIREAPPANDYOUCANMAKEHTTPREQUESTSFROMANYWHEREINYOURAPP", "original": "When you add a service provider to the `providers` array of the root module, it’s available throughout the app. Additionally, when you import a module that has providers, those providers are also available to all the classes in the app as long they have the lookup token. For example, if you import the `HttpClientModule` into your `AppModule`, its providers are then available to the entire app and you can make HTTP requests from anywhere in your app.", "translation": "当你把服务提供商添加到根模块的 `providers` 数组中时,它就在整个应用程序中可用了。\n另外,当你导入一个带有服务提供商的模块时,其中的服务提供商也同样对整个应用中的类是可用的 —— 只要它们有供查找用的服务令牌。\n比如,如果你把 `HttpClientModule` 导入了 `AppModule`,它里面的提供商就是对整个应用可用的,你可以在应用的任何地方发起 HTTP 请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "##LIMITINGPROVIDERSCOPEBYLAZYLOADINGMODULES", "original": "## Limiting provider scope by lazy loading modules", "translation": "## 使用惰性加载模块限制提供商的作用域", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "INTHEBASICCLIGENERATEDAPPMODULESAREEAGERLYLOADEDWHICHMEANSTHATTHEYAREALLLOADEDWHENTHEAPPLAUNCHESANGULARUSESANINJECTORSYSTEMTOMAKETHINGSAVAILABLEBETWEENMODULESINANEAGERLYLOADEDAPPTHEROOTAPPLICATIONINJECTORMAKESALLOFTHEPROVIDERSINALLOFTHEMODULESAVAILABLETHROUGHOUTTHEAPP", "original": "In the basic CLI generated app, modules are eagerly loaded which means that they are all loaded when the app launches. Angular uses an injector system to make things available between modules. In an eagerly loaded app, the root application injector makes all of the providers in all of the modules available throughout the app.", "translation": "在 CLI 生成的基本应用中,模块是立即加载的,这意味着它们都是由本应用启动的,Angular 会使用一个依赖注入体系来让一切服务都在模块间有效。对于立即加载式应用,应用中的根注入器会让所有服务提供商都对整个应用有效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "THISBEHAVIORNECESSARILYCHANGESWHENYOUUSELAZYLOADINGLAZYLOADINGISWHENYOULOADMODULESONLYWHENYOUNEEDTHEMFOREXAMPLEWHENROUTINGTHEYARENTLOADEDRIGHTAWAYLIKEWITHEAGERLYLOADEDMODULESTHISMEANSTHATANYSERVICESLISTEDINTHEIRPROVIDERARRAYSARENTAVAILABLEBECAUSETHEROOTINJECTORDOESNTKNOWABOUTTHESEMODULES", "original": "This behavior necessarily changes when you use lazy loading. Lazy loading is when you load modules only when you need them; for example, when routing. They aren’t loaded right away like with eagerly loaded modules. This means that any services listed in their provider arrays aren’t available because the root injector doesn’t know about these modules.", "translation": "当使用惰性加载时,这种行为需要进行改变。惰性加载就是只有当需要时才加载模块,比如路由中。它们没办法像立即加载模块那样进行加载。这意味着,在它们的 `providers` 数组中列出的服务都是不可用的,因为根注入器并不知道这些模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "WHENTHEANGULARROUTERLAZYLOADSAMODULEITCREATESANEWINJECTORTHISINJECTORISACHILDOFTHEROOTAPPLICATIONINJECTORIMAGINEATREEOFINJECTORSTHEREISASINGLEROOTINJECTORANDTHENACHILDINJECTORFOREACHLAZYLOADEDMODULETHEROUTERADDSALLOFTHEPROVIDERSFROMTHEROOTINJECTORTOTHECHILDINJECTORWHENTHEROUTERCREATESACOMPONENTWITHINTHELAZYLOADEDCONTEXTANGULARPREFERSSERVICEINSTANCESCREATEDFROMTHESEPROVIDERSTOTHESERVICEINSTANCESOFTHEAPPLICATIONROOTINJECTOR", "original": "When the Angular router lazy-loads a module, it creates a new injector. This injector is a child of the root application injector. Imagine a tree of injectors; there is a single root injector and then a child injector for each lazy loaded module. The router adds all of the providers from the root injector to the child injector. When the router creates a component within the lazy-loaded context, Angular prefers service instances created from these providers to the service instances of the application root injector.", "translation": "当 Angular 的路由器惰性加载一个模块时,它会创建一个新的注入器。这个注入器是应用的根注入器的一个子注入器。想象一棵注入器树,它有唯一的根注入器,而每一个惰性加载模块都有一个自己的子注入器。路由器会把根注入器中的所有提供商添加到子注入器中。如果路由器在惰性加载时创建组件, Angular 会更倾向于使用从这些提供商中创建的服务实例,而不是来自应用的根注入器的服务实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "ANYCOMPONENTCREATEDWITHINALAZYLOADEDMODULESCONTEXTSUCHASBYROUTERNAVIGATIONGETSTHELOCALINSTANCEOFTHESERVICENOTTHEINSTANCEINTHEROOTAPPLICATIONINJECTORCOMPONENTSINEXTERNALMODULESCONTINUETORECEIVETHEINSTANCECREATEDFORTHEAPPLICATIONROOT", "original": "Any component created within a lazy loaded module’s context, such as by router navigation, gets the local instance of the service, not the instance in the root application injector. Components in external modules continue to receive the instance created for the application root.", "translation": "任何在惰性加载模块的上下文中创建的组件(比如路由导航),都会获取该服务的局部实例,而不是应用的根注入器中的实例。而外部模块中的组件,仍然会收到来自于应用的根注入器创建的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "THOUGHYOUCANPROVIDESERVICESBYLAZYLOADINGMODULESNOTALLSERVICESCANBELAZYLOADEDFORINSTANCESOMEMODULESONLYWORKINTHEROOTMODULESUCHASTHEROUTERTHEROUTERWORKSWITHTHEGLOBALLOCATIONOBJECTINTHEBROWSER", "original": "Though you can provide services by lazy loading modules, not all services can be lazy loaded. For instance, some modules only work in the root module, such as the Router. The Router works with the global location object in the browser.", "translation": "虽然你可以使用惰性加载模块来提供实例,但不是所有的服务都能惰性加载。比如,像路由之类的模块只能在根模块中使用。路由器需要使用浏览器中的全局对象 `location` 进行工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "##LIMITINGPROVIDERSCOPEWITHCOMPONENTS", "original": "## Limiting provider scope with components", "translation": "## 使用组件限定服务提供商的作用域", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "ANOTHERWAYTOLIMITPROVIDERSCOPEISBYADDINGTHESERVICEYOUWANTTOLIMITTOTHECOMPONENTSPROVIDERSARRAYCOMPONENTPROVIDERSANDNGMODULEPROVIDERSAREINDEPENDENTOFEACHOTHERTHISMETHODISHELPFULFORWHENYOUWANTTOEAGERLYLOADAMODULETHATNEEDSASERVICEALLTOITSELFPROVIDINGASERVICEINTHECOMPONENTLIMITSTHESERVICEONLYTOTHATCOMPONENTOTHERCOMPONENTSINTHESAMEMODULECANTACCESSIT", "original": "Another way to limit provider scope is by adding the service you want to limit to the component’s\n`providers` array. Component providers and NgModule providers are independent of each other. This\nmethod is helpful for when you want to eagerly load a module that needs a service all to itself.\nProviding a service in the component limits the service only to that component (other components in\nthe same module can’t access it.)", "translation": "另一种限定提供商作用域的方式是把要限定的服务添加到组件的 `providers` 数组中。组件中的提供商和 NgModule 中的提供商是彼此独立的。\n当你要立即加载一个自带了全部所需服务的模块时,这种方式是有帮助的。\n在组件中提供服务,会限定该服务只能在该组件中有效(同一模块中的其它组件不能访问它)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "##PROVIDINGSERVICESINMODULESVSCOMPONENTS", "original": "## Providing services in modules vs. components", "translation": "## 在模块中提供服务还是在组件中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "GENERALLYPROVIDESERVICESTHEWHOLEAPPNEEDSINTHEROOTMODULEANDSCOPESERVICESBYPROVIDINGTHEMINLAZYLOADEDMODULES", "original": "Generally, provide services the whole app needs in the root module and scope services by providing them in lazy loaded modules.", "translation": "通常,要在根模块中提供整个应用都需要的服务,在惰性加载模块中提供限定范围的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "THEROUTERWORKSATTHEROOTLEVELSOIFYOUPUTPROVIDERSINACOMPONENTEVENAPPCOMPONENTLAZYLOADEDMODULESWHICHRELYONTHEROUTERCANTSEETHEM", "original": "The router works at the root level so if you put providers in a component, even `AppComponent`, lazy loaded modules, which rely on the router, can’t see them.", "translation": "路由器工作在根级,所以如果你把服务提供商放进组件(即使是 `AppComponent`)中,那些依赖于路由器的惰性加载模块,将无法看到它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "REGISTERAPROVIDERWITHACOMPONENTWHENYOUMUSTLIMITASERVICEINSTANCETOACOMPONENTANDITSCOMPONENTTREETHATISITSCHILDCOMPONENTSFOREXAMPLEAUSEREDITINGCOMPONENTUSEREDITORCOMPONENTTHATNEEDSAPRIVATECOPYOFACACHINGUSERSERVICESHOULDREGISTERTHEUSERSERVICEWITHTHEUSEREDITORCOMPONENTTHENEACHNEWINSTANCEOFTHEUSEREDITORCOMPONENTGETSITSOWNCACHEDSERVICEINSTANCE", "original": "Register a provider with a component when you must limit a service instance to a component and its component tree, that is, its child components. For example, a user editing component, `UserEditorComponent`, that needs a private copy of a caching `UserService` should register the `UserService` with the `UserEditorComponent`. Then each new instance of the `UserEditorComponent` gets its own cached service instance.", "translation": "当你必须把一个服务实例的作用域限定到组件及其组件树中时,可以使用组件注册一个服务提供商。\n比如,用户编辑组件 `UserEditorComponent`,它需要一个缓存 `UserService` 实例,那就应该把 `UserService` 注册进 `UserEditorComponent` 中。\n然后,每个 `UserEditorComponent` 的实例都会获取它自己的缓存服务实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "YOUMAYALSOBEINTERESTEDIN:", "original": "You may also be interested in:", - "translation": "你可能还对下列内容感兴趣:", + "translation": "你还可能对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "SINGLETONSERVICESGUIDESINGLETONSERVICESWHICHELABORATESONTHECONCEPTSCOVEREDONTHISPAGE", "original": "* [Singleton Services](guide/singleton-services), which elaborates on the concepts covered on this page.", "translation": "[单例服务](guide/singleton-services)详细解释了本页包含的那些概念。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "LAZYLOADINGMODULESGUIDELAZYLOADINGNGMODULES", "original": "* [Lazy Loading Modules](guide/lazy-loading-ngmodules).", "translation": "[惰性加载模块](guide/lazy-loading-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "NGMODULEFAQGUIDENGMODULEFAQ", "original": "* [NgModule FAQ](guide/ngmodule-faq).", "translation": "[NgModule 常见问题](guide/ngmodule-faq)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/providers.md" }, { + "key": "#QUICKSTART", "original": "# QuickStart", "translation": "# 快速上手", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "GOODTOOLSMAKEAPPLICATIONDEVELOPMENTQUICKERANDEASIERTOMAINTAINTHANIFYOUDIDEVERYTHINGBYHAND", "original": "Good tools make application development quicker and easier to maintain than\nif you did everything by hand.", "translation": "好的工具能让开发更加简单快捷。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THEANGULARCLIHTTPS:CLIANGULARIOISACOMMANDLINEINTERFACETOOLTHATCANCREATEAPROJECTADDFILESANDPERFORMAVARIETYOFONGOINGDEVELOPMENTTASKSSUCHASTESTINGBUNDLINGANDDEPLOYMENT", "original": "The [**Angular CLI**](https://cli.angular.io/) is a **_command line interface_** tool\nthat can create a project, add files, and perform a variety of ongoing development tasks such\nas testing, bundling, and deployment.", "translation": "[**Angular CLI**](https://cli.angular.io/)是一个**命令行界面**工具,它可以创建项目、添加文件以及执行一大堆开发任务,比如测试、打包和发布。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THEGOALINTHISGUIDEISTOBUILDANDRUNASIMPLEANGULARAPPLICATIONINTYPESCRIPTUSINGTHEANGULARCLIWHILEADHERINGTOTHESTYLEGUIDEGUIDESTYLEGUIDERECOMMENDATIONSTHATBENEFITEVERYANGULARPROJECT", "original": "The goal in this guide is to build and run a simple Angular\napplication in TypeScript, using the Angular CLI\nwhile adhering to the [Style Guide](guide/styleguide) recommendations that\nbenefit _every_ Angular project.", "translation": "本章的目标是构建并运行一个超级简单的 TypeScript Angular 应用。使用 Angular CLI 来让*每个* Angular 应用从[风格指南](guide/styleguide)的那些建议中获益。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "BYTHEENDOFTHECHAPTERYOULLHAVEABASICUNDERSTANDINGOFDEVELOPMENTWITHTHECLIANDAFOUNDATIONFORBOTHTHESEDOCUMENTATIONSAMPLESANDFORREALWORLDAPPLICATIONS", "original": "By the end of the chapter, you'll have a basic understanding of development with the CLI\nand a foundation for both these documentation samples and for real world applications.", "translation": "在本章的末尾,你会通过 CLI 对开发过程有一个最基本的理解,并将其作为其它文档范例以及真实应用的基础。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "ANDYOUCANALSOAHREFGENERATEDZIPSCLIQUICKSTARTCLIQUICKSTARTZIPTARGETBLANKDOWNLOADTHEEXAMPLEA", "original": "And you can also <a href=\"generated/zips/cli-quickstart/cli-quickstart.zip\" target=\"_blank\">download the example.</a>", "translation": "你还可以 <a href=\"generated/zips/cli-quickstart/cli-quickstart.zip\" target=\"_blank\">下载这个例子。</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "H2IDDEVENVSTEP1SETUPTHEDEVELOPMENTENVIRONMENTH2", "original": "<h2 id='devenv'>Step 1. Set up the Development Environment</h2>", "translation": "<h2 id='devenv'>步骤 1. 设置开发环境</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "YOUNEEDTOSETUPYOURDEVELOPMENTENVIRONMENTBEFOREYOUCANDOANYTHING", "original": "You need to set up your development environment before you can do anything.", "translation": "在开始工作之前,你必须设置好开发环境。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "INSTALLNODEJSANDNPMHTTPS:NODEJSORGENDOWNLOADIFTHEYARENOTALREADYONYOURMACHINE", "original": "Install **[Node.js® and npm](https://nodejs.org/en/download/)**\nif they are not already on your machine.", "translation": "如果你的电脑里没有 Node.js®和 npm,请安装**[它们](https://nodejs.org/en/download/)**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "VERIFYTHATYOUARERUNNINGATLEASTNODE69XANDNPM3XXBYRUNNINGNODEVANDNPMVINATERMINALCONSOLEWINDOWOLDERVERSIONSPRODUCEERRORSBUTNEWERVERSIONSAREFINE", "original": "**Verify that you are running at least node `6.9.x` and npm `3.x.x`**\nby running `node -v` and `npm -v` in a terminal/console window.\nOlder versions produce errors, but newer versions are fine.", "translation": "请先在终端/控制台窗口中运行命令 `node -v` 和 `npm -v`,\n**来验证一下你正在运行 node `6.9.x` 和 npm `3.x.x` 以上的版本。**\n更老的版本可能会出现错误,更新的版本则没问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THENINSTALLTHEANGULARCLIHTTPS:GITHUBCOMANGULARANGULARCLIGLOBALLY", "original": "Then **install the [Angular CLI](https://github.com/angular/angular-cli)** globally.", "translation": "然后全局安装 **[Angular CLI](https://github.com/angular/angular-cli)** 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "H2IDCREATEPROJSTEP2CREATEANEWPROJECTH2", "original": "<h2 id='create-proj'>Step 2. Create a new project</h2>", "translation": "<h2 id='create-proj'>步骤 2. 创建新项目</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "OPENATERMINALWINDOW", "original": "Open a terminal window.", "translation": "打开终端窗口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "GENERATEANEWPROJECTANDSKELETONAPPLICATIONBYRUNNINGTHEFOLLOWINGCOMMANDS:", "original": "Generate a new project and skeleton application by running the following commands:", "translation": "运行下列命令来生成一个新项目以及应用的骨架代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "PATIENCEPLEASEITTAKESTIMETOSETUPANEWPROJECTMOSTOFITISSPENTINSTALLINGNPMPACKAGES", "original": "Patience, please.\nIt takes time to set up a new project; most of it is spent installing npm packages.", "translation": "请耐心等待。\n创建新项目需要花费很多时间,大多数时候都是在安装那些 npm 包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "H2IDSERVESTEP3:SERVETHEAPPLICATIONH2", "original": "<h2 id='serve'>Step 3: Serve the application</h2>", "translation": "<h2 id='serve'>步骤 3. 启动开发服务器</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "GOTOTHEPROJECTDIRECTORYANDLAUNCHTHESERVER", "original": "Go to the project directory and launch the server.", "translation": "进入项目目录,并启动服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THENGSERVECOMMANDLAUNCHESTHESERVERWATCHESYOURFILESANDREBUILDSTHEAPPASYOUMAKECHANGESTOTHOSEFILES", "original": "The `ng serve` command launches the server, watches your files,\nand rebuilds the app as you make changes to those files.", "translation": "`ng serve` 命令会启动开发服务器,监听文件变化,并在修改这些文件时重新构建此应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "USINGTHEOPENORJUSTOOPTIONWILLAUTOMATICALLYOPENYOURBROWSERONHTTP:LOCALHOST:4200", "original": "Using the `--open` (or just `-o`) option will automatically open your browser\non `http://localhost:4200/`.", "translation": "使用 `--open`(或 `-o`)参数可以自动打开浏览器并访问 `http://localhost:4200/`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "YOURAPPGREETSYOUWITHAMESSAGE:", "original": "Your app greets you with a message:", "translation": "本应用会用一条消息来跟你打招呼:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "H2IDFIRSTCOMPONENTSTEP4:EDITYOURFIRSTANGULARCOMPONENTH2", "original": "<h2 id='first-component'>Step 4: Edit your first Angular component</h2>", "translation": "<h2 id='first-component'>步骤 4. 编辑你的第一个 Angular 组件</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THECLICREATEDTHEFIRSTANGULARCOMPONENTFORYOUTHISISTHEROOTCOMPONENTANDITISNAMEDAPPROOTYOUCANFINDITINSRCAPPAPPCOMPONENTTS", "original": "The CLI created the first Angular component for you.\nThis is the _root component_ and it is named `app-root`.\nYou can find it in `./src/app/app.component.ts`.", "translation": "这个 CLI 为你创建了第一个 Angular 组件。\n它就是名叫 `app-root` 的*根组件*。\n你可以在 `./src/app/app.component.ts` 目录下找到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { - "original": "Open the component file and change the `title` property from _Welcome to app!!_ to _Welcome to My First Angular App!!_:", - "translation": "打开这个组件文件,并且把 `title` 属性从 _Welcome to app!!_ 改为 _Welcome to My First Angular App!!_ :", + "key": "OPENTHECOMPONENTFILEANDCHANGETHETITLEPROPERTYFROMAPPTOMYFIRSTANGULARAPP", + "original": "Open the component file and change the `title` property from `'app'` to `'My First Angular App!'`.", + "translation": "打开这个组件文件,并且把 `title` 属性从 `'app'` 改为 `'My First Angular App!'`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THEBROWSERRELOADSAUTOMATICALLYWITHTHEREVISEDTITLETHATSNICEBUTITCOULDLOOKBETTER", "original": "The browser reloads automatically with the revised title. That's nice, but it could look better.", "translation": "浏览器会自动刷新,并具有修改之后的标题。不错,不过它还可以更好看一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "OPENSRCAPPAPPCOMPONENTCSSANDGIVETHECOMPONENTSOMESTYLE", "original": "Open `src/app/app.component.css` and give the component some style.", "translation": "打开 `src/app/app.component.css` 并给这个组件设置一些样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "LOOKINGGOOD", "original": "Looking good!", "translation": "漂亮!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "##WHATSNEXT", "original": "## What's next?", "translation": "## 接下来呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THATSABOUTALLYOUDEXPECTTODOINAHELLOWORLDAPP", "original": "That's about all you'd expect to do in a \"Hello, World\" app.", "translation": "这就是你期待这个 “Hello, World” 应用要做的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "YOUREREADYTOTAKETHETOUROFHEROESTUTORIALTUTORIALANDBUILDASMALLAPPLICATIONTHATDEMONSTRATESTHEGREATTHINGSYOUCANBUILDWITHANGULAR", "original": "You're ready to take the [Tour of Heroes Tutorial](tutorial) and build\na small application that demonstrates the great things you can build with Angular.", "translation": "现在,你可以开始[英雄指南](tutorial)教程,通过构建一个小型应用来学习如何用 Angular 构建各种大型应用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "ORYOUCANSTICKAROUNDABITLONGERTOLEARNABOUTTHEFILESINYOURBRANDNEWPROJECT", "original": "Or you can stick around a bit longer to learn about the files in your brand new project.", "translation": "或者,你也可以稍等一会儿,学学在这个新项目中的文件都是干什么用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "##PROJECTFILEREVIEW", "original": "## Project file review", "translation": "## 项目文件概览", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "ANANGULARCLIPROJECTISTHEFOUNDATIONFORBOTHQUICKEXPERIMENTSANDENTERPRISESOLUTIONS", "original": "An Angular CLI project is the foundation for both quick experiments and enterprise solutions.", "translation": "Angular CLI 项目是做快速试验和开发企业解决方案的基础。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THEFIRSTFILEYOUSHOULDCHECKOUTISREADMEMDITHASSOMEBASICINFORMATIONONHOWTOUSECLICOMMANDSWHENEVERYOUWANTTOKNOWMOREABOUTHOWANGULARCLIWORKSMAKESURETOVISITTHEANGULARCLIREPOSITORYHTTPS:GITHUBCOMANGULARANGULARCLIANDWIKIHTTPS:GITHUBCOMANGULARANGULARCLIWIKI", "original": "The first file you should check out is `README.md`.\nIt has some basic information on how to use CLI commands.\nWhenever you want to know more about how Angular CLI works make sure to visit\n[the Angular CLI repository](https://github.com/angular/angular-cli) and\n[Wiki](https://github.com/angular/angular-cli/wiki).", "translation": "你首先要看的文件是 `README.md`。\n它提供了一些如何使用 CLI 命令的基础信息。\n如果你想了解 Angular CLI 的工作原理,请访问 [Angular CLI 的仓库](https://github.com/angular/angular-cli)及其 \n [Wiki](https://github.com/angular/angular-cli/wiki)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "SOMEOFTHEGENERATEDFILESMIGHTBEUNFAMILIARTOYOU", "original": "Some of the generated files might be unfamiliar to you.", "translation": "有些生成的文件你可能觉得陌生。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "###THESRCFOLDER", "original": "### The `src` folder", "translation": "### `src` 文件夹", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "YOURAPPLIVESINTHESRCFOLDERALLANGULARCOMPONENTSTEMPLATESSTYLESIMAGESANDANYTHINGELSEYOURAPPNEEDSGOHEREANYFILESOUTSIDEOFTHISFOLDERAREMEANTTOSUPPORTBUILDINGYOURAPP", "original": "Your app lives in the `src` folder.\nAll Angular components, templates, styles, images, and anything else your app needs go here.\nAny files outside of this folder are meant to support building your app.", "translation": "你的应用代码位于 `src` 文件夹中。\n所有的 Angular 组件、模板、样式、图片以及你的应用所需的任何东西都在那里。\n这个文件夹之外的文件都是为构建应用提供支持用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "FILE", "original": "File", "translation": "文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "PURPOSE", "original": "Purpose", "translation": "用途", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "DEFINESTHEAPPCOMPONENTALONGWITHANHTMLTEMPLATECSSSTYLESHEETANDAUNITTESTITISTHEROOTCOMPONENTOFWHATWILLBECOMEATREEOFNESTEDCOMPONENTSASTHEAPPLICATIONEVOLVES", "original": "Defines the `AppComponent` along with an HTML template, CSS stylesheet, and a unit test.\n It is the **root** component of what will become a tree of nested components\n as the application evolves.", "translation": "使用 HTML 模板、CSS 样式和单元测试定义 `AppComponent` 组件。\n 它是**根**组件,随着应用的成长它会成为一棵组件树的根节点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "DEFINESAPPMODULETHEROOTMODULEGUIDEBOOTSTRAPPINGAPPMODULE:THEROOTMODULETHATTELLSANGULARHOWTOASSEMBLETHEAPPLICATIONRIGHTNOWITDECLARESONLYTHEAPPCOMPONENTSOONTHEREWILLBEMORECOMPONENTSTODECLARE", "original": "Defines `AppModule`, the [root module](guide/bootstrapping \"AppModule: the root module\") that tells Angular how to assemble the application.\n Right now it declares only the `AppComponent`.\n Soon there will be more components to declare.", "translation": "定义 `AppModule`,[根模块](guide/bootstrapping \"AppModule: 根模块\")为 Angular 描述如何组装应用。\n 目前,它只声明了 `AppComponent`。\n 不久,它将声明更多组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "AFOLDERWHEREYOUCANPUTIMAGESANDANYTHINGELSETOBECOPIEDWHOLESALEWHENYOUBUILDYOURAPPLICATION", "original": "A folder where you can put images and anything else to be copied wholesale\n when you build your application.", "translation": "这个文件夹下你可以放图片等任何东西,在构建应用时,它们全都会拷贝到发布包中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THISFOLDERCONTAINSONEFILEFOREACHOFYOURDESTINATIONENVIRONMENTSEACHEXPORTINGSIMPLECONFIGURATIONVARIABLESTOUSEINYOURAPPLICATIONTHEFILESAREREPLACEDONTHEFLYWHENYOUBUILDYOURAPPYOUMIGHTUSEADIFFERENTAPIENDPOINTFORDEVELOPMENTTHANYOUDOFORPRODUCTIONORMAYBEDIFFERENTANALYTICSTOKENSYOUMIGHTEVENUSESOMEMOCKSERVICESEITHERWAYTHECLIHASYOUCOVERED", "original": "This folder contains one file for each of your destination environments,\n each exporting simple configuration variables to use in your application.\n The files are replaced on-the-fly when you build your app.\n You might use a different API endpoint for development than you do for production\n or maybe different analytics tokens.\n You might even use some mock services.\n Either way, the CLI has you covered.", - "translation": "这个文件夹中包括为各个目标环境准备的文件,它们导出了一些应用中要用到的配置变量。\n 这些文件会在构建应用时被替换。\n 比如你可能在产品环境中使用不同的 API 端点地址,或使用不同的统计 Token 参数。\n 甚至使用一些模拟服务。\n 所有这些,CLI 都替你考虑到了。", + "translation": "这个文件夹中包括为各个目标环境准备的文件,它们导出了一些应用中要用到的配置变量。\n 这些文件会在构建应用时被替换。\n 比如你可能在生产环境中使用不同的 API 端点地址,或使用不同的统计 Token 参数。\n 甚至使用一些模拟服务。\n 所有这些,CLI 都替你考虑到了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "EVERYSITEWANTSTOLOOKGOODONTHEBOOKMARKBARGETSTARTEDWITHYOURVERYOWNANGULARICON", "original": "Every site wants to look good on the bookmark bar.\n Get started with your very own Angular icon.", "translation": "每个网站都希望自己在书签栏中能好看一点。\n 请把它换成你自己的图标。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THEMAINHTMLPAGETHATISSERVEDWHENSOMEONEVISITSYOURSITEMOSTOFTHETIMEYOULLNEVERNEEDTOEDITITTHECLIAUTOMATICALLYADDSALLJSANDCSSFILESWHENBUILDINGYOURAPPSOYOUNEVERNEEDTOADDANYSCRIPTORLINKTAGSHEREMANUALLY", "original": "The main HTML page that is served when someone visits your site.\n Most of the time you'll never need to edit it.\n The CLI automatically adds all `js` and `css` files when building your app so you\n never need to add any `<script>` or `<link>` tags here manually.", "translation": "这是别人访问你的网站是看到的主页面的 HTML 文件。\n 大多数情况下你都不用编辑它。\n 在构建应用时,CLI 会自动把所有 `js` 和 `css` 文件添加进去,所以你不必在这里手动添加任何 `<script>` 或 `<link>` 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THEMAINENTRYPOINTFORYOURAPPCOMPILESTHEAPPLICATIONWITHTHEJITCOMPILERGUIDEGLOSSARY#JITANDBOOTSTRAPSTHEAPPLICATIONSROOTMODULEAPPMODULETORUNINTHEBROWSERYOUCANALSOUSETHEAOTCOMPILERGUIDEAOTCOMPILERWITHOUTCHANGINGANYCODEBYAPPENDINGTHEAOTFLAGTOTHENGBUILDANDNGSERVECOMMANDS", "original": "The main entry point for your app.\n Compiles the application with the [JIT compiler](guide/glossary#jit)\n and bootstraps the application's root module (`AppModule`) to run in the browser.\n You can also use the [AOT compiler](guide/aot-compiler)\n without changing any code by appending the`--aot` flag to the `ng build` and `ng serve` commands.", "translation": "这是应用的主要入口点。\n 使用[JIT compiler](guide/glossary#jit)编译器编译本应用,并启动应用的根模块 `AppModule`,使其运行在浏览器中。\n 你还可以使用[AOT compiler](guide/glossary#ahead-of-time-aot-compilation)编译器,而不用修改任何代码 —— 只要给 `ng build` 或 `ng serve` 传入 `--aot` 参数就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "DIFFERENTBROWSERSHAVEDIFFERENTLEVELSOFSUPPORTOFTHEWEBSTANDARDSPOLYFILLSHELPNORMALIZETHOSEDIFFERENCESYOUSHOULDBEPRETTYSAFEWITHCOREJSANDZONEJSBUTBESURETOCHECKOUTTHEBROWSERSUPPORTGUIDEGUIDEBROWSERSUPPORTFORMOREINFORMATION", "original": "Different browsers have different levels of support of the web standards.\n Polyfills help normalize those differences.\n You should be pretty safe with `core-js` and `zone.js`, but be sure to check out\n the [Browser Support guide](guide/browser-support) for more information.", "translation": "不同的浏览器对 Web 标准的支持程度也不同。\n 腻子脚本(polyfill)能把这些不同点进行标准化。\n 你只要使用 `core-js` 和 `zone.js` 通常就够了,不过你也可以查看[浏览器支持指南](guide/browser-support)以了解更多信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "YOURGLOBALSTYLESGOHEREMOSTOFTHETIMEYOULLWANTTOHAVELOCALSTYLESINYOURCOMPONENTSFOREASIERMAINTENANCEBUTSTYLESTHATAFFECTALLOFYOURAPPNEEDTOBEINACENTRALPLACE", "original": "Your global styles go here.\n Most of the time you'll want to have local styles in your components for easier maintenance,\n but styles that affect all of your app need to be in a central place.", "translation": "这里是你的全局样式。\n 大多数情况下,你会希望在组件中使用局部样式,以利于维护,不过那些会影响你整个应用的样式你还是需要集中存放在这里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THISISTHEMAINENTRYPOINTFORYOURUNITTESTSITHASSOMECUSTOMCONFIGURATIONTHATMIGHTBEUNFAMILIARBUTITSNOTSOMETHINGYOULLNEEDTOEDIT", "original": "This is the main entry point for your unit tests.\n It has some custom configuration that might be unfamiliar, but it's not something you'll\n need to edit.", "translation": "这是单元测试的主要入口点。\n 它有一些你不熟悉的自定义配置,不过你并不需要编辑这里的任何东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "TYPESCRIPTCOMPILERCONFIGURATIONFORTHEANGULARAPPTSCONFIGAPPJSONANDFORTHEUNITTESTSTSCONFIGSPECJSON", "original": "TypeScript compiler configuration for the Angular app (`tsconfig.app.json`)\n and for the unit tests (`tsconfig.spec.json`).", "translation": "TypeScript 编译器的配置文件。`tsconfig.app.json` 是为 Angular 应用准备的,而 `tsconfig.spec.json` 是为单元测试准备的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "###THEROOTFOLDER", "original": "### The root folder", "translation": "### 根目录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "THESRCFOLDERISJUSTONEOFTHEITEMSINSIDETHEPROJECTSROOTFOLDEROTHERFILESHELPYOUBUILDTESTMAINTAINDOCUMENTANDDEPLOYTHEAPPTHESEFILESGOINTHEROOTFOLDERNEXTTOSRC", "original": "The `src/` folder is just one of the items inside the project's root folder.\nOther files help you build, test, maintain, document, and deploy the app.\nThese files go in the root folder next to `src/`.", "translation": "`src/` 文件夹是项目的根文件夹之一。\n其它文件是用来帮助你构建、测试、维护、文档化和发布应用的。它们放在根目录下,和 `src/` 平级。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "FILE", "original": "File", "translation": "文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "PURPOSE", + "original": "Purpose", + "translation": "用途", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" + }, + { + "key": "INSIDEE2ELIVETHEENDTOENDTESTSTHEYSHOULDNTBEINSIDESRCBECAUSEE2ETESTSAREREALLYASEPARATEAPPTHATJUSTSOHAPPENSTOTESTYOURMAINAPPTHATSALSOWHYTHEYHAVETHEIROWNTSCONFIGE2EJSON", "original": "Inside `e2e/` live the end-to-end tests.\n They shouldn't be inside `src/` because e2e tests are really a separate app that\n just so happens to test your main app.\n That's also why they have their own `tsconfig.e2e.json`.", "translation": "在 `e2e/` 下是端到端(end-to-end)测试。\n 它们不在 `src/` 下,是因为端到端测试实际上和应用是相互独立的,它只适用于测试你的应用而已。\n 这也就是为什么它会拥有自己的 `tsconfig.json`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "NODEJSCREATESTHISFOLDERANDPUTSALLTHIRDPARTYMODULESLISTEDINPACKAGEJSONINSIDEOFIT", "original": "`Node.js` creates this folder and puts all third party modules listed in\n `package.json` inside of it.", "translation": "`Node.js` 创建了这个文件夹,并且把 `package.json` 中列举的所有第三方模块都放在其中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "CONFIGURATIONFORANGULARCLIINTHISFILEYOUCANSETSEVERALDEFAULTSANDALSOCONFIGUREWHATFILESAREINCLUDEDWHENYOURPROJECTISBUILTCHECKOUTTHEOFFICIALDOCUMENTATIONIFYOUWANTTOKNOWMORE", "original": "Configuration for Angular CLI.\n In this file you can set several defaults and also configure what files are included\n when your project is built.\n Check out the official documentation if you want to know more.", "translation": "Angular CLI 的配置文件。\n 在这个文件中,你可以设置一系列默认值,还可以配置项目编译时要包含的那些文件。\n 要了解更多,请参阅它的官方文档。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "SIMPLECONFIGURATIONFORYOUREDITORTOMAKESUREEVERYONETHATUSESYOURPROJECTHASTHESAMEBASICCONFIGURATIONMOSTEDITORSSUPPORTANEDITORCONFIGFILESEEHTTP:EDITORCONFIGORGFORMOREINFORMATION", "original": "Simple configuration for your editor to make sure everyone that uses your project\n has the same basic configuration.\n Most editors support an `.editorconfig` file.\n See http://editorconfig.org for more information.", "translation": "给你的编辑器看的一个简单配置文件,它用来确保参与你项目的每个人都具有基本的编辑器配置。\n 大多数的编辑器都支持 `.editorconfig` 文件,详情参见 http://editorconfig.org 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "GITCONFIGURATIONTOMAKESUREAUTOGENERATEDFILESARENOTCOMMITEDTOSOURCECONTROL", "original": "Git configuration to make sure autogenerated files are not commited to source control.", "translation": "一个 Git 的配置文件,用来确保某些自动生成的文件不会被提交到源码控制系统中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "UNITTESTCONFIGURATIONFORTHEKARMATESTRUNNERHTTPS:KARMARUNNERGITHUBIOUSEDWHENRUNNINGNGTEST", "original": "Unit test configuration for the [Karma test runner](https://karma-runner.github.io),\n used when running `ng test`.", "translation": "给[Karma](https://karma-runner.github.io)的单元测试配置,当运行 `ng test` 时会用到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "NPMCONFIGURATIONLISTINGTHETHIRDPARTYPACKAGESYOURPROJECTUSESYOUCANALSOADDYOUROWNCUSTOMSCRIPTSHTTPS:DOCSNPMJSCOMMISCSCRIPTSHERE", "original": "`npm` configuration listing the third party packages your project uses.\n You can also add your own [custom scripts](https://docs.npmjs.com/misc/scripts) here.", "translation": "`npm` 配置文件,其中列出了项目使用到的第三方依赖包。\n 你还可以在这里添加自己的[自定义脚本](https://docs.npmjs.com/misc/scripts)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "ENDTOENDTESTCONFIGURATIONFORPROTRACTORHTTP:WWWPROTRACTORTESTORGUSEDWHENRUNNINGNGE2E", "original": "End-to-end test configuration for [Protractor](http://www.protractortest.org/),\n used when running `ng e2e`.", "translation": "给[Protractor](http://www.protractortest.org/)使用的端到端测试配置文件,当运行 `ng e2e` 的时候会用到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "BASICDOCUMENTATIONFORYOURPROJECTPREFILLEDWITHCLICOMMANDINFORMATIONMAKESURETOENHANCEITWITHPROJECTDOCUMENTATIONSOTHATANYONECHECKINGOUTTHEREPOCANBUILDYOURAPP", "original": "Basic documentation for your project, pre-filled with CLI command information.\n Make sure to enhance it with project documentation so that anyone\n checking out the repo can build your app!", "translation": "项目的基础文档,预先写入了 CLI 命令的信息。\n 别忘了用项目文档改进它,以便每个查看此仓库的人都能据此构建出你的应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "TYPESCRIPTCOMPILERCONFIGURATIONFORYOURIDETOPICKUPANDGIVEYOUHELPFULTOOLING", "original": "TypeScript compiler configuration for your IDE to pick up and give you helpful tooling.", "translation": "TypeScript 编译器的配置,你的 IDE 会借助它来给你提供更好的帮助。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "LINTINGCONFIGURATIONFORTSLINTHTTPS:PALANTIRGITHUBIOTSLINTTOGETHERWITHCODELYZERHTTP:CODELYZERCOMUSEDWHENRUNNINGNGLINTLINTINGHELPSKEEPYOURCODESTYLECONSISTENT", "original": "Linting configuration for [TSLint](https://palantir.github.io/tslint/) together with\n [Codelyzer](http://codelyzer.com/), used when running `ng lint`.\n Linting helps keep your code style consistent.", "translation": "给[TSLint](https://palantir.github.io/tslint/)和[Codelyzer](http://codelyzer.com/)用的配置信息,当运行 `ng lint` 时会用到。\n Lint 功能可以帮你保持代码风格的统一。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "###NEXTSTEP", "original": "### Next Step", "translation": "### 下一步", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "IFYOURENEWTOANGULARCONTINUEWITHTHETUTORIALTUTORIALTOUROFHEROESTUTORIALYOUCANSKIPTHESETUPSTEPSINCEYOUREALREADYUSINGTHEANGULARCLISETUP", "original": "If you're new to Angular, continue with the\n[tutorial](tutorial \"Tour of Heroes tutorial\").\nYou can skip the \"Setup\" step since you're already using the Angular CLI setup.", "translation": "如果你刚刚开始使用 Angular,请继续这个[教程](tutorial \"《英雄指南》教程\")。\n你可以跳过“环境设置”一章,因为你已经在使用 Angular CLI 设置好环境了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/quickstart.md" }, { + "key": "#REACTIVEFORMS", "original": "# Reactive Forms", "translation": "# 响应式表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "REACTIVEFORMSISANANGULARTECHNIQUEFORCREATINGFORMSINAREACTIVESTYLETHISGUIDEEXPLAINSREACTIVEFORMSASYOUFOLLOWTHESTEPSTOBUILDAHERODETAILEDITORFORM", "original": "_Reactive forms_ is an Angular technique for creating forms in a _reactive_ style.\nThis guide explains reactive forms as you follow the steps to build a \"Hero Detail Editor\" form.", "translation": "*响应式表单*是 Angular 中用*响应式*风格创建表单的技术。\n本章会在构建“英雄详情编辑器”的过程中,逐步讲解响应式表单的概念。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "TRYTHELIVEEXAMPLESTACKBLITZFINALTITLEREACTIVEFORMSFINALINSTACKBLITZREACTIVEFORMSLIVEEXAMPLELIVEEXAMPLE", "original": "Try the <live-example stackblitz=\"final\" title=\"Reactive Forms (final) in Stackblitz\">Reactive Forms live-example</live-example>.", "translation": "试试<live-example stackblitz=\"final\" title=\"Reactive Forms (final) in Stackblitz\">响应式表单的在线例子</live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "YOUCANALSORUNTHELIVEEXAMPLETITLEREACTIVEFORMSDEMOINSTACKBLITZREACTIVEFORMSDEMOLIVEEXAMPLEVERSIONANDCHOOSEONEOFTHEINTERMEDIATESTEPSFROMTHEDEMOPICKERATTHETOP", "original": "You can also run the <live-example title=\"Reactive Forms Demo in Stackblitz\">Reactive Forms Demo</live-example> version\nand choose one of the intermediate steps from the \"demo picker\" at the top.", "translation": "你还可以运行<live-example title=\"Reactive Forms Demo in Stackblitz\">响应式表单的演示程序</live-example>,并从顶部选取一个中间步骤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "##INTRODUCTIONTOREACTIVEFORMS", "original": "## Introduction to Reactive Forms", "translation": "## 响应式表单简介", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "ANGULAROFFERSTWOFORMBUILDINGTECHNOLOGIES:REACTIVEFORMSANDTEMPLATEDRIVENFORMSTHETWOTECHNOLOGIESBELONGTOTHEANGULARFORMSLIBRARYANDSHAREACOMMONSETOFFORMCONTROLCLASSES", "original": "Angular offers two form-building technologies: _reactive_ forms and _template-driven_ forms.\nThe two technologies belong to the `@angular/forms` library\nand share a common set of form control classes.", "translation": "Angular 提供了两种构建表单的技术:*响应式*表单和*模板驱动*表单。\n这两项技术都属于 `@angular/forms` 库,并且共享一组公共的表单控件类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "BUTTHEYDIVERGEMARKEDLYINPHILOSOPHYPROGRAMMINGSTYLEANDTECHNIQUETHEYEVENHAVETHEIROWNMODULES:THEREACTIVEFORMSMODULEANDTHEFORMSMODULE", "original": "But they diverge markedly in philosophy, programming style, and technique.\nThey even have their own modules: the `ReactiveFormsModule` and the `FormsModule`.", "translation": "但是它们在设计哲学、编程风格和具体技术上有显著区别。\n所以,它们都有自己的模块:`ReactiveFormsModule` 和 `FormsModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### _Reactive_ forms", - "translation": "### *响应式*表单", + "key": "###REACTIVEFORMS", + "original": "### Reactive forms", + "translation": "### 响应式表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "ANGULARREACTIVEFORMSFACILITATEAREACTIVESTYLEOFPROGRAMMINGTHATFAVORSEXPLICITMANAGEMENTOFTHEDATAFLOWINGBETWEENANONUIDATAMODELTYPICALLYRETRIEVEDFROMASERVERANDAUIORIENTEDFORMMODELTHATRETAINSTHESTATESANDVALUESOFTHEHTMLCONTROLSONSCREENREACTIVEFORMSOFFERTHEEASEOFUSINGREACTIVEPATTERNSTESTINGANDVALIDATION", "original": "Angular _reactive_ forms facilitate a _reactive style_ of programming\nthat favors explicit management of the data flowing between\na non-UI _data model_ (typically retrieved from a server) and a\nUI-oriented _form model_ that retains the states\nand values of the HTML controls on screen. Reactive forms offer the ease\nof using reactive patterns, testing, and validation.", "translation": "Angular 的*响应式*表单能让实现*响应式编程风格*更容易,这种编程风格更倾向于在非 UI 的*数据模型*(通常接收自服务器)之间显式的管理数据流,\n并且用一个 UI 导向的*表单模型*来保存屏幕上 HTML 控件的状态和值。\n响应式表单可以让使用响应式编程模式、测试和校验变得更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "WITHREACTIVEFORMSYOUCREATEATREEOFANGULARFORMCONTROLOBJECTSINTHECOMPONENTCLASSANDBINDTHEMTONATIVEFORMCONTROLELEMENTSINTHECOMPONENTTEMPLATEUSINGTECHNIQUESDESCRIBEDINTHISGUIDE", "original": "With _reactive_ forms, you create a tree of Angular form control objects\nin the component class and bind them to native form control elements in the\ncomponent template, using techniques described in this guide.", "translation": "使用*响应式*表单,你可以在组件中创建表单控件的对象树,并使用本章中传授的技巧把它们绑定到组件模板中的原生表单控件元素上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "YOUCREATEANDMANIPULATEFORMCONTROLOBJECTSDIRECTLYINTHECOMPONENTCLASSASTHECOMPONENTCLASSHASIMMEDIATEACCESSTOBOTHTHEDATAMODELANDTHEFORMCONTROLSTRUCTUREYOUCANPUSHDATAMODELVALUESINTOTHEFORMCONTROLSANDPULLUSERCHANGEDVALUESBACKOUTTHECOMPONENTCANOBSERVECHANGESINFORMCONTROLSTATEANDREACTTOTHOSECHANGES", "original": "You create and manipulate form control objects directly in the\ncomponent class. As the component class has immediate access to both the data\nmodel and the form control structure, you can push data model values into\nthe form controls and pull user-changed values back out. The component can\nobserve changes in form control state and react to those changes.", "translation": "你可以在组件类中直接创建和维护表单控件对象。由于组件类可以同时访问数据模型和表单控件结构,\n因此你可以把表单模型值的变化推送到表单控件中,并把变化后的值拉取回来。\n组件可以监听表单控件状态的变化,并对此做出响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "ONEADVANTAGEOFWORKINGWITHFORMCONTROLOBJECTSDIRECTLYISTHATVALUEANDVALIDITYUPDATESAREALWAYSSYNCHRONOUSANDUNDERYOURCONTROLGUIDEREACTIVEFORMS#ASYNCVSSYNCASYNCVSSYNCYOUWONTENCOUNTERTHETIMINGISSUESTHATSOMETIMESPLAGUEATEMPLATEDRIVENFORMANDREACTIVEFORMSCANBEEASIERTOUNITTEST", "original": "One advantage of working with form control objects directly is that value and validity updates\nare [always synchronous and under your control](guide/reactive-forms#async-vs-sync \"Async vs sync\").\nYou won't encounter the timing issues that sometimes plague a template-driven form\nand reactive forms can be easier to unit test.", "translation": "直接使用表单控件对象的优点之一是值和有效性状态的更新[总是同步的,并且在你的控制之下](guide/reactive-forms#async-vs-sync \"Async vs sync\")。\n你不会遇到时序问题,这个问题有时在模板驱动表单中会成为灾难。而且响应式表单更容易进行单元测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "INKEEPINGWITHTHEREACTIVEPARADIGMTHECOMPONENTPRESERVESTHEIMMUTABILITYOFTHEDATAMODELTREATINGITASAPURESOURCEOFORIGINALVALUESRATHERTHANUPDATETHEDATAMODELDIRECTLYTHECOMPONENTEXTRACTSUSERCHANGESANDFORWARDSTHEMTOANEXTERNALCOMPONENTORSERVICEWHICHDOESSOMETHINGWITHTHEMSUCHASSAVINGTHEMANDRETURNSANEWDATAMODELTOTHECOMPONENTTHATREFLECTSTHEUPDATEDMODELSTATE", "original": "In keeping with the reactive paradigm, the component\npreserves the immutability of the _data model_,\ntreating it as a pure source of original values.\nRather than update the data model directly,\nthe component extracts user changes and forwards them to an external component or service,\nwhich does something with them (such as saving them)\nand returns a new _data model_ to the component that reflects the updated model state.", "translation": "在响应式编程范式中,组件会负责维护*数据模型*的不可变性,把模型当做纯粹的原始数据源。\n组件不会直接更新数据模型,而是把用户的修改提取出来,把它们转发给外部的组件或服务,外部程序才会使用这些进行处理(比如保存它们),\n并且给组件返回一个新的*数据模型*,以反映模型状态的变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "USINGREACTIVEFORMDIRECTIVESDOESNOTREQUIREYOUTOFOLLOWALLREACTIVEPRINICIPLESBUTITDOESFACILITATETHEREACTIVEPROGRAMMINGAPPROACHSHOULDYOUCHOOSETOUSEIT", "original": "Using reactive form directives does not require you to follow all reactive priniciples,\nbut it does facilitate the reactive programming approach should you choose to use it.", "translation": "使用响应式表单的指令,并不要求你遵循所有的响应式编程原则,但它能让你更容易使用响应式编程方法,从而更愿意使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### _Template-driven_ forms", - "translation": "### *模板驱动*表单", + "key": "###TEMPLATEDRIVENFORMS", + "original": "### Template-driven forms", + "translation": "### 模板驱动表单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "TEMPLATEDRIVENFORMSINTRODUCEDINTHETEMPLATEGUIDEGUIDEFORMSTAKEACOMPLETELYDIFFERENTAPPROACH", "original": "_Template-driven_ forms, introduced in the [Template guide](guide/forms), take a completely different approach.", "translation": "在[模板](guide/forms)一章中介绍过的*模板驱动*表单,是一种完全不同的方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "YOUPLACEHTMLFORMCONTROLSSUCHASINPUTANDSELECTINTHECOMPONENTTEMPLATEANDBINDTHEMTODATAMODELPROPERTIESINTHECOMPONENTUSINGDIRECTIVESLIKENGMODEL", "original": "You place HTML form controls (such as `<input>` and `<select>`) in the component template and\nbind them to _data model_ properties in the component, using directives\nlike `ngModel`.", "translation": "你把 HTML 表单控件(比如 `<input>` 和 `<select>`)放进组件模板中,并用 `ngModel` 等指令把它们绑定到组件中*数据模型*的属性上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "YOUDONTCREATEANGULARFORMCONTROLOBJECTSANGULARDIRECTIVESCREATETHEMFORYOUUSINGTHEINFORMATIONINYOURDATABINDINGSYOUDONTPUSHANDPULLDATAVALUESANGULARHANDLESTHATFORYOUWITHNGMODELANGULARUPDATESTHEMUTABLEDATAMODELWITHUSERCHANGESASTHEYHAPPEN", "original": "You don't create Angular form control objects. Angular directives\ncreate them for you, using the information in your data bindings.\nYou don't push and pull data values. Angular handles that for you with `ngModel`.\nAngular updates the mutable _data model_ with user changes as they happen.", "translation": "你不用自己创建 Angular 表单控件对象。Angular 指令会使用数据绑定中的信息创建它们。\n你不用自己推送和拉取数据。Angular 使用 `ngModel` 来替你管理它们。\n当用户做出修改时,Angular 会据此更新可变的*数据模型*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "FORTHISREASONTHENGMODELDIRECTIVEISNOTPARTOFTHEREACTIVEFORMSMODULE", "original": "For this reason, the `ngModel` directive is not part of the ReactiveFormsModule.", "translation": "因此,`ngModel` 并不是 `ReactiveFormsModule` 模块的一部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "WHILETHISMEANSLESSCODEINTHECOMPONENTCLASSTEMPLATEDRIVENFORMSAREASYNCHRONOUSGUIDEREACTIVEFORMS#ASYNCVSSYNCASYNCVSSYNCWHICHMAYCOMPLICATEDEVELOPMENTINMOREADVANCEDSCENARIOS", "original": "While this means less code in the component class,\n[template-driven forms are asynchronous](guide/reactive-forms#async-vs-sync \"Async vs sync\")\nwhich may complicate development in more advanced scenarios.", "translation": "虽然这意味着组件中的代码更少,但是[模板驱动表单是异步工作的](guide/reactive-forms#async-vs-sync \"Async vs sync\"),这可能在更高级的场景中让开发复杂化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###ASYNCVSSYNC", "original": "### Async vs. sync", "translation": "### 异步 vs. 同步", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Reactive forms are synchronous. Template-driven forms are asynchronous. It's a difference that matters.", - "translation": "响应式表单是同步的。模板驱动表单是异步的。这个不同点很重要。", + "key": "REACTIVEFORMSARESYNCHRONOUSWHILETEMPLATEDRIVENFORMSAREASYNCHRONOUS", + "original": "Reactive forms are synchronous while template-driven forms are asynchronous.", + "translation": "响应式表单是同步的而模板驱动表单是异步的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "In reactive forms, you create the entire form control tree in code.\nYou can immediately update a value or drill down through the descendents of the parent form\nbecause all controls are always available.", + "key": "INREACTIVEFORMSYOUCREATETHEENTIREFORMCONTROLTREEINCODEYOUCANIMMEDIATELYUPDATEAVALUEORDRILLDOWNTHROUGHTHEDESCENDANTSOFTHEPARENTFORMBECAUSEALLCONTROLSAREALWAYSAVAILABLE", + "original": "In reactive forms, you create the entire form control tree in code.\nYou can immediately update a value or drill down through the descendants of the parent form\nbecause all controls are always available.", "translation": "使用响应式表单,你会在代码中创建整个表单控件树。\n你可以立即更新一个值或者深入到表单中的任意节点,因为所有的控件都始终是可用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "TEMPLATEDRIVENFORMSDELEGATECREATIONOFTHEIRFORMCONTROLSTODIRECTIVESTOAVOIDCHANGEDAFTERCHECKEDERRORSTHESEDIRECTIVESTAKEMORETHANONECYCLETOBUILDTHEENTIRECONTROLTREETHATMEANSYOUMUSTWAITATICKBEFOREMANIPULATINGANYOFTHECONTROLSFROMWITHINTHECOMPONENTCLASS", "original": "Template-driven forms delegate creation of their form controls to directives.\nTo avoid \"_changed after checked_\" errors,\nthese directives take more than one cycle to build the entire control tree.\nThat means you must wait a tick before manipulating any of the controls\nfrom within the component class.", "translation": "模板驱动表单会委托指令来创建它们的表单控件。\n为了消除“检查完后又变化了”的错误,这些指令需要消耗一个以上的变更检测周期来构建整个控件树。\n这意味着在从组件类中操纵任何控件之前,你都必须先等待一个节拍。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "FOREXAMPLEIFYOUINJECTTHEFORMCONTROLWITHAVIEWCHILDNGFORMQUERYANDEXAMINEITINTHENGAFTERVIEWINITLIFECYCLEHOOKGUIDELIFECYCLEHOOKS#AFTERVIEWLIFECYCLEHOOKSGUIDE:AFTERVIEWYOULLDISCOVERTHATITHASNOCHILDRENYOUMUSTWAITATICKUSINGSETTIMEOUTBEFOREYOUCANEXTRACTAVALUEFROMACONTROLTESTITSVALIDITYORSETITTOANEWVALUE", "original": "For example, if you inject the form control with a `@ViewChild(NgForm)` query and examine it in the\n[`ngAfterViewInit` lifecycle hook](guide/lifecycle-hooks#afterview \"Lifecycle hooks guide: AfterView\"),\nyou'll discover that it has no children.\nYou must wait a tick, using `setTimeout`, before you can\nextract a value from a control, test its validity, or set it to a new value.", "translation": "比如,如果你用 `@ViewChild(NgForm)` 查询来注入表单控件,并在[生命周期钩子 `ngAfterViewInit`](guide/lifecycle-hooks#afterview \"Lifecycle hooks guide: AfterView\")中检查它,就会发现它没有子控件。\n你必须使用 `setTimeout` 等待一个节拍才能从控件中提取值、测试有效性,或把它设置为新值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEASYNCHRONYOFTEMPLATEDRIVENFORMSALSOCOMPLICATESUNITTESTINGYOUMUSTWRAPYOURTESTBLOCKINASYNCORFAKEASYNCTOAVOIDLOOKINGFORVALUESINTHEFORMTHATARENTTHEREYETWITHREACTIVEFORMSEVERYTHINGISAVAILABLEWHENYOUEXPECTITTOBE", "original": "The asynchrony of template-driven forms also complicates unit testing.\nYou must wrap your test block in `async()` or `fakeAsync()` to\navoid looking for values in the form that aren't there yet.\nWith reactive forms, everything is available when you expect it to be.", "translation": "模板驱动表单的异步性让单元测试也变得复杂化了。\n你必须把测试代码包裹在 `async()` 或 `fakeAsync()` 中来解决要查阅的值尚不存在的情况。\n使用响应式表单,在所期望的时机一切都是可用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### Which is better, reactive or template-driven?", - "translation": "### 哪一个更好?响应式还是模板驱动?", + "key": "###CHOOSINGREACTIVEORTEMPLATEDRIVENFORMS", + "original": "### Choosing reactive or template-driven forms", + "translation": "### 选择响应式表单还是模板驱动表单?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Neither is \"better\".\nThey're two different architectural paradigms,\nwith their own strengths and weaknesses.\nChoose the approach that works best for you.\nYou may decide to use both in the same application.", - "translation": "没有哪个“更好”。\n它们是两种架构范式,各有优缺点。\n请自行选择更合适的方法,甚至可以在同一个应用中同时使用它们。", + "key": "REACTIVEANDTEMPLATEDRIVENFORMSARETWODIFFERENTARCHITECTURALPARADIGMSWITHTHEIROWNSTRENGTHSANDWEAKNESSESCHOOSETHEAPPROACHTHATWORKSBESTFORYOUYOUMAYDECIDETOUSEBOTHINTHESAMEAPPLICATION", + "original": "Reactive and template-driven forms are\ntwo different architectural paradigms,\nwith their own strengths and weaknesses.\nChoose the approach that works best for you.\nYou may decide to use both in the same application.", + "translation": "响应式表单和模板驱动表单是两种架构范式,各有优缺点。\n请自行选择更合适的方法,甚至可以在同一个应用中同时使用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The balance of this _reactive forms_ guide explores the _reactive_ paradigm and\nconcentrates exclusively on reactive forms techniques.\nFor information on _template-driven forms_, see the [_Forms_](guide/forms) guide.", - "translation": "在这章*响应式表单*中,只专注于*响应式*范式以及响应式表单技术的详情。\n要了解关于*模板驱动表单*的更多信息,参见[表单](guide/forms)一章。", + "key": "THERESTOFTHISPAGEEXPLORESTHEREACTIVEPARADIGMANDCONCENTRATESEXCLUSIVELYONREACTIVEFORMSTECHNIQUESFORINFORMATIONONTEMPLATEDRIVENFORMSSEETHEFORMSGUIDEFORMSGUIDE", + "original": "The rest of this page explores the _reactive_ paradigm and\nconcentrates exclusively on reactive forms techniques.\nFor information on _template-driven forms_, see the [_Forms_](guide/forms) guide.", + "translation": "本章其余的部分只专注于*响应式*范式以及响应式表单技术的详情。\n要了解关于*模板驱动表单*的更多信息,参见[表单](guide/forms)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "INTHENEXTSECTIONYOULLSETUPYOURPROJECTFORTHEREACTIVEFORMDEMOTHENYOULLLEARNABOUTTHEANGULARFORMCLASSESGUIDEREACTIVEFORMS#ESSENTIALSANDHOWTOUSETHEMINAREACTIVEFORM", "original": "In the next section, you'll set up your project for the reactive form demo.\nThen you'll learn about the [Angular form classes](guide/reactive-forms#essentials) and how to use them in a reactive form.", "translation": "在下一节,你要先准备一个响应式表单范例的项目,然后就可以开始学习[Angular 表单类](guide/reactive-forms#essentials),并在响应式表单中使用它们了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "##SETUP", "original": "## Setup", "translation": "## 准备工作", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "CREATEANEWPROJECTNAMEDCODEANGULARREACTIVEFORMSCODE:", "original": "Create a new project named <code>angular-reactive-forms</code>:", "translation": "创建一个名叫<code>angular-reactive-forms</code>的新项目:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "##CREATEADATAMODEL", "original": "## Create a data model", "translation": "## 创建数据模型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEFOCUSOFTHISGUIDEISAREACTIVEFORMSCOMPONENTTHATEDITSAHEROYOULLNEEDAHEROCLASSANDSOMEHERODATA", "original": "The focus of this guide is a reactive forms component that edits a hero.\nYou'll need a `hero` class and some hero data.", "translation": "本章的焦点是响应式表单组件以及编辑一个英雄。\n你需要一个 `Hero` 类和一些英雄数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "USINGTHECLIGENERATEANEWCLASSNAMEDDATAMODEL:", "original": "Using the CLI, generate a new class named `data-model`:", "translation": "使用 CLI 创建一个名叫 `data-model` 的新类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "And copy the content below:", - "translation": "并复制下列内容:", + "key": "ANDCOPYTHEFOLLOWINGINTODATAMODELTS:", + "original": "And copy the following into `data-model.ts`:", + "translation": "并把下列内容复制到 `data-model.ts` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEFILEEXPORTSTWOCLASSESANDTWOCONSTANTSTHEADDRESSANDHEROCLASSESDEFINETHEAPPLICATIONDATAMODELTHEHEROESANDSTATESCONSTANTSSUPPLYTHETESTDATA", "original": "The file exports two classes and two constants. The `Address`\nand `Hero` classes define the application _data model_.\nThe `heroes` and `states` constants supply the test data.", "translation": "这个文件导出两个类和两个常量。`Address` 和 `Hero` 类定义应用的*数据模型*。\n`heroes` 和 `states` 常量提供测试数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "##CREATEAREACTIVEFORMSCOMPONENT", "original": "## Create a _reactive forms_ component", "translation": "## 创建*响应式表单*组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "GENERATEANEWCOMPONENTNAMEDHERODETAIL:", "original": "Generate a new component named `HeroDetail`:", "translation": "生成一个名叫 `HeroDetail` 的新组件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "ANDIMPORT:", "original": "And import:", "translation": "并导入:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "NEXTUPDATETHEHERODETAILCOMPONENTCLASSWITHAFORMCONTROLFORMCONTROLISADIRECTIVETHATALLOWSYOUTOCREATEANDMANAGEAFORMCONTROLINSTANCEDIRECTLY", "original": "Next, update the `HeroDetailComponent` class with a `FormControl`.\n`FormControl` is a directive that allows you to create and manage\na `FormControl` instance directly.", "translation": "接下来,创建并导出一个带 `FormControl` 的 `HeroDetailComponent` 类。\n`FormControl` 是一个指令,它允许你直接创建并管理一个 `FormControl` 实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Here you are creating a `FormControl` called `name`.\nIt will be bound in the template to an HTML `input` box for the hero name.", - "translation": "这里你创建了一个名叫 `name` 的 `FormControl`。\n它将会绑定到模板中的一个 `input` 框,表示英雄的名字。", + "key": "THISCREATESAFORMCONTROLCALLEDNAMEITWILLBEBOUNDINTHETEMPLATETOANHTMLINPUTELEMENTFORTHEHERONAME", + "original": "This creates a `FormControl` called `name`.\nIt will be bound in the template to an HTML `<input>` element for the hero name.", + "translation": "这里创建了一个名叫 `name` 的 `FormControl`。\n它将会绑定到模板中的一个 `<input>` 元素,表示英雄的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "AFORMCONTROLCONSTRUCTORACCEPTSTHREEOPTIONALARGUMENTS:THEINITIALDATAVALUEANARRAYOFVALIDATORSANDANARRAYOFASYNCVALIDATORS", "original": "A `FormControl` constructor accepts three, optional arguments:\nthe initial data value, an array of validators, and an array of async validators.", "translation": "`FormControl` 构造函数接收三个可选参数:\n初始值、验证器数组和异步验证器数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "This simple control doesn't have data or validators.\nIn real apps, most form controls have both.", - "translation": "最简单的控件并不需要数据或验证器,但是在实际应用中,大部分表单控件都会同时具备它们。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "This guide touches only briefly on `Validators`. For an in-depth look at them,\nread the [Form Validation](guide/form-validation) guide.", - "translation": "本章中只会接触 `Validators` 中的一点点,要想更深入的了解它们,请阅读[表单验证](guide/form-validation)一章。", + "key": "THISSIMPLECONTROLDOESNTHAVEDATAORVALIDATORSINREALAPPSMOSTFORMCONTROLSHAVEBOTHFORINDEPTHINFORMATIONONVALIDATORSSEETHEFORMVALIDATIONGUIDEFORMVALIDATIONGUIDE", + "original": "This simple control doesn't have data or validators.\nIn real apps, most form controls have both. For in-depth information on\n`Validators`, see the [Form Validation](guide/form-validation) guide.", + "translation": "最简单的控件并不需要数据或验证器,但是在实际应用中,大部分表单控件都会同时具备它们。\n要想深入了解 `Validators`,参见[表单验证](guide/form-validation)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "##CREATETHETEMPLATE", "original": "## Create the template", "translation": "## 创建模板", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Now update the component's template, with the following markup.", - "translation": "现在,修改组件的模板文件 `src/app/hero-detail.component.html`,内容如下:", + "key": "NOWUPDATETHECOMPONENTSTEMPLATEWITHTHEFOLLOWINGMARKUP", + "original": "Now update the component's template with the following markup.", + "translation": "现在,把组件的模板文件 `src/app/hero-detail.component.html` 修改为如下内容:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "TOLETANGULARKNOWTHATTHISISTHEINPUTTHATYOUWANTTOASSOCIATETOTHENAMEFORMCONTROLINTHECLASSYOUNEEDFORMCONTROLNAMEINTHETEMPLATEONTHEINPUT", "original": "To let Angular know that this is the input that you want to\nassociate to the `name` `FormControl` in the class,\nyou need `[formControl]=\"name\"` in the template on the `<input>`.", "translation": "要让 Angular 知道你希望把这个输入框关联到类中的 `FormControl` 型属性 `name`,就要在模板中的 `<input>` 上加一句 `[formControl]=\"name\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Disregard the `form-control` _CSS_ class. It belongs to the\n<a href=\"http://getbootstrap.com/\" title=\"Bootstrap CSS\">Bootstrap CSS library</a>,\nnot Angular.\nIt _styles_ the form but in no way impacts the logic of the form.", + "key": "DISREGARDTHEFORMCONTROLCSSCLASSITBELONGSTOTHEAHREFHTTP:GETBOOTSTRAPCOMTITLEBOOTSTRAPCSSBOOTSTRAPCSSLIBRARYANOTANGULARANDSTYLESTHEFORMBUTINNOWAYIMPACTSTHELOGIC", + "original": "Disregard the `form-control` CSS class. It belongs to the\n<a href=\"http://getbootstrap.com/\" title=\"Bootstrap CSS\">Bootstrap CSS library</a>,\nnot Angular, and styles the form but in no way impacts the logic.", "translation": "请忽略 CSS 类 `form-control`,它属于<a href=\"http://getbootstrap.com/\" target=\"_blank\" title=\"Bootstrap CSS\">Bootstrap CSS library</a>而不是 Angular。\n它会为表单添加样式,但是对表单的逻辑毫无影响。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "## Import the _ReactiveFormsModule_", + "key": "##IMPORTTHEREACTIVEFORMSMODULE", + "original": "## Import the `ReactiveFormsModule`", "translation": "## 导入 `ReactiveFormsModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The HeroDetailComponent template uses `formControlName`\ndirective from the `ReactiveFormsModule`.", + "key": "THEHERODETAILCOMPONENTTEMPLATEUSESTHEFORMCONTROLNAMEDIRECTIVEFROMTHEREACTIVEFORMSMODULE", + "original": "The `HeroDetailComponent` template uses the `formControlName`\ndirective from the `ReactiveFormsModule`.", "translation": "`HeroDetailComponent` 的模板中使用了来自 `ReactiveFormsModule` 的 `formControlName`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "DOTHEFOLLOWINGTWOTHINGSINAPPMODULETS:", "original": "Do the following two things in `app.module.ts`:", "translation": "在 `app.module.ts` 中做了下面两件事:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "1USEAJAVASCRIPTIMPORTSTATEMENTTOACCESSTHEREACTIVEFORMSMODULE", "original": "1. Use a JavaScript `import` statement to access\nthe `ReactiveFormsModule`.", "translation": "使用 JavaScript 的 `import` 语句访问 `ReactiveFormsModule` 和 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "1ADDREACTIVEFORMSMODULETOTHEAPPMODULESIMPORTSLIST", "original": "1. Add `ReactiveFormsModule` to the `AppModule`'s `imports` list.", "translation": "把 `ReactiveFormsModule` 添加到 `AppModule` 的 `imports` 列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "## Display the _HeroDetailComponent_", + "key": "##DISPLAYTHEHERODETAILCOMPONENT", + "original": "## Display the `HeroDetailComponent`", "translation": "## 显示 `HeroDetailComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "REVISETHEAPPCOMPONENTTEMPLATESOITDISPLAYSTHEHERODETAILCOMPONENT", "original": "Revise the `AppComponent` template so it displays the `HeroDetailComponent`.", "translation": "修改 `AppComponent` 的模板,以便显示 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### Essential form classes", - "translation": "### 基础的表单类", + "key": "##ESSENTIALFORMCLASSES", + "original": "## Essential form classes", + "translation": "## 基础的表单类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "It may be helpful to read a brief description of the core form classes.", - "translation": "阅读一下这些核心表单类的简短描述也许会有用。", + "key": "THISGUIDEUSESFOURFUNDAMENTALCLASSESTOBUILDAREACTIVEFORM:", + "original": "This guide uses four fundamental classes to build a reactive form:", + "translation": "本文使用四个基础类来构建响应式表单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "* [_AbstractControl_](api/forms/AbstractControl \"API Reference: AbstractControl\")\nis the abstract base class for the three concrete form control classes:\n`FormControl`, `FormGroup`, and `FormArray`.\nIt provides their common behaviors and properties, some of which are _observable_.", - "translation": "[`AbstractControl`](api/forms/AbstractControl \"API Reference: AbstractControl\")是三个具体表单类的抽象基类。\n 并为它们提供了一些共同的行为和属性,其中有些是*可观察对象(Observable)*。", + "key": "CLASS", + "original": "Class", + "translation": "CSS 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "* [_FormControl_](api/forms/FormControl \"API Reference: FormControl\")\ntracks the value and validity status of an _individual_ form control.\nIt corresponds to an HTML form control such as an input box or selector.", - "translation": "[_FormControl_](api/forms/FormControl \"API Reference: FormControl\")\n 用于跟踪一个*单独的*表单控件的值和有效性状态。它对应于一个 HTML 表单控件,比如输入框和下拉框。", + "key": "DESCRIPTION", + "original": "Description", + "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "* [_FormGroup_](api/forms/FormGroup \"API Reference: FormGroup\")\ntracks the value and validity state of a _group_ of `AbstractControl` instances.\nThe group's properties include its child controls.\nThe top-level form in your component is a `FormGroup`.", - "translation": "[_FormGroup_](api/forms/FormGroup \"API Reference: FormGroup\")用于\n 跟踪*一组*`AbstractControl` 的实例的值和有效性状态。\n 该组的属性中包含了它的子控件。\n 组件中的顶级表单就是一个 `FormGroup`。", + "key": "ABSTRACTCONTROLAPIFORMSABSTRACTCONTROLAPIREFERENCE:FORMCONTROLISTHEABSTRACTBASECLASSFORTHETHREECONCRETEFORMCONTROLCLASSESFORMCONTROLFORMGROUPANDFORMARRAYITPROVIDESTHEIRCOMMONBEHAVIORSANDPROPERTIES", + "original": "[`AbstractControl`](api/forms/AbstractControl \"API Reference: FormControl\") is the abstract base class for the three concrete form control classes;\n`FormControl`, `FormGroup`, and `FormArray`.\nIt provides their common behaviors and properties.", + "translation": "[`AbstractControl`](api/forms/AbstractControl \"API Reference: FormControl\")是这三个具体表单类的抽象基类。\n 并为它们提供了一些共同的行为和属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "* [_FormArray_](api/forms/FormArray \"API Reference: FormArray\")\ntracks the value and validity state of a numerically indexed _array_ of `AbstractControl` instances.", - "translation": "[_FormArray_](api/forms/FormArray \"API Reference: FormArray\")用于跟踪 `AbstractControl` 实例组成的有序数组的值和有效性状态。", + "key": "FORMCONTROLAPIFORMSFORMCONTROLAPIREFERENCE:FORMCONTROLTRACKSTHEVALUEANDVALIDITYSTATUSOFANINDIVIDUALFORMCONTROLITCORRESPONDSTOANHTMLFORMCONTROLSUCHASANINPUTORSELECT", + "original": "[`FormControl`](api/forms/FormControl \"API Reference: FormControl\")\ntracks the value and validity status of an individual form control.\nIt corresponds to an HTML form control such as an `<input>` or `<select>`.", + "translation": "[_FormControl_](api/forms/FormControl \"API Reference: FormControl\")\n 用于跟踪一个*单独的*表单控件的值和有效性状态。它对应于一个 HTML 表单控件,比如 `<input>` 或 `<select>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You'll learn more about these classes as you work through this guide.", - "translation": "随着本章的深入,你将学到关于这些类的更多知识。", + "key": "FORMGROUPAPIFORMSFORMGROUPAPIREFERENCE:FORMGROUPTRACKSTHEVALUEANDVALIDITYSTATEOFAGROUPOFABSTRACTCONTROLINSTANCESTHEGROUPSPROPERTIESINCLUDEITSCHILDCONTROLSTHETOPLEVELFORMINYOURCOMPONENTISAFORMGROUP", + "original": "[`FormGroup`](api/forms/FormGroup \"API Reference: FormGroup\")\ntracks the value and validity state of a group of `AbstractControl` instances.\nThe group's properties include its child controls.\nThe top-level form in your component is a `FormGroup`.", + "translation": "[`FormGroup`](api/forms/FormGroup \"API Reference: FormGroup\")用于\n 跟踪*一组*`AbstractControl` 的实例的值和有效性状态。\n 该组的属性中包含了它的子控件。\n 组件中的顶级表单就是一个 `FormGroup`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### Style the app", - "translation": "### 为应用添加样式", + "key": "FORMARRAYAPIFORMSFORMARRAYAPIREFERENCE:FORMARRAYTRACKSTHEVALUEANDVALIDITYSTATEOFANUMERICALLYINDEXEDARRAYOFABSTRACTCONTROLINSTANCES", + "original": "[`FormArray`](api/forms/FormArray \"API Reference: FormArray\")\ntracks the value and validity state of a numerically indexed array of `AbstractControl` instances.", + "translation": "[`FormArray`](api/forms/FormArray \"API Reference: FormArray\")用于跟踪 `AbstractControl` 实例组成的有序数组的值和有效性状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You used bootstrap CSS classes in the template HTML of both the `AppComponent` and the `HeroDetailComponent`.\nAdd the `bootstrap` _CSS stylesheet_ to the head of `styles.css`:", - "translation": "你在 `AppComponent` 和 `HeroDetailComponent` 的模板中使用 Bootstrap 中的 CSS 类。请把 `bootstrap` 的*CSS 样式表文件*添加到 `index.html` 的 `head` 区。", + "key": "##STYLETHEAPP", + "original": "## Style the app", + "translation": "## 为应用添加样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Now that everything is wired up, the browser should display something like this:", - "translation": "这些做好之后,浏览器中应该显示成这样:", + "key": "TOUSETHEBOOTSTRAPCSSCLASSESTHATAREINTHETEMPLATEHTMLOFBOTHTHEAPPCOMPONENTANDTHEHERODETAILCOMPONENTADDTHEBOOTSTRAPCSSSTYLESHEETTOTHEHEADOFSTYLESCSS:", + "original": "To use the bootstrap CSS classes that are in the template HTML of both the `AppComponent` and the `HeroDetailComponent`,\nadd the `bootstrap` CSS stylesheet to the head of `styles.css`:", + "translation": "要在 `AppComponent` 和 `HeroDetailComponent` 的模板中使用 Bootstrap 中的 CSS 类。请把 `bootstrap` 的*CSS 样式表文件*添加到 `style.css` 的头部:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "NOWTHATEVERYTHINGISWIREDUPSERVETHEAPPWITH:", + "original": "Now that everything is wired up, serve the app with:", + "translation": "这些做好之后,启动应用服务器:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "THEBROWSERSHOULDDISPLAYSOMETHINGLIKETHIS:", + "original": "The browser should display something like this:", + "translation": "浏览器应该显示成这样:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "##ADDAFORMGROUP", "original": "## Add a FormGroup", "translation": "## 添加 FormGroup", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Usually, if you have multiple *FormControls*, you'll want to register\nthem within a parent `FormGroup`.\nThis is simple to do. To add a `FormGroup`, add it to the imports section\nof `hero-detail.component.ts`:", - "translation": "通常,如果有多个 *FormControl*,你会希望把它们注册进一个父 `FormGroup` 中。这很容易。只要把它加入 `hero-detail.component.ts` 的 `import` 区就可以了。", + "key": "USUALLYIFYOUHAVEMULTIPLEFORMCONTROLSYOUREGISTERTHEMWITHINAPARENTFORMGROUPTOADDAFORMGROUPADDITTOTHEIMPORTSSECTIONOFHERODETAILCOMPONENTTS:", + "original": "Usually, if you have multiple `FormControls`, you register\nthem within a parent `FormGroup`.\nTo add a `FormGroup`, add it to the imports section\nof `hero-detail.component.ts`:", + "translation": "通常,如果有多个 `FormControl`,你要把它们都注册进一个父 `FormGroup` 中。\n只要把它添加到 `hero-detail.component.ts` 的 `imports` 区就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "INTHECLASSWRAPTHEFORMCONTROLINAFORMGROUPCALLEDHEROFORMASFOLLOWS:", "original": "In the class, wrap the `FormControl` in a `FormGroup` called `heroForm` as follows:", "translation": "在这个类中,把 `FormControl` 包裹进了一个名叫 `heroForm` 的 `FormGroup` 中,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "NOWTHATYOUVEMADECHANGESINTHECLASSTHEYNEEDTOBEREFLECTEDINTHETEMPLATEUPDATEHERODETAILCOMPONENTHTMLBYREPLACINGITWITHTHEFOLLOWING", "original": "Now that you've made changes in the class, they need to be reflected in the\ntemplate. Update `hero-detail.component.html` by replacing it with the following.", "translation": "现在你改完了这个类,该把它映射到模板中了。把 `hero-detail.component.html` 改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Notice that now the single input is in a `form` element. The `novalidate`\nattribute in the `<form>` element prevents the browser\nfrom attempting native HTML validations.", - "translation": "注意,现在单行输入框位于一个 `form` 元素中。`<form>` 元素上的 `novalidate` 属性会阻止浏览器使用原生 HTML 中的表单验证器。", + "key": "NOTICETHATNOWTHESINGLEINPUTISINAFORMELEMENT", + "original": "Notice that now the single `<input>` is in a `<form>` element.", + "translation": "注意,现在单行输入框位于一个 `form` 元素中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "`formGroup` is a reactive form directive that takes an existing\n`FormGroup` instance and associates it with an HTML element.\nIn this case, it associates the `FormGroup` you saved as\n`heroForm` with the form element.", - "translation": "`formGroup` 是一个响应式表单的指令,它拿到一个现有 `FormGroup` 实例,并把它关联到一个 HTML 元素上。\n这种情况下,它关联到的是 `form` 元素上的 `FormGroup` 实例 `heroForm`。", + "key": "FORMGROUPISAREACTIVEFORMDIRECTIVETHATTAKESANEXISTINGFORMGROUPINSTANCEANDASSOCIATESITWITHANHTMLELEMENTINTHISCASEITASSOCIATESTHEFORMGROUPYOUSAVEDASHEROFORMWITHTHEFORMELEMENT", + "original": "`formGroup` is a reactive form directive that takes an existing\n`FormGroup` instance and associates it with an HTML element.\nIn this case, it associates the `FormGroup` you saved as\n`heroForm` with the `<form>` element.", + "translation": "`formGroup` 是一个响应式表单的指令,它拿到一个现有 `FormGroup` 实例,并把它关联到一个 HTML 元素上。\n这种情况下,它关联到的是 `<form>` 元素上的 `FormGroup` 实例 `heroForm`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Because the class now has a `FormGroup`, you must update the template\nsyntax for associating the input with the corresponding\n`FormControl` in the component class.\nWithout a parent `FormGroup`,\n`[formControl]=\"name\"` worked earlier because that directive\ncan stand alone, that is, it works without being in a `FormGroup`.\nWith a parent `FormGroup`, the `name` input needs the syntax\n`formControlName=name` in order to be associated\nwith the correct `FormControl`\nin the class. This syntax tells Angular to look for the parent\n`FormGroup`, in this case `heroForm`, and then _inside_ that group\nto look for a `FormControl` called `name`.", - "translation": "由于现在有了一个 `FormGroup`,因此你必须修改模板语法来把输入框关联到组件类中对应的 `FormControl` 上。\n以前没有父 `FormGroup` 的时候,`[formControl]=\"name\"` 也能正常工作,因为该指令可以独立工作,也就是说,不在 `FormGroup` 中时它也能用。\n有了 `FormGroup`,`name` 输入框就需要再添加一个语法 `formControlName=name`,以便让它关联到类中正确的 `FormControl` 上。\n这个语法告诉 Angular,查阅父 `FormGroup`(这里是 `heroForm`),然后在这个 `FormGroup` 中查阅一个名叫 `name` 的 `FormControl`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "Disregard the `form-group` _CSS_ class. It belongs to the\n<a href=\"http://getbootstrap.com/\" title=\"Bootstrap CSS\">Bootstrap CSS library</a>,\nnot Angular.\nLike the `form-control` class, it _styles_ the form\nbut in no way impacts its logic.", - "translation": "请无视 *CSS* 类 `form-group`,它属于<a href=\"http://getbootstrap.com/\" target=\"_blank\" title=\"Bootstrap CSS\">Bootstrap CSS library</a>而不是 Angular。\n就像 `form-control` 类一样,它只是为表单添加样式,而对表单逻辑毫无影响。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "The form looks great. But does it work?\nWhen the user enters a name, where does the value go?", - "translation": "表单看起来很棒,但是它能用吗?\n当用户输入名字时,它的值去了哪里?", + "key": "BECAUSETHECLASSNOWHASAFORMGROUPYOUMUSTUPDATETHETEMPLATESYNTAXFORASSOCIATINGTHEINPUTWITHTHECORRESPONDINGFORMCONTROLINTHECOMPONENTCLASSWITHOUTAPARENTFORMGROUPFORMCONTROLNAMEWORKEDEARLIERBECAUSETHATDIRECTIVECANSTANDALONETHATISITWORKSWITHOUTBEINGINAFORMGROUPWITHAPARENTFORMGROUPTHENAMEINPUTNEEDSTHESYNTAXFORMCONTROLNAMENAMEINORDERTOBEASSOCIATEDWITHTHECORRECTFORMCONTROLINTHECLASSTHISSYNTAXTELLSANGULARTOLOOKFORTHEPARENTFORMGROUPINTHISCASEHEROFORMANDTHENINSIDETHATGROUPTOLOOKFORAFORMCONTROLCALLEDNAME", + "original": "Because the class now has a `FormGroup`, you must update the template\nsyntax for associating the `<input>` with the corresponding\n`FormControl` in the component class.\nWithout a parent `FormGroup`,\n`[formControl]=\"name\"` worked earlier because that directive\ncan stand alone, that is, it works without being in a `FormGroup`.\nWith a parent `FormGroup`, the `name` `<input>` needs the syntax\n`formControlName=name` in order to be associated\nwith the correct `FormControl`\nin the class. This syntax tells Angular to look for the parent\n`FormGroup`, in this case `heroForm`, and then _inside_ that group\nto look for a `FormControl` called `name`.", + "translation": "由于现在有了一个 `FormGroup`,因此你必须修改模板语法来把这个 `<input>` 关联到组件类中对应的 `FormControl` 上。\n以前没有父 `FormGroup` 的时候,`[formControl]=\"name\"` 也能正常工作,因为该指令可以独立工作,也就是说,不在 `FormGroup` 中时它也能用。\n有了 `FormGroup`,`name` 这个 `<input>` 就需要再添加一个语法 `formControlName=name`,以便让它关联到类中正确的 `FormControl` 上。\n这个语法告诉 Angular,查阅父 `FormGroup`(这里是 `heroForm`),然后在这个 `FormGroup` 中查阅一个名叫 `name` 的 `FormControl`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "##TAKINGALOOKATTHEFORMMODEL", "original": "## Taking a look at the form model", "translation": "## 表单模型概览", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The value goes into the **_form model_** that backs the group's `FormControls`.\nTo see the form model, add the following line after the\nclosing `form` tag in the `hero-detail.component.html`:", - "translation": "这个值进入了幕后**表单模型**中的 `FormControl` 构成的表单组。\n要想知道表单模型是什么样的,请在 `hero-detail.component.html` 的 `form` 标签紧后面添加如下代码:", + "key": "WHENTHEUSERENTERSDATAINTOANINPUTTHEVALUEGOESINTOTHEFORMMODELTOSEETHEFORMMODELADDTHEFOLLOWINGLINEAFTERTHECLOSINGFORMTAGINTHEHERODETAILCOMPONENTHTML:", + "original": "When the user enters data into an `<input>`, the value\ngoes into the **_form model_**.\nTo see the form model, add the following line after the\nclosing `<form>` tag in the `hero-detail.component.html`:", + "translation": "当用户在 `<input>` 中输入数据时,它的值就会进入这个**表单模型**。\n要想知道表单模型是什么样的,请在 `hero-detail.component.html` 的 `<form>` 标签紧后面添加如下代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEHEROFORMVALUERETURNSTHEFORMMODELPIPINGITTHROUGHTHEJSONPIPERENDERSTHEMODELASJSONINTHEBROWSER:", "original": "The `heroForm.value` returns the _form model_.\nPiping it through the `JsonPipe` renders the model as JSON in the browser:", "translation": "`heroForm.value` 会返回表单模型。\n用 `JsonPipe` 管道把这个模型以 JSON 格式渲染到浏览器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The initial `name` property value is the empty string.\nType into the _name_ input box and watch the keystokes appear in the JSON.", - "translation": "最初的 `name` 属性是个空字符串,在 *name* 输入框中输入之后,可以看到这些按键出现在了 JSON 中。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "Great! You have the basics of a form.", - "translation": "真棒!你有了一个基本版表单。", + "key": "THEINITIALNAMEPROPERTYVALUEISTHEEMPTYSTRINGTYPEINTOTHENAMEINPUTANDWATCHTHEKEYSTROKESAPPEARINTHEJSON", + "original": "The initial `name` property value is the empty string.\nType into the name `<input>` and watch the keystrokes appear in the JSON.", + "translation": "最初的 `name` 属性是个空字符串,在 *name* `<input>` 中输入之后,可以看到这些按键出现在了 JSON 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "INREALLIFEAPPSFORMSGETBIGFASTFORMBUILDERMAKESFORMDEVELOPMENTANDMAINTENANCEEASIER", "original": "In real life apps, forms get big fast.\n`FormBuilder` makes form development and maintenance easier.", "translation": "在真实的应用中,表单很快就会变大。\n`FormBuilder` 能让表单开发和维护变得更简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "## Introduction to _FormBuilder_", + "key": "##INTRODUCTIONTOFORMBUILDER", + "original": "## Introduction to `FormBuilder`", "translation": "## `FormBuilder` 简介", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEFORMBUILDERCLASSHELPSREDUCEREPETITIONANDCLUTTERBYHANDLINGDETAILSOFCONTROLCREATIONFORYOU", "original": "The `FormBuilder` class helps reduce repetition and\nclutter by handling details of control creation for you.", "translation": "`FormBuilder` 类能通过处理控件创建的细节问题来帮你减少重复劳动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "To use `FormBuilder`, you need to import it into `hero-detail.component.ts`:", - "translation": "要使用 `FormBuilder`,你就要先把它导入到 `hero-detail.component.ts` 中:", + "key": "TOUSEFORMBUILDERIMPORTITINTOHERODETAILCOMPONENTTSYOUCANREMOVEFORMCONTROL:", + "original": "To use `FormBuilder`, import it into `hero-detail.component.ts`. You can remove `FormControl`:", + "translation": "要使用 `FormBuilder`,就要先把它导入到 `hero-detail.component.ts` 中。你可以删除 `FormControl`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Use it now to refactor the `HeroDetailComponent` into something that's a little easier to read and write,\nby following this plan:", - "translation": "现在,你要遵循下列步骤用 `FormBuilder` 来把 `HeroDetailComponent` 重构得更加容易读写。", + "key": "USEITTOREFACTORTHEHERODETAILCOMPONENTINTOSOMETHINGTHATSEASIERTOREADANDWRITEBYFOLLOWINGTHISPLAN:", + "original": "Use it to refactor the `HeroDetailComponent` into something that's easier to read and write,\nby following this plan:", + "translation": "遵循下列步骤来用 `FormBuilder` 把 `HeroDetailComponent` 重构得更容易读写:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "EXPLICITLYDECLARETHETYPEOFTHEHEROFORMPROPERTYTOBEFORMGROUPYOULLINITIALIZEITLATER", "original": "* Explicitly declare the type of the `heroForm` property to be `FormGroup`; you'll initialize it later.", "translation": "明确把 `heroForm` 属性的类型声明为 `FormGroup`,稍后你会初始化它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "INJECTAFORMBUILDERINTOTHECONSTRUCTOR", "original": "* Inject a `FormBuilder` into the constructor.", "translation": "把 `FormBuilder` 注入到构造函数中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "* Add a new method that uses the `FormBuilder` to define the `heroForm`; call it `createForm`.", - "translation": "添加一个名叫 `createForm` 的新方法,它会用 `FormBuilder` 来定义 `heroForm`。", + "key": "ADDANEWMETHODTHATUSESTHEFORMBUILDERTODEFINETHEHEROFORMCALLITCREATEFORM", + "original": "* Add a new method that uses the `FormBuilder` to define the `heroForm`; call it `createForm()`.", + "translation": "添加一个名叫 `createForm()` 的新方法,它会用 `FormBuilder` 来定义 `heroForm`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "* Call `createForm` in the constructor.", - "translation": "在构造函数中调用 `createForm`。", + "key": "CALLCREATEFORMINTHECONSTRUCTOR", + "original": "* Call `createForm()` in the constructor.", + "translation": "在构造函数中调用 `createForm()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEREVISEDHERODETAILCOMPONENTLOOKSLIKETHIS:", "original": "The revised `HeroDetailComponent` looks like this:", "translation": "修改过的 `HeroDetailComponent` 代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "FORMBUILDERGROUPISAFACTORYMETHODTHATCREATESAFORMGROUPNBSPFORMBUILDERGROUPTAKESANOBJECTWHOSEKEYSANDVALUESAREFORMCONTROLNAMESANDTHEIRDEFINITIONSINTHISEXAMPLETHENAMECONTROLISDEFINEDBYITSINITIALDATAVALUEANEMPTYSTRING", "original": "`FormBuilder.group` is a factory method that creates a `FormGroup`.  \n`FormBuilder.group` takes an object whose keys and values are `FormControl` names and their definitions.\nIn this example, the `name` control is defined by its initial data value, an empty string.", "translation": "`FormBuilder.group` 是一个用来创建 `FormGroup` 的工厂方法,它接受一个对象,对象的键和值分别是 `FormControl` 的名字和它的定义。\n在这个例子中,`name` 控件的初始值是空字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Defining a group of controls in a single object makes for a compact, readable style.\nIt beats writing an equivalent series of `new FormControl(...)` statements.", - "translation": "把一组控件定义在一个单一对象中,可以更加紧凑、易读。\n完成相同功能时,这种形式优于一系列 `new FormControl(...)` 语句。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "### Validators.required", - "translation": "### Validators.required 验证器", + "key": "DEFININGAGROUPOFCONTROLSINASINGLEOBJECTMAKESYOURCODEMORECOMPACTANDREADABLEBECAUSEYOUDONTHAVETOWRITEREPEATEDNEWFORMCONTROLSTATEMENTS", + "original": "Defining a group of controls in a single object makes your code more compact and readable because you don't have to write repeated `new FormControl(...)` statements.", + "translation": "把一组控件定义在一个单一对象中,可以让你的代码更加紧凑、易读。\n因为你不必写一系列重复的 `new FormControl(...)` 语句。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THOUGHTHISGUIDEDOESNTGODEEPLYINTOVALIDATIONSHEREISONEEXAMPLETHATDEMONSTRATESTHESIMPLICITYOFUSINGVALIDATORSREQUIREDINREACTIVEFORMS", "original": "Though this guide doesn't go deeply into validations, here is one example that\ndemonstrates the simplicity of using `Validators.required` in reactive forms.", "translation": "虽然本章不会深入讲解验证机制,但还是有一个例子来示范如何简单的在响应式表单中使用 `Validators.required`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "FIRSTIMPORTTHEVALIDATORSSYMBOL", "original": "First, import the `Validators` symbol.", "translation": "首先,导入 `Validators` 符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "TOMAKETHENAMEFORMCONTROLREQUIREDREPLACETHENAMEPROPERTYINTHEFORMGROUPWITHANARRAYTHEFIRSTITEMISTHEINITIALVALUEFORNAMETHESECONDISTHEREQUIREDVALIDATORVALIDATORSREQUIRED", "original": "To make the `name` `FormControl` required, replace the `name`\nproperty in the `FormGroup` with an array.\nThe first item is the initial value for `name`;\nthe second is the required validator, `Validators.required`.", "translation": "要想让 `name` 这个 `FormControl` 是必须的,请把 `FormGroup` 中的 `name` 属性改为一个数组。第一个条目是 `name` 的初始值,第二个是 `required` 验证器:`Validators.required`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Reactive validators are simple, composable functions.\nConfiguring validation is harder in template-driven forms where you must wrap validators in a directive.", + "key": "REACTIVEVALIDATORSARESIMPLECOMPOSABLEFUNCTIONSCONFIGURINGVALIDATIONISDIFFERENTINTEMPLATEDRIVENFORMSINTHATYOUMUSTWRAPVALIDATORSINADIRECTIVE", + "original": "Reactive validators are simple, composable functions.\nConfiguring validation is different in template-driven forms in that you must wrap validators in a directive.", "translation": "响应式验证器是一些简单、可组合的函数。\n在模板驱动表单中配置验证器有些困难,因为你必须把验证器包装进指令中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "UPDATETHEDIAGNOSTICMESSAGEATTHEBOTTOMOFTHETEMPLATETODISPLAYTHEFORMSVALIDITYSTATUS", "original": "Update the diagnostic message at the bottom of the template to display the form's validity status.", "translation": "修改模板底部的诊断信息,以显示表单的有效性状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEBROWSERDISPLAYSTHEFOLLOWING:", "original": "The browser displays the following:", "translation": "浏览器会显示下列内容:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "`Validators.required` is working. The status is `INVALID` because the input box has no value.\nType into the input box to see the status change from `INVALID` to `VALID`.", + "key": "VALIDATORSREQUIREDISWORKINGTHESTATUSISINVALIDBECAUSETHEINPUTHASNOVALUETYPEINTOTHEINPUTTOSEETHESTATUSCHANGEFROMINVALIDTOVALID", + "original": "`Validators.required` is working. The status is `INVALID` because the `<input>` has no value.\nType into the `<input>` to see the status change from `INVALID` to `VALID`.", "translation": "`Validators.required` 生效了,但状态还是 `INVALID`,因为输入框中还没有值。\n在输入框中输入,就会看到这个状态从 `INVALID` 变成了 `VALID`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "INAREALAPPYOUDREPLACETHEDIAGNOSICMESSAGEWITHAUSERFRIENDLYEXPERIENCE", "original": "In a real app, you'd replace the diagnosic message with a user-friendly experience.", "translation": "在真实的应用中,你要把这些诊断信息替换成用户友好的信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "USINGVALIDATORSREQUIREDISOPTIONALFORTHERESTOFTHEGUIDEITREMAINSINEACHOFTHEFOLLOWINGEXAMPLESWITHTHESAMECONFIGURATION", "original": "Using `Validators.required` is optional for the rest of the guide.\nIt remains in each of the following examples with the same configuration.", "translation": "在本章的其余部分,`Validators.required` 是可有可无的,但在每个与此范例配置相同的范例中都会保留它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "FORMOREONVALIDATINGANGULARFORMSSEETHEFORMVALIDATIONGUIDEFORMVALIDATIONGUIDE", "original": "For more on validating Angular forms, see the\n[Form Validation](guide/form-validation) guide.", "translation": "要了解 Angular 表单验证器的更多知识,参见[表单验证器](guide/form-validation)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### More FormControls", - "translation": "### 更多的表单控件(FormControl)", + "key": "###MOREFORMCONTROLS", + "original": "### More `FormControl`s", + "translation": "### 更多的 `FormControl`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "A hero has more than a name.\nA hero has an address, a super power and sometimes a sidekick too.", - "translation": "每个英雄可以有多个名字,还有一个住址、一项超能力,有时还会有一个副手。", + "key": "THISSECTIONADDSADDITIONALFORMCONTROLSFORTHEADDRESSASUPERPOWERANDASIDEKICK", + "original": "This section adds additional `FormControl`s for the address, a super power, and a sidekick.", + "translation": "本节要添加一些 `FormControl`,用来表示住址、一项超能力,和一个副手。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The address has a state property. The user will select a state with a `<select>` box and you'll populate\nthe `<option>` elements with states. So import `states` from `data-model.ts`.", - "translation": "住址中有一个所在州属性,用户将会从 `<select>` 框中选择一个州,你会用 `<option>` 元素渲染各个州。从 `data-model.ts` 中导入 `states`(州列表)。", + "key": "ADDITIONALLYTHEADDRESSHASASTATEPROPERTYTHEUSERWILLSELECTASTATEWITHASELECTANDYOULLPOPULATETHEOPTIONELEMENTSWITHSTATESSOIMPORTSTATESFROMDATAMODELTS", + "original": "Additionally, the address has a state property. The user will select a state with a `<select>` and you'll populate\nthe `<option>` elements with states. So import `states` from `data-model.ts`.", + "translation": "另外,住址中有一个所在州属性,用户将会从 `<select>` 框中选择一个州,你会用 `<option>` 元素渲染各个州。从 `data-model.ts` 中导入 `states`(州列表)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "DECLARETHESTATESPROPERTYANDADDSOMEADDRESSFORMCONTROLSTOTHEHEROFORMASFOLLOWS", "original": "Declare the `states` property and add some address `FormControls` to the `heroForm` as follows.", "translation": "声明 `states` 属性并往 `heroForm` 中添加一些表示住址的 `FormControl`,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Then add corresponding markup in `hero-detail.component.html`\nwithin the `form` element.", - "translation": "然后在 `hero-detail.component.html` 文件中把对应的脚本添加到 `form` 元素中。", + "key": "THENADDCORRESPONDINGMARKUPINHERODETAILCOMPONENTHTMLASFOLLOWS", + "original": "Then add corresponding markup in `hero-detail.component.html` as follows.", + "translation": "然后把下列代码添加到 `hero-detail.component.html` 文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "*Reminder*: Ignore the many mentions of `form-group`,\n`form-control`, `center-block`, and `checkbox` in this markup.\nThose are _bootstrap_ CSS classes that Angular itself ignores.\nPay attention to the `[formGroup]` and `formControlName` attributes.\nThey are the Angular directives that bind the HTML controls to the\nAngular `FormGroup` and `FormControl` properties in the component class.", + "key": "NOTE:IGNORETHEMANYMENTIONSOFFORMGROUPFORMCONTROLCENTERBLOCKANDCHECKBOXINTHISMARKUPTHOSEAREBOOTSTRAPCSSCLASSESTHATANGULARITSELFIGNORESPAYATTENTIONTOTHEFORMGROUPANDFORMCONTROLNAMEATTRIBUTESTHEYARETHEANGULARDIRECTIVESTHATBINDTHEHTMLCONTROLSTOTHEANGULARFORMGROUPANDFORMCONTROLPROPERTIESINTHECOMPONENTCLASS", + "original": "*Note*: Ignore the many mentions of `form-group`,\n`form-control`, `center-block`, and `checkbox` in this markup.\nThose are _bootstrap_ CSS classes that Angular itself ignores.\nPay attention to the `[formGroup]` and `formControlName` attributes.\nThey are the Angular directives that bind the HTML controls to the\nAngular `FormGroup` and `FormControl` properties in the component class.", "translation": "*注意*:不用管这些脚本中提到的 `form-group`、`form-control`、`center-block` 和 `checkbox` 等。\n它们是来自 *Bootstrap* 的 CSS 类,Angular 本身不会管它们。\n注意 `formGroupName` 和 `formControlName` 属性。\n他们是 Angular 指令,用于把相应的 HTML 控件绑定到组件中的 `FormGroup` 和 `FormControl` 类型的属性上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The revised template includes more text inputs, a select box for the `state`, radio buttons for the `power`,\nand a checkbox for the `sidekick`.", + "key": "THEREVISEDTEMPLATEINCLUDESMORETEXTINPUTELEMENTSASELECTFORTHESTATERADIOBUTTONSFORTHEPOWERANDACHECKBOXFORTHESIDEKICK", + "original": "The revised template includes more text `<input>` elements, a `<select>` for the `state`, radio buttons for the `power`,\nand a `<checkbox>` for the `sidekick`.", "translation": "修改过的模板包含更多文本输入框,一个 `state` 选择框,`power`(超能力)的单选按钮和一个 `sidekick` 检查框。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You must bind the option's value property with `[value]=\"state\"`.\nIf you do not bind the value, the select shows the first option from the data model.", - "translation": "你要用 `[value]=\"state\"` 来绑定选项的 `value` 属性。\n如果不绑定这个值,这个选择框就会显示来自数据模型中的第一个选项。", + "key": "YOUMUSTBINDTHEVALUEPROPERTYOFTHEOPTIONWITHVALUESTATEIFYOUDONOTBINDTHEVALUETHESELECTSHOWSTHEFIRSTOPTIONFROMTHEDATAMODEL", + "original": "You must bind the value property of the `<option>` with `[value]=\"state\"`.\nIf you do not bind the value, the select shows the first option from the data model.", + "translation": "你要用 `[value]=\"state\"` 来绑定 `<option>` 的 `value` 属性。\n如果不绑定这个值,这个选择框就会显示来自数据模型中的第一个选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THECOMPONENTCLASSDEFINESCONTROLPROPERTIESWITHOUTREGARDFORTHEIRREPRESENTATIONINTHETEMPLATEYOUDEFINETHESTATEPOWERANDSIDEKICKCONTROLSTHESAMEWAYYOUDEFINEDTHENAMECONTROLYOUTIETHESECONTROLSTOTHETEMPLATEHTMLELEMENTSINTHESAMEWAYSPECIFYINGTHEFORMCONTROLNAMEWITHTHEFORMCONTROLNAMEDIRECTIVE", "original": "The component _class_ defines control properties without regard for their representation in the template.\nYou define the `state`, `power`, and `sidekick` controls the same way you defined the `name` control.\nYou tie these controls to the template HTML elements in the same way,\nspecifying the `FormControl` name with the `formControlName` directive.", "translation": "组件*类*定义了控件属性而不用管它们在模板中的表现形式。\n你可以像定义 `name` 控件一样定义 `state`、`power` 和 `sidekick` 控件,并用 `formControlName` 指令来指定 `FormControl` 的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "SEETHEAPIREFERENCEFORMOREINFORMATIONABOUTRADIOBUTTONSAPIFORMSRADIOCONTROLVALUEACCESSORAPI:RADIOCONTROLVALUEACCESSORSELECTSAPIFORMSSELECTCONTROLVALUEACCESSORAPI:SELECTCONTROLVALUEACCESSORANDCHECKBOXESAPIFORMSCHECKBOXCONTROLVALUEACCESSORAPI:CHECKBOXCONTROLVALUEACCESSOR", "original": "See the API reference for more information about\n[radio buttons](api/forms/RadioControlValueAccessor \"API: RadioControlValueAccessor\"),\n[selects](api/forms/SelectControlValueAccessor \"API: SelectControlValueAccessor\"), and\n[checkboxes](api/forms/CheckboxControlValueAccessor \"API: CheckboxControlValueAccessor\").", "translation": "参见 API 参考手册中的[radio buttons](api/forms/RadioControlValueAccessor \"API: RadioControlValueAccessor\")、\n [selects](api/forms/SelectControlValueAccessor \"API: SelectControlValueAccessor\")和\n [checkboxes](api/forms/CheckboxControlValueAccessor \"API: CheckboxControlValueAccessor\")", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###NESTEDFORMGROUPS", "original": "### Nested FormGroups", "translation": "### 多级 `FormGroup`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "This form is getting big and unwieldy. You can group some of the related `FormControls`\ninto a nested `FormGroup`. The `street`, `city`, `state`, and `zip` are properties\nthat would make a good _address_ `FormGroup`.\nNesting groups and controls in this way allows you to\nmirror the hierarchical structure of the data model\nand helps track validation and state for related sets of controls.", - "translation": "这个表单变得越来越大、越来越笨重。\n你可以把一些相关的 `FormControl` 组织到多级 `FormGroup` 中。\n`street`、`city`、`state` 和 `zip` 属性就可以作为一个名叫 `address` 的 `FormGroup`。\n用这种方式,多级表单组和控件可以让你轻松地映射多层结构的数据模型,以帮你跟踪这组相关控件的有效性和状态。", + "key": "TOMANAGETHESIZEOFTHEFORMMOREEFFECTIVELYYOUCANGROUPSOMEOFTHERELATEDFORMCONTROLSINTOANESTEDFORMGROUPFOREXAMPLETHESTREETCITYSTATEANDZIPAREIDEALPROPERTIESFORANADDRESSFORMGROUPNESTINGGROUPSANDCONTROLSINTHISWAYALLOWSYOUTOMIRRORTHEHIERARCHICALSTRUCTUREOFTHEDATAMODELANDHELPSTRACKVALIDATIONANDSTATEFORRELATEDSETSOFCONTROLS", + "original": "To manage the size of the form more effectively, you can group some of the related `FormControls`\ninto a nested `FormGroup`. For example, the `street`, `city`, `state`, and `zip` are ideal properties for an address `FormGroup`.\nNesting groups and controls in this way allows you to\nmirror the hierarchical structure of the data model\nand helps track validation and state for related sets of controls.", + "translation": "要想更有效的管理这个表单的大小,你可以把一些相关的 `FormControl` 组织到多级 `FormGroup` 中。\n比如,`street`、`city`、`state` 和 `zip` 就可以作为一个名叫 `address` 的 `FormGroup` 中的理想属性。\n用这种方式,多级表单组和控件可以让你轻松地映射多层结构的数据模型,以帮你跟踪这组相关控件的有效性和状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You used the `FormBuilder` to create one `FormGroup` in this component called `heroForm`.\nLet that be the parent `FormGroup`.\nUse `FormBuilder` again to create a child `FormGroup` that encapsulates the address controls;\nassign the result to a new `address` property of the parent `FormGroup`.", + "key": "YOUUSEDTHEFORMBUILDERTOCREATEONEFORMGROUPINTHISCOMPONENTCALLEDHEROFORMLETTHATBETHEPARENTFORMGROUPUSEFORMBUILDERAGAINTOCREATEACHILDFORMGROUPTHATENCAPSULATESTHEADDRESSCONTROLSASSIGNTHERESULTTOANEWADDRESSPROPERTYOFTHEPARENTFORMGROUP", + "original": "You used the `FormBuilder` to create one `FormGroup` in this component called `heroForm`.\nLet that be the parent `FormGroup`.\nUse `FormBuilder` again to create a child `FormGroup` that encapsulates the `address` controls;\nassign the result to a new `address` property of the parent `FormGroup`.", "translation": "你用 `FormBuilder` 在这个名叫 `heroForm` 的组件中创建一个 `FormGroup`,并把它用作父 `FormGroup`。\n再次使用 `FormBuilder` 创建一个子级 `FormGroup`,其中包括这些住址控件。把结果赋值给父 `FormGroup` 中新的 `address` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You’ve changed the structure of the form controls in the component class;\nyou must make corresponding adjustments to the component template.", - "translation": "你已经修改了组件类中表单控件的结构,还必须对组件模板进行相应的调整。", + "key": "WHENYOUCHANGETHESTRUCTUREOFTHEFORMCONTROLSINTHECOMPONENTCLASSYOUMUSTMAKECORRESPONDINGADJUSTMENTSTOTHECOMPONENTTEMPLATE", + "original": "When you change the structure of the form controls in the component class,\nyou must make corresponding adjustments to the component template.", + "translation": "当你修改组件类中表单控件的结构时,还必须对组件模板进行相应的调整。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "In `hero-detail.component.html`, wrap the address-related `FormControls` in a `div`.\nAdd a `formGroupName` directive to the `div` and bind it to `\"address\"`.\nThat's the property of the _address_ child `FormGroup` within the parent `FormGroup` called `heroForm`.", - "translation": "在 `hero-detail.component.html` 中,把与住址有关的 `FormControl` 包裹进一个 `div` 中。\n往这个 `div` 上添加一个 `formGroupName` 指令,并且把它绑定到 `\"address\"` 上。\n这个 `address` 属性是一个 `FormGroup`,它的父 `FormGroup` 就是 `heroForm`。", + "key": "INHERODETAILCOMPONENTHTMLWRAPTHEADDRESSRELATEDFORMCONTROLSINADIVADDAFORMGROUPNAMEDIRECTIVETOTHEDIVANDBINDITTOADDRESSTHATSTHEPROPERTYOFTHEADDRESSCHILDFORMGROUPWITHINTHEPARENTFORMGROUPCALLEDHEROFORMLEAVETHEDIVWITHTHENAMEINPUT", + "original": "In `hero-detail.component.html`, wrap the address-related `FormControls` in a `<div>`.\nAdd a `formGroupName` directive to the `div` and bind it to `\"address\"`.\nThat's the property of the `address` child `FormGroup` within the parent `FormGroup` called `heroForm`. Leave the `<div>` with the `name` `<input>`.", + "translation": "在 `hero-detail.component.html` 中,把与住址有关的 `FormControl` 包裹进一个 `div` 中。\n往这个 `<div>` 上添加一个 `formGroupName` 指令,并且把它绑定到 `\"address\"` 上。\n这个 `address` 属性是一个 `FormGroup`,它的父 `FormGroup` 就是 `heroForm`。\n把这个 `name` `<input>` 留在此 `<div>` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "To make this change visually obvious, slip in an `<h4>` header near the top with the text, _Secret Lair_.\nThe new _address_ HTML looks like this:", - "translation": "要让这个变化更加明显,在文本的顶部加入一个 `<h4>` 头:*Secret Lair*。\n新的*住址*组的 HTML 如下:", + "key": "TOMAKETHISCHANGEVISUALLYOBVIOUSADDANH4HEADERNEARTHETOPWITHTHETEXTSECRETLAIRTHENEWADDRESSHTMLLOOKSLIKETHIS:", + "original": "To make this change visually obvious, add an `<h4>` header near the top with the text, _Secret Lair_.\nThe new address HTML looks like this:", + "translation": "要让这个变化更加明显,在文本的顶部加入一个 `<h4>` 头:*Secret Lair*。\n新的住址组的 HTML 如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "After these changes, the JSON output in the browser shows the revised _form model_\nwith the nested address `FormGroup`:", - "translation": "做完这些之后,浏览器中的 JSON 输出就变成了带有多级 `FormGroup` 的住址。", + "key": "AFTERTHESECHANGESTHEJSONOUTPUTINTHEBROWSERSHOWSTHEREVISEDFORMMODELWITHTHENESTEDADDRESSFORMGROUP:", + "original": "After these changes, the JSON output in the browser shows the revised form model\nwith the nested address `FormGroup`:", + "translation": "做完这些之后,浏览器中的 JSON 输出就变成了带有多级 `FormGroup` 的表单模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Great! You’ve made a group and you can see that the template\nand the form model are talking to one another.", - "translation": "真棒!你制作了一个控件组,并且可以看到模板和表单模型已经能彼此通讯了。", + "key": "THISSHOWSTHATTHETEMPLATEANDTHEFORMMODELARETALKINGTOONEANOTHER", + "original": "This shows that the template\nand the form model are talking to one another.", + "translation": "这时模板和表单模型在彼此通讯了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "## Inspect _FormControl_ Properties", + "key": "##INSPECTFORMCONTROLPROPERTIES", + "original": "## Inspect `FormControl` Properties", "translation": "## 查看 `FormControl` 的属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "At the moment, you're dumping the entire form model onto the page.\nSometimes you're interested only in the state of one particular `FormControl`.", - "translation": "此刻,你把整个表单模型展示在了页面里。\n但有时你可能只关心一个特定 `FormControl` 的状态。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "You can inspect an individual `FormControl` within a form by extracting it with the `.get()` method.\nYou can do this _within_ the component class or display it on the\npage by adding the following to the template,\nimmediately after the `{{form.value | json}}` interpolation as follows:", + "key": "YOUCANINSPECTANINDIVIDUALFORMCONTROLWITHINAFORMBYEXTRACTINGITWITHTHEGETMETHODYOUCANDOTHISWITHINTHECOMPONENTCLASSORDISPLAYITONTHEPAGEBYADDINGTHEFOLLOWINGTOTHETEMPLATEIMMEDIATELYAFTERTHEFORMVALUEJSONINTERPOLATIONASFOLLOWS:", + "original": "You can inspect an individual `FormControl` within a form by extracting it with the `get()` method.\nYou can do this within the component class or display it on the\npage by adding the following to the template,\nimmediately after the `{{form.value | json}}` interpolation as follows:", "translation": "你可以使用 `.get()` 方法来提取表单中一个单独 `FormControl` 的状态。\n你可以在组件类中这么做,或者通过往模板中添加下列代码来把它显示在页面中,就添加在 `{{form.value | json}}` 插值表达式的紧后面:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "To get the state of a `FormControl` that’s inside a `FormGroup`, use dot notation to path to the control.", + "key": "TOGETTHESTATEOFAFORMCONTROLTHATSINSIDEAFORMGROUPUSEDOTNOTATIONTOTRAVERSETOTHECONTROL", + "original": "To get the state of a `FormControl` that’s inside a `FormGroup`, use dot notation to traverse to the control.", "translation": "要点取得 `FormGroup` 中的 `FormControl` 的状态,使用点语法来指定到控件的路径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You can use this technique to display _any_ property of a `FormControl`\nsuch as one of the following:", - "translation": "你可以使用此技术来显示 `FromControl` 的*任意*属性,代码如下:", + "key": "NOTE:IFYOURECODINGALONGREMEMBERTOREMOVETHISREFERENCETOADDRESSSTREETWHENYOUGETTOTHESECTIONONFORMARRAYINTHATSECTIONYOUCHANGETHENAMEOFADDRESSINTHECOMPONENTCLASSANDITWILLTHROWANERRORIFYOULEAVEITINTHETEMPLATE", + "original": "*Note*: If you're coding along, remember to remove this reference to `address.street` when you get to the section on `FormArray`. In that section, you change the name of address in the component class and it will throw an error if you leave it in the template.", + "translation": "*注意*:如果你正在边看边跟着写代码,当你到达 `FormArray` 那节时,别忘了移除到 `address.street` 的引用。那一节中,你要在组件类中修改这个地址的名字,如果你把它留在模板中,就会抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "YOUCANUSETHISTECHNIQUETODISPLAYANYPROPERTYOFAFORMCONTROLSUCHASONEOFTHEFOLLOWING:", + "original": "You can use this technique to display any property of a `FormControl`\nsuch as one of the following:", + "translation": "你可以使用此技术来显示 `FromControl` 的任意属性,代码如下:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "PROPERTY", "original": "Property", "translation": "属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEVALUEOFAFORMCONTROL", "original": "the value of a `FormControl`.", "translation": "`FormControl` 的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEVALIDITYOFAFORMCONTROLPOSSIBLEVALUES:VALIDINVALIDPENDINGORDISABLED", "original": "the validity of a `FormControl`. Possible values: `VALID`,\n `INVALID`, `PENDING`, or `DISABLED`.", "translation": "`FormControl` 的有效性。可能的值有 `VALID`、`INVALID`、`PENDING` 或 `DISABLED`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "TRUEIFTHEUSERHASNOTCHANGEDTHEVALUEINTHEUIITSOPPOSITEISMYCONTROLDIRTY", "original": "`true` if the user has _not_ changed the value in the UI.\n Its opposite is `myControl.dirty`.", "translation": "如果用户*尚未*改变过这个控件的值,则为 `true`。它总是与 `myControl.dirty` 相反。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "TRUEIFTHECONTROLUSERHASNOTYETENTEREDTHEHTMLCONTROLANDTRIGGEREDITSBLUREVENTITSOPPOSITEISMYCONTROLTOUCHED", "original": "`true` if the control user has not yet entered the HTML control\n and triggered its blur event. Its opposite is `myControl.touched`.", "translation": "如果用户尚未进入这个 HTML 控件,也没有触发过它的 `blur`(失去焦点)事件,则为 `true`。\n 它是 `myControl.touched` 的反义词。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Learn about other `FormControl` properties in the\n[_AbstractControl_](api/forms/AbstractControl) API reference.", + "key": "READABOUTOTHERFORMCONTROLPROPERTIESINTHEABSTRACTCONTROLAPIFORMSABSTRACTCONTROLAPIREFERENCE", + "original": "Read about other `FormControl` properties in the\n[_AbstractControl_](api/forms/AbstractControl) API reference.", "translation": "要了解 `FormControl` 的更多属性,参见 API 参考手册的[_AbstractControl_](api/forms/AbstractControl)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "ONECOMMONREASONFORINSPECTINGFORMCONTROLPROPERTIESISTOMAKESURETHEUSERENTEREDVALIDVALUESREADMOREABOUTVALIDATINGANGULARFORMSINTHEFORMVALIDATIONGUIDEFORMVALIDATIONGUIDE", "original": "One common reason for inspecting `FormControl` properties is to\nmake sure the user entered valid values.\nRead more about validating Angular forms in the\n[Form Validation](guide/form-validation) guide.", "translation": "检查 `FormControl` 属性的另一个原因是确保用户输入了有效的值。\n要了解更多关于 Angular 表单验证的知识,参见[表单验证](guide/form-validation)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "## The _data model_ and the _form model_", - "translation": "## *数据模型*与*表单模型*", + "key": "##THEDATAMODELANDTHEFORMMODEL", + "original": "## The data model and the form model", + "translation": "## 数据模型与表单模型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "ATTHEMOMENTTHEFORMISDISPLAYINGEMPTYVALUESTHEHERODETAILCOMPONENTSHOULDDISPLAYVALUESOFAHEROPOSSIBLYAHERORETRIEVEDFROMAREMOTESERVER", "original": "At the moment, the form is displaying empty values.\nThe `HeroDetailComponent` should display values of a hero,\npossibly a hero retrieved from a remote server.", "translation": "此刻,表单显示的是空值。\n`HeroDetailComponent` 应该显示一个英雄的值,这个值可能接收自远端服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "In this app, the `HeroDetailComponent` gets its hero from a parent `HeroListComponent`", + "key": "INTHISAPPTHEHERODETAILCOMPONENTGETSITSHEROFROMAPARENTHEROLISTCOMPONENT", + "original": "In this app, the `HeroDetailComponent` gets its hero from a parent `HeroListComponent`.", "translation": "在这个应用中,`HeroDetailComponent` 从它的父组件 `HeroListComponent` 中取得一个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEHEROFROMTHESERVERISTHEDATAMODELTHEFORMCONTROLSTRUCTUREISTHEFORMMODEL", "original": "The `hero` from the server is the **_data model_**.\nThe `FormControl` structure is the **_form model_**.", "translation": "来自服务器的 `hero` 就是**数据模型**,而 `FormControl` 的结构就是**表单模型**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The component must copy the hero values in the _data model_ into the _form model_.\nThere are two important implications:", - "translation": "组件必须把*数据模型*中的英雄值复制到*表单模型*中。这里隐含着两个非常重要的点。", + "key": "THECOMPONENTMUSTCOPYTHEHEROVALUESINTHEDATAMODELINTOTHEFORMMODELTHEREARETWOIMPORTANTIMPLICATIONS:", + "original": "The component must copy the hero values in the data model into the form model.\nThere are two important implications:", + "translation": "组件必须把数据模型中的英雄值复制到表单模型中。这里隐含着两个非常重要的点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "1. The developer must understand how the properties of the _data model_\nmap to the properties of the _form model_.", - "translation": "开发人员必须理解*数据模型*是如何映射到*表单模型*中的属性的。", + "key": "1THEDEVELOPERMUSTUNDERSTANDHOWTHEPROPERTIESOFTHEDATAMODELMAPTOTHEPROPERTIESOFTHEFORMMODEL", + "original": "1. The developer must understand how the properties of the data model\nmap to the properties of the form model.", + "translation": "开发人员必须理解数据模型是如何映射到表单模型中的属性的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "2. User changes flow from the DOM elements to the _form model_, not to the _data model_.\nThe form controls never update the _data model_.", - "translation": "用户修改时的数据流是从 DOM 元素流向*表单模型*的,而不是*数据模型*。表单控件永远不会修改*数据模型*。", + "key": "2USERCHANGESFLOWFROMTHEDOMELEMENTSTOTHEFORMMODELNOTTOTHEDATAMODEL", + "original": "2. User changes flow from the DOM elements to the form model, not to the data model.", + "translation": "用户修改时的数据流是从 DOM 元素流向表单模型的,而不是数据模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The _form_ and _data_ model structures need not match exactly.\nYou often present a subset of the _data model_ on a particular screen.\nBut it makes things easier if the shape of the _form model_ is close to the shape of the _data model_.", - "translation": "*表单模型*和*数据模型*的结构并不需要精确匹配。在一个特定的屏幕上,你通常只会展现*数据模型*的一个子集。\n但是*表单模型*的形态越接近*数据模型*,事情就会越简单。", + "key": "THEFORMCONTROLSNEVERUPDATETHEDATAMODEL", + "original": "The form controls never update the _data model_.", + "translation": "表单控件永远不会修改*数据模型*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEFORMANDDATAMODELSTRUCTURESDONTNEEDTOMATCHEXACTLYYOUOFTENPRESENTASUBSETOFTHEDATAMODELONAPARTICULARSCREENBUTITMAKESTHINGSEASIERIFTHESHAPEOFTHEFORMMODELISCLOSETOTHESHAPEOFTHEDATAMODEL", + "original": "The form and data model structures don't need to match exactly.\nYou often present a subset of the data model on a particular screen.\nBut it makes things easier if the shape of the form model is close to the shape of the data model.", + "translation": "表单模型和数据模型的结构并不需要精确匹配。在一个特定的屏幕上,你通常只会展现数据模型的一个子集。\n但是表单模型的形态越接近数据模型,事情就会越简单。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "INTHISHERODETAILCOMPONENTTHETWOMODELSAREQUITECLOSE", "original": "In this `HeroDetailComponent`, the two models are quite close.", "translation": "在 `HeroDetailComponent` 中,这两个模型是非常接近的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Recall the definition of `Hero` in `data-model.ts`:", - "translation": "回忆一下 `data-model.ts` 中的 `Hero` 定义:", + "key": "HEREARETHEDEFINITIONSOFHEROANDADDRESSINDATAMODELTS:", + "original": "Here are the definitions of `Hero` and `Address` in `data-model.ts`:", + "translation": "回忆一下 `data-model.ts` 中 `Hero` 和 `Address` 的 定义:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "HEREAGAINISTHECOMPONENTSFORMGROUPDEFINITION", "original": "Here, again, is the component's `FormGroup` definition.", "translation": "这里又是组件的 `FormGroup` 定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEREARETWOSIGNIFICANTDIFFERENCESBETWEENTHESEMODELS:", "original": "There are two significant differences between these models:", "translation": "在这些模型中有两点显著的差异:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "1THEHEROHASANIDTHEFORMMODELDOESNOTBECAUSEYOUGENERALLYDONTSHOWPRIMARYKEYSTOUSERS", "original": "1. The `Hero` has an `id`. The form model does not because you generally don't show primary keys to users.", "translation": "`Hero` 有一个 `id`。表单模型中则没有,因为你通常不会把主键展示给用户。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "1. The `Hero` has an array of addresses. This form model presents only one address,\na choice [revisited below](guide/reactive-forms#form-array \"Form arrays\").", - "translation": "`Hero` 有一个住址数组。这个表单模型只表示了一个住址,[稍后的修改](guide/reactive-forms#form-array \"Form arrays\")则可以表示多个。", + "key": "1THEHEROHASANARRAYOFADDRESSESTHISFORMMODELPRESENTSONLYONEADDRESSWHICHISCOVEREDINTHESECTIONONFORMARRAYGUIDEREACTIVEFORMS#FORMARRAYFORMARRAYSBELOW", + "original": "1. The `Hero` has an array of addresses. This form model presents only one address,\nwhich is covered in the section on [`FormArray`](guide/reactive-forms#form-array \"Form arrays\") below.", + "translation": "`Hero` 有一个住址数组。这个表单模型只表示了一个住址,稍后的 [`FormArray`] (guide/reactive-forms#form-array \"Form arrays\")则可以表示多个。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Nonetheless, the two models are pretty close in shape and you'll see in a moment how this alignment facilitates copying the _data model_ properties\nto the _form model_ with the `patchValue` and `setValue` methods.", - "translation": "虽然如此,这两个模型的形态仍然是非常接近的,你很快就会看到如何用 `patchValue` 和 `setValue` 方法来把*数据模型*拷贝到*表单模型*中。", + "key": "KEEPINGTHETWOMODELSCLOSEINSHAPEFACILITATESCOPYINGTHEDATAMODELPROPERTIESTOTHEFORMMODELWITHTHEPATCHVALUEANDSETVALUEMETHODSINTHENEXTSECTION", + "original": "Keeping the two models close in shape facilitates copying the data model properties\nto the form model with the `patchValue()` and `setValue()` methods in the next section.", + "translation": "保持这两个模型的形态尽可能接近,可以在下一节中轻松使用 `patchValue()` 和 `setValue()` 方法把数据模型拷贝到表单模型中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Take a moment to refactor the _address_ `FormGroup` definition for brevity and clarity as follows:", - "translation": "花一点时间来重构一下 `address` 这个 `FormGroup` 定义,来让它更简洁清晰,代码如下:", + "key": "FIRSTREFACTORTHEADDRESSFORMGROUPDEFINITIONASFOLLOWS:", + "original": "First, refactor the `address` `FormGroup` definition as follows:", + "translation": "首先把 `address` 这个 `FormGroup` 的定义重构成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Also be sure to update the import from `data-model` so you can reference the `Hero` and `Address` classes:", + "key": "ALSOBESURETOUPDATETHEIMPORTFROMDATAMODELSOYOUCANREFERENCETHEHEROANDADDRESSCLASSES:", + "original": "Also be sure to update the `import` from `data-model` so you can reference the `Hero` and `Address` classes:", "translation": "为了确保从 `data-model` 中导入,你可以引用 `Hero` 和 `Address` 类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "## Populate the form model with _setValue_ and _patchValue_", - "translation": "## 使用 `setValue` 和 `patchValue` 来操纵表单模型", + "key": "##POPULATETHEFORMMODELWITHSETVALUEANDPATCHVALUE", + "original": "## Populate the form model with `setValue()` and `patchValue()`", + "translation": "## 使用 `setValue()` 和 `patchValue()` 来操纵表单模型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Previously you created a control and initialized its value at the same time.\nYou can also initialize or reset the values _later_ with the\n`setValue` and `patchValue` methods.", - "translation": "以前,你创建了控件,并同时初始化它的值。\n你也可以稍后用 `setValue` 和 `patchValue` 来初始化或重置这些值。", + "key": "NOTE:IFYOURECODINGALONGTHISSECTIONISOPTIONALASTHERESTOFTHESTEPSDONOTRELYONIT", + "original": "*Note*: If you're coding along, this section is optional as the rest of the steps do not rely on it.", + "translation": "*注意*:如果你正在跟着写代码,那么本节是可选的,因为剩下的步骤并不依赖它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### _setValue_", - "translation": "### _setValue_ 方法", + "key": "PREVIOUSLYYOUCREATEDACONTROLANDINITIALIZEDITSVALUEATTHESAMETIMEYOUCANALSOINITIALIZEORRESETTHEVALUESLATERWITHTHESETVALUEANDPATCHVALUEMETHODS", + "original": "Previously, you created a control and initialized its value at the same time.\nYou can also initialize or reset the values later with the\n`setValue()` and `patchValue()` methods.", + "translation": "以前,你创建了控件,并同时初始化它的值。\n你也可以稍后用 `setValue()` 和 `patchValue()` 来初始化或重置这些值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "With **`setValue`**, you assign _every_ form control value _at once_\nby passing in a data object whose properties exactly match the _form model_ behind the `FormGroup`.", - "translation": "借助**`setValue`**,你可以*立即*设置*每个*表单控件的值,只要把与*表单模型*的属性精确匹配的数据模型传进去就可以了。", + "key": "WITHSETVALUEYOUASSIGNEVERYFORMCONTROLVALUEATONCEBYPASSINGINADATAOBJECTWHOSEPROPERTIESEXACTLYMATCHTHEFORMMODELBEHINDTHEFORMGROUP", + "original": "With `setValue()`, you assign every form control value at once\nby passing in a data object whose properties exactly match the form model behind the `FormGroup`.", + "translation": "借助**`setValue()`**,你可以设置每个表单控件的值,只要把与表单模型的属性精确匹配的数据模型传进去就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The `setValue` method checks the data object thoroughly before assigning any form control values.", - "translation": "`setValue` 方法会在赋值给任何表单控件之前先检查数据对象的值。", + "key": "THESETVALUEMETHODCHECKSTHEDATAOBJECTTHOROUGHLYBEFOREASSIGNINGANYFORMCONTROLVALUES", + "original": "The `setValue()` method checks the data object thoroughly before assigning any form control values.", + "translation": "`setValue()` 方法会在赋值给任何表单控件之前先检查数据对象的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "It will not accept a data object that doesn't match the FormGroup structure or is\nmissing values for any control in the group. This way, it can return helpful\nerror messages if you have a typo or if you've nested controls incorrectly.\n`patchValue` will fail silently.", - "translation": "它不会接受一个与 FormGroup 结构不同或缺少表单组中任何一个控件的数据对象。\n这种方式下,如果你有什么拼写错误或控件嵌套的不正确,它就能返回一些有用的错误信息。\n`patchValue` 会默默地失败。", + "key": "ITWILLNOTACCEPTADATAOBJECTTHATDOESNTMATCHTHEFORMGROUPSTRUCTUREORISMISSINGVALUESFORANYCONTROLINTHEGROUPTHISWAYITCANRETURNHELPFULERRORMESSAGESIFYOUHAVEATYPOORIFYOUVENESTEDCONTROLSINCORRECTLYCONVERSELYPATCHVALUEWILLFAILSILENTLY", + "original": "It will not accept a data object that doesn't match the `FormGroup` structure or is\nmissing values for any control in the group. This way, it can return helpful\nerror messages if you have a typo or if you've nested controls incorrectly.\nConversely, `patchValue()` will fail silently.", + "translation": "它不会接受一个与 `FormGroup` 结构不同或缺少表单组中任何一个控件的数据对象。\n这种方式下,如果你有什么拼写错误或控件嵌套的不正确,它就能返回一些有用的错误信息。\n反之,`patchValue()` 会默默地失败。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "On the other hand,`setValue` will catch\nthe error and report it clearly.", - "translation": "而 `setValue` 会捕获错误,并清晰的报告它。", + "key": "NOTICETHATYOUCANALMOSTUSETHEENTIREHEROASTHEARGUMENTTOSETVALUEBECAUSEITSSHAPEISSIMILARTOTHECOMPONENTSFORMGROUPSTRUCTURE", + "original": "Notice that you can almost use the entire `hero` as the argument to `setValue()`\nbecause its shape is similar to the component's `FormGroup` structure.", + "translation": "注意,你几乎可以直接把这个 `hero` 用作 `setValue()` 的参数,因为它的形态与组件的 `FormGroup` 结构是非常像的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Notice that you can _almost_ use the entire `hero` as the argument to `setValue`\nbecause its shape is similar to the component's `FormGroup` structure.", - "translation": "注意,你*几乎*可以把这个 `hero` 用作 `setValue` 的参数,因为它的形态与组件的 `FormGroup` 结构是非常像的。", + "key": "YOUCANONLYSHOWTHEHEROSFIRSTADDRESSANDYOUMUSTACCOUNTFORTHEPOSSIBILITYTHATTHEHEROHASNOADDRESSESATALLASINTHECONDITIONALSETTINGOFTHEADDRESSPROPERTYINTHEDATAOBJECTARGUMENT:", + "original": "You can only show the hero's first address and you must account for the possibility that the `hero` has no addresses at all, as in the conditional setting of the `address` property in the data object argument:", + "translation": "你现在只能显示英雄的第一个住址,不过你还必须考虑 `hero` 完全没有住址的可能性。\n就像这个在数据对象参数中对 `address` 属性进行有条件的设置:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You can only show the hero's first address and you must account for the possibility that the `hero` has no addresses at all.\nThis explains the conditional setting of the `address` property in the data object argument:", - "translation": "你现在只能显示英雄的第一个住址,不过你还必须考虑 `hero` 完全没有住址的可能性。\n下面的例子解释了如何在数据对象参数中对 `address` 属性进行有条件的设置:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "### _patchValue_", - "translation": "### _patchValue_ 方法", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "With **`patchValue`**, you can assign values to specific controls in a `FormGroup`\nby supplying an object of key/value pairs for just the controls of interest.", - "translation": "借助**`patchValue`**,你可以通过提供一个只包含要更新的控件的键值对象来把值赋给 `FormGroup` 中的指定控件。", + "key": "WITHPATCHVALUEYOUCANASSIGNVALUESTOSPECIFICCONTROLSINAFORMGROUPBYSUPPLYINGANOBJECTOFKEYVALUEPAIRSFORTHEM", + "original": "With **`patchValue()`**, you can assign values to specific controls in a `FormGroup`\nby supplying an object of key/value pairs for them.", + "translation": "借助**`patchValue()`**,你可以通过提供一个只包含要更新的控件的键值对象来把值赋给 `FormGroup` 中的指定控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THISEXAMPLESETSONLYTHEFORMSNAMECONTROL", "original": "This example sets only the form's `name` control.", "translation": "这个例子只会设置表单的 `name` 控件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "With **`patchValue`** you have more flexibility to cope with wildly divergent data and form models.\nBut unlike `setValue`, `patchValue` cannot check for missing control\nvalues and does not throw helpful errors.", - "translation": "借助**`patchValue`**,你可以更灵活地解决数据模型和表单模型之间的差异。\n但是和 `setValue` 不同,`patchValue` 不会检查缺失的控件值,并且不会抛出有用的错误信息。", + "key": "WITHPATCHVALUEYOUHAVEMOREFLEXIBILITYTOCOPEWITHDIVERGENTDATAANDFORMMODELSBUTUNLIKESETVALUEPATCHVALUECANNOTCHECKFORMISSINGCONTROLVALUESANDDOESNTTHROWHELPFULERRORS", + "original": "With `patchValue()` you have more flexibility to cope with divergent data and form models.\nBut unlike `setValue()`, `patchValue()` cannot check for missing control\nvalues and doesn't throw helpful errors.", + "translation": "借助**`patchValue()`**,你可以更灵活地解决数据模型和表单模型之间的差异。\n但是和 `setValue()` 不同,`patchValue()` 不会检查缺失的控件值,并且不会抛出有用的错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### When to set form model values (_ngOnChanges_)", - "translation": "### 什么时候设置表单的模型值(`ngOnChanges`)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "Now you know _how_ to set the _form model_ values. But _when_ do you set them?\nThe answer depends upon when the component gets the _data model_ values.", - "translation": "现在,你已经知道了*如何*设置*表单模型*的值,但是*什么时候*设置它门呢?\n答案取决于组件何时得到*数据模型*的值。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "The `HeroDetailComponent` in this reactive forms sample is nested within a _master/detail_ `HeroListComponent` ([discussed below](guide/reactive-forms#hero-list)).\nThe `HeroListComponent` displays hero names to the user.\nWhen the user clicks on a hero, the list component passes the selected hero into the `HeroDetailComponent`\nby binding to its `hero` input property.", - "translation": "这个响应式表单范例中的 `HeroDetailComponent` 组件嵌套在一个*主/从*结构的 `HeroListComponent`([稍后讨论](guide/reactive-forms#hero-list))中。\n`HeroListComponent` 组件把英雄的名字显示给用户。\n当用户点击一个英雄时,列表组件把所选的英雄通过输入属性 `hero` 传给 `HeroDetailComponent`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "In this approach, the value of `hero` in the `HeroDetailComponent` changes\nevery time the user selects a new hero.\nYou should call _setValue_ in the [ngOnChanges](guide/lifecycle-hooks#onchanges)\nhook, which Angular calls whenever the input `hero` property changes\nas the following steps demonstrate.", - "translation": "这种方式下,每当用户选择一个新英雄时,`HeroDetailComponent` 中的 `hero` 值就会发生变化。\n你可以在[ngOnChanges](guide/lifecycle-hooks#onchanges)钩子中调用 `setValue`,就像例子中所演示的那样,\n每当输入属性 `hero` 发生变化时,Angular 就会调用它。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "First, import the `OnChanges` and `Input` symbols in `hero-detail.component.ts`.", - "translation": "首先,在 `hero-detail.component.ts` 中导入 `OnChanges` 和 `Input` 符号。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "Add the `hero` input property.", - "translation": "添加输入属性 `hero`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "Add the `ngOnChanges` method to the class as follows:", - "translation": "向该类中添加 `ngOnChanges` 方法,代码如下:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "### _reset_ the form flags", - "translation": "### *重置*表单的标识。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "You should reset the form when the hero changes so that\ncontrol values from the previous hero are cleared and\nstatus flags are restored to the _pristine_ state.\nYou could call `reset` at the top of `ngOnChanges` like this.", - "translation": "你应该在更换英雄的时候重置表单,以便来自前一个英雄的控件值被清除,并且其状态被恢复为 `pristine`(原始)状态。\n你可以在 `ngOnChanges` 的顶部调用 `reset`,就像这样:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "The `reset` method has an optional `state` value so you can reset the flags _and_ the control values at the same time.\nInternally, `reset` passes the argument to `setValue`.\nA little refactoring and `ngOnChanges` becomes this:", - "translation": "`reset` 方法有一个可选的 `state` 值,让你能在重置状态的同时*顺便设置*控件的值。\n在内部实现上,`reset` 会把该参数传给了 `setValue`。\n略微重构之后,`ngOnChanges` 会变成这样:", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "### Create the _HeroListComponent_ and _HeroService_", + "key": "##CREATETHEHEROLISTCOMPONENTANDHEROSERVICE", + "original": "## Create the `HeroListComponent` and `HeroService`", "translation": "### 创建 `HeroListComponent` 和 `HeroService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The `HeroDetailComponent` is a nested sub-component of the `HeroListComponent` in a _master/detail_ view.\nTogether they look a bit like this:", + "key": "TODEMONSTRATEFURTHERREACTIVEFORMSTECHNIQUESITISHELPFULTOADDMOREFUNCTIONALITYTOTHEEXAMPLEBYADDINGAHEROLISTCOMPONENTANDAHEROSERVICE", + "original": "To demonstrate further reactive forms techniques, it is helpful to add more functionality to the example by adding a `HeroListComponent` and a `HeroService`.", + "translation": "要更好地演示后面的响应式表单技巧,可以通过加入 `HeroListComponent` 和 `HeroService` 来为这个范例添加更多功能。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "THEHERODETAILCOMPONENTISANESTEDSUBCOMPONENTOFTHEHEROLISTCOMPONENTINAMASTERDETAILVIEWTOGETHERTHEYLOOKLIKETHIS:", + "original": "The `HeroDetailComponent` is a nested sub-component of the `HeroListComponent` in a _master/detail_ view. Together they look like this:", "translation": "`HeroDetalComponent` 是一个嵌套在 `HeroListComponent` 的*主从*视图中的子组件。如果把它们放在一起就是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "FIRSTADDAHEROLISTCOMPONENTWITHTHEFOLLOWINGCOMMAND:", + "original": "First, add a `HeroListComponent` with the following command:", + "translation": "首先使用下列命令添加一个 `HeroListComponent`:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "GIVETHEHEROLISTCOMPONENTTHEFOLLOWINGCONTENTS:", + "original": "Give the `HeroListComponent` the following contents:", + "translation": "把 `HeroListComponent` 修改为如下内容:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "NEXTADDAHEROSERVICEUSINGTHEFOLLOWINGCOMMAND:", + "original": "Next, add a `HeroService` using the following command:", + "translation": "接着使用下列命令添加 `HeroService`:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "THENGIVEITTHEFOLLOWINGCONTENTS:", + "original": "Then, give it the following contents:", + "translation": "然后,把它的内容改为:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "THEHEROLISTCOMPONENTUSESANINJECTEDHEROSERVICETORETRIEVEHEROESFROMTHESERVERANDTHENPRESENTSTHOSEHEROESTOTHEUSERASASERIESOFBUTTONSTHEHEROSERVICEEMULATESANHTTPSERVICEITRETURNSANOBSERVABLEOFHEROESTHATRESOLVESAFTERASHORTDELAYBOTHTOSIMULATENETWORKLATENCYANDTOINDICATEVISUALLYTHENECESSARILYASYNCHRONOUSNATUREOFTHEAPPLICATION", "original": "The `HeroListComponent` uses an injected `HeroService` to retrieve heroes from the server\nand then presents those heroes to the user as a series of buttons.\nThe `HeroService` emulates an HTTP service.\nIt returns an `Observable` of heroes that resolves after a short delay,\nboth to simulate network latency and to indicate visually\nthe necessarily asynchronous nature of the application.", "translation": "`HeroListComponent` 使用一个注入进来的 `HeroService` 来从服务器获取英雄列表,然后用一系列按钮把这些英雄展示给用户。\n`HeroService` 模拟了 HTTP 服务。\n它返回一个英雄组成的 `Observable` 对象,并会在短暂的延迟之后被解析出来,这是为了模拟网络延迟,并展示应用在自然延迟下的异步效果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "When the user clicks on a hero,\nthe component sets its `selectedHero` property which\nis bound to the `hero` input property of the `HeroDetailComponent`.\nThe `HeroDetailComponent` detects the changed hero and re-sets its form\nwith that hero's data values.", - "translation": "当用户点击一个英雄时,组件设置它的 `selectedHero` 属性,它绑定到 `HeroDetailComponent` 的输入属性 `hero` 上。\n`HeroDetailComponent` 检测到英雄的变化,并使用当前英雄的值重置此表单。", + "key": "WHENTHEUSERCLICKSONAHEROTHECOMPONENTSETSITSSELECTEDHEROPROPERTYWHICHISBOUNDTOTHEHEROINPUTPROPERTYOFTHEHERODETAILCOMPONENTTHEHERODETAILCOMPONENTDETECTSTHECHANGEDHEROANDRESETSITSFORMWITHTHATHEROSDATAVALUES", + "original": "When the user clicks on a hero,\nthe component sets its `selectedHero` property which\nis bound to the `hero` `@Input()` property of the `HeroDetailComponent`.\nThe `HeroDetailComponent` detects the changed hero and resets its form\nwith that hero's data values.", + "translation": "当用户点击一个英雄时,组件设置它的 `selectedHero` 属性,它绑定到 `HeroDetailComponent` 的 `@Input()` 属性 `hero` 上。\n`HeroDetailComponent` 检测到英雄的变化,并使用当前英雄的值重置此表单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "A \"Refresh\" button clears the hero list and the current selected hero before refetching the heroes.", - "translation": "\"刷新\"按钮清除英雄列表和当前选中的英雄,然后重新获取英雄列表。", + "key": "AREFRESHBUTTONCLEARSTHEHEROLISTANDTHECURRENTSELECTEDHEROBEFOREREFETCHINGTHEHEROES", + "original": "A refresh button clears the hero list and the current selected hero before refetching the heroes.", + "translation": "\"刷新\"按钮会清除英雄列表和当前选中的英雄,然后重新获取英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The remaining `HeroListComponent` and `HeroService` implementation details are not relevant to understanding reactive forms.\nThe techniques involved are covered elsewhere in the documentation, including the _Tour of Heroes_\n[here](tutorial/toh-pt3 \"ToH: Multiple Components\") and [here](tutorial/toh-pt4 \"ToH: Services\").", - "translation": "`HeroListComponent` 和 `HeroService` 的其余部分的实现细节与响应式表单无关。\n那些技术涵盖于本文档中的其它部分,包括*《英雄指南》*中的[这里](tutorial/toh-pt3 \"ToH: Multiple Components\")和[这里](tutorial/toh-pt4 \"ToH: Services\")。", + "key": "NOTICETHATHEROLISTCOMPONENTTSIMPORTSOBSERVABLEANDFINALLYWHILEHEROSERVICETSIMPORTSOBSERVABLEOFANDDELAYFROMRXJS", + "original": "Notice that `hero-list.component.ts` imports `Observable` and `finally` while `hero.service.ts` imports `Observable`, `of`,\nand `delay` from `rxjs`.", + "translation": "注意,`hero-list.component.ts` 从 `rxjs` 中导入了 `Observable` 和 `finally`,而 `hero.service.ts` 导入了 `Observable`、`of` 和 `delay`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "If you're coding along with the steps in this reactive forms tutorial,\ngenerate the pertinent files based on the\n[source code displayed below](guide/reactive-forms#source-code \"Reactive Forms source code\").\nNotice that `hero-list.component.ts` imports `Observable` and `finally` while `hero.service.ts` imports `Observable`, `of`,\nand `delay` from `rxjs`.\nThen return here to learn about _form array_ properties.", - "translation": "如果你正在随着本教程写代码,可以基于[下面显示的代码](guide/reactive-forms#source-code \"Reactive Forms source code\")来创建相应的文件。\n注意,`hero-list.component.ts` 从 `rxjs` 中导入了 `Observable` 和 `finally`,而 `hero.service.ts` 导入了 `Observable`、`of` 和 `delay`。\n然后回来继续学习*表单数组*的属性。", + "key": "ADDTHENGONCHANGESMETHODTOTHECLASSASFOLLOWS:", + "original": "Add the `ngOnChanges` method to the class as follows:", + "translation": "向该类中添加 `ngOnChanges` 方法,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "## Use _FormArray_ to present an array of _FormGroups_", + "key": "##USEFORMARRAYTOPRESENTANARRAYOFFORMGROUPS", + "original": "## Use _FormArray_ to present an array of `FormGroups`", "translation": "## 使用 `FormArray` 来表示 `FormGroup` 数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "So far, you've seen `FormControls` and `FormGroups`.\nA `FormGroup` is a named object whose property values are `FormControls` and other `FormGroups`.", - "translation": "以前,你已见过 `FormControl` 和 `FormGroup`。\n`FormGroup` 是一个命名对象,它的属性值是 `FormControl` 和其它的 `FormGroup`。", + "key": "AFORMGROUPISANAMEDOBJECTWHOSEPROPERTYVALUESAREFORMCONTROLSANDOTHERFORMGROUPS", + "original": "A `FormGroup` is a named object whose property values are `FormControls` and other `FormGroups`.", + "translation": "`FormGroup` 是一个命名对象,它的属性值是 `FormControl` 和其它的 `FormGroup`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "SOMETIMESYOUNEEDTOPRESENTANARBITRARYNUMBEROFCONTROLSORGROUPSFOREXAMPLEAHEROMAYHAVEZEROONEORANYNUMBEROFADDRESSES", "original": "Sometimes you need to present an arbitrary number of controls or groups.\nFor example, a hero may have zero, one, or any number of addresses.", "translation": "有时你需要表示任意数量的控件或控件组。\n比如,一个英雄可能拥有 0、1 或任意数量的住址。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The `Hero.addresses` property is an array of `Address` instances.\nAn _address_ `FormGroup` can display one `Address`.\nAn Angular `FormArray` can display an array of _address_ `FormGroups`.", - "translation": "`Hero.addresses` 属性就是一个 `Address` 实例的数组。\n一个住址的 `FormGroup` 可以显示一个 `Address` 对象。\n而 `FormArray` 可以显示一个住址 `FormGroup` 的数组。", + "key": "THEHEROADDRESSESPROPERTYISANARRAYOFADDRESSINSTANCESANADDRESSFORMGROUPCANDISPLAYONEADDRESSANANGULARFORMARRAYCANDISPLAYANARRAYOFADDRESSFORMGROUPS", + "original": "The `Hero.addresses` property is an array of `Address` instances.\nAn `address` `FormGroup` can display one `Address`.\nAn Angular `FormArray` can display an array of `address` `FormGroups`.", + "translation": "`Hero.addresses` 属性就是一个 `Address` 实例的数组。\n一个 `address` 的 `FormGroup` 可以显示一个 `Address` 对象。\n而 `FormArray` 可以显示一个 `address` `FormGroup` 的数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "TOGETACCESSTOTHEFORMARRAYCLASSIMPORTITINTOHERODETAILCOMPONENTTS:", "original": "To get access to the `FormArray` class, import it into `hero-detail.component.ts`:", "translation": "要访问 `FormArray` 类,请先把它导入 `hero-detail.component.ts` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "To _work_ with a `FormArray` you do the following:", - "translation": "要想使用 `FormArray`,你要这么做:", + "key": "TOWORKWITHAFORMARRAYDOTHEFOLLOWING:", + "original": "To work with a `FormArray` do the following:", + "translation": "要使用 `FormArray`,就要这么做:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "1. Define the items (`FormControls` or `FormGroups`) in the array.", - "translation": "在数组中定义条目(`FormControl` 或 `FormGroup`)。", + "key": "1DEFINETHEITEMSINTHEARRAYTHATISFORMCONTROLSORFORMGROUPS", + "original": "1. Define the items in the array; that is, `FormControls` or `FormGroups`.", + "translation": "在数组中定义条目 `FormControl` 或 `FormGroup`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "1. Initialize the array with items created from data in the _data model_.", + "key": "1INITIALIZETHEARRAYWITHITEMSCREATEDFROMDATAINTHEDATAMODEL", + "original": "1. Initialize the array with items created from data in the data model.", "translation": "把这个数组初始化微一组从*数据模型*中的数据创建的条目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "1ADDANDREMOVEITEMSASTHEUSERREQUIRES", "original": "1. Add and remove items as the user requires.", "translation": "根据用户的需求添加或移除这些条目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "In this guide, you define a `FormArray` for `Hero.addresses` and\nlet the user add or modify addresses (removing addresses is your homework).", - "translation": "在本章中,你为 `Hero.addresses` 定义了一个 `FormArray`,并且让用户添加或修改这些住址(移除住址功能请课后自行实现)。", + "key": "DEFINEAFORMARRAYFORHEROADDRESSESANDLETTHEUSERADDORMODIFYADDRESSES", + "original": "Define a `FormArray` for `Hero.addresses` and\nlet the user add or modify addresses.", + "translation": "为 `Hero.addresses` 定义了一个 `FormArray`,并且让用户添加或修改这些住址。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You’ll need to redefine the form model in the `HeroDetailComponent` constructor,\nwhich currently only displays the first hero address in an _address_ `FormGroup`.", - "translation": "你需要在 `HeroDetailComponent` 的构造函数中重新定义表单模型,它现在只用 `FormGroup` 显示第一个英雄住址。", + "key": "YOULLNEEDTOREDEFINETHEFORMMODELINTHEHERODETAILCOMPONENTCREATEFORMMETHODWHICHCURRENTLYONLYDISPLAYSTHEFIRSTHEROADDRESSINANADDRESSFORMGROUP:", + "original": "You’ll need to redefine the form model in the `HeroDetailComponent` `createForm()` method,\nwhich currently only displays the first hero address in an `address` `FormGroup`:", + "translation": "你需要在 `HeroDetailComponent` 的 `createForm()` 中重新定义表单模型,它现在只在 `address` `FormGroup` 中显示第一个英雄住址。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### From _address_ to _secret lairs_", - "translation": "### 从*住址*到*秘密小屋*(Secret Lair)", + "key": "###FROMADDRESSTOSECRETLAIRS", + "original": "### From `address` to `secretLairs`", + "translation": "### 从 `address`(住址)到 *`secretLairs`(秘密小屋)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "From the user's point of view, heroes don't have _addresses_.\n_Addresses_ are for mere mortals. Heroes have _secret lairs_!\nReplace the _address_ `FormGroup` definition with a _secretLairs_ `FormArray` definition:", - "translation": "从用户的视角来看,英雄们没有*住址*。\n只有我们凡人才有*住址*,英雄们拥有的是*秘密小屋*!\n把 `FormGroup` 型的住址替换为 `FormArray` 型的 `secretLairs` 定义:", + "key": "FROMTHEUSERSPOINTOFVIEWHEROESDONTHAVEADDRESSESADDRESSESAREFORMEREMORTALSHEROESHAVESECRETLAIRSREPLACETHEADDRESSFORMGROUPDEFINITIONWITHASECRETLAIRSFORMARRAYDEFINITION:", + "original": "From the user's point of view, heroes don't have _addresses_.\nAddresses are for mere mortals. Heroes have _secret lairs_!\nReplace the address `FormGroup` definition with a `secretLairs` `FormArray` definition:", + "translation": "在用户看来,英雄们没有*住址*。\n只有我们凡人才有*住址*,英雄们拥有的是*秘密小屋*!\n把 `FormGroup` 型的住址替换为 `FormArray` 型的 `secretLairs` 定义:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Changing the form control name from `address` to `secretLairs` drives home an important point:\nthe _form model_ doesn't have to match the _data model_.", - "translation": "把表单的控件名从 `address` 改为 `secretLairs` 时遇到了一个重要问题:*表单模型*与*数据模型*不再匹配了。", + "key": "INHERODETAILCOMPONENTHTMLCHANGEFORMARRAYNAMEADDRESSTOFORMARRAYNAMESECRETLAIRS", + "original": "In `hero-detail.component.html` change `formArrayName=\"address\"` to `formArrayName=\"secretLairs\"`.", + "translation": "在 `hero-detail.component.html` 中 把 `formArrayName=\"address\"` 改为 `formArrayName=\"secretLairs\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Obviously there has to be a relationship between the two.\nBut it can be anything that makes sense within the application domain.", + "key": "CHANGINGTHEFORMCONTROLNAMEFROMADDRESSTOSECRETLAIRSUNDERSCORESANIMPORTANTPOINT:THEFORMMODELDOESNTHAVETOMATCHTHEDATAMODEL", + "original": "Changing the form control name from `address` to `secretLairs` underscores an important point:\nthe _form model_ doesn't have to match the _data model_.", + "translation": "把表单的控件名从 `address` 改为 `secretLairs` 时导致了一个重要问题:*表单模型*与*数据模型*不再匹配了。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "OBVIOUSLYTHEREHASTOBEARELATIONSHIPBETWEENTHETWOBUTITCANBEANYTHINGTHATMAKESSENSEWITHINTHEAPPLICATIONDOMAIN", + "original": "Obviously, there has to be a relationship between the two.\nBut it can be anything that makes sense within the application domain.", "translation": "显然,必须在两者之间建立关联。但它在应用领域中的意义不限于此,它可以用于任何东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "PRESENTATIONREQUIREMENTSOFTENDIFFERFROMDATAREQUIREMENTSTHEREACTIVEFORMSAPPROACHBOTHEMPHASIZESANDFACILITATESTHISDISTINCTION", "original": "_Presentation_ requirements often differ from _data_ requirements.\nThe reactive forms approach both emphasizes and facilitates this distinction.", "translation": "*展现*的需求经常会与*数据*的需求不同。\n响应式表单的方法既强调这种差异,也能为这种差异提供了便利。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "### Initialize the \"secretLairs\" _FormArray_", + "key": "###INITIALIZETHESECRETLAIRSFORMARRAY", + "original": "### Initialize the `secretLairs` _FormArray_", "translation": "### 初始化 `FormArray` 型的 `secretLairs`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEDEFAULTFORMDISPLAYSANAMELESSHEROWITHNOADDRESSES", "original": "The default form displays a nameless hero with no addresses.", "translation": "默认的表单显示一个无地址的无名英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "You need a method to populate (or repopulate) the _secretLairs_ with actual hero addresses whenever\nthe parent `HeroListComponent` sets the `HeroDetailComponent.hero` input property to a new `Hero`.", - "translation": "你需要一个方法来用实际英雄的地址填充(或重新填充)`secretLairs`,\n而不用管父组件 `HeroListComponent` 何时把输入属性 `HeroDetailComponent.hero` 设置为一个新的 `Hero`。", + "key": "YOUNEEDAMETHODTOPOPULATEORREPOPULATETHESECRETLAIRSWITHACTUALHEROADDRESSESWHENEVERTHEPARENTHEROLISTCOMPONENTSETSTHEHERODETAILCOMPONENTHEROINPUTPROPERTYTOANEWHERO", + "original": "You need a method to populate (or repopulate) the `secretLairs` with actual hero addresses whenever\nthe parent `HeroListComponent` sets the `HeroDetailComponent.hero` `@Input()` property to a new `Hero`.", + "translation": "你需要一个方法来用实际英雄的地址填充(或重新填充)`secretLairs`,\n而不用管父组件 `HeroListComponent` 何时把 `@Input()` 属性 `HeroDetailComponent.hero` 设置为一个新的 `Hero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The following `setAddresses` method replaces the _secretLairs_ `FormArray` with a new `FormArray`,\ninitialized by an array of hero address `FormGroups`.", - "translation": "下面的 `setAddresses` 方法把 `secretLairs` 数组替换为一个新的 `FormArray`,使用一组表示英雄地址的 `FormGroup` 来进行初始化。", + "key": "THEFOLLOWINGSETADDRESSESMETHODREPLACESTHESECRETLAIRSFORMARRAYWITHANEWFORMARRAYINITIALIZEDBYANARRAYOFHEROADDRESSFORMGROUPSADDTHISTOTHEHERODETAILCOMPONENTCLASS:", + "original": "The following `setAddresses()` method replaces the `secretLairs` `FormArray` with a new `FormArray`,\ninitialized by an array of hero address `FormGroups`. Add this to the `HeroDetailComponent` class:", + "translation": "下面的 `setAddresses()` 方法把 `secretLairs` 这个 `FormArray` 替换为一个新的 `FormArray`,使用一组表示英雄地址的 `FormGroup` 来进行初始化。在 `HeroDetailComponent` 类中添加下列内容:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Notice that you replace the previous `FormArray` with the **`FormGroup.setControl` method**, not with `setValue`.\nYou're replacing a _control_, not the _value_ of a control.", - "translation": "注意,你使用**`FormGroup.setControl` 方法**,而不是 `setValue` 方法来设置前一个 `FormArray`。\n你所要替换的是*控件*,而不是控件的*值*。", + "key": "NOTICETHATYOUREPLACETHEPREVIOUSFORMARRAYWITHTHEFORMGROUPSETCONTROLMETHODNOTWITHSETVALUEYOUREREPLACINGACONTROLNOTTHEVALUEOFACONTROL", + "original": "Notice that you replace the previous `FormArray` with the\n`FormGroup.setControl()` method, not with `setValue()`.\nYou're replacing a _control_, not the _value_ of a control.", + "translation": "注意,你使用 `FormGroup.setControl()` 方法,而不是 `setValue()` 方法来替换前一个 `FormArray`。\n你所要替换的是*控件*,而不是控件的*值*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Notice also that the _secretLairs_ `FormArray` contains **`FormGroups`**, not `Addresses`.", + "key": "NOTICEALSOTHATTHESECRETLAIRSFORMARRAYCONTAINSFORMGROUPSNOTADDRESSES", + "original": "Notice also that the `secretLairs` `FormArray` contains `FormGroups`, not `Addresses`.", "translation": "还要注意,`secretLairs` 数组中包含的是**`FormGroup`,而不是 `Address`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "NEXTCALLSETADDRESSESFROMWITHINREBUILDFORM:", + "original": "Next, call `setAddresses()` from within `rebuildForm()`:", + "translation": "接着,在 `rebuildForm()` 中调用 `setAddresses()`:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "###GETTHEFORMARRAY", "original": "### Get the _FormArray_", "translation": "### 获取 `FormArray`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The `HeroDetailComponent` should be able to display, add, and remove items from the _secretLairs_ `FormArray`.", - "translation": "`HeroDetailComponent` 应该能从 `secretLairs` 中显示、添加和删除条目。", + "key": "THEHERODETAILCOMPONENTSHOULDBEABLETODISPLAYADDANDREMOVEITEMSFROMTHESECRETLAIRSFORMARRAY", + "original": "The `HeroDetailComponent` should be able to display, add, and remove items from the `secretLairs` `FormArray`.", + "translation": "`HeroDetailComponent` 应该能从 `secretLairs` `FormArray` 中显示、添加和删除条目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Use the `FormGroup.get` method to acquire a reference to that `FormArray`.\nWrap the expression in a `secretLairs` convenience property for clarity and re-use.", - "translation": "使用 `FormGroup.get` 方法来获取到 `FormArray` 的引用。\n把这个表达式包装进一个名叫 `secretLairs` 的便捷属性中来让它更清晰,并供复用。", + "key": "USETHEFORMGROUPGETMETHODTOACQUIREAREFERENCETOTHATFORMARRAYWRAPTHEEXPRESSIONINASECRETLAIRSCONVENIENCEPROPERTYFORCLARITYANDREUSEADDTHEFOLLOWINGTOHERODETAILCOMPONENT", + "original": "Use the `FormGroup.get()` method to acquire a reference to that `FormArray`.\nWrap the expression in a `secretLairs` convenience property for clarity and re-use. Add the following to `HeroDetailComponent`.", + "translation": "使用 `FormGroup.get()` 方法来获取到 `FormArray` 的引用。\n把这个表达式包装进一个名叫 `secretLairs` 的便捷属性中来让它更清晰,并供复用。\n在 `HeroDetailComponent` 中添加下列内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###DISPLAYTHEFORMARRAY", "original": "### Display the _FormArray_", "translation": "### 显示 `FormArray`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The current HTML template displays a single _address_ `FormGroup`.\nRevise it to display zero, one, or more of the hero's _address_ `FormGroups`.", + "key": "THECURRENTHTMLTEMPLATEDISPLAYSASINGLEADDRESSFORMGROUPREVISEITTODISPLAYZEROONEORMOREOFTHEHEROSADDRESSFORMGROUPS", + "original": "The current HTML template displays a single `address` `FormGroup`.\nRevise it to display zero, one, or more of the hero's `address` `FormGroups`.", "translation": "当前 HTML 模板显示单个的地址 `FormGroup`。\n要把它修改成能显示 0、1 或更多个表示英雄地址的 `FormGroup`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THISISMOSTLYAMATTEROFWRAPPINGTHEPREVIOUSTEMPLATEHTMLFORANADDRESSINADIVANDREPEATINGTHATDIVWITHNGFOR", "original": "This is mostly a matter of wrapping the previous template HTML for an address in a `<div>` and\nrepeating that `<div>` with `*ngFor`.", "translation": "要改的部分主要是把以前表示地址的 HTML 模板包裹进一个 `<div>` 中,并且使用 `*ngFor` 来重复渲染这个 `<div>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The trick lies in knowing how to write the `*ngFor`. There are three key points:", - "translation": "诀窍在于要知道如何编写 `*ngFor`。主要有三点:", + "key": "THEREARETHREEKEYPOINTSWHENWRITINGTHENGFOR:", + "original": "There are three key points when writing the `*ngFor`:", + "translation": "写这个 `*ngFor` 有三个要点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "1. Add another wrapping `<div>`, around the `<div>` with `*ngFor`, and\nset its `formArrayName` directive to `\"secretLairs\"`.\nThis step establishes the _secretLairs_ `FormArray` as the context for form controls in the inner, repeated HTML template.", + "key": "1ADDANOTHERWRAPPINGDIVAROUNDTHEDIVWITHNGFORANDSETITSFORMARRAYNAMEDIRECTIVETOSECRETLAIRSTHISSTEPESTABLISHESTHESECRETLAIRSFORMARRAYASTHECONTEXTFORFORMCONTROLSINTHEINNERREPEATEDHTMLTEMPLATE", + "original": "1. Add another wrapping `<div>`, around the `<div>` with `*ngFor`, and\nset its `formArrayName` directive to `\"secretLairs\"`.\nThis step establishes the `secretLairs` `FormArray` as the context for form controls in the inner, repeated HTML template.", "translation": "在 `*ngFor` 的 `<div>` 之外套上另一个包装 `<div>`,并且把它的 `formArrayName` 指令设为 `\"secretLairs\"`。\n 这一步为内部的表单控件建立了一个 `FormArray` 型的 `secretLairs` 作为上下文,以便重复渲染 HTML 模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "1. The source of the repeated items is the `FormArray.controls`, not the `FormArray` itself.\nEach control is an _address_ `FormGroup`, exactly what the previous (now repeated) template HTML expected.", + "key": "1THESOURCEOFTHEREPEATEDITEMSISTHEFORMARRAYCONTROLSNOTTHEFORMARRAYITSELFEACHCONTROLISANADDRESSFORMGROUPEXACTLYWHATTHEPREVIOUSNOWREPEATEDTEMPLATEHTMLEXPECTED", + "original": "1. The source of the repeated items is the `FormArray.controls`, not the `FormArray` itself.\nEach control is an `address` `FormGroup`, exactly what the previous (now repeated) template HTML expected.", "translation": "这些重复条目的数据源是 `FormArray.controls` 而不是 `FormArray` 本身。\n 每个控件都是一个 `FormGroup` 型的地址对象,与以前的模板 HTML 所期望的格式完全一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "1. Each repeated `FormGroup` needs a unique `formGroupName` which must be the index of the `FormGroup` in the `FormArray`.\nYou'll re-use that index to compose a unique label for each address.", + "key": "1EACHREPEATEDFORMGROUPNEEDSAUNIQUEFORMGROUPNAMEWHICHMUSTBETHEINDEXOFTHEFORMGROUPINTHEFORMARRAYYOULLREUSETHATINDEXTOCOMPOSEAUNIQUELABELFOREACHADDRESS", + "original": "1. Each repeated `FormGroup` needs a unique `formGroupName`, which must be the index of the `FormGroup` in the `FormArray`.\nYou'll re-use that index to compose a unique label for each address.", "translation": "每个被重复渲染的 `FormGroup` 都需要一个独一无二的 `formGroupName`,它必须是 `FormGroup` 在这个 `FormArray` 中的索引。\n 你将复用这个索引,以便为每个地址组合出一个独一无二的标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Here's the skeleton for the _secret lairs_ section of the HTML template:", + "key": "HERESTHESKELETONFORTHESECRETLAIRSSECTIONOFTHEHTMLTEMPLATE:", + "original": "Here's the skeleton for the secret lairs section of the HTML template:", "translation": "下面是 HTML 模板中*秘密小屋*部分的代码骨架:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Here's the complete template for the _secret lairs_ section:", + "key": "HERESTHECOMPLETETEMPLATEFORTHESECRETLAIRSSECTIONADDTHISTOHERODETAILCOMPONENTTEMPLATEREPLACINGTHEFORGROUPNAMEADDRESSDIV:", + "original": "Here's the complete template for the secret lairs section. Add this to `HeroDetailComponent` template, replacing the `forGroupName=address` `<div>`:", "translation": "这里是*秘密小屋*部分的完整模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###ADDANEWLAIRTOTHEFORMARRAY", "original": "### Add a new lair to the _FormArray_", "translation": "### 把新的小屋添加到 `FormArray` 中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Add an `addLair` method that gets the _secretLairs_ `FormArray` and appends a new _address_ `FormGroup` to it.", - "translation": "添加一个 `addLair` 方法,它获取 `secretLairs` 数组,并把新的表示地址的 `FormGroup` 添加到其中。", + "key": "ADDANADDLAIRMETHODTHATGETSTHESECRETLAIRSFORMARRAYANDAPPENDSANEWADDRESSFORMGROUPTOIT", + "original": "Add an `addLair()` method that gets the `secretLairs` `FormArray` and appends a new `address` `FormGroup` to it.", + "translation": "添加一个 `addLair()` 方法,它获取 `secretLairs` 数组,并把新的表示地址的 `FormGroup` 添加到其中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Place a button on the form so the user can add a new _secret lair_ and wire it to the component's `addLair` method.", - "translation": "把一个按钮放在表单中,以便用户可以添加新的*秘密小屋*,并把它传给组件的 `addLair` 方法。", + "key": "PLACEABUTTONONTHEFORMSOTHEUSERCANADDANEWSECRETLAIRANDWIREITTOTHECOMPONENTSADDLAIRMETHODPUTITJUSTBEFORETHECLOSINGDIVOFTHESECRETLAIRSFORMARRAY", + "original": "Place a button on the form so the user can add a new _secret lair_ and wire it to the component's `addLair()` method. Put it just before the closing `</div>` of the `secretLairs` `FormArray`.", + "translation": "把一个按钮放在表单中,以便用户可以添加新的*秘密小屋*,并把它传给组件的 `addLair()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Be sure to **add the `type=\"button\"` attribute**.\nIn fact, you should always specify a button's `type`.\nWithout an explicit type, the button type defaults to \"submit\".\nWhen you later add a _form submit_ action, every \"submit\" button triggers the submit action which\nmight do something like save the current changes.\nYou do not want to save changes when the user clicks the _Add a Secret Lair_ button.", - "translation": "务必确保**添加了 `type=\"button\"` 属性**。\n事实上,你应该总是指定按钮的 `type`。\n如果不明确指定类型,按钮的默认类型就是“submit”(提交)。\n当你稍后添加了*表单提交*的动作时,每个“submit”按钮都是触发一次提交操作,而它将可能会做一些处理,比如保存当前的修改。\n你显然不会希望每当用户点击“Add a Secret Lair”按钮时就保存一次。", + "key": "BESURETOADDTHETYPEBUTTONATTRIBUTEBECAUSEWITHOUTANEXPLICITTYPETHEBUTTONTYPEDEFAULTSTOSUBMITWHENYOULATERADDAFORMSUBMITACTIONEVERYSUBMITBUTTONTRIGGERSTHESUBMITACTIONWHICHMIGHTDOSOMETHINGLIKESAVETHECURRENTCHANGESYOUDONOTWANTTOSAVECHANGESWHENTHEUSERCLICKSTHEADDASECRETLAIRBUTTON", + "original": "Be sure to add the `type=\"button\"` attribute \nbecause without an explicit type, the button type defaults to \"submit\".\nWhen you later add a form submit action, every \"submit\" button triggers the submit action which\nmight do something like save the current changes.\nYou do not want to save changes when the user clicks the _Add a Secret Lair_ button.", + "translation": "务必确保添加了 `type=\"button\"` 属性。\n因为如果不明确指定类型,按钮的默认类型就是“submit”(提交)。\n当你稍后添加了提交表单的动作时,每个“submit”按钮都是触发一次提交操作,而它将可能会做一些处理,比如保存当前的修改。\n你显然不会希望每当用户点击“Add a Secret Lair”按钮时就保存一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###TRYIT", "original": "### Try it!", "translation": "### 试试看!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "BACKINTHEBROWSERSELECTTHEHERONAMEDMAGNETAMAGNETADOESNTHAVEANADDRESSASYOUCANSEEINTHEDIAGNOSTICJSONATTHEBOTTOMOFTHEFORM", "original": "Back in the browser, select the hero named \"Magneta\".\n\"Magneta\" doesn't have an address, as you can see in the diagnostic JSON at the bottom of the form.", "translation": "回到浏览器中,选择名叫“Magneta”的英雄。\n\"Magneta\"没有地址,你会在表单底部的诊断用 JSON 中看到这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "CLICKTHEADDASECRETLAIRBUTTONANEWADDRESSSECTIONAPPEARSWELLDONE", "original": "Click the \"_Add a Secret Lair_\" button.\nA new address section appears. Well done!", "translation": "点击“Add a Secret Lair”按钮,一个新的地址区就出现了,干得好!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###REMOVEALAIR", "original": "### Remove a lair", "translation": "### 移除一个小屋", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THISEXAMPLECANADDADDRESSESBUTITCANTREMOVETHEMFOREXTRACREDITWRITEAREMOVELAIRMETHODANDWIREITTOABUTTONONTHEREPEATINGADDRESSHTML", "original": "This example can _add_ addresses but it can't _remove_ them.\nFor extra credit, write a `removeLair` method and wire it to a button on the repeating address HTML.", "translation": "这个例子可以*添加*地址,但是还不能*移除*它们。\n作为练习,你可以自己写一个 `removeLair` 方法,并且把它关联到地址 HTML 模板的一个按钮上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "##OBSERVECONTROLCHANGES", "original": "## Observe control changes", "translation": "## 监视控件的变化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Angular calls `ngOnChanges` when the user picks a hero in the parent `HeroListComponent`.\nPicking a hero changes the `HeroDetailComponent.hero` input property.", - "translation": "每当用户在父组件 `HeroListComponent` 中选取了一个英雄,Angular 就会调用一次 `ngOnChanges`。\n选取英雄会修改输入属性 `HeroDetailComponent.hero`。", + "key": "ANGULARCALLSNGONCHANGESWHENTHEUSERPICKSAHEROINTHEPARENTHEROLISTCOMPONENTPICKINGAHEROCHANGESTHEHERODETAILCOMPONENTHEROINPUTPROPERTY", + "original": "Angular calls `ngOnChanges()` when the user picks a hero in the parent `HeroListComponent`.\nPicking a hero changes the `HeroDetailComponent.hero` `@Input()` property.", + "translation": "每当用户在父组件 `HeroListComponent` 中选取了一个英雄,Angular 就会调用一次 `ngOnChanges`。\n选取英雄会修改输入属性 `HeroDetailComponent.hero()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Angular does _not_ call `ngOnChanges` when the user modifies the hero's _name_ or _secret lairs_.\nFortunately, you can learn about such changes by subscribing to one of the form control properties\nthat raises a change event.", - "translation": "当用户修改英雄的*名字*或*秘密小屋*时,Angular*并不会*调用 `ngOnChanges`。\n幸运的是,你可以通过订阅表单控件的属性之一来了解这些变化,此属性会发出变更通知。", + "key": "ANGULARDOESNOTCALLNGONCHANGESWHENTHEUSERMODIFIESTHEHEROSNAMEORSECRETLAIRSFORTUNATELYYOUCANLEARNABOUTSUCHCHANGESBYSUBSCRIBINGTOONEOFTHEFORMCONTROLPROPERTIESTHATRAISESACHANGEEVENT", + "original": "Angular does _not_ call `ngOnChanges()` when the user modifies the hero's `name` or `secretLairs`.\nFortunately, you can learn about such changes by subscribing to one of the `FormControl` properties\nthat raises a change event.", + "translation": "当用户修改英雄的*名字*或*秘密小屋*时,Angular*并不会*调用 `ngOnChanges()`。\n幸运的是,你可以通过订阅表单控件的属性之一来了解这些变化,此属性会发出变更通知。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THESEAREPROPERTIESSUCHASVALUECHANGESTHATRETURNANRXJSOBSERVABLEYOUDONTNEEDTOKNOWMUCHABOUTRXJSOBSERVABLETOMONITORFORMCONTROLVALUES", "original": "These are properties, such as `valueChanges`, that return an RxJS `Observable`.\nYou don't need to know much about RxJS `Observable` to monitor form control values.", "translation": "有一些属性,比如 `valueChanges`,可以返回一个 RxJS 的 `Observable` 对象。\n要监听控件值的变化,你并不需要对 RxJS 的 `Observable` 了解更多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Add the following method to log changes to the value of the _name_ `FormControl`.", - "translation": "添加下列方法,以监听姓名这个 `FormControl` 中值的变化。", + "key": "ADDTHEFOLLOWINGMETHODTOLOGCHANGESTOTHEVALUEOFTHENAMEFORMCONTROL", + "original": "Add the following method to log changes to the value of the `name` `FormControl`.", + "translation": "添加下列方法,以监听 `name` 这个 `FormControl` 中值的变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Call it in the constructor, after creating the form.", - "translation": "在构造函数中调用它,就在创建表单的代码之后:", + "key": "CALLITINTHECONSTRUCTORAFTERCREATEFORM", + "original": "Call it in the constructor, after `createForm()`.", + "translation": "在构造函数中调用它,就在 `createForm()` 之后。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The `logNameChange` method pushes name-change values into a `nameChangeLog` array.\nDisplay that array at the bottom of the component template with this `*ngFor` binding:", - "translation": "`logNameChange` 方法会把一条改名记录追加到 `nameChangeLog` 数组中。\n用 `*ngFor` 绑定在组件模板的底部显示这个数组:", + "key": "THELOGNAMECHANGEMETHODPUSHESNAMECHANGEVALUESINTOANAMECHANGELOGARRAYDISPLAYTHATARRAYATTHEBOTTOMOFTHECOMPONENTTEMPLATEWITHTHISNGFORBINDING:", + "original": "The `logNameChange()` method pushes name-change values into a `nameChangeLog` array.\nDisplay that array at the bottom of the component template with this `*ngFor` binding:", + "translation": "`logNameChange()` 方法会把一条改名记录追加到 `nameChangeLog` 数组中。\n用 `*ngFor` 绑定在组件模板的底部显示这个数组:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Return to the browser, select a hero (e.g, \"Magneta\"), and start typing in the _name_ input box.\nYou should see a new name in the log after each keystroke.", - "translation": "返回浏览器,选择一个英雄(比如“Magneta”),并开始在*姓名*输入框中键入。\n你会看到,每次按键都会记录一个新名字。", + "key": "RETURNTOTHEBROWSERSELECTAHEROFOREXAMPLEMAGNETAANDSTARTTYPINGINTHENAMEINPUTYOUSHOULDSEEANEWNAMEINTHELOGAFTEREACHKEYSTROKE", + "original": "Return to the browser, select a hero; for example, Magneta, and start typing in the `name` `<input>`.\nYou should see a new name in the log after each keystroke.", + "translation": "返回浏览器,选择一个英雄(比如“Magneta”),并开始在 `name` 输入框中键入。\n你会看到,每次按键都会记录一个新名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###WHENTOUSEIT", "original": "### When to use it", "translation": "### 什么时候用它", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "An interpolation binding is the easier way to _display_ a name change.\nSubscribing to an observable form control property is handy for triggering\napplication logic _within_ the component class.", - "translation": "插值表达式绑定时显示姓名变化比较简单的方式。\n*在组件类中*订阅表单控件属性变化的可观察对象以触发应用逻辑则是比较难的方式。", + "key": "ANINTERPOLATIONBINDINGISTHEEASIERWAYTODISPLAYANAMECHANGESUBSCRIBINGTOANOBSERVABLEFORMCONTROLPROPERTYISHANDYFORTRIGGERINGAPPLICATIONLOGICWITHINTHECOMPONENTCLASS", + "original": "An interpolation binding is the easier way to display a name change.\nSubscribing to an observable `FormControl` property is handy for triggering\napplication logic within the component class.", + "translation": "插值表达式绑定时显示姓名变化比较简单的方式。\n在组件类中订阅表单控件属性变化的可观察对象以触发应用逻辑则是比较难的方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "##SAVEFORMDATA", "original": "## Save form data", "translation": "## 保存表单数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The `HeroDetailComponent` captures user input but it doesn't do anything with it.\nIn a real app, you'd probably save those hero changes.\nIn a real app, you'd also be able to revert unsaved changes and resume editing.\nAfter you implement both features in this section, the form will look like this:", + "key": "THEHERODETAILCOMPONENTCAPTURESUSERINPUTBUTITDOESNTDOANYTHINGWITHITINAREALAPPYOUDPROBABLYSAVETHOSEHEROCHANGESREVERTUNSAVEDCHANGESANDRESUMEEDITINGAFTERYOUIMPLEMENTBOTHFEATURESINTHISSECTIONTHEFORMWILLLOOKLIKETHIS:", + "original": "The `HeroDetailComponent` captures user input but it doesn't do anything with it.\nIn a real app, you'd probably save those hero changes, revert unsaved changes, and resume editing.\nAfter you implement both features in this section, the form will look like this:", "translation": "`HeroDetailComponent` 捕获了用户输入,但没有用它做任何事。\n在真实的应用中,你可能要保存这些英雄的变化。\n在真实的应用中,你还要能丢弃未保存的变更,然后继续编辑。\n在实现完本节的这些特性之后,表单是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###SAVE", "original": "### Save", "translation": "### 保存", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "In this sample application, when the user submits the form,\nthe `HeroDetailComponent` will pass an instance of the hero _data model_\nto a save method on the injected `HeroService`.", - "translation": "在这个范例应用中,当用户提交表单时,`HeroDetailComponent` 会把英雄实例的*数据模型*传给所注入进来的 `HeroService` 的一个方法来进行保存。", + "key": "WHENTHEUSERSUBMITSTHEFORMTHEHERODETAILCOMPONENTWILLPASSANINSTANCEOFTHEHERODATAMODELTOASAVEMETHODONTHEINJECTEDHEROSERVICEADDTHEFOLLOWINGTOHERODETAILCOMPONENT", + "original": "When the user submits the form,\nthe `HeroDetailComponent` will pass an instance of the hero _data model_\nto a save method on the injected `HeroService`. Add the following to `HeroDetailComponent`.", + "translation": "当用户提交表单时,`HeroDetailComponent` 会把英雄实例的*数据模型*传给所注入进来的 `HeroService` 的一个方法来进行保存。\n在 `HeroDetailComponent` 中添加如下内容:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "This original `hero` had the pre-save values. The user's changes are still in the _form model_.\nSo you create a new `hero` from a combination of original hero values (the `hero.id`)\nand deep copies of the changed form model values, using the `prepareSaveHero` helper.", - "translation": "原始的 `hero` 中有一些保存之前的值,用户的修改仍然是在*表单模型*中。\n所以你要根据原始英雄(根据 `hero.id` 找到它)的值组合出一个新的 `hero` 对象,并用 `prepareSaveHero` 助手来深层复制变化后的模型值。", + "key": "THISORIGINALHEROHADTHEPRESAVEVALUESTHEUSERSCHANGESARESTILLINTHEFORMMODELSOYOUCREATEANEWHEROFROMACOMBINATIONOFORIGINALHEROVALUESTHEHEROIDANDDEEPCOPIESOFTHECHANGEDFORMMODELVALUESUSINGTHEPREPARESAVEHEROHELPER", + "original": "This original `hero` had the pre-save values. The user's changes are still in the _form model_.\nSo you create a new `hero` from a combination of original hero values (the `hero.id`)\nand deep copies of the changed form model values, using the `prepareSaveHero()` helper.", + "translation": "原始的 `hero` 中有一些保存之前的值,用户的修改仍然是在*表单模型*中。\n所以你要根据原始英雄(根据 `hero.id` 找到它)的值组合出一个新的 `hero` 对象,并用 `prepareSaveHero()` 助手来深层复制变化后的模型值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "MAKESURETOIMPORTHEROSERVICEANDADDITTOTHECONSTRUCTOR:", + "original": "Make sure to import `HeroService` and add it to the constructor:", + "translation": "确保导入了 `HeroService` 并把它加入了构造函数中:", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" + }, + { + "key": "ADDRESSDEEPCOPY", "original": "**Address deep copy**", "translation": "**地址的深层复制**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "HADYOUASSIGNEDTHEFORMMODELSECRETLAIRSTOSAVEHEROADDRESSESSEELINECOMMENTEDOUTTHEADDRESSESINSAVEHEROADDRESSESARRAYWOULDBETHESAMEOBJECTSASTHELAIRSINTHEFORMMODELSECRETLAIRSAUSERSSUBSEQUENTCHANGESTOALAIRSTREETWOULDMUTATEANADDRESSSTREETINTHESAVEHERO", "original": "Had you assigned the `formModel.secretLairs` to `saveHero.addresses` (see line commented out),\nthe addresses in `saveHero.addresses` array would be the same objects\nas the lairs in the `formModel.secretLairs`.\nA user's subsequent changes to a lair street would mutate an address street in the `saveHero`.", "translation": "你已经把 `formModel.secretLairs` 赋值给了 `saveHero.addresses`(参见注释掉的部分),\n`saveHero.addresses` 数组中的地址和 `formModel.secretLairs` 中的会是同一个对象。\n用户随后对小屋所在街道的修改将会改变 `saveHero` 中的街道地址。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEPREPARESAVEHEROMETHODMAKESCOPIESOFTHEFORMMODELSSECRETLAIRSOBJECTSSOTHATCANTHAPPEN", "original": "The `prepareSaveHero` method makes copies of the form model's `secretLairs` objects so that can't happen.", "translation": "但 `prepareSaveHero` 方法会制作表单模型中的 `secretLairs` 对象的复本,因此实际上并没有修改原有对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###REVERTCANCELCHANGES", "original": "### Revert (cancel changes)", "translation": "### 丢弃(撤销修改)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "The user cancels changes and reverts the form to the original state by pressing the _Revert_ button.", + "key": "THEUSERCANCELSCHANGESANDREVERTSTHEFORMTOTHEORIGINALSTATEBYPRESSINGTHEREVERTBUTTON", + "original": "The user cancels changes and reverts the form to the original state by pressing the Revert button.", "translation": "用户可以撤销修改,并通过点击 *Revert* 按钮来把表单恢复到原始状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "Reverting is easy. Simply re-execute the `ngOnChanges` method that built the _form model_ from the original, unchanged `hero` _data model_.", - "translation": "丢弃很容易。只要重新执行 `ngOnChanges` 方法就可以拆而,它会重新从原始的、未修改过的 `hero` 数据模型来构建出*表单模型*。", + "key": "REVERTINGISEASYSIMPLYREEXECUTETHEREBUILDFORMMETHODTHATBUILTTHEFORMMODELFROMTHEORIGINALUNCHANGEDHERODATAMODEL", + "original": "Reverting is easy. Simply re-execute the `rebuildForm()` method that built the form model from the original, unchanged `hero` data model.", + "translation": "丢弃很容易。只要重新执行 `rebuildForm()` 方法就可以根据原始的、未修改过的 `hero` 数据模型重新构建出表单模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "###BUTTONS", "original": "### Buttons", "translation": "### 按钮", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "ADDTHESAVEANDREVERTBUTTONSNEARTHETOPOFTHECOMPONENTSTEMPLATE:", "original": "Add the \"Save\" and \"Revert\" buttons near the top of the component's template:", "translation": "把“Save”和“Revert”按钮添加到组件模板的顶部:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "THEBUTTONSAREDISABLEDUNTILTHEUSERDIRTIESTHEFORMBYCHANGINGAVALUEINANYOFITSFORMCONTROLSHEROFORMDIRTY", "original": "The buttons are disabled until the user \"dirties\" the form by changing a value in any of its form controls (`heroForm.dirty`).", "translation": "这些按钮默认是禁用的,直到用户通过修改任何一个表单控件的值“弄脏”了表单中的数据(即 `heroForm.dirty`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "CLICKINGABUTTONOFTYPESUBMITTRIGGERSTHENGSUBMITEVENTWHICHCALLSTHECOMPONENTSONSUBMITMETHODCLICKINGTHEREVERTBUTTONTRIGGERSACALLTOTHECOMPONENTSREVERTMETHODUSERSNOWCANSAVEORREVERTCHANGES", "original": "Clicking a button of type `\"submit\"` triggers the `ngSubmit` event which calls the component's `onSubmit` method.\nClicking the revert button triggers a call to the component's `revert` method.\nUsers now can save or revert changes.", "translation": "点击一个类型为 `\"submit\"` 的按钮会触发 `ngSubmit` 事件,而它会调用组件的 `onSubmit` 方法。\n点击“Revert”按钮则会调用组件的 `revert` 方法。\n现在,用户可以保存或放弃修改了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { - "original": "This is the final step in the demo.\nTry the <live-example stackblitz=\"final\" title=\"Reactive Forms (final) in Stackblitz\"></live-example>.", - "translation": "这是本演示的最后一步。\n去试试<live-example stackblitz=\"final\" title=\"Reactive Forms (final) in Stackblitz\"></live-example>吧。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "## Summary", - "translation": "## 小结", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "* How to create a reactive form component and its corresponding template.", - "translation": "如何创建一个响应式表单控件及其对应的模板。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "* How to use `FormBuilder` to simplify coding a reactive form.", - "translation": "如何使用 `FormBuilder` 来简化响应式表单的编码工作。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "* Grouping `FormControls`.", - "translation": "分组 `FormControl`。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "* Inspecting `FormControl` properties.", - "translation": "审查 `FormControl` 的属性。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "* Setting data with `patchValue` and `setValue`.", - "translation": "使用 `patchValue` 和 `setValue` 设置数据。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "* Adding groups dynamically with `FormArray`.", - "translation": "使用 `FormArray` 动态添加控件组。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "* Observing changes to the value of a `FormControl`.", - "translation": "监听 `FormControl` 中值的变化。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { - "original": "* Saving form changes.", - "translation": "保存表单中的更改。", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" - }, - { + "key": "THEKEYFILESOFTHEFINALVERSIONAREASFOLLOWS:", "original": "The key files of the final version are as follows:", "translation": "最终版中的核心文件如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "YOUCANDOWNLOADTHECOMPLETESOURCEFORALLSTEPSINTHISGUIDEFROMTHELIVEEXAMPLETITLEREACTIVEFORMSDEMOINSTACKBLITZREACTIVEFORMSDEMOLIVEEXAMPLELIVEEXAMPLE", "original": "You can download the complete source for all steps in this guide\nfrom the <live-example title=\"Reactive Forms Demo in Stackblitz\">Reactive Forms Demo</live-example> live example.", "translation": "你可以到<live-example title=\"Reactive Forms Demo in Stackblitz\">响应式表单在线例子</live-example>中下载本章所有步骤的完整代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/reactive-forms.md" }, { + "key": "#ROUTINGNAVIGATION", "original": "# Routing & Navigation", "translation": "# 路由与导航", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEANGULARROUTERENABLESNAVIGATIONFROMONEVIEWGUIDEGLOSSARY#VIEWTOTHENEXTASUSERSPERFORMAPPLICATIONTASKS", "original": "The Angular **`Router`** enables navigation from one [view](guide/glossary#view) to the next\nas users perform application tasks.", "translation": "在用户使用应用程序时,Angular 的***路由器***能让用户从一个[视图](guide/glossary#view)导航到另一个视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISGUIDECOVERSTHEROUTERSPRIMARYFEATURESILLUSTRATINGTHEMTHROUGHTHEEVOLUTIONOFASMALLAPPLICATIONTHATYOUCANLIVEEXAMPLERUNLIVEINTHEBROWSERLIVEEXAMPLE", "original": "This guide covers the router's primary features, illustrating them through the evolution\nof a small application that you can <live-example>run live in the browser</live-example>.", "translation": "本章涵盖了该路由器的主要特性,通过一个小型应用的成长演进来讲解它。参见<live-example></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##OVERVIEW", "original": "## Overview", "translation": "## 概览", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEBROWSERISAFAMILIARMODELOFAPPLICATIONNAVIGATION:", "original": "The browser is a familiar model of application navigation:", "translation": "浏览器具有熟悉的导航模式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ENTERAURLINTHEADDRESSBARANDTHEBROWSERNAVIGATESTOACORRESPONDINGPAGE", "original": "* Enter a URL in the address bar and the browser navigates to a corresponding page.", "translation": "在地址栏输入 URL,浏览器就会导航到相应的页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CLICKLINKSONTHEPAGEANDTHEBROWSERNAVIGATESTOANEWPAGE", "original": "* Click links on the page and the browser navigates to a new page.", "translation": "在页面中点击链接,浏览器就会导航到一个新页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CLICKTHEBROWSERSBACKANDFORWARDBUTTONSANDTHEBROWSERNAVIGATESBACKWARDANDFORWARDTHROUGHTHEHISTORYOFPAGESYOUVESEEN", "original": "* Click the browser's back and forward buttons and the browser navigates\n backward and forward through the history of pages you've seen.", "translation": "点击浏览器的前进和后退按钮,浏览器就会在你的浏览历史中向前或向后导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEANGULARROUTERTHEROUTERBORROWSFROMTHISMODELITCANINTERPRETABROWSERURLASANINSTRUCTIONTONAVIGATETOACLIENTGENERATEDVIEWITCANPASSOPTIONALPARAMETERSALONGTOTHESUPPORTINGVIEWCOMPONENTTHATHELPITDECIDEWHATSPECIFICCONTENTTOPRESENTYOUCANBINDTHEROUTERTOLINKSONAPAGEANDITWILLNAVIGATETOTHEAPPROPRIATEAPPLICATIONVIEWWHENTHEUSERCLICKSALINKYOUCANNAVIGATEIMPERATIVELYWHENTHEUSERCLICKSABUTTONSELECTSFROMADROPBOXORINRESPONSETOSOMEOTHERSTIMULUSFROMANYSOURCEANDTHEROUTERLOGSACTIVITYINTHEBROWSERSHISTORYJOURNALSOTHEBACKANDFORWARDBUTTONSWORKASWELL", "original": "The Angular `Router` (\"the router\") borrows from this model.\nIt can interpret a browser URL as an instruction to navigate to a client-generated view.\nIt can pass optional parameters along to the supporting view component that help it decide what specific content to present.\nYou can bind the router to links on a page and it will navigate to\nthe appropriate application view when the user clicks a link.\nYou can navigate imperatively when the user clicks a button, selects from a drop box,\nor in response to some other stimulus from any source. And the router logs activity\nin the browser's history journal so the back and forward buttons work as well.", "translation": "Angular 的 `Router`(即“路由器”)借鉴了这个模型。它把浏览器中的 URL 看做一个操作指南,\n 据此导航到一个由客户端生成的视图,并可以把参数传给支撑视图的相应组件,帮它决定具体该展现哪些内容。\n 你可以为页面中的链接绑定一个路由,这样,当用户点击链接时,就会导航到应用中相应的视图。\n 当用户点击按钮、从下拉框中选取,或响应来自任何地方的事件时,你也可以在代码控制下进行导航。\n 路由器还在浏览器的历史日志中记录下这些活动,这样浏览器的前进和后退按钮也能照常工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##THEBASICS", "original": "## The Basics", "translation": "## 基础知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISGUIDEPROCEEDSINPHASESMARKEDBYMILESTONESSTARTINGFROMASIMPLETWOPAGERANDBUILDINGTOWARDAMODULARMULTIVIEWDESIGNWITHCHILDROUTES", "original": "This guide proceeds in phases, marked by milestones, starting from a simple two-pager\nand building toward a modular, multi-view design with child routes.", "translation": "本章包括一系列里程碑,从一个单模块、两个页面的简单程序逐步走向带有多个子路由的多视图设计。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANINTRODUCTIONTOAFEWCOREROUTERCONCEPTSWILLHELPORIENTYOUTOTHEDETAILSTHATFOLLOW", "original": "An introduction to a few core router concepts will help orient you to the details that follow.", "translation": "先对路由的一些核心概念做一个介绍,它能帮你逐步过渡到细节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###LTBASEHREF", "original": "### *<base href>*", "translation": "### *<base href>* 元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MOSTROUTINGAPPLICATIONSSHOULDADDABASEELEMENTTOTHEINDEXHTMLASTHEFIRSTCHILDINTHEHEADTAGTOTELLTHEROUTERHOWTOCOMPOSENAVIGATIONURLS", "original": "Most routing applications should add a `<base>` element to the `index.html` as the first child in the `<head>` tag\nto tell the router how to compose navigation URLs.", "translation": "大多数带路由的应用都要在**`index.html`**的 `<head>` 标签下先添加一个 `<base>` 元素,来告诉路由器该如何合成导航用的 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFTHEAPPFOLDERISTHEAPPLICATIONROOTASITISFORTHESAMPLEAPPLICATIONSETTHEHREFVALUEEXACTLYASSHOWNHERE", "original": "If the `app` folder is the application root, as it is for the sample application,\nset the `href` value *exactly* as shown here.", "translation": "如果 `app` 文件夹是该应用的根目录(就像范例应用中一样),那就把 `href` 的值设置为下面这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTERIMPORTS", "original": "### Router imports", "translation": "### 从路由库中导入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEANGULARROUTERISANOPTIONALSERVICETHATPRESENTSAPARTICULARCOMPONENTVIEWFORAGIVENURLITISNOTPARTOFTHEANGULARCOREITISINITSOWNLIBRARYPACKAGEANGULARROUTERIMPORTWHATYOUNEEDFROMITASYOUWOULDFROMANYOTHERANGULARPACKAGE", "original": "The Angular Router is an optional service that presents a particular component view for a given URL.\nIt is not part of the Angular core. It is in its own library package, `@angular/router`.\nImport what you need from it as you would from any other Angular package.", "translation": "Angular 的路由器是一个可选的服务,它用来呈现指定的 URL 所对应的视图。\n它并不是 Angular 核心库的一部分,而是在它自己的 `@angular/router` 包中。\n像其它 Angular 包一样,你可以从它导入所需的一切。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOULLLEARNABOUTMOREOPTIONSINTHEDETAILSBELOW#BROWSERURLSTYLES", "original": "You'll learn about more options in the [details below](#browser-url-styles).", "translation": "你将会在[后面](guide/router#browser-url-styles)学到更多选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CONFIGURATION", "original": "### Configuration", "translation": "### 配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AROUTEDANGULARAPPLICATIONHASONESINGLETONINSTANCEOFTHEROUTERSERVICEWHENTHEBROWSERSURLCHANGESTHATROUTERLOOKSFORACORRESPONDINGROUTEFROMWHICHITCANDETERMINETHECOMPONENTTODISPLAY", "original": "A routed Angular application has one singleton instance of the *`Router`* service.\nWhen the browser's URL changes, that router looks for a corresponding `Route`\nfrom which it can determine the component to display.", "translation": "每个带路由的 Angular 应用都有一个*`Router`(路由器)*服务的单例对象。\n当浏览器的 URL 变化时,路由器会查找对应的 `Route`(路由),并据此决定该显示哪个组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AROUTERHASNOROUTESUNTILYOUCONFIGUREITTHEFOLLOWINGEXAMPLECREATESFOURROUTEDEFINITIONSCONFIGURESTHEROUTERVIATHEROUTERMODULEFORROOTMETHODANDADDSTHERESULTTOTHEAPPMODULESIMPORTSARRAY", "original": "A router has no routes until you configure it.\nThe following example creates four route definitions, configures the router via the `RouterModule.forRoot` method,\nand adds the result to the `AppModule`'s `imports` array.", "translation": "路由器需要先配置才会有路由信息。\n下面的例子创建了四个路由定义,并用 `RouterModule.forRoot` 方法来配置路由器,\n并把它的返回值添加到 `AppModule` 的 `imports` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPROUTESARRAYOFROUTESDESCRIBESHOWTONAVIGATEPASSITTOTHEROUTERMODULEFORROOTMETHODINTHEMODULEIMPORTSTOCONFIGURETHEROUTER", "original": "The `appRoutes` array of *routes* describes how to navigate.\nPass it to the `RouterModule.forRoot` method in the module `imports` to configure the router.", "translation": "这里的路由数组 `appRoutes` 描述如何进行导航。\n把它传给 `RouterModule.forRoot` 方法并传给本模块的 `imports` 数组就可以配置路由器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHROUTEMAPSAURLPATHTOACOMPONENTTHEREARENOLEADINGSLASHESINTHEPATHTHEROUTERPARSESANDBUILDSTHEFINALURLFORYOUALLOWINGYOUTOUSEBOTHRELATIVEANDABSOLUTEPATHSWHENNAVIGATINGBETWEENAPPLICATIONVIEWS", "original": "Each `Route` maps a URL `path` to a component.\nThere are _no leading slashes_ in the _path_.\nThe router parses and builds the final URL for you,\nallowing you to use both relative and absolute paths when navigating between application views.", "translation": "每个 `Route` 都会把一个 URL 的 `path` 映射到一个组件。\n注意,`path` 不能以*斜杠(`/`)*开头。\n路由器会为解析和构建最终的 URL,这样当你在应用的多个视图之间导航时,可以任意使用相对路径和绝对路径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THE:IDINTHESECONDROUTEISATOKENFORAROUTEPARAMETERINAURLSUCHASHERO4242ISTHEVALUEOFTHEIDPARAMETERTHECORRESPONDINGHERODETAILCOMPONENTWILLUSETHATVALUETOFINDANDPRESENTTHEHEROWHOSEIDIS42YOULLLEARNMOREABOUTROUTEPARAMETERSLATERINTHISGUIDE", "original": "The `:id` in the second route is a token for a route parameter. In a URL such as `/hero/42`, \"42\"\nis the value of the `id` parameter. The corresponding `HeroDetailComponent`\nwill use that value to find and present the hero whose `id` is 42.\nYou'll learn more about route parameters later in this guide.", "translation": "第二个路由中的 `:id` 是一个路由参数的令牌(Token)。比如 `/hero/42` 这个 URL 中,“42”就是 `id` 参数的值。\n此 URL 对应的 `HeroDetailComponent` 组件将据此查找和展现 `id` 为 42 的英雄。\n在本章中稍后的部分,你将会学习关于路由参数的更多知识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEDATAPROPERTYINTHETHIRDROUTEISAPLACETOSTOREARBITRARYDATAASSOCIATEDWITHTHISSPECIFICROUTETHEDATAPROPERTYISACCESSIBLEWITHINEACHACTIVATEDROUTEUSEITTOSTOREITEMSSUCHASPAGETITLESBREADCRUMBTEXTANDOTHERREADONLYSTATICDATAYOULLUSETHERESOLVEGUARD#RESOLVEGUARDTORETRIEVEDYNAMICDATALATERINTHEGUIDE", "original": "The `data` property in the third route is a place to store arbitrary data associated with\nthis specific route. The data property is accessible within each activated route. Use it to store\nitems such as page titles, breadcrumb text, and other read-only, _static_ data.\nYou'll use the [resolve guard](#resolve-guard) to retrieve _dynamic_ data later in the guide.", "translation": "第三个路由中的 `data` 属性用来存放于每个具体路由有关的任意信息。该数据可以被任何一个激活路由访问,并能用来保存诸如\n页标题、面包屑以及其它静态只读数据。本章稍后的部分,你将使用[resolve 守卫](guide/router#resolve-guard)来获取动态数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEEMPTYPATHINTHEFOURTHROUTEREPRESENTSTHEDEFAULTPATHFORTHEAPPLICATIONTHEPLACETOGOWHENTHEPATHINTHEURLISEMPTYASITTYPICALLYISATTHESTARTTHISDEFAULTROUTEREDIRECTSTOTHEROUTEFORTHEHEROESURLANDTHEREFOREWILLDISPLAYTHEHEROESLISTCOMPONENT", "original": "The **empty path** in the fourth route represents the default path for the application,\nthe place to go when the path in the URL is empty, as it typically is at the start.\nThis default route redirects to the route for the `/heroes` URL and, therefore, will display the `HeroesListComponent`.", "translation": "第四个路由中的空路径(`''`)表示应用的默认路径,当 URL 为空时就会访问那里,因此它通常会作为起点。\n这个默认路由会重定向到 URL `/heroes`,并显示 `HeroesListComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPATHINTHELASTROUTEISAWILDCARDTHEROUTERWILLSELECTTHISROUTEIFTHEREQUESTEDURLDOESNTMATCHANYPATHSFORROUTESDEFINEDEARLIERINTHECONFIGURATIONTHISISUSEFULFORDISPLAYINGA404NOTFOUNDPAGEORREDIRECTINGTOANOTHERROUTE", "original": "The `**` path in the last route is a **wildcard**. The router will select this route\nif the requested URL doesn't match any paths for routes defined earlier in the configuration.\nThis is useful for displaying a \"404 - Not Found\" page or redirecting to another route.", "translation": "最后一个路由中的 `**` 路径是一个**通配符**。当所请求的 URL 不匹配前面定义的路由表中的任何路径时,路由器就会选择此路由。\n这个特性可用于显示“404 - Not Found”页,或自动重定向到其它路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEORDEROFTHEROUTESINTHECONFIGURATIONMATTERSANDTHISISBYDESIGNTHEROUTERUSESAFIRSTMATCHWINSSTRATEGYWHENMATCHINGROUTESSOMORESPECIFICROUTESSHOULDBEPLACEDABOVELESSSPECIFICROUTESINTHECONFIGURATIONABOVEROUTESWITHASTATICPATHARELISTEDFIRSTFOLLOWEDBYANEMPTYPATHROUTETHATMATCHESTHEDEFAULTROUTETHEWILDCARDROUTECOMESLASTBECAUSEITMATCHESEVERYURLANDSHOULDBESELECTEDONLYIFNOOTHERROUTESAREMATCHEDFIRST", "original": "**The order of the routes in the configuration matters** and this is by design. The router uses a **first-match wins**\nstrategy when matching routes, so more specific routes should be placed above less specific routes.\nIn the configuration above, routes with a static path are listed first, followed by an empty path route,\nthat matches the default route.\nThe wildcard route comes last because it matches _every URL_ and should be selected _only_ if no other routes are matched first.", "translation": "**这些路由的定义顺序**是刻意如此设计的。路由器使用**先匹配者优先**的策略来匹配路由,所以,具体路由应该放在通用路由的前面。在上面的配置中,带静态路径的路由被放在了前面,后面是空路径路由,因此它会作为默认路由。而通配符路由被放在最后面,这是因为它能匹配上*每一个 URL*,因此应该**只有在**前面找不到其它能匹配的路由时才匹配它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFYOUNEEDTOSEEWHATEVENTSAREHAPPENINGDURINGTHENAVIGATIONLIFECYCLETHEREISTHEENABLETRACINGOPTIONASPARTOFTHEROUTERSDEFAULTCONFIGURATIONTHISOUTPUTSEACHROUTEREVENTTHATTOOKPLACEDURINGEACHNAVIGATIONLIFECYCLETOTHEBROWSERCONSOLETHISSHOULDONLYBEUSEDFORDEBUGGINGPURPOSESYOUSETTHEENABLETRACING:TRUEOPTIONINTHEOBJECTPASSEDASTHESECONDARGUMENTTOTHEROUTERMODULEFORROOTMETHOD", "original": "If you need to see what events are happening during the navigation lifecycle, there is the **enableTracing** option as part of the router's default configuration. This outputs each router event that took place during each navigation lifecycle to the browser console. This should only be used for _debugging_ purposes. You set the `enableTracing: true` option in the object passed as the second argument to the `RouterModule.forRoot()` method.", "translation": "如果你想要看到在导航的生命周期中发生过哪些事件,可以使用路由器默认配置中的 **enableTracing** 选项。它会把每个导航生命周期中的事件输出到浏览器的控制台。\n这应该只用于*调试*。你只需要把 `enableTracing: true` 选项作为第二个参数传给 `RouterModule.forRoot()` 方法就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTEROUTLET", "original": "### Router outlet", "translation": "### 路由出口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "GIVENTHISCONFIGURATIONWHENTHEBROWSERURLFORTHISAPPLICATIONBECOMESHEROESTHEROUTERMATCHESTHATURLTOTHEROUTEPATHHEROESANDDISPLAYSTHEHEROLISTCOMPONENTAFTERAROUTEROUTLETTHATYOUVEPLACEDINTHEHOSTVIEWSHTML", "original": "Given this configuration, when the browser URL for this application becomes `/heroes`,\nthe router matches that URL to the route path `/heroes` and displays the `HeroListComponent`\n_after_ a `RouterOutlet` that you've placed in the host view's HTML.", "translation": "有了这份配置,当本应用在浏览器中的 URL 变为 `/heroes` 时,路由器就会匹配到 `path` 为 `heroes` 的 `Route`,并在宿主视图中的*`RouterOutlet`*之后显示 `HeroListComponent` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTERLINKS", "original": "### Router links", "translation": "### 路由器链接", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWYOUHAVEROUTESCONFIGUREDANDAPLACETORENDERTHEMBUTHOWDOYOUNAVIGATETHEURLCOULDARRIVEDIRECTLYFROMTHEBROWSERADDRESSBARBUTMOSTOFTHETIMEYOUNAVIGATEASARESULTOFSOMEUSERACTIONSUCHASTHECLICKOFANANCHORTAG", "original": "Now you have routes configured and a place to render them, but\nhow do you navigate? The URL could arrive directly from the browser address bar.\nBut most of the time you navigate as a result of some user action such as the click of\nan anchor tag.", "translation": "现在,你已经有了配置好的一些路由,还找到了渲染它们的地方,但又该如何导航到它呢?固然,从浏览器的地址栏直接输入 URL 也能做到,但是大多数情况下,导航是某些用户操作的结果,比如点击一个 A 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CONSIDERTHEFOLLOWINGTEMPLATE:", "original": "Consider the following template:", "translation": "考虑下列模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERLINKDIRECTIVESONTHEANCHORTAGSGIVETHEROUTERCONTROLOVERTHOSEELEMENTSTHENAVIGATIONPATHSAREFIXEDSOYOUCANASSIGNASTRINGTOTHEROUTERLINKAONETIMEBINDING", "original": "The `RouterLink` directives on the anchor tags give the router control over those elements.\nThe navigation paths are fixed, so you can assign a string to the `routerLink` (a \"one-time\" binding).", "translation": "`a` 标签上的 `RouterLink` 指令让路由器得以控制这个 `a` 元素。\n这里的导航路径是固定的,因此可以把一个字符串赋给 `routerLink`(“一次性”绑定)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HADTHENAVIGATIONPATHBEENMOREDYNAMICYOUCOULDHAVEBOUNDTOATEMPLATEEXPRESSIONTHATRETURNEDANARRAYOFROUTELINKPARAMETERSTHELINKPARAMETERSARRAYTHEROUTERRESOLVESTHATARRAYINTOACOMPLETEURL", "original": "Had the navigation path been more dynamic, you could have bound to a template expression that\nreturned an array of route link parameters (the _link parameters array_).\nThe router resolves that array into a complete URL.", "translation": "如果需要更加动态的导航路径,那就把它绑定到一个返回*链接参数数组*的模板表达式。\n路由器会把这个数组解析成完整的 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERLINKACTIVEDIRECTIVEONEACHANCHORTAGHELPSVISUALLYDISTINGUISHTHEANCHORFORTHECURRENTLYSELECTEDACTIVEROUTETHEROUTERADDSTHEACTIVECSSCLASSTOTHEELEMENTWHENTHEASSOCIATEDROUTERLINKBECOMESACTIVEYOUCANADDTHISDIRECTIVETOTHEANCHORORTOITSPARENTELEMENT", "original": "The **`RouterLinkActive`** directive on each anchor tag helps visually distinguish the anchor for the currently selected \"active\" route.\nThe router adds the `active` CSS class to the element when the associated *RouterLink* becomes active.\nYou can add this directive to the anchor or to its parent element.", "translation": "每个 `a` 标签上的**`RouterLinkActive`**指令可以帮用户在外观上区分出当前选中的“活动”路由。\n当与它关联的 *RouterLink* 被激活时,路由器会把 CSS 类 `active` 添加到这个元素上。\n你可以把该指令添加到 `a` 元素或它的父元素上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTERSTATE", "original": "### Router state", "translation": "### 路由器状态", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AFTERTHEENDOFEACHSUCCESSFULNAVIGATIONLIFECYCLETHEROUTERBUILDSATREEOFACTIVATEDROUTEOBJECTSTHATMAKEUPTHECURRENTSTATEOFTHEROUTERYOUCANACCESSTHECURRENTROUTERSTATEFROMANYWHEREINTHEAPPLICATIONUSINGTHEROUTERSERVICEANDTHEROUTERSTATEPROPERTY", "original": "After the end of each successful navigation lifecycle, the router builds a tree of `ActivatedRoute` objects\nthat make up the current state of the router. You can access the current `RouterState` from anywhere in the\napplication using the `Router` service and the `routerState` property.", "translation": "在导航时的每个生命周期成功完成时,路由器会构建出一个 `ActivatedRoute` 组成的树,它表示路由器的当前状态。\n你可以在应用中的任何地方用 `Router` 服务及其 `routerState` 属性来访问当前的 `RouterState` 值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHACTIVATEDROUTEINTHEROUTERSTATEPROVIDESMETHODSTOTRAVERSEUPANDDOWNTHEROUTETREETOGETINFORMATIONFROMPARENTCHILDANDSIBLINGROUTES", "original": "Each `ActivatedRoute` in the `RouterState` provides methods to traverse up and down the route tree\nto get information from parent, child and sibling routes.", "translation": "`RouterState` 中的每个 `ActivatedRoute` 都提供了从任意激活路由开始向上或向下遍历路由树的一种方式,以获得关于父、子、兄弟路由的信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ACTIVATEDROUTE", "original": "### Activated route", "translation": "### 激活的路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTEPATHANDPARAMETERSAREAVAILABLETHROUGHANINJECTEDROUTERSERVICECALLEDTHEACTIVATEDROUTEAPIROUTERACTIVATEDROUTEITHASAGREATDEALOFUSEFULINFORMATIONINCLUDING:", "original": "The route path and parameters are available through an injected router service called the\n[ActivatedRoute](api/router/ActivatedRoute).\nIt has a great deal of useful information including:", "translation": "该路由的路径和参数可以通过注入进来的一个名叫[ActivatedRoute](api/router/ActivatedRoute)的路由服务来获取。\n它有一大堆有用的信息,包括:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PROPERTY", "original": "Property", "translation": "属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANOBSERVABLEOFTHEROUTEPATHSREPRESENTEDASANARRAYOFSTRINGSFOREACHPARTOFTHEROUTEPATH", "original": "An `Observable` of the route path(s), represented as an array of strings for each part of the route path.", "translation": "路由路径的 `Observable` 对象,是一个由路由路径中的各个部分组成的字符串数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANOBSERVABLETHATCONTAINSTHEDATAOBJECTPROVIDEDFORTHEROUTEALSOCONTAINSANYRESOLVEDVALUESFROMTHERESOLVEGUARD#RESOLVEGUARD", "original": "An `Observable` that contains the `data` object provided for the route. Also contains any resolved values from the [resolve guard](#resolve-guard).", "translation": "一个 `Observable`,其中包含提供给路由的 `data` 对象。也包含由[解析守卫(resolve guard)](#resolve-guard)解析而来的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANOBSERVABLETHATCONTAINSAMAPAPIROUTERPARAMMAPOFTHEREQUIREDANDOPTIONALPARAMETERS#OPTIONALROUTEPARAMETERSSPECIFICTOTHEROUTETHEMAPSUPPORTSRETRIEVINGSINGLEANDMULTIPLEVALUESFROMTHESAMEPARAMETER", "original": "An `Observable` that contains a [map](api/router/ParamMap) of the required and [optional parameters](#optional-route-parameters) specific to the route. The map supports retrieving single and multiple values from the same parameter.", "translation": "一个 `Observable`,其中包含一个由当前路由的必要参数和[可选参数](#optional-route-parameters)组成的[map](api/router/ParamMap)对象。用这个 map 可以获取来自同名参数的单一值或多重值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANOBSERVABLETHATCONTAINSAMAPAPIROUTERPARAMMAPOFTHEQUERYPARAMETERS#QUERYPARAMETERSAVAILABLETOALLROUTESTHEMAPSUPPORTSRETRIEVINGSINGLEANDMULTIPLEVALUESFROMTHEQUERYPARAMETER", "original": "An `Observable` that contains a [map](api/router/ParamMap) of the [query parameters](#query-parameters) available to all routes.\n The map supports retrieving single and multiple values from the query parameter.", "translation": "一个 `Observable`,其中包含一个对所有路由都有效的[查询参数](#query-parameters)组成的[map](api/router/ParamMap)对象。\n 用这个 map 可以获取来自查询参数的单一值或多重值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANOBSERVABLEOFTHEURLFRAGMENT#FRAGMENTAVAILABLETOALLROUTES", "original": "An `Observable` of the URL [fragment](#fragment) available to all routes.", "translation": "一个适用于所有路由的 URL 的 [fragment(片段)](#fragment)的 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THENAMEOFTHEROUTEROUTLETUSEDTORENDERTHEROUTEFORANUNNAMEDOUTLETTHEOUTLETNAMEISPRIMARY", "original": "The name of the `RouterOutlet` used to render the route. For an unnamed outlet, the outlet name is _primary_.", "translation": "要把该路由渲染到的 `RouterOutlet` 的名字。对于无名路由,它的路由名是 `primary`,而不是空串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTECONFIGURATIONUSEDFORTHEROUTETHATCONTAINSTHEORIGINPATH", "original": "The route configuration used for the route that contains the origin path.", "translation": "用于该路由的路由配置信息,其中包含原始路径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTESPARENTACTIVATEDROUTEWHENTHISROUTEISACHILDROUTE#CHILDROUTINGCOMPONENT", "original": "The route's parent `ActivatedRoute` when this route is a [child route](#child-routing-component).", "translation": "当该路由是一个[子路由](#child-routing-component)时,表示该路由的父级 `ActivatedRoute`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CONTAINSTHEFIRSTACTIVATEDROUTEINTHELISTOFTHISROUTESCHILDROUTES", "original": "Contains the first `ActivatedRoute` in the list of this route's child routes.", "translation": "包含该路由的子路由列表中的第一个 `ActivatedRoute`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CONTAINSALLTHECHILDROUTES#CHILDROUTINGCOMPONENTACTIVATEDUNDERTHECURRENTROUTE", "original": "Contains all the [child routes](#child-routing-component) activated under the current route.", "translation": "包含当前路由下所有已激活的[子路由](#child-routing-component)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TWOOLDERPROPERTIESARESTILLAVAILABLETHEYARELESSCAPABLETHANTHEIRREPLACEMENTSDISCOURAGEDANDMAYBEDEPRECATEDINAFUTUREANGULARVERSION", "original": "Two older properties are still available. They are less capable than their replacements, discouraged, and may be deprecated in a future Angular version.", "translation": "有两个旧式属性仍然是有效的,但它们不如其替代品那样强力,建议不再用它们,它们还将在未来的 Angular 版本中废弃。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PARAMSMDASHANOBSERVABLETHATCONTAINSTHEREQUIREDANDOPTIONALPARAMETERS#OPTIONALROUTEPARAMETERSSPECIFICTOTHEROUTEUSEPARAMMAPINSTEAD", "original": "**`params`** — An `Observable` that contains the required and [optional parameters](#optional-route-parameters) specific to the route. Use `paramMap` instead.", "translation": "**`params`** —— 一个 `Observable` 对象,其中包含当前路由的必要参数和[可选参数](#optional-route-parameters)。请改用 `paramMap`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "QUERYPARAMSMDASHANOBSERVABLETHATCONTAINSTHEQUERYPARAMETERS#QUERYPARAMETERSAVAILABLETOALLROUTESUSEQUERYPARAMMAPINSTEAD", "original": "**`queryParams`** — An `Observable` that contains the [query parameters](#query-parameters) available to all routes.\nUse `queryParamMap` instead.", "translation": "**`queryParams`** —— 一个 `Observable` 对象,其中包含对所有路由都有效的[查询参数](#query-parameters)。请改用 `queryParamMap`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTEREVENTS", "original": "### Router events", "translation": "### 路由事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DURINGEACHNAVIGATIONTHEROUTEREMITSNAVIGATIONEVENTSTHROUGHTHEROUTEREVENTSPROPERTYTHESEEVENTSRANGEFROMWHENTHENAVIGATIONSTARTSANDENDSTOMANYPOINTSINBETWEENTHEFULLLISTOFNAVIGATIONEVENTSISDISPLAYEDINTHETABLEBELOW", "original": "During each navigation, the `Router` emits navigation events through the `Router.events` property. These events range from when the navigation starts and ends to many points in between. The full list of navigation events is displayed in the table below.", "translation": "在每次导航中,`Router` 都会通过 `Router.events` 属性发布一些导航事件。这些事件的范围涵盖了从开始导航到结束导航之间的很多时间点。下表中列出了全部导航事件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ROUTEREVENT", "original": "Router Event", "translation": "路由器事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANEVENTAPIROUTERNAVIGATIONSTARTTRIGGEREDWHENNAVIGATIONSTARTS", "original": "An [event](api/router/NavigationStart) triggered when navigation starts.", "translation": "本[事件](api/router/NavigationStart)会在导航开始时触发。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANEVENTAPIROUTERROUTESRECOGNIZEDTRIGGEREDWHENTHEROUTERPARSESTHEURLANDTHEROUTESARERECOGNIZED", "original": "An [event](api/router/RoutesRecognized) triggered when the Router parses the URL and the routes are recognized.", "translation": "本[事件](api/router/RoutesRecognized)会在路由器解析完 URL,并识别出了相应的路由时触发", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANEVENTAPIROUTERROUTECONFIGLOADSTARTTRIGGEREDBEFORETHEROUTERLAZYLOADS#ASYNCHRONOUSROUTINGAROUTECONFIGURATION", "original": "An [event](api/router/RouteConfigLoadStart) triggered before the `Router`\n [lazy loads](#asynchronous-routing) a route configuration.", "translation": "本[事件](api/router/RouteConfigLoadStart)会在 `Router` 对一个路由配置进行[惰性加载](#asynchronous-routing)之前触发。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANEVENTAPIROUTERROUTECONFIGLOADENDTRIGGEREDAFTERAROUTEHASBEENLAZYLOADED", "original": "An [event](api/router/RouteConfigLoadEnd) triggered after a route has been lazy loaded.", "translation": "本[事件](api/router/RouteConfigLoadEnd)会在路由被惰性加载之后触发。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANEVENTAPIROUTERNAVIGATIONENDTRIGGEREDWHENNAVIGATIONENDSSUCCESSFULLY", "original": "An [event](api/router/NavigationEnd) triggered when navigation ends successfully.", "translation": "本[事件](api/router/NavigationEnd)会在导航成功结束之后触发。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANEVENTAPIROUTERNAVIGATIONCANCELTRIGGEREDWHENNAVIGATIONISCANCELEDTHISISDUETOAROUTEGUARD#GUARDSRETURNINGFALSEDURINGNAVIGATION", "original": "An [event](api/router/NavigationCancel) triggered when navigation is canceled.\n This is due to a [Route Guard](#guards) returning false during navigation.", "translation": "本[事件](api/router/NavigationCancel)会在导航被取消之后触发。\n 这可能是因为在导航期间某个[路由守卫](#guards)返回了 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANEVENTAPIROUTERNAVIGATIONERRORTRIGGEREDWHENNAVIGATIONFAILSDUETOANUNEXPECTEDERROR", "original": "An [event](api/router/NavigationError) triggered when navigation fails due to an unexpected error.", "translation": "这个[事件](api/router/NavigationError)会在导航由于意料之外的错误而失败时触发。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESEEVENTSARELOGGEDTOTHECONSOLEWHENTHEENABLETRACINGOPTIONISENABLEDALSOSINCETHEEVENTSAREPROVIDEDASANOBSERVABLEYOUCANFILTERFOREVENTSOFINTERESTANDSUBSCRIBETOTHEMTOMAKEDECISIONSBASEDONTHESEQUENCEOFEVENTSINTHENAVIGATIONPROCESS", "original": "These events are logged to the console when the `enableTracing` option is enabled also. Since the events are provided as an `Observable`, you can `filter()` for events of interest and `subscribe()` to them to make decisions based on the sequence of events in the navigation process.", "translation": "当打开了 `enableTracing` 选项时,这些事件也同时会记录到控制台中。由于这些事件是以 `Observable` 的形式提供的,所以你可以对自己感兴趣的事件进行 `filter()`,并 `subscribe()` 它们,以便根据导航过程中的事件顺序做出决策。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###SUMMARY", "original": "### Summary", "translation": "### 总结一下", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPLICATIONHASACONFIGUREDROUTERTHESHELLCOMPONENTHASAROUTEROUTLETWHEREITCANDISPLAYVIEWSPRODUCEDBYTHEROUTERITHASROUTERLINKSTHATUSERSCANCLICKTONAVIGATEVIATHEROUTER", "original": "The application has a configured router.\nThe shell component has a `RouterOutlet` where it can display views produced by the router.\nIt has `RouterLink`s that users can click to navigate via the router.", "translation": "该应用有一个配置过的路由器。\n外壳组件中有一个 `RouterOutlet`,它能显示路由器所生成的视图。\n它还有一些 `RouterLink`,用户可以点击它们,来通过路由器进行导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HEREARETHEKEYROUTERTERMSANDTHEIRMEANINGS:", "original": "Here are the key `Router` terms and their meanings:", "translation": "下面是一些*路由器*中的关键词汇及其含义:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ROUTERPART", "original": "Router Part", "translation": "路由器部件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MEANING", "original": "Meaning", "translation": "含义", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CODEROUTERCODE", "original": "<code>Router</code>", "translation": "<code>Router</code>(路由器)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DISPLAYSTHEAPPLICATIONCOMPONENTFORTHEACTIVEURLMANAGESNAVIGATIONFROMONECOMPONENTTOTHENEXT", "original": "Displays the application component for the active URL.\n Manages navigation from one component to the next.", "translation": "为激活的 URL 显示应用组件。管理从一个组件到另一个组件的导航", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { - "original": "<code>RouterModule</code>", - "translation": "<code>RouterModule</code>(路由器模块)", - "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" - }, - { + "key": "ASEPARATENGMODULETHATPROVIDESTHENECESSARYSERVICEPROVIDERSANDDIRECTIVESFORNAVIGATINGTHROUGHAPPLICATIONVIEWS", "original": "A separate NgModule that provides the necessary service providers\n and directives for navigating through application views.", "translation": "一个独立的 Angular 模块,用于提供所需的服务提供商,以及用来在应用视图之间进行导航的指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CODEROUTESCODE", "original": "<code>Routes</code>", "translation": "<code>Routes</code>(路由数组)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DEFINESANARRAYOFROUTESEACHMAPPINGAURLPATHTOACOMPONENT", "original": "Defines an array of Routes, each mapping a URL path to a component.", "translation": "定义了一个路由数组,每一个都会把一个 URL 路径映射到一个组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CODEROUTECODE", "original": "<code>Route</code>", "translation": "<code>Route</code>(路由)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DEFINESHOWTHEROUTERSHOULDNAVIGATETOACOMPONENTBASEDONAURLPATTERNMOSTROUTESCONSISTOFAPATHANDACOMPONENTTYPE", "original": "Defines how the router should navigate to a component based on a URL pattern.\n Most routes consist of a path and a component type.", "translation": "定义路由器该如何根据 URL 模式(pattern)来导航到组件。大多数路由都由路径和组件类构成。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CODEROUTEROUTLETCODE", "original": "<code>RouterOutlet</code>", "translation": "<code>RouterOutlet</code>(路由出口)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEDIRECTIVECODELTROUTEROUTLETCODETHATMARKSWHERETHEROUTERDISPLAYSAVIEW", "original": "The directive (<code><router-outlet></code>) that marks where the router displays a view.", "translation": "该指令(<code><router-outlet></code>)用来标记出路由器该在哪里显示视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CODEROUTERLINKCODE", "original": "<code>RouterLink</code>", "translation": "<code>RouterLink</code>(路由链接)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEDIRECTIVEFORBINDINGACLICKABLEHTMLELEMENTTOAROUTECLICKINGANELEMENTWITHACODEROUTERLINKCODEDIRECTIVETHATISBOUNDTOAISTRINGIORAILINKPARAMETERSARRAYITRIGGERSANAVIGATION", "original": "The directive for binding a clickable HTML element to\n a route. Clicking an element with a <code>routerLink</code> directive\n that is bound to a <i>string</i> or a <i>link parameters array</i> triggers a navigation.", "translation": "这个指令把可点击的 HTML 元素绑定到某个路由。点击带有 <code>routerLink</code> 指令(绑定到<i>字符串</i>或<i>链接参数数组</i>)的元素时就会触发一次导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CODEROUTERLINKACTIVECODE", "original": "<code>RouterLinkActive</code>", "translation": "<code>RouterLinkActive</code>(活动路由链接)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEDIRECTIVEFORADDINGREMOVINGCLASSESFROMANHTMLELEMENTWHENANASSOCIATEDCODEROUTERLINKCODECONTAINEDONORINSIDETHEELEMENTBECOMESACTIVEINACTIVE", "original": "The directive for adding/removing classes from an HTML element when an associated\n <code>routerLink</code> contained on or inside the element becomes active/inactive.", "translation": "当 HTML 元素上或元素内的<code>routerLink</code>变为激活或非激活状态时,该指令为这个 HTML 元素添加或移除 CSS 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CODEACTIVATEDROUTECODE", "original": "<code>ActivatedRoute</code>", "translation": "<code>ActivatedRoute</code>(激活的路由)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASERVICETHATISPROVIDEDTOEACHROUTECOMPONENTTHATCONTAINSROUTESPECIFICINFORMATIONSUCHASROUTEPARAMETERSSTATICDATARESOLVEDATAGLOBALQUERYPARAMSANDTHEGLOBALFRAGMENT", "original": "A service that is provided to each route component that contains route specific\n information such as route parameters, static data, resolve data, global query params, and the global fragment.", "translation": "为每个路由组件提供提供的一个服务,它包含特定于路由的信息,比如路由参数、静态数据、解析数据、全局查询参数和全局碎片(fragment)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CODEROUTERSTATECODE", "original": "<code>RouterState</code>", "translation": "<code>RouterState</code>(路由器状态)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECURRENTSTATEOFTHEROUTERINCLUDINGATREEOFTHECURRENTLYACTIVATEDROUTESTOGETHERWITHCONVENIENCEMETHODSFORTRAVERSINGTHEROUTETREE", "original": "The current state of the router including a tree of the currently activated\n routes together with convenience methods for traversing the route tree.", "translation": "路由器的当前状态包含了一棵由程序中激活的路由构成的树。它包含一些用于遍历路由树的快捷方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BILINKPARAMETERSARRAYIB", "original": "<b><i>Link parameters array</i></b>", "translation": "<b><i>链接参数数组</i></b>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANARRAYTHATTHEROUTERINTERPRETSASAROUTINGINSTRUCTIONYOUCANBINDTHATARRAYTOACODEROUTERLINKCODEORPASSTHEARRAYASANARGUMENTTOTHECODEROUTERNAVIGATECODEMETHOD", "original": "An array that the router interprets as a routing instruction.\n You can bind that array to a <code>RouterLink</code> or pass the array as an argument to\n the <code>Router.navigate</code> method.", "translation": "这个数组会被路由器解释成一个路由操作指南。你可以把一个<code>RouterLink</code>绑定到该数组,或者把它作为参数传给<code>Router.navigate</code>方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BIROUTINGCOMPONENTIB", "original": "<b><i>Routing component</i></b>", "translation": "<b><i>路由组件</i></b>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANANGULARCOMPONENTWITHACODEROUTEROUTLETCODETHATDISPLAYSVIEWSBASEDONROUTERNAVIGATIONS", "original": "An Angular component with a <code>RouterOutlet</code> that displays views based on router navigations.", "translation": "一个带有<code>RouterOutlet</code>的 Angular 组件,它根据路由器的导航来显示相应的视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##THESAMPLEAPPLICATION", "original": "## The sample application", "translation": "## 范例应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISGUIDEDESCRIBESDEVELOPMENTOFAMULTIPAGEROUTEDSAMPLEAPPLICATIONALONGTHEWAYITHIGHLIGHTSDESIGNDECISIONSANDDESCRIBESKEYFEATURESOFTHEROUTERSUCHAS:", "original": "This guide describes development of a multi-page routed sample application.\nAlong the way, it highlights design decisions and describes key features of the router such as:", "translation": "本章要讲的是如何开发一个带路由的多页面应用。\n接下来会重点讲它的设计决策,并描述路由的关键特性,比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ORGANIZINGTHEAPPLICATIONFEATURESINTOMODULES", "original": "* Organizing the application features into modules.", "translation": "把应用的各个特性组织成模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NAVIGATINGTOACOMPONENTHEROESLINKTOHEROESLIST", "original": "* Navigating to a component (*Heroes* link to \"Heroes List\").", "translation": "导航到组件(*Heroes* 链接到“英雄列表”组件)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INCLUDINGAROUTEPARAMETERPASSINGTHEHEROIDWHILEROUTINGTOTHEHERODETAIL", "original": "* Including a route parameter (passing the Hero `id` while routing to the \"Hero Detail\").", "translation": "包含一个路由参数(当路由到“英雄详情”时,把该英雄的 `id` 传进去)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CHILDROUTESTHECRISISCENTERHASITSOWNROUTES", "original": "* Child routes (the *Crisis Center* has its own routes).", "translation": "子路由(*危机中心*特性有一组自己的路由)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECANACTIVATEGUARDCHECKINGROUTEACCESS", "original": "* The `CanActivate` guard (checking route access).", "translation": "`CanActivate` 守卫(检查路由的访问权限)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECANACTIVATECHILDGUARDCHECKINGCHILDROUTEACCESS", "original": "* The `CanActivateChild` guard (checking child route access).", "translation": "`CanActivateChild` 守卫(检查子路由的访问权限)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECANDEACTIVATEGUARDASKPERMISSIONTODISCARDUNSAVEDCHANGES", "original": "* The `CanDeactivate` guard (ask permission to discard unsaved changes).", "translation": "`CanDeactivate` 守卫(询问是否丢弃未保存的更改)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THERESOLVEGUARDPREFETCHINGROUTEDATA", "original": "* The `Resolve` guard (pre-fetching route data).", "translation": "`Resolve` 守卫(预先获取路由数据)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LAZYLOADINGFEATUREMODULES", "original": "* Lazy loading feature modules.", "translation": "惰性加载特性模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECANLOADGUARDCHECKBEFORELOADINGFEATUREMODULEASSETS", "original": "* The `CanLoad` guard (check before loading feature module assets).", "translation": "`CanLoad` 守卫(在加载特性模块之前进行检查)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEGUIDEPROCEEDSASASEQUENCEOFMILESTONESASIFYOUWEREBUILDINGTHEAPPSTEPBYSTEPBUTITISNOTATUTORIALANDITGLOSSESOVERDETAILSOFANGULARAPPLICATIONCONSTRUCTIONTHATAREMORETHOROUGHLYCOVEREDELSEWHEREINTHEDOCUMENTATION", "original": "The guide proceeds as a sequence of milestones as if you were building the app step-by-step.\nBut, it is not a tutorial and it glosses over details of Angular application construction\nthat are more thoroughly covered elsewhere in the documentation.", "translation": "如果打算一步步构建出本应用,本章就会经过一系列里程碑。\n但是,本章并不是一个教程,它隐藏了构造 Angular 应用的细节,那些细节会在本文档的其它地方展开。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEFULLSOURCEFORTHEFINALVERSIONOFTHEAPPCANBESEENANDDOWNLOADEDFROMTHELIVEEXAMPLELIVEEXAMPLE", "original": "The full source for the final version of the app can be seen and downloaded from the <live-example></live-example>.", "translation": "本应用的最终版源码可以在<live-example></live-example>中查看和下载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###THESAMPLEAPPLICATIONINACTION", "original": "### The sample application in action", "translation": "### 范例程序的动图", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMAGINEANAPPLICATIONTHATHELPSTHEHEROEMPLOYMENTAGENCYRUNITSBUSINESSHEROESNEEDWORKANDTHEAGENCYFINDSCRISESFORTHEMTOSOLVE", "original": "Imagine an application that helps the _Hero Employment Agency_ run its business.\nHeroes need work and the agency finds crises for them to solve.", "translation": "假设本程序会用来帮助“英雄管理局”运行他们的业务。\n英雄们需要找工作,而“英雄管理局”为他们寻找待解决的危机。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPLICATIONHASTHREEMAINFEATUREAREAS:", "original": "The application has three main feature areas:", "translation": "本应用具有三个主要的特性区:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1ACRISISCENTERFORMAINTAININGTHELISTOFCRISESFORASSIGNMENTTOHEROES", "original": "1. A *Crisis Center* for maintaining the list of crises for assignment to heroes.", "translation": "*危机中心*用于维护要指派给英雄的危机列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1AHEROESAREAFORMAINTAININGTHELISTOFHEROESEMPLOYEDBYTHEAGENCY", "original": "1. A *Heroes* area for maintaining the list of heroes employed by the agency.", "translation": "*英雄*区用于维护管理局雇佣的英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1ANADMINAREATOMANAGETHELISTOFCRISESANDHEROES", "original": "1. An *Admin* area to manage the list of crises and heroes.", "translation": "*管理*区会管理危机和英雄的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TRYITBYCLICKINGONTHISLIVEEXAMPLETITLEHEROEMPLOYMENTAGENCYLIVEEXAMPLELIVEEXAMPLELINKLIVEEXAMPLE", "original": "Try it by clicking on this <live-example title=\"Hero Employment Agency Live Example\">live example link</live-example>.", "translation": "点击<live-example title=\"英雄职介中心的在线例子\"></live-example>试用一下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ONCETHEAPPWARMSUPYOULLSEEAROWOFNAVIGATIONBUTTONSANDTHEHEROESVIEWWITHITSLISTOFHEROES", "original": "Once the app warms up, you'll see a row of navigation buttons\nand the *Heroes* view with its list of heroes.", "translation": "等应用热身完毕,你就会看到一排导航按钮,以及一个*英雄列表*视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SELECTONEHEROANDTHEAPPTAKESYOUTOAHEROEDITINGSCREEN", "original": "Select one hero and the app takes you to a hero editing screen.", "translation": "选择其中之一,该应用就会把你带到此英雄的编辑页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALTERTHENAMECLICKTHEBACKBUTTONANDTHEAPPRETURNSTOTHEHEROESLISTWHICHDISPLAYSTHECHANGEDHERONAMENOTICETHATTHENAMECHANGETOOKEFFECTIMMEDIATELY", "original": "Alter the name.\nClick the \"Back\" button and the app returns to the heroes list which displays the changed hero name.\nNotice that the name change took effect immediately.", "translation": "修改完名字,再点击“后退”按钮,应用又回到了英雄列表页,其中显示的英雄名已经变了。注意,对名字的修改会立即生效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HADYOUCLICKEDTHEBROWSERSBACKBUTTONINSTEADOFTHEBACKBUTTONTHEAPPWOULDHAVERETURNEDYOUTOTHEHEROESLISTASWELLANGULARAPPNAVIGATIONUPDATESTHEBROWSERHISTORYASNORMALWEBNAVIGATIONDOES", "original": "Had you clicked the browser's back button instead of the \"Back\" button,\nthe app would have returned you to the heroes list as well.\nAngular app navigation updates the browser history as normal web navigation does.", "translation": "另外你也可以点击浏览器本身的后退按钮,这样也同样会回到英雄列表页。\n在 Angular 应用中导航也会和标准的 Web 导航一样更新浏览器中的历史。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWCLICKTHECRISISCENTERLINKFORALISTOFONGOINGCRISES", "original": "Now click the *Crisis Center* link for a list of ongoing crises.", "translation": "现在,点击*危机中心*链接,前往*危机*列表页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SELECTACRISISANDTHEAPPLICATIONTAKESYOUTOACRISISEDITINGSCREENTHECRISISDETAILAPPEARSINACHILDVIEWONTHESAMEPAGEBENEATHTHELIST", "original": "Select a crisis and the application takes you to a crisis editing screen.\nThe _Crisis Detail_ appears in a child view on the same page, beneath the list.", "translation": "选择其中之一,该应用就会把你带到此危机的编辑页面。\n*危机详情*出现在了当前页的子视图区,也就是在列表的紧下方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALTERTHENAMEOFACRISISNOTICETHATTHECORRESPONDINGNAMEINTHECRISISLISTDOESNOTCHANGE", "original": "Alter the name of a crisis.\nNotice that the corresponding name in the crisis list does _not_ change.", "translation": "修改危机的名称。\n注意,危机列表中的相应名称**并没有**修改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UNLIKEHERODETAILWHICHUPDATESASYOUTYPECRISISDETAILCHANGESARETEMPORARYUNTILYOUEITHERSAVEORDISCARDTHEMBYPRESSINGTHESAVEORCANCELBUTTONSBOTHBUTTONSNAVIGATEBACKTOTHECRISISCENTERANDITSLISTOFCRISES", "original": "Unlike *Hero Detail*, which updates as you type,\n*Crisis Detail* changes are temporary until you either save or discard them by pressing the \"Save\" or \"Cancel\" buttons.\nBoth buttons navigate back to the *Crisis Center* and its list of crises.", "translation": "这和*英雄详情*页略有不同。*英雄详情*会立即保存你所做的更改。\n而*危机详情*页中,你的更改都是临时的 —— 除非按“保存”按钮保存它们,或者按“取消”按钮放弃它们。\n这两个按钮都会导航回*危机中心*,显示危机列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DONOTCLICKEITHERBUTTONYETCLICKTHEBROWSERBACKBUTTONORTHEHEROESLINKINSTEAD", "original": "***Do not click either button yet***.\nClick the browser back button or the \"Heroes\" link instead.", "translation": "***先不要点击这些按钮***。\n而是点击浏览器的后退按钮,或者点击“Heroes”链接。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UPPOPSADIALOGBOX", "original": "Up pops a dialog box.", "translation": "这时会弹出一个对话框。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANSAYOKANDLOSEYOURCHANGESORCLICKCANCELANDCONTINUEEDITING", "original": "You can say \"OK\" and lose your changes or click \"Cancel\" and continue editing.", "translation": "你可以回答“确定”以放弃这些更改,或者回答“取消”来继续编辑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BEHINDTHISBEHAVIORISTHEROUTERSCANDEACTIVATEGUARDTHEGUARDGIVESYOUACHANCETOCLEANUPORASKTHEUSERSPERMISSIONBEFORENAVIGATINGAWAYFROMTHECURRENTVIEW", "original": "Behind this behavior is the router's `CanDeactivate` guard.\nThe guard gives you a chance to clean-up or ask the user's permission before navigating away from the current view.", "translation": "这种行为的幕后是路由器的 `CanDeactivate` 守卫。\n该守卫让你有机会进行清理工作或在离开当前视图之前请求用户的许可。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEADMINANDLOGINBUTTONSILLUSTRATEOTHERROUTERCAPABILITIESTOBECOVEREDLATERINTHEGUIDETHISSHORTINTRODUCTIONWILLDOFORNOW", "original": "The `Admin` and `Login` buttons illustrate other router capabilities to be covered later in the guide.\nThis short introduction will do for now.", "translation": "`Admin` 和 `Login` 按钮用于演示路由器的其它能力,本章稍后的部分会讲解它们。这里只是个简短的讲解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PROCEEDTOTHEFIRSTAPPLICATIONMILESTONE", "original": "Proceed to the first application milestone.", "translation": "这就开始本应用的第一个里程碑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##MILESTONE1:GETTINGSTARTEDWITHTHEROUTER", "original": "## Milestone 1: Getting started with the router", "translation": "## 里程碑 1:从路由器开始", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BEGINWITHASIMPLEVERSIONOFTHEAPPTHATNAVIGATESBETWEENTWOEMPTYVIEWS", "original": "Begin with a simple version of the app that navigates between two empty views.", "translation": "开始本应用的一个简版,它在两个空路由之间导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###SETTHELTBASEHREF", "original": "### Set the *<base href>*", "translation": "### 设置*<base href>*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERUSESTHEBROWSERSAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIHISTORYAPI#ADDINGANDMODIFYINGHISTORYENTRIESTITLEHTML5BROWSERHISTORYPUSHSTATEHISTORYPUSHSTATEAFORNAVIGATIONTHANKSTOPUSHSTATEYOUCANMAKEINAPPURLPATHSLOOKTHEWAYYOUWANTTHEMTOLOOKEGLOCALHOST:3000CRISISCENTERTHEINAPPURLSCANBEINDISTINGUISHABLEFROMSERVERURLS", "original": "The router uses the browser's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries\" title=\"HTML5 browser history push-state\">history.pushState</a>\nfor navigation. Thanks to `pushState`, you can make in-app URL paths look the way you want them to\nlook, e.g. `localhost:3000/crisis-center`. The in-app URLs can be indistinguishable from server URLs.", "translation": "路由器使用浏览器的<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries\" target=\"_blank\" title=\"HTML5 browser history push-state\">history.pushState</a>进行导航。\n感谢 `pushState`!有了它,你就能按所期望的样子来显示应用内部的 URL 路径,比如:`localhost:3000/crisis-center`。虽然你使用的全部是客户端合成的视图,但应用内部的这些 URL 看起来和来自服务器的没有什么不同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MODERNHTML5BROWSERSWERETHEFIRSTTOSUPPORTPUSHSTATEWHICHISWHYMANYPEOPLEREFERTOTHESEURLSASHTML5STYLEURLS", "original": "Modern HTML5 browsers were the first to support `pushState` which is why many people refer to these URLs as\n\"HTML5 style\" URLs.", "translation": "现代 HTML 5 浏览器是最早支持 `pushState` 的,这也就是很多人喜欢把这种 URL 称作“HTML 5 风格的”URL 的原因。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HTML5STYLENAVIGATIONISTHEROUTERDEFAULTINTHELOCATIONSTRATEGYANDBROWSERURLSTYLES#BROWSERURLSTYLESAPPENDIXLEARNWHYHTML5STYLEISPREFERREDHOWTOADJUSTITSBEHAVIORANDHOWTOSWITCHTOTHEOLDERHASH#STYLEIFNECESSARY", "original": "HTML5 style navigation is the router default.\nIn the [LocationStrategy and browser URL styles](#browser-url-styles) Appendix,\nlearn why HTML5 style is preferred, how to adjust its behavior, and how to switch to the\nolder hash (#) style, if necessary.", "translation": "HTML 5 风格的导航是路由器的默认值。请到下面的附录[浏览器 URL 风格](guide/router#browser-url-styles)中学习为什么首选“HTML 5”风格、如何调整它的行为,以及如何在必要时切换回老式的 hash(#)风格。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUMUSTADDAAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBHTMLELEMENTBASETITLEBASEHREFLTBASEHREFGTELEMENTATOTHEAPPSINDEXHTMLFORPUSHSTATEROUTINGTOWORKTHEBROWSERUSESTHEBASEHREFVALUETOPREFIXRELATIVEURLSWHENREFERENCINGCSSFILESSCRIPTSANDIMAGES", "original": "You must **add a\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base\" title=\"base href\"><base href> element</a>**\nto the app's `index.html` for `pushState` routing to work.\nThe browser uses the `<base href>` value to prefix *relative* URLs when referencing\nCSS files, scripts, and images.", "translation": "你必须往本应用的 `index.html` 中**添加一个<a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base\" target=\"_blank\" title=\"base href\"><base href> 元素</a>**,这样 `pushState` 才能正常工作。\n当引用 CSS 文件、脚本和图片时,浏览器会用 `<base href>` 的值作为*相对*URL 的前缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDTHEBASEELEMENTJUSTAFTERTHEHEADTAGIFTHEAPPFOLDERISTHEAPPLICATIONROOTASITISFORTHISAPPLICATIONSETTHEHREFVALUEININDEXHTMLEXACTLYASSHOWNHERE", "original": "Add the `<base>` element just after the `<head>` tag.\nIf the `app` folder is the application root, as it is for this application,\nset the `href` value in **`index.html`** *exactly* as shown here.", "translation": "把 `<base>` 元素添加到 `<head>` 元素中。\n如果 `app` 目录是应用的根目录,对于本应用,可以像这样设置**`index.html`**中的 `href` 值:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HEADERLIVEEXAMPLENOTEHEADER", "original": "<header>Live example note</header>", "translation": "<header>在线例子说明</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALIVECODINGENVIRONMENTLIKESTACKBLITZSETSTHEAPPLICATIONBASEADDRESSDYNAMICALLYSOYOUCANTSPECIFYAFIXEDADDRESSTHATSWHYTHEEXAMPLECODEREPLACESTHEBASEHREFWITHASCRIPTTHATWRITESTHEBASETAGONTHEFLY", "original": "A live coding environment like Stackblitz sets the application base address dynamically so you can't specify a fixed address.\nThat's why the example code replaces the `<base href...>` with a script that writes the `<base>` tag on the fly.", "translation": "像 Stackblitz 这样的在线编程环境会动态设置应用的基地址(base href),因此你没办法指定固定的地址。\n这就是为什么范例代码中要用一个脚本动态写入 `<base>` 标签,而不是直接写 `<base href...>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUONLYNEEDTHISTRICKFORTHELIVEEXAMPLENOTPRODUCTIONCODE", "original": "You only need this trick for the live example, not production code.", "translation": "你只应该在在线例子这种情况下使用这种小花招,不要把它用到产品的正式代码中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###IMPORTINGFROMTHEROUTERLIBRARY", "original": "### Importing from the router library", "translation": "### 从路由库中导入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BEGINBYIMPORTINGSOMESYMBOLSFROMTHEROUTERLIBRARYTHEROUTERISINITSOWNANGULARROUTERPACKAGEITSNOTPARTOFTHEANGULARCORETHEROUTERISANOPTIONALSERVICEBECAUSENOTALLAPPLICATIONSNEEDROUTINGANDDEPENDINGONYOURREQUIREMENTSYOUMAYNEEDADIFFERENTROUTINGLIBRARY", "original": "Begin by importing some symbols from the router library.\nThe Router is in its own `@angular/router` package.\nIt's not part of the Angular core. The router is an optional service because not all applications\nneed routing and, depending on your requirements, you may need a different routing library.", "translation": "先从路由库导入一些符号。\n路由器在它自己的 `@angular/router` 包中。\n它不是 Angular 内核的一部分。该路由器是可选的服务,这是因为并不是所有应用都需要路由,并且,如果需要,你还可能需要另外的路由库。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUTEACHTHEROUTERHOWTONAVIGATEBYCONFIGURINGITWITHROUTES", "original": "You teach the router how to navigate by configuring it with routes.", "translation": "通过一些路由来配置路由器,你可以教路由器如何进行导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####DEFINEROUTES", "original": "#### Define routes", "translation": "#### 定义路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AROUTERMUSTBECONFIGUREDWITHALISTOFROUTEDEFINITIONS", "original": "A router must be configured with a list of route definitions.", "translation": "路由器必须用“路由定义”的列表进行配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEFIRSTCONFIGURATIONDEFINESANARRAYOFTWOROUTESWITHSIMPLEPATHSLEADINGTOTHECRISISLISTCOMPONENTANDHEROLISTCOMPONENT", "original": "The first configuration defines an array of two routes with simple paths leading to the\n`CrisisListComponent` and `HeroListComponent`.", "translation": "第一个配置中定义了由两个路由构成的数组,它们分别通过路径(path)导航到了 `CrisisListComponent` 和 `HeroListComponent` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHDEFINITIONTRANSLATESTOAROUTEAPIROUTERROUTEOBJECTWHICHHASTWOTHINGS:APATHTHEURLPATHSEGMENTFORTHISROUTEANDACOMPONENTTHECOMPONENTASSOCIATEDWITHTHISROUTE", "original": "Each definition translates to a [Route](api/router/Route) object which has two things: a\n`path`, the URL path segment for this route; and a\n`component`, the component associated with this route.", "translation": "每个定义都被翻译成了一个[Route](api/router/Route)对象。该对象有一个 `path` 字段,表示该路由中的 URL 路径部分,和一个 `component` 字段,表示与该路由相关联的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERDRAWSUPONITSREGISTRYOFDEFINITIONSWHENTHEBROWSERURLCHANGESORWHENAPPLICATIONCODETELLSTHEROUTERTONAVIGATEALONGAROUTEPATH", "original": "The router draws upon its registry of definitions when the browser URL changes\nor when application code tells the router to navigate along a route path.", "translation": "当浏览器的 URL 变化时或在代码中告诉路由器导航到一个路径时,路由器就会翻出它用来保存这些路由定义的注册表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INSIMPLERTERMSYOUMIGHTSAYTHISOFTHEFIRSTROUTE:", "original": "In simpler terms, you might say this of the first route:", "translation": "直白的说,你可以这样解释第一个路由:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENTHEBROWSERSLOCATIONURLCHANGESTOMATCHTHEPATHSEGMENTCRISISCENTERTHENTHEROUTERACTIVATESANINSTANCEOFTHECRISISLISTCOMPONENTANDDISPLAYSITSVIEW", "original": "* When the browser's location URL changes to match the path segment `/crisis-center`, then\nthe router activates an instance of the `CrisisListComponent` and displays its view.", "translation": "当浏览器地址栏的 URL 变化时,如果它匹配上了路径部分 `/crisis-center`,路由器就会激活一个 `CrisisListComponent` 的实例,并显示它的视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENTHEAPPLICATIONREQUESTSNAVIGATIONTOTHEPATHCRISISCENTERTHEROUTERACTIVATESANINSTANCEOFCRISISLISTCOMPONENTDISPLAYSITSVIEWANDUPDATESTHEBROWSERSADDRESSLOCATIONANDHISTORYWITHTHEURLFORTHATPATH", "original": "* When the application requests navigation to the path `/crisis-center`, the router\nactivates an instance of `CrisisListComponent`, displays its view, and updates the\nbrowser's address location and history with the URL for that path.", "translation": "**当应用程序请求导航到路径 `/crisis-center` 时,路由器激活一个 `CrisisListComponent` 的实例,显示它的视图,并将该路径更新到浏览器地址栏和历史。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HEREISTHEFIRSTCONFIGURATIONPASSTHEARRAYOFROUTESAPPROUTESTOTHEROUTERMODULEFORROOTMETHODITRETURNSAMODULECONTAININGTHECONFIGUREDROUTERSERVICEPROVIDERPLUSOTHERPROVIDERSTHATTHEROUTINGLIBRARYREQUIRESONCETHEAPPLICATIONISBOOTSTRAPPEDTHEROUTERPERFORMSTHEINITIALNAVIGATIONBASEDONTHECURRENTBROWSERURL", "original": "Here is the first configuration. Pass the array of routes, `appRoutes`, to the `RouterModule.forRoot` method.\nIt returns a module, containing the configured `Router` service provider, plus other providers that the routing library requires.\nOnce the application is bootstrapped, the `Router` performs the initial navigation based on the current browser URL.", "translation": "下面是第一个配置。把路由数组传递到 `RouterModule.forRoot` 方法,该方法返回一个包含已配置的 `Router` 服务提供商模块和一些其它路由包需要的服务提供商。应用启动时,`Router` 将在当前浏览器 URL 的基础上进行初始导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDINGTHECONFIGUREDROUTERMODULETOTHEAPPMODULEISSUFFICIENTFORSIMPLEROUTECONFIGURATIONSASTHEAPPLICATIONGROWSYOULLWANTTOREFACTORTHEROUTINGCONFIGURATIONINTOASEPARATEFILEANDCREATEAROUTINGMODULE#ROUTINGMODULEASPECIALTYPEOFSERVICEMODULEDEDICATEDTOTHEPURPOSEOFROUTINGINFEATUREMODULES", "original": "Adding the configured `RouterModule` to the `AppModule` is sufficient for simple route configurations.\nAs the application grows, you'll want to refactor the routing configuration into a separate file\nand create a **[Routing Module](#routing-module)**, a special type of `Service Module` dedicated to the purpose\nof routing in feature modules.", "translation": "作为简单的路由配置,将添加配置好的 `RouterModule` 到 `AppModule` 中就足够了。\n随着应用的成长,你将需要将路由配置重构到单独的文件,并创建**[路由模块](#routing-module)** - 一种特别的、专门为特性模块的路由器服务的**服务模块**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PROVIDINGTHEROUTERMODULEINTHEAPPMODULEMAKESTHEROUTERAVAILABLEEVERYWHEREINTHEAPPLICATION", "original": "Providing the `RouterModule` in the `AppModule` makes the Router available everywhere in the application.", "translation": "在 `AppModule` 中提供 `RouterModule`,让该路由器在应用的任何地方都能被使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###THEAPPCOMPONENTSHELL", "original": "### The *AppComponent* shell", "translation": "### *AppComponent* 外壳组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROOTAPPCOMPONENTISTHEAPPLICATIONSHELLITHASATITLEANAVIGATIONBARWITHTWOLINKSANDAROUTEROUTLETWHERETHEROUTERSWAPSVIEWSONANDOFFTHEPAGEHERESWHATYOUGET:", "original": "The root `AppComponent` is the application shell. It has a title, a navigation bar with two links,\nand a *router outlet* where the router swaps views on and off the page. Here's what you get:", "translation": "根组件 `AppComponent` 是本应用的壳。它在顶部有一个标题、一个带两个链接的导航条,在底部有一个*路由器出口*,路由器会在它所指定的位置上把视图切入或调出页面。就像下图中所标出的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECORRESPONDINGCOMPONENTTEMPLATELOOKSLIKETHIS:", "original": "The corresponding component template looks like this:", "translation": "该组件所对应的模板是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTEROUTLET", "original": "### *RouterOutlet*", - "translation": "### *RouterOutlet* 指令", + "translation": "### 路由出口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTEROUTLETISADIRECTIVEFROMTHEROUTERLIBRARYTHATMARKSTHESPOTINTHETEMPLATEWHERETHEROUTERSHOULDDISPLAYTHEVIEWSFORTHATOUTLET", "original": "The `RouterOutlet` is a directive from the router library that marks\nthe spot in the template where the router should display the views for that outlet.", "translation": "`RouterOutlet` 是一个来自路由库的组件。\n路由器会在 `<router-outlet>` 标签中显示视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERADDSTHEROUTEROUTLETELEMENTTOTHEDOMANDSUBSEQUENTLYINSERTSTHENAVIGATEDVIEWELEMENTIMMEDIATELYAFTERTHEROUTEROUTLET", "original": "The router adds the `<router-outlet>` element to the DOM\nand subsequently inserts the navigated view element\nimmediately _after_ the `<router-outlet>`.", "translation": "路由器会把 `<router-outlet>` 元素添加到了 DOM 中,紧接着立即在这个 `<router-outlet>` *之后*插入导航到的视图元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTERLINKBINDING", "original": "### *RouterLink* binding", "translation": "### `routerLink` 绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ABOVETHEOUTLETWITHINTHEANCHORTAGSYOUSEEATTRIBUTEBINDINGSGUIDETEMPLATESYNTAX#ATTRIBUTEBINDINGTOTHEROUTERLINKDIRECTIVETHATLOOKLIKEROUTERLINK", "original": "Above the outlet, within the anchor tags, you see\n[attribute bindings](guide/template-syntax#attribute-binding) to\nthe `RouterLink` directive that look like `routerLink=\"...\"`.", "translation": "在出口上方的 A 标签中,有一个绑定 `RouterLink` 指令的[属性绑定](guide/template-syntax#property-binding),就像这样:`routerLink=\"...\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THELINKSINTHISEXAMPLEEACHHAVEASTRINGPATHTHEPATHOFAROUTETHATYOUCONFIGUREDEARLIERTHEREARENOROUTEPARAMETERSYET", "original": "The links in this example each have a string path, the path of a route that\nyou configured earlier. There are no route parameters yet.", "translation": "例子中的每个链接都有一个字符串型的路径,也就是你以前配置过的路由路径,但还没有指定路由参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANALSOADDMORECONTEXTUALINFORMATIONTOTHEROUTERLINKBYPROVIDINGQUERYSTRINGPARAMETERSORAURLFRAGMENTFORJUMPINGTODIFFERENTAREASONTHEPAGEQUERYSTRINGPARAMETERSAREPROVIDEDTHROUGHTHEQUERYPARAMSBINDINGWHICHTAKESANOBJECTEGNAME:VALUEWHILETHEURLFRAGMENTTAKESASINGLEVALUEBOUNDTOTHEFRAGMENTINPUTBINDING", "original": "You can also add more contextual information to the `RouterLink` by providing query string parameters\nor a URL fragment for jumping to different areas on the page. Query string parameters\nare provided through the `[queryParams]` binding which takes an object (e.g. `{ name: 'value' }`), while the URL fragment\ntakes a single value bound to the `[fragment]` input binding.", "translation": "你还可以通过提供查询字符串参数为 `RouterLink` 提供更多情境信息,或提供一个 URL 片段(Fragment 或 hash)来跳转到本页面中的其它区域。\n查询字符串可以由 `[queryParams]` 绑定来提供,它需要一个对象型参数(如 `{ name: 'value' }`),而 URL 片段需要一个绑定到 `[fragment]` 的单一值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LEARNABOUTTHEHOWYOUCANALSOUSETHELINKPARAMETERSARRAYINTHEAPPENDIXBELOW#LINKPARAMETERSARRAY", "original": "Learn about the how you can also use the _link parameters array_ in the [appendix below](#link-parameters-array).", "translation": "还可以到[后面的附录](guide/router#link-parameters-array)中学习如何使用**链接参数数组**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTERLINKACTIVEBINDING", "original": "### *RouterLinkActive* binding", "translation": "### `routerLinkActive` 绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ONEACHANCHORTAGYOUALSOSEEPROPERTYBINDINGSGUIDETEMPLATESYNTAX#PROPERTYBINDINGTOTHEROUTERLINKACTIVEDIRECTIVETHATLOOKLIKEROUTERLINKACTIVE", "original": "On each anchor tag, you also see [property bindings](guide/template-syntax#property-binding) to\nthe `RouterLinkActive` directive that look like `routerLinkActive=\"...\"`.", "translation": "每个 A 标签还有一个到 `RouterLinkActive` 指令的[属性绑定](guide/template-syntax#property-binding),就像 `routerLinkActive=\"...\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THETEMPLATEEXPRESSIONTOTHERIGHTOFTHEEQUALSCONTAINSASPACEDELIMITEDSTRINGOFCSSCLASSESTHATTHEROUTERWILLADDWHENTHISLINKISACTIVEANDREMOVEWHENTHELINKISINACTIVEYOUCANALSOSETTHEROUTERLINKACTIVEDIRECTIVETOASTRINGOFCLASSESSUCHASROUTERLINKACTIVEACTIVEFLUFFYORBINDITTOACOMPONENTPROPERTYTHATRETURNSSUCHASTRING", "original": "The template expression to the right of the equals (=) contains a space-delimited string of CSS classes\nthat the Router will add when this link is active (and remove when the link is inactive).\nYou can also set the `RouterLinkActive` directive to a string of classes such as `[routerLinkActive]=\"'active fluffy'\"`\nor bind it to a component property that returns such a string.", "translation": "等号(=)右侧的模板表达式包含用空格分隔的一些 CSS 类。当路由激活时路由器就会把它们添加到此链接上(反之则移除)。你还可以把 `RouterLinkActive` 指令绑定到一个 CSS 类组成的数组,如 `[routerLinkActive]=\"['...']\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERLINKACTIVEDIRECTIVETOGGLESCSSCLASSESFORACTIVEROUTERLINKSBASEDONTHECURRENTROUTERSTATETHISCASCADESDOWNTHROUGHEACHLEVELOFTHEROUTETREESOPARENTANDCHILDROUTERLINKSCANBEACTIVEATTHESAMETIMETOOVERRIDETHISBEHAVIORYOUCANBINDTOTHEROUTERLINKACTIVEOPTIONSINPUTBINDINGWITHTHEEXACT:TRUEEXPRESSIONBYUSINGEXACT:TRUEAGIVENROUTERLINKWILLONLYBEACTIVEIFITSURLISANEXACTMATCHTOTHECURRENTURL", "original": "The `RouterLinkActive` directive toggles css classes for active `RouterLink`s based on the current `RouterState`.\nThis cascades down through each level of the route tree, so parent and child router links can be active at the same time.\nTo override this behavior, you can bind to the `[routerLinkActiveOptions]` input binding with the `{ exact: true }` expression.\nBy using `{ exact: true }`, a given `RouterLink` will only be active if its URL is an exact match to the current URL.", "translation": "`RouterLinkActive` 指令会基于当前的 `RouterState` 对象来为激活的 `RouterLink` 切换 CSS 类。\n这会一直沿着路由树往下进行级联处理,所以父路由链接和子路由链接可能会同时激活。\n要改变这种行为,可以把 `[routerLinkActiveOptions]` 绑定到 `{exact: true}` 表达式。\n如果使用了 `{ exact: true }`,那么只有在其 URL 与当前 URL 精确匹配时才会激活指定的 `RouterLink`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTERDIRECTIVES", "original": "### *Router directives*", "translation": "### *路由器指令集*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ROUTERLINKROUTERLINKACTIVEANDROUTEROUTLETAREDIRECTIVESPROVIDEDBYTHEANGULARROUTERMODULEPACKAGETHEYAREREADILYAVAILABLEFORYOUTOUSEINTHETEMPLATE", "original": "`RouterLink`, `RouterLinkActive` and `RouterOutlet` are directives provided by the Angular `RouterModule` package.\nThey are readily available for you to use in the template.", "translation": "`RouterLink`、`RouterLinkActive` 和 `RouterOutlet` 是由 `RouterModule` 包提供的指令。\n现在你可以把它用在模板中了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECURRENTSTATEOFAPPCOMPONENTTSLOOKSLIKETHIS:", "original": "The current state of `app.component.ts` looks like this:", "translation": "`app.component.ts` 目前是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###WILDCARDROUTE", "original": "### Wildcard route", "translation": "### 通配符路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVECREATEDTWOROUTESINTHEAPPSOFARONETOCRISISCENTERANDTHEOTHERTOHEROESANYOTHERURLCAUSESTHEROUTERTOTHROWANERRORANDCRASHTHEAPP", "original": "You've created two routes in the app so far, one to `/crisis-center` and the other to `/heroes`.\nAny other URL causes the router to throw an error and crash the app.", "translation": "你以前在应用中创建过两个路由,一个是 `/crisis-center`,另一个是 `/heroes`。\n所有其它 URL 都会导致路由器抛出错误,并让应用崩溃。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDAWILDCARDROUTETOINTERCEPTINVALIDURLSANDHANDLETHEMGRACEFULLYAWILDCARDROUTEHASAPATHCONSISTINGOFTWOASTERISKSITMATCHESEVERYURLTHEROUTERWILLSELECTTHISROUTEIFITCANTMATCHAROUTEEARLIERINTHECONFIGURATIONAWILDCARDROUTECANNAVIGATETOACUSTOM404NOTFOUNDCOMPONENTORREDIRECT#REDIRECTTOANEXISTINGROUTE", "original": "Add a **wildcard** route to intercept invalid URLs and handle them gracefully.\nA _wildcard_ route has a path consisting of two asterisks. It matches _every_ URL.\nThe router will select _this_ route if it can't match a route earlier in the configuration.\nA wildcard route can navigate to a custom \"404 Not Found\" component or [redirect](#redirect) to an existing route.", "translation": "可以添加一个**通配符**路由来拦截所有无效的 URL,并优雅的处理它们。\n*通配符*路由的 `path` 是两个星号(`**`),它会匹配*任何* URL。\n当路由器匹配不上以前定义的那些路由时,它就会选择*这个*路由。\n通配符路由可以导航到自定义的“404 Not Found”组件,也可以[重定向](guide/router#redirect)到一个现有路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERSELECTSTHEROUTEWITHAFIRSTMATCHWINS#EXAMPLECONFIGSTRATEGYWILDCARDROUTESARETHELEASTSPECIFICROUTESINTHEROUTECONFIGURATIONBESUREITISTHELASTROUTEINTHECONFIGURATION", "original": "The router selects the route with a [_first match wins_](#example-config) strategy.\nWildcard routes are the least specific routes in the route configuration.\nBe sure it is the _last_ route in the configuration.", "translation": "路由器使用[先匹配者优先](guide/router#example-config)的策略来选择路由。\n通配符路由是路由配置中最没有特定性的那个,因此务必确保它是配置中的*最后一个*路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TOTESTTHISFEATUREADDABUTTONWITHAROUTERLINKTOTHEHEROLISTCOMPONENTTEMPLATEANDSETTHELINKTOSIDEKICKS", "original": "To test this feature, add a button with a `RouterLink` to the `HeroListComponent` template and set the link to `\"/sidekicks\"`.", "translation": "要测试本特性,请往 `HeroListComponent` 的模板中添加一个带 `RouterLink` 的按钮,并且把它的链接设置为 `\"/sidekicks\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPLICATIONWILLFAILIFTHEUSERCLICKSTHATBUTTONBECAUSEYOUHAVENTDEFINEDASIDEKICKSROUTEYET", "original": "The application will fail if the user clicks that button because you haven't defined a `\"/sidekicks\"` route yet.", "translation": "当用户点击该按钮时,应用就会失败,因为你尚未定义过 `\"/sidekicks\"` 路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INSTEADOFADDINGTHESIDEKICKSROUTEDEFINEAWILDCARDROUTEINSTEADANDHAVEITNAVIGATETOASIMPLEPAGENOTFOUNDCOMPONENT", "original": "Instead of adding the `\"/sidekicks\"` route, define a `wildcard` route instead and have it navigate to a simple `PageNotFoundComponent`.", "translation": "不要添加 `\"/sidekicks\"` 路由,而是定义一个“通配符”路由,让它直接导航到 `PageNotFoundComponent` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATETHEPAGENOTFOUNDCOMPONENTTODISPLAYWHENUSERSVISITINVALIDURLS", "original": "Create the `PageNotFoundComponent` to display when users visit invalid URLs.", "translation": "创建 `PageNotFoundComponent`,以便在用户访问无效网址时显示它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASWITHTHEOTHERCOMPONENTSADDTHEPAGENOTFOUNDCOMPONENTTOTHEAPPMODULEDECLARATIONS", "original": "As with the other components, add the `PageNotFoundComponent` to the `AppModule` declarations.", "translation": "像其它组件一样,把 `PageNotFoundComponent` 添加到 `AppModule` 的声明中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWWHENTHEUSERVISITSSIDEKICKSORANYOTHERINVALIDURLTHEBROWSERDISPLAYSPAGENOTFOUNDTHEBROWSERADDRESSBARCONTINUESTOPOINTTOTHEINVALIDURL", "original": "Now when the user visits `/sidekicks`, or any other invalid URL, the browser displays \"Page not found\".\nThe browser address bar continues to point to the invalid URL.", "translation": "现在,当用户访问 `/sidekicks` 或任何无效的 URL 时,浏览器就会显示“Page not found”。\n浏览器的地址栏仍指向无效的 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###THEDEFAULTROUTETOHEROES", "original": "### The _default_ route to heroes", "translation": "### 把*默认*路由设置为英雄列表", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENTHEAPPLICATIONLAUNCHESTHEINITIALURLINTHEBROWSERBARISSOMETHINGLIKE:", "original": "When the application launches, the initial URL in the browser bar is something like:", "translation": "应用启动时,浏览器地址栏中的初始 URL 是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THATDOESNTMATCHANYOFTHECONCRETECONFIGUREDROUTESWHICHMEANSTHEROUTERFALLSTHROUGHTOTHEWILDCARDROUTEANDDISPLAYSTHEPAGENOTFOUNDCOMPONENT", "original": "That doesn't match any of the concrete configured routes which means\nthe router falls through to the wildcard route and displays the `PageNotFoundComponent`.", "translation": "它不能匹配上任何具体的路由,于是就会走到通配符路由中去,并且显示 `PageNotFoundComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPLICATIONNEEDSADEFAULTROUTETOAVALIDPAGETHEDEFAULTPAGEFORTHISAPPISTHELISTOFHEROESTHEAPPSHOULDNAVIGATETHEREASIFTHEUSERCLICKEDTHEHEROESLINKORPASTEDLOCALHOST:3000HEROESINTOTHEADDRESSBAR", "original": "The application needs a **default route** to a valid page.\nThe default page for this app is the list of heroes.\nThe app should navigate there as if the user clicked the \"Heroes\" link or pasted `localhost:3000/heroes` into the address bar.", "translation": "这个应用需要一个有效的**默认路由**,在这里应该用英雄列表作为默认页。当用户点击\"Heroes\"链接或把 `localhost:3000/heroes` 粘贴到地址栏时,它应该导航到列表页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###REDIRECTINGROUTES", "original": "### Redirecting routes", "translation": "### 重定向路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPREFERREDSOLUTIONISTOADDAREDIRECTROUTETHATTRANSLATESTHEINITIALRELATIVEURLTOTHEDESIREDDEFAULTPATHHEROESTHEBROWSERADDRESSBARSHOWSHEROESASIFYOUDNAVIGATEDTHEREDIRECTLY", "original": "The preferred solution is to add a `redirect` route that translates the initial relative URL (`''`)\nto the desired default path (`/heroes`). The browser address bar shows `.../heroes` as if you'd navigated there directly.", "translation": "首选方案是添加一个 `redirect` 路由来把最初的相对路径(`''`)转换成期望的默认路径(`/heroes`)。\n浏览器地址栏会显示 `.../heroes`,就像你直接导航到那里一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDTHEDEFAULTROUTESOMEWHEREABOVETHEWILDCARDROUTEITSJUSTABOVETHEWILDCARDROUTEINTHEFOLLOWINGEXCERPTSHOWINGTHECOMPLETEAPPROUTESFORTHISMILESTONE", "original": "Add the default route somewhere _above_ the wildcard route.\nIt's just above the wildcard route in the following excerpt showing the complete `appRoutes` for this milestone.", "translation": "在通配符路由*上方*添加一个默认路由。\n在下方的代码片段中,它出现在通配符路由的紧上方,展示了这个里程碑的完整 `appRoutes`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AREDIRECTROUTEREQUIRESAPATHMATCHPROPERTYTOTELLTHEROUTERHOWTOMATCHAURLTOTHEPATHOFAROUTETHEROUTERTHROWSANERRORIFYOUDONTINTHISAPPTHEROUTERSHOULDSELECTTHEROUTETOTHEHEROLISTCOMPONENTONLYWHENTHEENTIREURLMATCHESSOSETTHEPATHMATCHVALUETOFULL", "original": "A redirect route requires a `pathMatch` property to tell the router how to match a URL to the path of a route.\nThe router throws an error if you don't.\nIn this app, the router should select the route to the `HeroListComponent` only when the *entire URL* matches `''`,\nso set the `pathMatch` value to `'full'`.", "translation": "重定向路由需要一个 `pathMatch` 属性,来告诉路由器如何用 URL 去匹配路由的路径,否则路由器就会报错。\n在本应用中,路由器应该只有在*完整的 URL*等于 `''` 时才选择 `HeroListComponent` 组件,因此要把 `pathMatch` 设置为 `'full'`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TECHNICALLYPATHMATCHFULLRESULTSINAROUTEHITWHENTHEREMAININGUNMATCHEDSEGMENTSOFTHEURLMATCHINTHISEXAMPLETHEREDIRECTISINATOPLEVELROUTESOTHEREMAININGURLANDTHEENTIREURLARETHESAMETHING", "original": "Technically, `pathMatch = 'full'` results in a route hit when the *remaining*, unmatched segments of the URL match `''`.\nIn this example, the redirect is in a top level route so the *remaining* URL and the *entire* URL are the same thing.", "translation": "从技术角度说,`pathMatch = 'full'` 导致 URL 中*剩下的*、未匹配的部分必须等于 `''`。\n在这个例子中,跳转路由在一个顶级路由中,因此*剩下的*URL 和*完整的*URL 是一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEOTHERPOSSIBLEPATHMATCHVALUEISPREFIXWHICHTELLSTHEROUTERTOMATCHTHEREDIRECTROUTEWHENTHEREMAININGURLBEGINSWITHTHEREDIRECTROUTESPREFIXPATH", "original": "The other possible `pathMatch` value is `'prefix'` which tells the router\nto match the redirect route when the *remaining* URL ***begins*** with the redirect route's _prefix_ path.", "translation": "`pathMatch` 的另一个可能的值是 `'prefix'`,它会告诉路由器:当*剩下的*URL 以这个跳转路由中的 `prefix` 值开头时,就会匹配上这个跳转路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DONTDOTHATHEREIFTHEPATHMATCHVALUEWEREPREFIXEVERYURLWOULDMATCH", "original": "Don't do that here.\nIf the `pathMatch` value were `'prefix'`, _every_ URL would match `''`.", "translation": "在这里不能这么做!如果 `pathMatch` 的值是 `'prefix'`,那么*每个*URL 都会匹配上 `''`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TRYSETTINGITTOPREFIXTHENCLICKTHEGOTOSIDEKICKSBUTTONREMEMBERTHATSABADURLANDYOUSHOULDSEETHEPAGENOTFOUNDPAGEINSTEADYOURESTILLONTHEHEROESPAGEENTERABADURLINTHEBROWSERADDRESSBARYOUREINSTANTLYREROUTEDTOHEROESEVERYURLGOODORBADTHATFALLSTHROUGHTOTHISROUTEDEFINITIONWILLBEAMATCH", "original": "Try setting it to `'prefix'` then click the `Go to sidekicks` button.\nRemember that's a bad URL and you should see the \"Page not found\" page.\nInstead, you're still on the \"Heroes\" page.\nEnter a bad URL in the browser address bar.\nYou're instantly re-routed to `/heroes`.\n_Every_ URL, good or bad, that falls through to _this_ route definition\nwill be a match.", "translation": "尝试把它设置为 `'prefix'`,然后点击 `Go to sidekicks` 按钮。别忘了,它是一个无效 URL,本应显示“Page not found”页。\n但是,你仍然在“英雄列表”页中。在地址栏中输入一个无效的 URL,你又被路由到了 `/heroes`。\n*每一个* URL,无论有效与否,都会匹配上这个路由定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEDEFAULTROUTESHOULDREDIRECTTOTHEHEROLISTCOMPONENTONLYWHENTHEENTIREURLISREMEMBERTORESTORETHEREDIRECTTOPATHMATCHFULL", "original": "The default route should redirect to the `HeroListComponent` _only_ when the _entire_ url is `''`.\nRemember to restore the redirect to `pathMatch = 'full'`.", "translation": "默认路由应该只有在*整个*URL 等于 `''` 时才重定向到 `HeroListComponent`,别忘了把重定向路由设置为 `pathMatch = 'full'`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LEARNMOREINVICTORSAVKINSPOSTONREDIRECTSHTTP:VICTORSAVKINCOMPOST146722301646ANGULARROUTEREMPTYPATHSCOMPONENTLESSROUTES", "original": "Learn more in Victor Savkin's\n[post on redirects](http://victorsavkin.com/post/146722301646/angular-router-empty-paths-componentless-routes).", "translation": "要了解更多,参见 Victor Savkin 的帖子[关于重定向](http://victorsavkin.com/post/146722301646/angular-router-empty-paths-componentless-routes)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###BASICSWRAPUP", "original": "### Basics wrap up", "translation": "### “起步阶段”总结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVEGOTAVERYBASICNAVIGATINGAPPONETHATCANSWITCHBETWEENTWOVIEWSWHENTHEUSERCLICKSALINK", "original": "You've got a very basic navigating app, one that can switch between two views\nwhen the user clicks a link.", "translation": "你得到了一个非常基本的、带导航的应用,当用户点击链接时,它能在两个视图之间切换。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVELEARNEDHOWTODOTHEFOLLOWING:", "original": "You've learned how to do the following:", "translation": "你学到了如何:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LOADTHEROUTERLIBRARY", "original": "* Load the router library.", "translation": "加载路由库", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDANAVBARTOTHESHELLTEMPLATEWITHANCHORTAGSROUTERLINKANDROUTERLINKACTIVEDIRECTIVES", "original": "* Add a nav bar to the shell template with anchor tags, `routerLink` and `routerLinkActive` directives.", "translation": "往壳组件的模板中添加一个导航条,导航条中有一些 A 标签、`routerLink` 指令和 `routerLinkActive` 指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDAROUTEROUTLETTOTHESHELLTEMPLATEWHEREVIEWSWILLBEDISPLAYED", "original": "* Add a `router-outlet` to the shell template where views will be displayed.", "translation": "往壳组件的模板中添加一个 `router-outlet` 指令,视图将会被显示在那里", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CONFIGURETHEROUTERMODULEWITHROUTERMODULEFORROOT", "original": "* Configure the router module with `RouterModule.forRoot`.", "translation": "用 `RouterModule.forRoot` 配置路由器模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SETTHEROUTERTOCOMPOSEHTML5BROWSERURLS", "original": "* Set the router to compose HTML5 browser URLs.", "translation": "设置路由器,使其合成 HTML5 模式的浏览器 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HANDLEINVALIDROUTESWITHAWILDCARDROUTE", "original": "* handle invalid routes with a `wildcard` route.", "translation": "使用通配符路由来处理无效路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NAVIGATETOTHEDEFAULTROUTEWHENTHEAPPLAUNCHESWITHANEMPTYPATH", "original": "* navigate to the default route when the app launches with an empty path.", "translation": "当应用在空路径下启动时,导航到默认路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THERESTOFTHESTARTERAPPISMUNDANEWITHLITTLEINTERESTFROMAROUTERPERSPECTIVEHEREARETHEDETAILSFORREADERSINCLINEDTOBUILDTHESAMPLETHROUGHTOTHISMILESTONE", "original": "The rest of the starter app is mundane, with little interest from a router perspective.\nHere are the details for readers inclined to build the sample through to this milestone.", "translation": "这个初学者应用的其它部分有点平淡无奇,从路由器的角度来看也很平淡。\n如果你还是倾向于在这个里程碑里构建它们,参见下面的构建详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESTARTERAPPSSTRUCTURELOOKSLIKETHIS:", "original": "The starter app's structure looks like this:", "translation": "这个初学者应用的结构是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HEREARETHEFILESDISCUSSEDINTHISMILESTONE", "original": "Here are the files discussed in this milestone.", "translation": "下面是当前里程碑中讨论过的文件列表:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##MILESTONE2:ROUTINGMODULE", "original": "## Milestone 2: *Routing module*", "translation": "## 里程碑 #2:**路由模块**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHEINITIALROUTECONFIGURATIONYOUPROVIDEDASIMPLESETUPWITHTWOROUTESUSEDTOCONFIGURETHEAPPLICATIONFORROUTINGTHISISPERFECTLYFINEFORSIMPLEROUTINGASTHEAPPLICATIONGROWSANDYOUMAKEUSEOFMOREROUTERFEATURESSUCHASGUARDSRESOLVERSANDCHILDROUTINGYOULLNATURALLYWANTTOREFACTORTHEROUTINGCONFIGURATIONINTOITSOWNFILEWERECOMMENDMOVINGTHEROUTINGINFORMATIONINTOASPECIALPURPOSEMODULECALLEDAROUTINGMODULE", "original": "In the initial route configuration, you provided a simple setup with two routes used\nto configure the application for routing. This is perfectly fine for simple routing.\nAs the application grows and you make use of more `Router` features, such as guards,\nresolvers, and child routing, you'll naturally want to refactor the routing configuration into its own file.\nWe recommend moving the routing information into a special-purpose module called a *Routing Module*.", "translation": "在原始的路由配置中,你提供了仅有两个路由的简单配置来设置应用的路由。对于简单的路由,这没有问题。\n 随着应用的成长,你用到了更多**路由器**特性,比如守卫、解析器和子路由等,你会很自然地想要重构路由。\n 我们建议将路由信息移到一个单独的特殊用途的模块,叫做**路由模块**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTINGMODULEHASSEVERALCHARACTERISTICS:", "original": "The **Routing Module** has several characteristics:", "translation": "**路由模块**有一系列特性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SEPARATESROUTINGCONCERNSFROMOTHERAPPLICATIONCONCERNS", "original": "* Separates routing concerns from other application concerns.", "translation": "把路由这个关注点从其它应用类关注点中分离出去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PROVIDESAMODULETOREPLACEORREMOVEWHENTESTINGTHEAPPLICATION", "original": "* Provides a module to replace or remove when testing the application.", "translation": "测试特性模块时,可以替换或移除路由模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PROVIDESAWELLKNOWNLOCATIONFORROUTINGSERVICEPROVIDERSINCLUDINGGUARDSANDRESOLVERS", "original": "* Provides a well-known location for routing service providers including guards and resolvers.", "translation": "为路由服务提供商(包括守卫和解析器等)提供一个共同的地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DOESNOTDECLARECOMPONENTS", "original": "* Does **not** declare components.", "translation": "**不要**声明组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###REFACTORTHEROUTINGCONFIGURATIONINTOAROUTINGMODULE", "original": "### Refactor the routing configuration into a _routing module_", "translation": "### 将路由配置重构为*路由模块*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEAFILENAMEDAPPROUTINGMODULETSINTHEAPPFOLDERTOCONTAINTHEROUTINGMODULE", "original": "Create a file named `app-routing.module.ts` in the `/app` folder to contain the routing module.", "translation": "在 `/app` 目录下创建一个名叫 `app-routing.module.ts` 的文件,以包含这个路由模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTTHECRISISLISTCOMPONENTANDTHEHEROLISTCOMPONENTCOMPONENTSJUSTLIKEYOUDIDINTHEAPPMODULETSTHENMOVETHEROUTERIMPORTSANDROUTINGCONFIGURATIONINCLUDINGROUTERMODULEFORROOTINTOTHISROUTINGMODULE", "original": "Import the `CrisisListComponent` and the `HeroListComponent` components\njust like you did in the `app.module.ts`. Then move the `Router` imports\nand routing configuration, including `RouterModule.forRoot`, into this routing module.", "translation": "导入 `CrisisListComponent` 和 `HeroListComponent` 组件,就像 `app.module.ts` 中一样。然后把 `Router` 的导入语句和路由配置以及 `RouterModule.forRoot` 移入这个路由模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "FOLLOWINGCONVENTIONADDACLASSNAMEAPPROUTINGMODULEANDEXPORTITSOYOUCANIMPORTITLATERINAPPMODULE", "original": "Following convention, add a class name `AppRoutingModule` and export it\nso you can import it later in `AppModule`.", "translation": "遵循规约,添加一个 `AppRoutingModule` 类并导出它,以便稍后在 `AppModule` 中导入它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "FINALLYREEXPORTTHEANGULARROUTERMODULEBYADDINGITTOTHEMODULEEXPORTSARRAYBYREEXPORTINGTHEROUTERMODULEHEREANDIMPORTINGAPPROUTINGMODULEINAPPMODULETHECOMPONENTSDECLAREDINAPPMODULEWILLHAVEACCESSTOROUTERDIRECTIVESSUCHASROUTERLINKANDROUTEROUTLET", "original": "Finally, re-export the Angular `RouterModule` by adding it to the module `exports` array.\nBy re-exporting the `RouterModule` here and importing `AppRoutingModule` in `AppModule`,\nthe components declared in `AppModule` will have access to router directives such as `RouterLink` and `RouterOutlet`.", "translation": "最后,可以通过把它添加到该模块的 `exports` 数组中来再次导出 `RouterModule`。\n通过在 `AppModule` 中导入 `AppRoutingModule` 并再次导出 `RouterModule`,那些声明在 `AppModule` 中的组件就可以访问路由指令了,比如 `RouterLink` 和 `RouterOutlet`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AFTERTHESESTEPSTHEFILESHOULDLOOKLIKETHIS", "original": "After these steps, the file should look like this.", "translation": "做完这些之后,该文件变成了这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NEXTUPDATETHEAPPMODULETSFILEFIRSTIMPORTINGTHENEWLYCREATEDAPPROUTINGMODULEFROMAPPROUTINGMODULETSTHENREPLACINGROUTERMODULEFORROOTINTHEIMPORTSARRAYWITHTHEAPPROUTINGMODULE", "original": "Next, update the `app.module.ts` file,\nfirst importing the newly created `AppRoutingModule`from `app-routing.module.ts`,\nthen replacing `RouterModule.forRoot` in the `imports` array with the `AppRoutingModule`.", "translation": "接下来,修改 `app.module.ts` 文件,首先从 `app-routing.module.ts` 中导入新创建的 `AppRoutingModule`,\n然后把 `imports` 数组中的 `RouterModule.forRoot` 替换为 `AppRoutingModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LATERINTHISGUIDEYOUWILLCREATEMULTIPLEROUTINGMODULES#HEROROUTINGMODULEANDDISCOVERTHATYOUMUSTIMPORTTHOSEROUTINGMODULESINTHECORRECTORDER#ROUTINGMODULEORDER", "original": "Later in this guide you will create [multiple routing modules](#hero-routing-module) and discover that\nyou must import those routing modules [in the correct order](#routing-module-order).", "translation": "本章稍后的部分,你将创建一个[多路由模块](guide/router#hero-routing-module),并揭示你为何必须[以正确的顺序导入那些路由模块](guide/router#routing-module-order)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPLICATIONCONTINUESTOWORKJUSTTHESAMEANDYOUCANUSEAPPROUTINGMODULEASTHECENTRALPLACETOMAINTAINFUTUREROUTINGCONFIGURATION", "original": "The application continues to work just the same, and you can use `AppRoutingModule` as\nthe central place to maintain future routing configuration.", "translation": "应用继续正常运行,你可以把路由模块作为为每个特性模块维护路由配置的中心地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###DOYOUNEEDAROUTINGMODULE", "original": "### Do you need a _Routing Module_?", "translation": "### 你需要**路由模块**吗?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTINGMODULEREPLACESTHEROUTINGCONFIGURATIONINTHEROOTORFEATUREMODULEEITHERCONFIGUREROUTESINTHEROUTINGMODULEORWITHINTHEMODULEITSELFBUTNOTINBOTH", "original": "The _Routing Module_ *replaces* the routing configuration in the root or feature module.\n_Either_ configure routes in the Routing Module _or_ within the module itself but not in both.", "translation": "**路由模块**在根模块或者特性模块替换了路由配置。在路由模块或者在模块内部配置路由,但不要同时在两处都配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTINGMODULEISADESIGNCHOICEWHOSEVALUEISMOSTOBVIOUSWHENTHECONFIGURATIONISCOMPLEXANDINCLUDESSPECIALIZEDGUARDANDRESOLVERSERVICESITCANSEEMLIKEOVERKILLWHENTHEACTUALCONFIGURATIONISDEADSIMPLE", "original": "The Routing Module is a design choice whose value is most obvious when the configuration is complex\nand includes specialized guard and resolver services.\nIt can seem like overkill when the actual configuration is dead simple.", "translation": "路由模块是设计选择,它的价值在配置很复杂,并包含专门守卫和解析器服务时尤其明显。\n在配置很简单时,它可能看起来很多余。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SOMEDEVELOPERSSKIPTHEROUTINGMODULEFOREXAMPLEAPPROUTINGMODULEWHENTHECONFIGURATIONISSIMPLEANDMERGETHEROUTINGCONFIGURATIONDIRECTLYINTOTHECOMPANIONMODULEFOREXAMPLEAPPMODULE", "original": "Some developers skip the Routing Module (for example, `AppRoutingModule`) when the configuration is simple and\nmerge the routing configuration directly into the companion module (for example, `AppModule`).", "translation": "在配置很简单时,一些开发者跳过路由模块(例如 `AppRoutingModule`),并将路由配置直接混合在关联模块中(比如 `AppModule` )。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CHOOSEONEPATTERNORTHEOTHERANDFOLLOWTHATPATTERNCONSISTENTLY", "original": "Choose one pattern or the other and follow that pattern consistently.", "translation": "从中选择一种模式,并坚持模式的一致性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MOSTDEVELOPERSSHOULDALWAYSIMPLEMENTAROUTINGMODULEFORTHESAKEOFCONSISTENCYITKEEPSTHECODECLEANWHENCONFIGURATIONBECOMESCOMPLEXITMAKESTESTINGTHEFEATUREMODULEEASIERITSEXISTENCECALLSATTENTIONTOTHEFACTTHATAMODULEISROUTEDITISWHEREDEVELOPERSEXPECTTOFINDANDEXPANDROUTINGCONFIGURATION", "original": "Most developers should always implement a Routing Module for the sake of consistency.\nIt keeps the code clean when configuration becomes complex.\nIt makes testing the feature module easier.\nIts existence calls attention to the fact that a module is routed.\nIt is where developers expect to find and expand routing configuration.", "translation": "大多数开发者都应该采用路由模块,以保持一致性。\n它在配置复杂时,能确保代码干净。\n它让测试特性模块更加容易。\n它的存在让人一眼就能看出这个模块是带路由的。\n开发者可以很自然的从路由模块中查找和扩展路由配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##MILESTONE3:HEROESFEATURE", "original": "## Milestone 3: Heroes feature", "translation": "## 里程碑 #2 英雄特征区", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVESEENHOWTONAVIGATEUSINGTHEROUTERLINKDIRECTIVENOWYOULLLEARNTHEFOLLOWING:", "original": "You've seen how to navigate using the `RouterLink` directive.\nNow you'll learn the following:", "translation": "你刚刚学习了如何用 `RouterLink` 指令进行导航。接下来要:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ORGANIZETHEAPPANDROUTESINTOFEATUREAREASUSINGMODULES", "original": "* Organize the app and routes into *feature areas* using modules.", "translation": "用模块把应用和路由组织为一些*特性区*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NAVIGATEIMPERATIVELYFROMONECOMPONENTTOANOTHER", "original": "* Navigate imperatively from one component to another.", "translation": "命令式的从一个组件导航到另一个", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PASSREQUIREDANDOPTIONALINFORMATIONINROUTEPARAMETERS", "original": "* Pass required and optional information in route parameters.", "translation": "通过路由传递必要信息和可选信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISEXAMPLERECREATESTHEHEROESFEATUREINTHESERVICESEPISODEOFTHETOUROFHEROESTUTORIALTUTORIALTOHPT4TOUROFHEROES:SERVICESANDYOULLBECOPYINGMUCHOFTHECODEFROMTHELIVEEXAMPLENAMETOHPT4TITLETOUROFHEROES:SERVICESEXAMPLECODELIVEEXAMPLE", "original": "This example recreates the heroes feature in the \"Services\" episode of the\n[Tour of Heroes tutorial](tutorial/toh-pt4 \"Tour of Heroes: Services\"),\nand you'll be copying much of the code\nfrom the <live-example name=\"toh-pt4\" title=\"Tour of Heroes: Services example code\"></live-example>.", "translation": "这个例子重写了[《英雄指南》](tutorial/toh-pt4 \"Tour of Heroes: Services\")的“服务”部分的英雄列表特性,你可以从<live-example name=\"toh-pt4\" title=\"英雄指南:各个服务的范例代码\"></live-example>中复制大部分代码过来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HERESHOWTHEUSERWILLEXPERIENCETHISVERSIONOFTHEAPP:", "original": "Here's how the user will experience this version of the app:", "translation": "下面是用户将看到的版本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ATYPICALAPPLICATIONHASMULTIPLEFEATUREAREASEACHDEDICATEDTOAPARTICULARBUSINESSPURPOSE", "original": "A typical application has multiple *feature areas*,\neach dedicated to a particular business purpose.", "translation": "典型的应用具有多个*特性区*,每个特性区都专注于特定的业务用途。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHILEYOUCOULDCONTINUETOADDFILESTOTHESRCAPPFOLDERTHATISUNREALISTICANDULTIMATELYNOTMAINTAINABLEMOSTDEVELOPERSPREFERTOPUTEACHFEATUREAREAINITSOWNFOLDER", "original": "While you could continue to add files to the `src/app/` folder,\nthat is unrealistic and ultimately not maintainable.\nMost developers prefer to put each feature area in its own folder.", "translation": "虽然你也可以把文件都放在 `src/app/` 目录下,但那样是不现实的,而且很难维护。\n大部分开发人员更喜欢把每个特性区都放在它自己的目录下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUAREABOUTTOBREAKUPTHEAPPINTODIFFERENTFEATUREMODULESEACHWITHITSOWNCONCERNSTHENYOULLIMPORTINTOTHEMAINMODULEANDNAVIGATEAMONGTHEM", "original": "You are about to break up the app into different *feature modules*, each with its own concerns.\nThen you'll import into the main module and navigate among them.", "translation": "你准备把应用拆分成多个不同的*特性模块*,每个特有模块都有自己的关注点。\n然后,你就会把它们导入到主模块中,并且在它们之间导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ADDHEROESFUNCTIONALITY", "original": "### Add heroes functionality", "translation": "### 添加英雄管理功能", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "FOLLOWTHESESTEPS:", "original": "Follow these steps:", "translation": "按照下列步骤:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATETHESRCAPPHEROESFOLDERYOULLBEADDINGFILESIMPLEMENTINGHEROMANAGEMENTTHERE", "original": "* Create the `src/app/heroes` folder; you'll be adding files implementing *hero management* there.", "translation": "创建 `src/app/heroes` 文件夹,你将会把*英雄管理*功能的实现文件放在这里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DELETETHEPLACEHOLDERHEROLISTCOMPONENTTSTHATSINTHEAPPFOLDER", "original": "* Delete the placeholder `hero-list.component.ts` that's in the `app` folder.", "translation": "在 `app` 目录下删除占位用的 `hero-list.component.ts` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEANEWHEROLISTCOMPONENTTSUNDERSRCAPPHEROES", "original": "* Create a new `hero-list.component.ts` under `src/app/heroes`.", "translation": "在 `src/app/heroes` 目录下创建新的 `hero-list.component.ts` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "COPYINTOITTHECONTENTSOFTHEAPPCOMPONENTTSFROMTHELIVEEXAMPLENAMETOHPT4TITLETOUROFHEROES:SERVICESEXAMPLECODESERVICESTUTORIALLIVEEXAMPLE", "original": "* Copy into it the contents of the `app.component.ts` from\n the <live-example name=\"toh-pt4\" title=\"Tour of Heroes: Services example code\">\"Services\" tutorial</live-example>.", "translation": "把<live-example name=\"toh-pt4\" title=\"《英雄指南》:各个服务的范例代码\"></live-example>复制到 `app.component.ts` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MAKEAFEWMINORBUTNECESSARYCHANGES:", "original": "* Make a few minor but necessary changes:", "translation": "做一些微小但必要的修改:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DELETETHESELECTORROUTEDCOMPONENTSDONTNEEDTHEM", "original": "* Delete the `selector` (routed components don't need them).", "translation": "删除 `selector`(路由组件不需要它们)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DELETETHEH1", "original": "* Delete the `<h1>`.", "translation": "删除 `<h1>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RELABELTHEH2TOH2HEROESH2", "original": "* Relabel the `<h2>` to `<h2>HEROES</h2>`.", "translation": "给 `<h2>` 加文字,改成 `<h2>HEROES</h2>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DELETETHEHERODETAILATTHEBOTTOMOFTHETEMPLATE", "original": "* Delete the `<hero-detail>` at the bottom of the template.", "translation": "删除模板底部的 `<hero-detail>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RENAMETHEAPPCOMPONENTCLASSTOHEROLISTCOMPONENT", "original": "* Rename the `AppComponent` class to `HeroListComponent`.", "translation": "把 `AppComponent` 类改名为 `HeroListComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "COPYTHEHERODETAILCOMPONENTTSANDTHEHEROSERVICETSFILESINTOTHEHEROESSUBFOLDER", "original": "* Copy the `hero-detail.component.ts` and the `hero.service.ts` files into the `heroes` subfolder.", "translation": "把 `hero-detail.component.ts` 和 `hero.service.ts` 复制到 `heroes` 子目录下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEAPREROUTINGHEROESMODULETSINTHEHEROESFOLDERTHATLOOKSLIKETHIS:", "original": "* Create a (pre-routing) `heroes.module.ts` in the heroes folder that looks like this:", "translation": "在 `heroes` 子目录下(不带路由)的 `heroes.module.ts` 文件,内容如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENYOUREDONEYOULLHAVETHESEHEROMANAGEMENTFILES:", "original": "When you're done, you'll have these *hero management* files:", "translation": "安排完这些,你就有了四个*英雄管理*特性区的文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###HEROFEATUREROUTINGREQUIREMENTS", "original": "### *Hero* feature routing requirements", "translation": "### *英雄*特性区的路由需求", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEHEROESFEATUREHASTWOINTERACTINGCOMPONENTSTHEHEROLISTANDTHEHERODETAILTHELISTVIEWISSELFSUFFICIENTYOUNAVIGATETOITITGETSALISTOFHEROESANDDISPLAYSTHEM", "original": "The heroes feature has two interacting components, the hero list and the hero detail.\nThe list view is self-sufficient; you navigate to it, it gets a list of heroes and displays them.", "translation": "“英雄”特性有两个相互协作的组件,列表和详情。\n列表视图是自给自足的,你导航到它,它会自行获取英雄列表并显示他们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEDETAILVIEWISDIFFERENTITDISPLAYSAPARTICULARHEROITCANTKNOWWHICHHEROTOSHOWONITSOWNTHATINFORMATIONMUSTCOMEFROMOUTSIDE", "original": "The detail view is different. It displays a particular hero. It can't know which hero to show on its own.\nThat information must come from outside.", "translation": "详情视图就不同了。它要显示一个特定的英雄,但是它本身却无法知道显示哪一个,此信息必须来自外部。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENTHEUSERSELECTSAHEROFROMTHELISTTHEAPPSHOULDNAVIGATETOTHEDETAILVIEWANDSHOWTHATHEROYOUTELLTHEDETAILVIEWWHICHHEROTODISPLAYBYINCLUDINGTHESELECTEDHEROSIDINTHEROUTEURL", "original": "When the user selects a hero from the list, the app should navigate to the detail view\nand show that hero.\nYou tell the detail view which hero to display by including the selected hero's id in the route URL.", "translation": "当用户从列表中选择了一个英雄时,应用就导航到详情页以显示那个英雄。\n 通过把所选英雄的 id 编码进路由的 URL 中,就能告诉详情视图该显示哪个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###HEROFEATUREROUTECONFIGURATION", "original": "### *Hero* feature route configuration", "translation": "### *英雄*特性区的路由配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEANEWHEROESROUTINGMODULETSINTHEHEROESFOLDERUSINGTHESAMETECHNIQUESYOULEARNEDWHILECREATINGTHEAPPROUTINGMODULE", "original": "Create a new `heroes-routing.module.ts` in the `heroes` folder\nusing the same techniques you learned while creating the `AppRoutingModule`.", "translation": "在 `heroes` 目录下创建一个新的 `heroes-routing.module.ts` 文件,使用的技术和以前创建 `AppRoutingModule` 时的一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PUTTHEROUTINGMODULEFILEINTHESAMEFOLDERASITSCOMPANIONMODULEFILEHEREBOTHHEROESROUTINGMODULETSANDHEROESMODULETSAREINTHESAMESRCAPPHEROESFOLDER", "original": "Put the routing module file in the same folder as its companion module file.\nHere both `heroes-routing.module.ts` and `heroes.module.ts` are in the same `src/app/heroes` folder.", "translation": "把路由模块文件和它对应的模块文件放在同一个目录下。\n比如这里的 `heroes-routing.module.ts` 和 `heroes.module.ts` 都位于 `src/app/heroes` 目录下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CONSIDERGIVINGEACHFEATUREMODULEITSOWNROUTECONFIGURATIONFILEITMAYSEEMLIKEOVERKILLEARLYWHENTHEFEATUREROUTESARESIMPLEBUTROUTESHAVEATENDENCYTOGROWMORECOMPLEXANDCONSISTENCYINPATTERNSPAYSOFFOVERTIME", "original": "Consider giving each feature module its own route configuration file.\nIt may seem like overkill early when the feature routes are simple.\nBut routes have a tendency to grow more complex and consistency in patterns pays off over time.", "translation": "将路由模块文件放到它相关的模块文件所在目录里。\n这里,`heroes-routing.module.ts` 和 `heroes.module.ts` 都在 `app/heroes` 目录中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTTHEHEROCOMPONENTSFROMTHEIRNEWLOCATIONSINTHESRCAPPHEROESFOLDERDEFINETHETWOHEROROUTESANDEXPORTTHEHEROROUTINGMODULECLASS", "original": "Import the hero components from their new locations in the `src/app/heroes/` folder, define the two hero routes,\nand export the `HeroRoutingModule` class.", "translation": "从新位置 `src/app/heroes/` 目录中导入英雄相关的组件,定义两个“英雄管理”路由,并导出 `HeroRoutingModule` 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWTHATYOUHAVEROUTESFORTHEHEROESMODULEREGISTERTHEMWITHTHEROUTERVIATHEROUTERMODULEALMOSTASYOUDIDINTHEAPPROUTINGMODULE", "original": "Now that you have routes for the `Heroes` module, register them with the `Router` via the\n`RouterModule` _almost_ as you did in the `AppRoutingModule`.", "translation": "现在,你有了 `Heroes` 模块的路由,还得在 `RouterModule` 中把它们注册给*路由器*,和 `AppRoutingModule` 中的做法几乎完全一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEREISASMALLBUTCRITICALDIFFERENCEINTHEAPPROUTINGMODULEYOUUSEDTHESTATICROUTERMODULEFORROOTMETHODTOREGISTERTHEROUTESANDAPPLICATIONLEVELSERVICEPROVIDERSINAFEATUREMODULEYOUUSETHESTATICFORCHILDMETHOD", "original": "There is a small but critical difference.\nIn the `AppRoutingModule`, you used the static **`RouterModule.forRoot`** method to register the routes and application level service providers.\nIn a feature module you use the static **`forChild`** method.", "translation": "这里有少量但是关键的不同点。\n在 `AppRoutingModule` 中,你使用了静态的 `RouterModule.`**`forRoot`**方法来注册路由和全应用级服务提供商。\n在特性模块中,你要改用**`forChild`**静态方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ONLYCALLROUTERMODULEFORROOTINTHEROOTAPPROUTINGMODULEORTHEAPPMODULEIFTHATSWHEREYOUREGISTERTOPLEVELAPPLICATIONROUTESINANYOTHERMODULEYOUMUSTCALLTHEROUTERMODULEFORCHILDMETHODTOREGISTERADDITIONALROUTES", "original": "Only call `RouterModule.forRoot` in the root `AppRoutingModule`\n(or the `AppModule` if that's where you register top level application routes).\nIn any other module, you must call the **`RouterModule.forChild`** method to register additional routes.", "translation": "只在根模块 `AppRoutingModule` 中调用 `RouterModule.forRoot`(如果在 `AppModule` 中注册应用的顶级路由,那就在 `AppModule` 中调用)。\n在其它模块中,你就必须调用**`RouterModule.forChild`**方法来注册附属路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ADDTHEROUTINGMODULETOTHEHEROESMODULE", "original": "### Add the routing module to the _HeroesModule_", "translation": "### 把路由模块添加到 `HeroesModule` 中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDTHEHEROROUTINGMODULETOTHEHEROMODULEJUSTASYOUADDEDAPPROUTINGMODULETOTHEAPPMODULE", "original": "Add the `HeroRoutingModule` to the `HeroModule`\njust as you added `AppRoutingModule` to the `AppModule`.", "translation": "把 `HeroRoutingModule` 添加到 `HeroModule` 中,就像为 `AppModule` 添加 `AppRoutingModule` 一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "OPENHEROESMODULETSIMPORTTHEHEROROUTINGMODULETOKENFROMHEROESROUTINGMODULETSANDADDITTOTHEIMPORTSARRAYOFTHEHEROESMODULETHEFINISHEDHEROESMODULELOOKSLIKETHIS:", "original": "Open `heroes.module.ts`.\nImport the `HeroRoutingModule` token from `heroes-routing.module.ts` and\nadd it to the `imports` array of the `HeroesModule`.\nThe finished `HeroesModule` looks like this:", "translation": "打开 `heroes.module.ts`,从 `heroes-routing.module.ts` 中导入 `HeroRoutingModule` 并把它添加到 `HeroesModule` 的 `imports` 数组中。\n写完后的 `HeroesModule` 是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###REMOVEDUPLICATEHEROROUTES", "original": "### Remove duplicate hero routes", "translation": "### 移除重复的“英雄管理”路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEHEROROUTESARECURRENTLYDEFINEDINTWOPLACES:INTHEHEROESROUTINGMODULEBYWAYOFTHEHEROESMODULEANDINTHEAPPROUTINGMODULE", "original": "The hero routes are currently defined in _two_ places: in the `HeroesRoutingModule`,\nby way of the `HeroesModule`, and in the `AppRoutingModule`.", "translation": "英雄类的路由目前定义在两个地方:`HeroesRoutingModule` 中(并最终给 `HeroesModule`)和 `AppRoutingModule` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ROUTESPROVIDEDBYFEATUREMODULESARECOMBINEDTOGETHERINTOTHEIRIMPORTEDMODULESROUTESBYTHEROUTERTHISALLOWSYOUTOCONTINUEDEFININGTHEFEATUREMODULEROUTESWITHOUTMODIFYINGTHEMAINROUTECONFIGURATION", "original": "Routes provided by feature modules are combined together into their imported module's routes by the router.\nThis allows you to continue defining the feature module routes without modifying the main route configuration.", "translation": "由特性模块提供的路由会被路由器再组合上它们所导入的模块的路由。\n这让你可以继续定义特性路由模块中的路由,而不用修改主路由配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BUTYOUDONTWANTTODEFINETHESAMEROUTESTWICEREMOVETHEHEROLISTCOMPONENTIMPORTANDTHEHEROESROUTEFROMTHEAPPROUTINGMODULETS", "original": "But you don't want to define the same routes twice.\nRemove the `HeroListComponent` import and the `/heroes` route from the `app-routing.module.ts`.", "translation": "但你显然不希望把同一个路由定义两次,那就移除 `HeroListComponent` 的导入和来自 `app-routing.module.ts` 中的 `/heroes` 路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LEAVETHEDEFAULTANDTHEWILDCARDROUTESTHESEARECONCERNSATTHETOPLEVELOFTHEAPPLICATIONITSELF", "original": "**Leave the default and the wildcard routes!**\nThese are concerns at the top level of the application itself.", "translation": "**保留默认路由和通配符路由!**\n它们是应用程序顶层该自己处理的关注点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###IMPORTHEROMODULEINTOAPPMODULE", "original": "### Import hero module into AppModule", "translation": "### 把“英雄管理”模块导入到 AppModule", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEHEROESFEATUREMODULEISREADYBUTTHEAPPLICATIONDOESNTKNOWABOUTTHEHEROESMODULEYETOPENAPPMODULETSANDREVISEITASFOLLOWS", "original": "The heroes feature module is ready, but the application doesn't know about the `HeroesModule` yet.\nOpen `app.module.ts` and revise it as follows.", "translation": "英雄这个特性模块已经就绪,但应用仍然不知道 `HeroesModule` 的存在。\n打开 `app.module.ts`,并按照下述步骤修改它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTTHEHEROESMODULEANDADDITTOTHEIMPORTSARRAYINTHENGMODULEMETADATAOFTHEAPPMODULE", "original": "Import the `HeroesModule` and add it to the `imports` array in the `@NgModule` metadata of the `AppModule`.", "translation": "导入 `HeroesModule` 并且把它加到根模块 `AppModule` 的 `@NgModule` 元数据中的 `imports` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "REMOVETHEHEROLISTCOMPONENTFROMTHEAPPMODULESDECLARATIONSBECAUSEITSNOWPROVIDEDBYTHEHEROESMODULETHISISIMPORTANTTHERECANBEONLYONEOWNERFORADECLAREDCOMPONENTINTHISCASETHEHEROESMODULEISTHEOWNEROFTHEHEROESCOMPONENTSANDISMAKINGTHEMAVAILABLETOCOMPONENTSINTHEAPPMODULEVIATHEHEROESMODULE", "original": "Remove the `HeroListComponent` from the `AppModule`'s `declarations` because it's now provided by the `HeroesModule`.\nThis is important. There can be only _one_ owner for a declared component.\nIn this case, the `Heroes` module is the owner of the `Heroes` components and is making them available to\ncomponents in the `AppModule` via the `HeroesModule`.", "translation": "从 `AppModule` 的 `declarations` 中移除 `HeroListComponent`,因为它现在已经改由 `HeroesModule` 提供了。\n这一步很重要!因为一个组件只能声明在*一个*属主模块中。\n这个例子中,`Heroes` 模块就是 `Heroes` 组件的属主模块,而 `AppModule` 要通过导入 `HeroesModule` 才能使用这些组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASARESULTTHEAPPMODULENOLONGERHASSPECIFICKNOWLEDGEOFTHEHEROFEATUREITSCOMPONENTSORITSROUTEDETAILSYOUCANEVOLVETHEHEROFEATUREWITHMORECOMPONENTSANDDIFFERENTROUTESTHATSAKEYBENEFITOFCREATINGASEPARATEMODULEFOREACHFEATUREAREA", "original": "As a result, the `AppModule` no longer has specific knowledge of the hero feature, its components, or its route details.\nYou can evolve the hero feature with more components and different routes.\nThat's a key benefit of creating a separate module for each feature area.", "translation": "最终,`AppModule` 不再了解那些特定于“英雄”特性的知识,比如它的组件、路由细节等。\n你可以让“英雄”特性独立演化,添加更多的组件或各种各样的路由。\n这就是为每个特性区创建独立模块后获得的核心优势。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AFTERTHESESTEPSTHEAPPMODULESHOULDLOOKLIKETHIS:", "original": "After these steps, the `AppModule` should look like this:", "translation": "经过这些步骤,`AppModule` 变成了这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###MODULEIMPORTORDERMATTERS", "original": "### Module import order matters", "translation": "### 导入模块的顺序很重要", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LOOKATTHEMODULEIMPORTSARRAYNOTICETHATTHEAPPROUTINGMODULEISLASTMOSTIMPORTANTLYITCOMESAFTERTHEHEROESMODULE", "original": "Look at the module `imports` array. Notice that the `AppRoutingModule` is _last_.\nMost importantly, it comes _after_ the `HeroesModule`.", "translation": "看看该模块的 `imports` 数组。注意,`AppRoutingModule` 是*最后一个*。最重要的是,它位于 `HeroesModule` 之后。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEORDEROFROUTECONFIGURATIONMATTERSTHEROUTERACCEPTSTHEFIRSTROUTETHATMATCHESANAVIGATIONREQUESTPATH", "original": "The order of route configuration matters.\nThe router accepts the first route that matches a navigation request path.", "translation": "路由配置的顺序很重要。\n路由器会接受第一个匹配上导航所要求的路径的那个路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENALLROUTESWEREINONEAPPROUTINGMODULEYOUPUTTHEDEFAULTANDWILDCARD#WILDCARDROUTESLASTAFTERTHEHEROESROUTESOTHATTHEROUTERHADACHANCETOMATCHAURLTOTHEHEROESROUTEBEFOREHITTINGTHEWILDCARDROUTEANDNAVIGATINGTOPAGENOTFOUND", "original": "When all routes were in one `AppRoutingModule`,\nyou put the default and [wildcard](#wildcard) routes last, after the `/heroes` route,\nso that the router had a chance to match a URL to the `/heroes` route _before_\nhitting the wildcard route and navigating to \"Page not found\".", "translation": "当所有路由都在同一个 `AppRoutingModule` 时,你要把默认路由和[通配符路由](guide/router#wildcard)放在最后(这里是在 `/heroes` 路由后面),\n这样路由器才有机会匹配到 `/heroes` 路由,否则它就会先遇到并匹配上该通配符路由,并导航到“页面未找到”路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTESARENOLONGERINONEFILETHEYAREDISTRIBUTEDACROSSTWOMODULESAPPROUTINGMODULEANDHEROESROUTINGMODULE", "original": "The routes are no longer in one file.\nThey are distributed across two modules, `AppRoutingModule` and `HeroesRoutingModule`.", "translation": "这些路由不再位于单一文件中。他们分布在两个不同的模块中:`AppRoutingModule` 和 `HeroesRoutingModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHROUTINGMODULEAUGMENTSTHEROUTECONFIGURATIONINTHEORDEROFIMPORTIFYOULISTAPPROUTINGMODULEFIRSTTHEWILDCARDROUTEWILLBEREGISTEREDBEFORETHEHEROROUTESTHEWILDCARDROUTEMDASHWHICHMATCHESEVERYURLMDASHWILLINTERCEPTTHEATTEMPTTONAVIGATETOAHEROROUTE", "original": "Each routing module augments the route configuration _in the order of import_.\nIf you list `AppRoutingModule` first, the wildcard route will be registered\n_before_ the hero routes.\nThe wildcard route — which matches _every_ URL —\nwill intercept the attempt to navigate to a hero route.", "translation": "每个路由模块都会根据*导入的顺序*把自己的路由配置追加进去。\n如果你先列出了 `AppRoutingModule`,那么通配符路由就会被注册在“英雄管理”路由*之前*。\n通配符路由(它匹配*任意*URL)将会拦截住每一个到“英雄管理”路由的导航,因此事实上屏蔽了所有“英雄管理”路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "REVERSETHEROUTINGMODULESANDSEEFORYOURSELFTHATACLICKOFTHEHEROESLINKRESULTSINPAGENOTFOUNDLEARNABOUTINSPECTINGTHERUNTIMEROUTERCONFIGURATIONBELOW#INSPECTCONFIGINSPECTTHEROUTERCONFIG", "original": "Reverse the routing modules and see for yourself that\na click of the heroes link results in \"Page not found\".\nLearn about inspecting the runtime router configuration\n[below](#inspect-config \"Inspect the router config\").", "translation": "反转路由模块的导入顺序,你就会看到当点击英雄相关的链接时被导向了“页面未找到”路由。\n要学习如何在运行时查看路由器配置,参见[稍后的内容](guide/router#inspect-config \"Inspect the router config\")。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTEDEFINITIONWITHAPARAMETER", "original": "### Route definition with a parameter", "translation": "### 带参数的路由定义", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RETURNTOTHEHEROESROUTINGMODULEANDLOOKATTHEROUTEDEFINITIONSAGAINTHEROUTETOHERODETAILCOMPONENTHASATWIST", "original": "Return to the `HeroesRoutingModule` and look at the route definitions again.\nThe route to `HeroDetailComponent` has a twist.", "translation": "回到 `HeroesRoutingModule` 并再次检查这些路由定义。\n`HeroDetailComponent` 的路由有点特殊。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOTICETHE:IDTOKENINTHEPATHTHATCREATESASLOTINTHEPATHFORAROUTEPARAMETERINTHISCASETHEROUTERWILLINSERTTHEIDOFAHEROINTOTHATSLOT", "original": "Notice the `:id` token in the path. That creates a slot in the path for a **Route Parameter**.\nIn this case, the router will insert the `id` of a hero into that slot.", "translation": "注意路径中的 `:id` 令牌。它为*路由参数*在路径中创建一个“空位”。在这里,路由器把英雄的 `id` 插入到那个“空位”中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFYOUTELLTHEROUTERTONAVIGATETOTHEDETAILCOMPONENTANDDISPLAYMAGNETAYOUEXPECTAHEROIDTOAPPEARINTHEBROWSERURLLIKETHIS:", "original": "If you tell the router to navigate to the detail component and display \"Magneta\",\nyou expect a hero id to appear in the browser URL like this:", "translation": "如果要告诉路由器导航到详情组件,并让它显示“Magneta”,你会期望这个英雄的 `id` 像这样显示在浏览器的 URL 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFAUSERENTERSTHATURLINTOTHEBROWSERADDRESSBARTHEROUTERSHOULDRECOGNIZETHEPATTERNANDGOTOTHESAMEMAGNETADETAILVIEW", "original": "If a user enters that URL into the browser address bar, the router should recognize the\npattern and go to the same \"Magneta\" detail view.", "translation": "如果用户把此 URL 输入到浏览器的地址栏中,路由器就会识别出这种模式,同样进入“Magneta”的详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HEADERROUTEPARAMETER:REQUIREDOROPTIONALHEADER", "original": "<header>Route parameter: Required or optional?</header>", "translation": "<header>路由参数:必须的还是可选的?</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EMBEDDINGTHEROUTEPARAMETERTOKEN:IDINTHEROUTEDEFINITIONPATHISAGOODCHOICEFORTHISSCENARIOBECAUSETHEIDISREQUIREDBYTHEHERODETAILCOMPONENTANDBECAUSETHEVALUE15INTHEPATHCLEARLYDISTINGUISHESTHEROUTETOMAGNETAFROMAROUTEFORSOMEOTHERHERO", "original": "Embedding the route parameter token, `:id`,\nin the route definition path is a good choice for this scenario\nbecause the `id` is *required* by the `HeroDetailComponent` and because\nthe value `15` in the path clearly distinguishes the route to \"Magneta\" from\na route for some other hero.", "translation": "在这个场景下,把路由参数的令牌 `:id` 嵌入到路由定义的 `path` 中是一个好主意,因为对于 `HeroDetailComponent` 来说 `id` 是*必须的*,\n而且路径中的值 `15` 已经足够把到“Magneta”的路由和到其它英雄的路由明确区分开。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###SETTINGTHEROUTEPARAMETERSINTHELISTVIEW", "original": "### Setting the route parameters in the list view", "translation": "### 在列表视图中设置路由参数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AFTERNAVIGATINGTOTHEHERODETAILCOMPONENTYOUEXPECTTOSEETHEDETAILSOFTHESELECTEDHEROYOUNEEDTWOPIECESOFINFORMATION:THEROUTINGPATHTOTHECOMPONENTANDTHEHEROSID", "original": "After navigating to the `HeroDetailComponent`, you expect to see the details of the selected hero.\nYou need *two* pieces of information: the routing path to the component and the hero's `id`.", "translation": "然后导航到 `HeroDetailComponent` 组件。在那里,你期望看到所选英雄的详情,这需要两部分信息:导航目标和该英雄的 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ACCORDINGLYTHELINKPARAMETERSARRAYHASTWOITEMS:THEROUTINGPATHANDAROUTEPARAMETERTHATSPECIFIESTHEIDOFTHESELECTEDHERO", "original": "Accordingly, the _link parameters array_ has *two* items: the routing _path_ and a _route parameter_ that specifies the\n`id` of the selected hero.", "translation": "因此,这个*链接参数数组*中有两个条目:目标路由的**`path`(路径)**,和一个用来指定所选英雄 `id` 的**路由参数**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERCOMPOSESTHEDESTINATIONURLFROMTHEARRAYLIKETHIS:LOCALHOST:3000HERO15", "original": "The router composes the destination URL from the array like this:\n`localhost:3000/hero/15`.", "translation": "路由器从该数组中组合出了目标 URL:\n`localhost:3000/hero/15`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HOWDOESTHETARGETHERODETAILCOMPONENTLEARNABOUTTHATIDDONTANALYZETHEURLLETTHEROUTERDOIT", "original": "How does the target `HeroDetailComponent` learn about that `id`?\nDon't analyze the URL. Let the router do it.", "translation": "目标组件 `HeroDetailComponent` 该怎么知道这个 `id` 参数呢?\n当然不会是自己去分析 URL 了!那是路由器的工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTEREXTRACTSTHEROUTEPARAMETERID:15FROMTHEURLANDSUPPLIESITTOTHEHERODETAILCOMPONENTVIATHEACTIVATEDROUTESERVICE", "original": "The router extracts the route parameter (`id:15`) from the URL and supplies it to\nthe `HeroDetailComponent` via the `ActivatedRoute` service.", "translation": "路由器从 URL 中解析出路由参数(`id:15`),并通过 **ActivatedRoute** 服务来把它提供给 `HeroDetailComponent` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ACTIVATEDROUTEINACTION", "original": "### _Activated Route_ in action", "translation": "### _Activated Route_ 实战", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTTHEROUTERACTIVATEDROUTEANDPARAMMAPTOKENSFROMTHEROUTERPACKAGE", "original": "Import the `Router`, `ActivatedRoute`, and `ParamMap` tokens from the router package.", "translation": "从路由器(`router`)包中导入 `Router`、`ActivatedRoute` 和 `Params` 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTTHESWITCHMAPOPERATORBECAUSEYOUNEEDITLATERTOPROCESSTHEOBSERVABLEROUTEPARAMETERS", "original": "Import the `switchMap` operator because you need it later to process the `Observable` route parameters.", "translation": "这里导入 `switchMap` 操作符是因为你稍后将会处理路由参数的可观察对象 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASUSUALYOUWRITEACONSTRUCTORTHATASKSANGULARTOINJECTSERVICESTHATTHECOMPONENTREQUIRESANDREFERENCETHEMASPRIVATEVARIABLES", "original": "As usual, you write a constructor that asks Angular to inject services\nthat the component requires and reference them as private variables.", "translation": "通常,你会直接写一个构造函数,让 Angular 把组件所需的服务注入进来,自动定义同名的私有变量,并把它们存进去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LATERINTHENGONINITMETHODYOUUSETHEACTIVATEDROUTESERVICETORETRIEVETHEPARAMETERSFORTHEROUTEPULLTHEHEROIDFROMTHEPARAMETERSANDRETRIEVETHEHEROTODISPLAY", "original": "Later, in the `ngOnInit` method, you use the `ActivatedRoute` service to retrieve the parameters for the route,\npull the hero `id` from the parameters and retrieve the hero to display.", "translation": "然后,在 `ngOnInit` 方法中,你用 `ActivatedRoute` 服务来接收路由的参数,从参数中取得该英雄的 `id`,并接收此英雄用于显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPARAMMAPPROCESSINGISABITTRICKYWHENTHEMAPCHANGESYOUGETTHEIDPARAMETERFROMTHECHANGEDPARAMETERS", "original": "The `paramMap` processing is a bit tricky. When the map changes, you `get()`\nthe `id` parameter from the changed parameters.", "translation": "`paramMap` 的处理过程有点稍复杂。当这个 map 的值变化时,你可以从变化之后的参数中 `get()` 到其 `id` 参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THENYOUTELLTHEHEROSERVICETOFETCHTHEHEROWITHTHATIDANDRETURNTHERESULTOFTHEHEROSERVICEREQUEST", "original": "Then you tell the `HeroService` to fetch the hero with that `id` and return the result of the `HeroService` request.", "translation": "然后,让 `HeroService` 去获取一个具有此 `id` 的英雄,并返回这个 `HeroService` 请求的结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUMIGHTTHINKTOUSETHERXJSMAPOPERATORBUTTHEHEROSERVICERETURNSANOBSERVABLEHEROSOYOUFLATTENTHEOBSERVABLEWITHTHESWITCHMAPOPERATORINSTEAD", "original": "You might think to use the RxJS `map` operator.\nBut the `HeroService` returns an `Observable<Hero>`.\nSo you flatten the `Observable` with the `switchMap` operator instead.", "translation": "你可能想使用 RxJS 的 `map` 操作符。\n但 `HeroService` 返回的是一个 `Observable<Hero>`。\n所以你要改用 `switchMap` 操作符来打平这个 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESWITCHMAPOPERATORALSOCANCELSPREVIOUSINFLIGHTREQUESTSIFTHEUSERRENAVIGATESTOTHISROUTEWITHANEWIDWHILETHEHEROSERVICEISSTILLRETRIEVINGTHEOLDIDSWITCHMAPDISCARDSTHATOLDREQUESTANDRETURNSTHEHEROFORTHENEWID", "original": "The `switchMap` operator also cancels previous in-flight requests. If the user re-navigates to this route\nwith a new `id` while the `HeroService` is still retrieving the old `id`, `switchMap` discards that old request and returns the hero for the new `id`.", "translation": "`switchMap` 操作符还会取消以前未完成的在途请求。如果用户使用新的 `id` 再次导航到该路由,而 `HeroService` 仍在接受老 `id` 对应的英雄,那么 `switchMap` 就会抛弃老的请求,并返回这个新 `id` 的英雄信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEOBSERVABLESUBSCRIPTIONWILLBEHANDLEDBYTHEASYNCPIPEANDTHECOMPONENTSHEROPROPERTYWILLBERESETWITHTHERETRIEVEDHERO", "original": "The observable `Subscription` will be handled by the `AsyncPipe` and the component's `hero` property will be (re)set with the retrieved hero.", "translation": "这个可观察对象的 `Subscription`(订阅)将会由 `AsyncPipe` 处理,并且组件的 `hero` 属性将会设置为刚刚接收到的这个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPARAMMAPAPIISINSPIREDBYTHEURLSEARCHPARAMSINTERFACEHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIURLSEARCHPARAMSITPROVIDESMETHODSTOHANDLEPARAMETERACCESSFORBOTHROUTEPARAMETERSPARAMMAPANDQUERYPARAMETERSQUERYPARAMMAP", "original": "The `ParamMap` API is inspired by the [URLSearchParams interface](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams). It provides methods\nto handle parameter access for both route parameters (`paramMap`) and query parameters (`queryParamMap`).", "translation": "`ParamMap` API 是参照[URLSearchParams 接口](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)来设计的。它提供了一些方法来处理对路由参数(`paramMap`)和查询参数(`queryParamMap`)中的参数访问。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MEMBER", "original": "Member", "translation": "成员", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RETURNSTRUEIFTHEPARAMETERNAMEISINTHEMAPOFPARAMETERS", "original": "Returns `true` if the parameter name is in the map of parameters.", "translation": "如果参数名位于参数列表中,就返回 `true` 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RETURNSTHEPARAMETERNAMEVALUEASTRINGIFPRESENTORNULLIFTHEPARAMETERNAMEISNOTINTHEMAPRETURNSTHEFIRSTELEMENTIFTHEPARAMETERVALUEISACTUALLYANARRAYOFVALUES", "original": "Returns the parameter name value (a `string`) if present, or `null` if the parameter name is not in the map. Returns the _first_ element if the parameter value is actually an array of values.", "translation": "如果这个 map 中有参数名对应的参数值(字符串),就返回它,否则返回 `null`。如果参数值实际上是一个数组,就返回它的*第一个*元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RETURNSASTRINGARRAYOFTHEPARAMETERNAMEVALUEIFFOUNDORANEMPTYARRAYIFTHEPARAMETERNAMEVALUEISNOTINTHEMAPUSEGETALLWHENASINGLEPARAMETERCOULDHAVEMULTIPLEVALUES", "original": "Returns a `string array` of the parameter name value if found, or an empty `array` if the parameter name value is not in the map. Use `getAll` when a single parameter could have multiple values.", "translation": "如果这个 map 中有参数名对应的值,就返回一个字符串数组,否则返回空数组。当一个参数名可能对应多个值的时候,请使用 `getAll`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RETURNSASTRINGARRAYOFALLPARAMETERNAMESINTHEMAP", "original": "Returns a `string array` of all parameter names in the map.", "translation": "返回这个 map 中的所有参数名组成的字符串数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####OBSERVABLEIPARAMMAPIANDCOMPONENTREUSE", "original": "#### Observable <i>paramMap</i> and component reuse", "translation": "#### <i>参数</i>的可观察对象(Observable)与组件复用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHISEXAMPLEYOURETRIEVETHEROUTEPARAMETERMAPFROMANOBSERVABLETHATIMPLIESTHATTHEROUTEPARAMETERMAPCANCHANGEDURINGTHELIFETIMEOFTHISCOMPONENT", "original": "In this example, you retrieve the route parameter map from an `Observable`.\nThat implies that the route parameter map can change during the lifetime of this component.", "translation": "在这个例子中,你接收了路由参数的 `Observable` 对象。\n这种写法暗示着这些路由参数在该组件的生存期内可能会变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEYMIGHTBYDEFAULTTHEROUTERREUSESACOMPONENTINSTANCEWHENITRENAVIGATESTOTHESAMECOMPONENTTYPEWITHOUTVISITINGADIFFERENTCOMPONENTFIRSTTHEROUTEPARAMETERSCOULDCHANGEEACHTIME", "original": "They might. By default, the router re-uses a component instance when it re-navigates to the same component type\nwithout visiting a different component first. The route parameters could change each time.", "translation": "确实如此!默认情况下,如果它没有访问过其它组件就导航到了同一个组件实例,那么路由器倾向于复用组件实例。如果复用,这些参数可以变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SUPPOSEAPARENTCOMPONENTNAVIGATIONBARHADFORWARDANDBACKBUTTONSTHATSCROLLEDTHROUGHTHELISTOFHEROESEACHCLICKNAVIGATEDIMPERATIVELYTOTHEHERODETAILCOMPONENTWITHTHENEXTORPREVIOUSID", "original": "Suppose a parent component navigation bar had \"forward\" and \"back\" buttons\nthat scrolled through the list of heroes.\nEach click navigated imperatively to the `HeroDetailComponent` with the next or previous `id`.", "translation": "假设父组件的导航栏有“前进”和“后退”按钮,用来轮流显示英雄列表中中英雄的详情。\n 每次点击都会强制导航到带前一个或后一个 `id` 的 `HeroDetailComponent` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUDONTWANTTHEROUTERTOREMOVETHECURRENTHERODETAILCOMPONENTINSTANCEFROMTHEDOMONLYTORECREATEITFORTHENEXTIDTHATCOULDBEVISIBLYJARRINGBETTERTOSIMPLYREUSETHESAMECOMPONENTINSTANCEANDUPDATETHEPARAMETER", "original": "You don't want the router to remove the current `HeroDetailComponent` instance from the DOM only to re-create it for the next `id`.\nThat could be visibly jarring.\nBetter to simply re-use the same component instance and update the parameter.", "translation": "你不希望路由器仅仅从 DOM 中移除当前的 `HeroDetailComponent` 实例,并且用下一个 `id` 重新创建它。\n 那可能导致界面抖动。\n 更好的方式是复用同一个组件实例,并更新这些参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UNFORTUNATELYNGONINITISONLYCALLEDONCEPERCOMPONENTINSTANTIATIONYOUNEEDAWAYTODETECTWHENTHEROUTEPARAMETERSCHANGEFROMWITHINTHESAMEINSTANCETHEOBSERVABLEPARAMMAPPROPERTYHANDLESTHATBEAUTIFULLY", "original": "Unfortunately, `ngOnInit` is only called once per component instantiation.\nYou need a way to detect when the route parameters change from _within the same instance_.\nThe observable `paramMap` property handles that beautifully.", "translation": "不幸的是,`ngOnInit` 对每个实例只调用一次。\n 你需要一种方式来检测*在同一个实例中*路由参数什么时候发生了变化。\n 而 `params` 属性这个可观察对象(Observable)干净漂亮的处理了这种情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENSUBSCRIBINGTOANOBSERVABLEINACOMPONENTYOUALMOSTALWAYSARRANGETOUNSUBSCRIBEWHENTHECOMPONENTISDESTROYED", "original": "When subscribing to an observable in a component, you almost always arrange to unsubscribe when the component is destroyed.", "translation": "当在组件中订阅一个可观察对象时,你通常总是要在组件销毁时取消这个订阅。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEREAREAFEWEXCEPTIONALOBSERVABLESWHERETHISISNOTNECESSARYTHEACTIVATEDROUTEOBSERVABLESAREAMONGTHEEXCEPTIONS", "original": "There are a few exceptional observables where this is not necessary.\nThe `ActivatedRoute` observables are among the exceptions.", "translation": "但是也有少数例外情况不需要取消订阅。\n`ActivateRoute` 中的各种可观察对象就是属于这种情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEACTIVATEDROUTEANDITSOBSERVABLESAREINSULATEDFROMTHEROUTERITSELFTHEROUTERDESTROYSAROUTEDCOMPONENTWHENITISNOLONGERNEEDEDANDTHEINJECTEDACTIVATEDROUTEDIESWITHIT", "original": "The `ActivatedRoute` and its observables are insulated from the `Router` itself.\nThe `Router` destroys a routed component when it is no longer needed and the injected `ActivatedRoute` dies with it.", "translation": "`ActivateRoute` 及其可观察对象都是由 `Router` 本身负责管理的。\n`Router` 会在不再需要时销毁这个路由组件,而注入进去的 `ActivateRoute` 也随之销毁了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "FEELFREETOUNSUBSCRIBEANYWAYITISHARMLESSANDNEVERABADPRACTICE", "original": "Feel free to unsubscribe anyway. It is harmless and never a bad practice.", "translation": "不过,你仍然可以随意取消订阅,这不会造成任何损害,而且也不是一项坏的实践。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####SNAPSHOT:THENOOBSERVABLEALTERNATIVE", "original": "#### _Snapshot_: the _no-observable_ alternative", "translation": "#### *Snapshot*(快照):当不需要 Observable 时的替代品", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISAPPLICATIONWONTREUSETHEHERODETAILCOMPONENTTHEUSERALWAYSRETURNSTOTHEHEROLISTTOSELECTANOTHERHEROTOVIEWTHERESNOWAYTONAVIGATEFROMONEHERODETAILTOANOTHERHERODETAILWITHOUTVISITINGTHELISTCOMPONENTINBETWEENTHEREFORETHEROUTERCREATESANEWHERODETAILCOMPONENTINSTANCEEVERYTIME", "original": "_This_ application won't re-use the `HeroDetailComponent`.\nThe user always returns to the hero list to select another hero to view.\nThere's no way to navigate from one hero detail to another hero detail\nwithout visiting the list component in between.\nTherefore, the router creates a new `HeroDetailComponent` instance every time.", "translation": "本应用不需要复用 `HeroDetailComponent`。\n 用户总是会先返回英雄列表,再选择另一位英雄。\n 所以,不存在从一个英雄详情导航到另一个而不用经过英雄列表的情况。\n 这意味着路由器每次都会创建一个全新的 `HeroDetailComponent` 实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENYOUKNOWFORCERTAINTHATAHERODETAILCOMPONENTINSTANCEWILLNEVERNEVEREVERBEREUSEDYOUCANSIMPLIFYTHECODEWITHTHESNAPSHOT", "original": "When you know for certain that a `HeroDetailComponent` instance will *never, never, ever*\nbe re-used, you can simplify the code with the *snapshot*.", "translation": "假如你很确定这个 `HeroDetailComponent` 组件的实例*永远、永远*不会被复用,那就可以使用*快照*来简化这段代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTESNAPSHOTPROVIDESTHEINITIALVALUEOFTHEROUTEPARAMETERMAPYOUCANACCESSTHEPARAMETERSDIRECTLYWITHOUTSUBSCRIBINGORADDINGOBSERVABLEOPERATORSITSMUCHSIMPLERTOWRITEANDREAD:", "original": "The `route.snapshot` provides the initial value of the route parameter map.\nYou can access the parameters directly without subscribing or adding observable operators.\nIt's much simpler to write and read:", "translation": "`route.snapshot` 提供了路由参数的初始值。\n你可以通过它来直接访问参数,而不用订阅或者添加 Observable 的操作符。\n这样在读写时就会更简单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "REMEMBER:YOUONLYGETTHEINITIALVALUEOFTHEPARAMETERMAPWITHTHISTECHNIQUESTICKWITHTHEOBSERVABLEPARAMMAPAPPROACHIFTHERESEVENACHANCETHATTHEROUTERCOULDREUSETHECOMPONENTTHISSAMPLESTAYSWITHTHEOBSERVABLEPARAMMAPSTRATEGYJUSTINCASE", "original": "**Remember:** you only get the _initial_ value of the parameter map with this technique.\nStick with the observable `paramMap` approach if there's even a chance that the router\ncould re-use the component.\nThis sample stays with the observable `paramMap` strategy just in case.", "translation": "**记住:**,用这种技巧,你只得到了这些参数的*初始*值。\n如果有可能连续多次导航到此组件,那么就该用 `paramMap` 可观察对象的方式。\n这个例子中仍然使用了 `paramMap` 的可观察对象策略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###NAVIGATINGBACKTOTHELISTCOMPONENT", "original": "### Navigating back to the list component", "translation": "### 导航回列表组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEHERODETAILCOMPONENTHASABACKBUTTONWIREDTOITSGOTOHEROESMETHODTHATNAVIGATESIMPERATIVELYBACKTOTHEHEROLISTCOMPONENT", "original": "The `HeroDetailComponent` has a \"Back\" button wired to its `gotoHeroes` method that navigates imperatively\nback to the `HeroListComponent`.", "translation": "`HeroDetailComponent` 组件有一个“Back”按钮,关联到它的 `gotoHeroes` 方法,该方法会导航回 `HeroListComponent` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERNAVIGATEMETHODTAKESTHESAMEONEITEMLINKPARAMETERSARRAYTHATYOUCANBINDTOAROUTERLINKDIRECTIVEITHOLDSTHEPATHTOTHEHEROLISTCOMPONENT:", "original": "The router `navigate` method takes the same one-item _link parameters array_\nthat you can bind to a `[routerLink]` directive.\nIt holds the _path to the `HeroListComponent`_:", "translation": "路由的 `navigate` 方法同样接受一个单条目的*链接参数数组*,你也可以把它绑定到 `[routerLink]` 指令上。\n它保存着**到 `HeroListComponent` 组件的路径**:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTEPARAMETERS:REQUIREDOROPTIONAL", "original": "### Route Parameters: Required or optional?", "translation": "### 路由参数:必须还是可选?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "USEROUTEPARAMETERS#ROUTEPARAMETERSTOSPECIFYAREQUIREDPARAMETERVALUEWITHINTHEROUTEURLASYOUDOWHENNAVIGATINGTOTHEHERODETAILCOMPONENTINORDERTOVIEWTHEHEROWITHID15:", "original": "Use [*route parameters*](#route-parameters) to specify a *required* parameter value *within* the route URL\nas you do when navigating to the `HeroDetailComponent` in order to view the hero with *id* 15:", "translation": "如果想导航到 `HeroDetailComponent` 以对 id 为 15 的英雄进行查看并编辑,就要在路由的 URL 中使用[*路由参数*](guide/router#route-parameters)来指定*必要*参数值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANALSOADDOPTIONALINFORMATIONTOAROUTEREQUESTFOREXAMPLEWHENRETURNINGTOTHEHEROESLISTFROMTHEHERODETAILVIEWITWOULDBENICEIFTHEVIEWEDHEROWASPRESELECTEDINTHELIST", "original": "You can also add *optional* information to a route request.\nFor example, when returning to the heroes list from the hero detail view,\nit would be nice if the viewed hero was preselected in the list.", "translation": "你也能在路由请求中添加*可选*信息。\n比如,当从 `HeroDetailComponent` 返回英雄列表时,如果能自动选中刚刚查看过的英雄就好了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOULLIMPLEMENTTHISFEATUREINAMOMENTBYINCLUDINGTHEVIEWEDHEROSIDINTHEURLASANOPTIONALPARAMETERWHENRETURNINGFROMTHEHERODETAILCOMPONENT", "original": "You'll implement this feature in a moment by including the viewed hero's `id`\nin the URL as an optional parameter when returning from the `HeroDetailComponent`.", "translation": "当从 `HeroDetailComponent` 返回时,你很快就会通过把正在查看的英雄的 `id` 作为可选参数包含在 URL 中来实现这个特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "OPTIONALINFORMATIONTAKESOTHERFORMSSEARCHCRITERIAAREOFTENLOOSELYSTRUCTUREDEGNAMEWINDMULTIPLEVALUESARECOMMONMDASHAFTER12312015BEFORE112017MDASHINNOPARTICULARORDERMDASHBEFORE112017AFTER12312015MDASHINAVARIETYOFFORMATSMDASHDURINGCURRENTYEAR", "original": "Optional information takes other forms. Search criteria are often loosely structured, e.g., `name='wind*'`.\nMultiple values are common—`after='12/31/2015' & before='1/1/2017'`—in no\nparticular order—`before='1/1/2017' & after='12/31/2015'`— in a\nvariety of formats—`during='currentYear'`.", "translation": "可选信息有很多种形式。搜索条件通常就不是严格结构化的,比如 `name='wind*'`;有多个值也很常见,如 `after='12/31/2015'&before='1/1/2017'`;\n而且顺序无关,如 `before='1/1/2017'&after='12/31/2015'`,还可能有很多种变体格式,如 `during='currentYear'`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESEKINDSOFPARAMETERSDONTFITEASILYINAURLPATHEVENIFYOUCOULDDEFINEASUITABLEURLTOKENSCHEMEDOINGSOGREATLYCOMPLICATESTHEPATTERNMATCHINGREQUIREDTOTRANSLATEANINCOMINGURLTOANAMEDROUTE", "original": "These kinds of parameters don't fit easily in a URL *path*. Even if you could define a suitable URL token scheme,\ndoing so greatly complicates the pattern matching required to translate an incoming URL to a named route.", "translation": "这么多种参数要放在 URL 的*路径*中可不容易。即使你能制定出一个合适的 URL 方案,实现起来也太复杂了,得通过模式匹配才能把 URL 翻译成命名路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "OPTIONALPARAMETERSARETHEIDEALVEHICLEFORCONVEYINGARBITRARILYCOMPLEXINFORMATIONDURINGNAVIGATIONOPTIONALPARAMETERSARENTINVOLVEDINPATTERNMATCHINGANDAFFORDFLEXIBILITYOFEXPRESSION", "original": "Optional parameters are the ideal vehicle for conveying arbitrarily complex information during navigation.\nOptional parameters aren't involved in pattern matching and afford flexibility of expression.", "translation": "可选参数是在导航期间传送任意复杂信息的理想载体。\n可选参数不涉及到模式匹配并在表达上提供了巨大的灵活性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERSUPPORTSNAVIGATIONWITHOPTIONALPARAMETERSASWELLASREQUIREDROUTEPARAMETERSDEFINEOPTIONALPARAMETERSINASEPARATEOBJECTAFTERYOUDEFINETHEREQUIREDROUTEPARAMETERS", "original": "The router supports navigation with optional parameters as well as required route parameters.\nDefine _optional_ parameters in a separate object _after_ you define the required route parameters.", "translation": "和必要参数一样,路由器也支持通过可选参数导航。\n在你定义完必要参数之后,再通过一个*独立的对象*来定义*可选参数*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INGENERALPREFERAREQUIREDROUTEPARAMETERWHENTHEVALUEISMANDATORYFOREXAMPLEIFNECESSARYTODISTINGUISHONEROUTEPATHFROMANOTHERPREFERANOPTIONALPARAMETERWHENTHEVALUEISOPTIONALCOMPLEXANDORMULTIVARIATE", "original": "In general, prefer a *required route parameter* when\nthe value is mandatory (for example, if necessary to distinguish one route path from another);\nprefer an *optional parameter* when the value is optional, complex, and/or multivariate.", "translation": "通常,对于强制性的值(比如用于区分两个路由路径的)使用*必备参数*;当这个值是可选的、复杂的或多值的时,使用可选参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###HEROESLIST:OPTIONALLYSELECTINGAHERO", "original": "### Heroes list: optionally selecting a hero", "translation": "### 英雄列表:选定一个英雄(也可不选)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENNAVIGATINGTOTHEHERODETAILCOMPONENTYOUSPECIFIEDTHEREQUIREDIDOFTHEHEROTOEDITINTHEROUTEPARAMETERANDMADEITTHESECONDITEMOFTHELINKPARAMETERSARRAY#LINKPARAMETERSARRAY", "original": "When navigating to the `HeroDetailComponent` you specified the _required_ `id` of the hero-to-edit in the\n*route parameter* and made it the second item of the [_link parameters array_](#link-parameters-array).", "translation": "当导航到 `HeroDetailComponent` 时,你可以在*路由参数*中指定一个所要编辑的英雄 `id`,只要把它作为[链接参数数组](guide/router#link-parameters-array)中的第二个条目就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTEREMBEDDEDTHEIDVALUEINTHENAVIGATIONURLBECAUSEYOUHADDEFINEDITASAROUTEPARAMETERWITHAN:IDPLACEHOLDERTOKENINTHEROUTEPATH:", "original": "The router embedded the `id` value in the navigation URL because you had defined it\nas a route parameter with an `:id` placeholder token in the route `path`:", "translation": "路由器在导航 URL 中内嵌了 `id` 的值,这是因为你把它用一个 `:id` 占位符当做路由参数定义在了路由的 `path` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENTHEUSERCLICKSTHEBACKBUTTONTHEHERODETAILCOMPONENTCONSTRUCTSANOTHERLINKPARAMETERSARRAYWHICHITUSESTONAVIGATEBACKTOTHEHEROLISTCOMPONENT", "original": "When the user clicks the back button, the `HeroDetailComponent` constructs another _link parameters array_\nwhich it uses to navigate back to the `HeroListComponent`.", "translation": "当用户点击后退按钮时,`HeroDetailComponent` 构造了另一个*链接参数数组*,可以用它导航回 `HeroListComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISARRAYLACKSAROUTEPARAMETERBECAUSEYOUHADNOREASONTOSENDINFORMATIONTOTHEHEROLISTCOMPONENT", "original": "This array lacks a route parameter because you had no reason to send information to the `HeroListComponent`.", "translation": "该数组缺少一个路由参数,这是因为你那时没有理由往 `HeroListComponent` 发送信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWYOUHAVEAREASONYOUDLIKETOSENDTHEIDOFTHECURRENTHEROWITHTHENAVIGATIONREQUESTSOTHATTHEHEROLISTCOMPONENTCANHIGHLIGHTTHATHEROINITSLISTTHISISANICETOHAVEFEATURETHELISTWILLDISPLAYPERFECTLYWELLWITHOUTIT", "original": "Now you have a reason. You'd like to send the id of the current hero with the navigation request so that the\n`HeroListComponent` can highlight that hero in its list.\nThis is a _nice-to-have_ feature; the list will display perfectly well without it.", "translation": "但现在有了。你要在导航请求中同时发送当前英雄的 id,以便 `HeroListComponent` 可以在列表中高亮这个英雄。\n 这是一个*有更好,没有也无所谓*的特性,就算没有它,列表照样能显示得很完美。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SENDTHEIDWITHANOBJECTTHATCONTAINSANOPTIONALIDPARAMETERFORDEMONSTRATIONPURPOSESTHERESANEXTRAJUNKPARAMETERFOOINTHEOBJECTTHATTHEHEROLISTCOMPONENTSHOULDIGNOREHERESTHEREVISEDNAVIGATIONSTATEMENT:", "original": "Send the `id` with an object that contains an _optional_ `id` parameter.\nFor demonstration purposes, there's an extra junk parameter (`foo`) in the object that the `HeroListComponent` should ignore.\nHere's the revised navigation statement:", "translation": "传送一个包含*可选*`id` 参数的对象。\n为了演示,这里还在对象中定义了一个没用的额外参数(`foo`),`HeroListComponent` 应该忽略它。\n下面是修改过的导航语句:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPLICATIONSTILLWORKSCLICKINGBACKRETURNSTOTHEHEROLISTVIEW", "original": "The application still works. Clicking \"back\" returns to the hero list view.", "translation": "该应用仍然能工作。点击“back”按钮返回英雄列表视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LOOKATTHEBROWSERADDRESSBAR", "original": "Look at the browser address bar.", "translation": "注意浏览器的地址栏。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITSHOULDLOOKSOMETHINGLIKETHISDEPENDINGONWHEREYOURUNIT:", "original": "It should look something like this, depending on where you run it:", "translation": "它应该是这样的,不过也取决于你在哪里运行它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEIDVALUEAPPEARSINTHEURLASID15FOOFOONOTINTHEURLPATHTHEPATHFORTHEHEROESROUTEDOESNTHAVEAN:IDTOKEN", "original": "The `id` value appears in the URL as (`;id=15;foo=foo`), not in the URL path.\nThe path for the \"Heroes\" route doesn't have an `:id` token.", "translation": "`id` 的值像这样出现在 URL 中(`;id=15;foo=foo`),但不在 URL 的路径部分。\n“Heroes”路由的路径部分并没有定义 `:id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEOPTIONALROUTEPARAMETERSARENOTSEPARATEDBYANDASTHEYWOULDBEINTHEURLQUERYSTRINGTHEYARESEPARATEDBYSEMICOLONSTHISISMATRIXURLNOTATIONMDASHSOMETHINGYOUMAYNOTHAVESEENBEFORE", "original": "The optional route parameters are not separated by \"?\" and \"&\" as they would be in the URL query string.\nThey are **separated by semicolons \";\"**\nThis is *matrix URL* notation — something you may not have seen before.", "translation": "可选的路由参数没有使用“?”和“&”符号分隔,因为它们将用在 URL 查询字符串中。\n它们是**用“;”分隔的**。\n这是*矩阵 URL*标记法 —— 你以前可能从未见过。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MATRIXURLNOTATIONISANIDEAFIRSTINTRODUCEDINA1996PROPOSALHTTP:WWWW3ORGDESIGNISSUESMATRIXURISHTMLBYTHEFOUNDEROFTHEWEBTIMBERNERSLEE", "original": "*Matrix URL* notation is an idea first introduced\nin a [1996 proposal](http://www.w3.org/DesignIssues/MatrixURIs.html) by the founder of the web, Tim Berners-Lee.", "translation": "*Matrix URL*写法首次提出是在[1996 提案](http://www.w3.org/DesignIssues/MatrixURIs.html)中,提出者是 Web 的奠基人:Tim Berners-Lee。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALTHOUGHMATRIXNOTATIONNEVERMADEITINTOTHEHTMLSTANDARDITISLEGALANDITBECAMEPOPULARAMONGBROWSERROUTINGSYSTEMSASAWAYTOISOLATEPARAMETERSBELONGINGTOPARENTANDCHILDROUTESTHEROUTERISSUCHASYSTEMANDPROVIDESSUPPORTFORTHEMATRIXNOTATIONACROSSBROWSERS", "original": "Although matrix notation never made it into the HTML standard, it is legal and\nit became popular among browser routing systems as a way to isolate parameters\nbelonging to parent and child routes. The Router is such a system and provides\nsupport for the matrix notation across browsers.", "translation": "虽然 Matrix 写法未曾进入过 HTML 标准,但它是合法的。而且在浏览器的路由系统中,它作为从父路由和子路由中单独隔离出参数的方式而广受欢迎。Angular 的路由器正是这样一个路由系统,并支持跨浏览器的 Matrix 写法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESYNTAXMAYSEEMSTRANGETOYOUBUTUSERSAREUNLIKELYTONOTICEORCAREASLONGASTHEURLCANBEEMAILEDANDPASTEDINTOABROWSERADDRESSBARASTHISONECAN", "original": "The syntax may seem strange to you but users are unlikely to notice or care\nas long as the URL can be emailed and pasted into a browser address bar\nas this one can.", "translation": "这种语法对你来说可能有点奇怪,不过用户不会在意这一点,因为该 URL 可以正常的通过邮件发出去或粘贴到浏览器的地址栏中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ROUTEPARAMETERSINTHEACTIVATEDROUTESERVICE", "original": "### Route parameters in the *ActivatedRoute* service", "translation": "### *ActivatedRoute* 服务中的路由参数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THELISTOFHEROESISUNCHANGEDNOHEROROWISHIGHLIGHTED", "original": "The list of heroes is unchanged. No hero row is highlighted.", "translation": "英雄列表仍没有改变,没有哪个英雄列被加亮显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THELIVEEXAMPLELIVEEXAMPLEDOESHIGHLIGHTTHESELECTEDROWBECAUSEITDEMONSTRATESTHEFINALSTATEOFTHEAPPLICATIONWHICHINCLUDESTHESTEPSYOUREABOUTTOCOVERATTHEMOMENTTHISGUIDEISDESCRIBINGTHESTATEOFAFFAIRSPRIORTOTHOSESTEPS", "original": "The <live-example></live-example> *does* highlight the selected\nrow because it demonstrates the final state of the application which includes the steps you're *about* to cover.\nAt the moment this guide is describing the state of affairs *prior* to those steps.", "translation": "<live-example></live-example>*高亮了*选中的行,因为它演示的是应用的最终状态,因此包含了你*即将*接触到的步骤。\n此刻,本文描述的仍是那些步骤*之前*的状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEHEROLISTCOMPONENTISNTEXPECTINGANYPARAMETERSATALLANDWOULDNTKNOWWHATTODOWITHTHEMYOUCANCHANGETHAT", "original": "The `HeroListComponent` isn't expecting any parameters at all and wouldn't know what to do with them.\nYou can change that.", "translation": "`HeroListComponent` 还完全不需要任何参数,也不知道该怎么处理它们。你可以改变这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PREVIOUSLYWHENNAVIGATINGFROMTHEHEROLISTCOMPONENTTOTHEHERODETAILCOMPONENTYOUSUBSCRIBEDTOTHEROUTEPARAMETERMAPOBSERVABLEANDMADEITAVAILABLETOTHEHERODETAILCOMPONENTINTHEACTIVATEDROUTESERVICEYOUINJECTEDTHATSERVICEINTHECONSTRUCTOROFTHEHERODETAILCOMPONENT", "original": "Previously, when navigating from the `HeroListComponent` to the `HeroDetailComponent`,\nyou subscribed to the route parameter map `Observable` and made it available to the `HeroDetailComponent`\nin the `ActivatedRoute` service.\nYou injected that service in the constructor of the `HeroDetailComponent`.", "translation": "以前,当从 `HeroListComponent` 导航到 `HeroDetailComponent` 时,你通过 `ActivatedRoute` 服务订阅了路由参数这个 `Observable`,并让它能用在 `HeroDetailComponent` 中。\n你把该服务注入到了 `HeroDetailComponent` 的构造函数中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISTIMEYOULLBENAVIGATINGINTHEOPPOSITEDIRECTIONFROMTHEHERODETAILCOMPONENTTOTHEHEROLISTCOMPONENT", "original": "This time you'll be navigating in the opposite direction, from the `HeroDetailComponent` to the `HeroListComponent`.", "translation": "这次,你要进行反向导航,从 `HeroDetailComponent` 到 `HeroListComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "FIRSTYOUEXTENDTHEROUTERIMPORTSTATEMENTTOINCLUDETHEACTIVATEDROUTESERVICESYMBOL:", "original": "First you extend the router import statement to include the `ActivatedRoute` service symbol:", "translation": "首先,你扩展该路由的导入语句,以包含进 `ActivatedRoute` 服务的类;", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTTHESWITCHMAPOPERATORTOPERFORMANOPERATIONONTHEOBSERVABLEOFROUTEPARAMETERMAP", "original": "Import the `switchMap` operator to perform an operation on the `Observable` of route parameter map.", "translation": "导入 `switchMap` 操作符,在路由参数的 `Observable` 对象上执行操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THENYOUINJECTTHEACTIVATEDROUTEINTHEHEROLISTCOMPONENTCONSTRUCTOR", "original": "Then you inject the `ActivatedRoute` in the `HeroListComponent` constructor.", "translation": "接着,你注入 `ActivatedRoute` 到 `HeroListComponent` 的构造函数中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEACTIVATEDROUTEPARAMMAPPROPERTYISANOBSERVABLEMAPOFROUTEPARAMETERSTHEPARAMMAPEMITSANEWMAPOFVALUESTHATINCLUDESIDWHENTHEUSERNAVIGATESTOTHECOMPONENTINNGONINITYOUSUBSCRIBETOTHOSEVALUESSETTHESELECTEDIDANDGETTHEHEROES", "original": "The `ActivatedRoute.paramMap` property is an `Observable` map of route parameters. The `paramMap` emits a new map of values that includes `id`\nwhen the user navigates to the component. In `ngOnInit` you subscribe to those values, set the `selectedId`, and get the heroes.", "translation": "ActivatedRoute.paramMap 属性是一个路由参数的可观察对象。当用户导航到这个组件时,paramMap 会发射一个新值,其中包含 `id`。\n在 ngOnInit 中,你订阅了这些值,设置到 selectedId,并获取英雄数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UPDATETHETEMPLATEWITHACLASSBINDINGGUIDETEMPLATESYNTAX#CLASSBINDINGTHEBINDINGADDSTHESELECTEDCSSCLASSWHENTHECOMPARISONRETURNSTRUEANDREMOVESITWHENFALSELOOKFORITWITHINTHEREPEATEDLITAGASSHOWNHERE:", "original": "Update the template with a [class binding](guide/template-syntax#class-binding).\nThe binding adds the `selected` CSS class when the comparison returns `true` and removes it when `false`.\nLook for it within the repeated `<li>` tag as shown here:", "translation": "用 [CSS 类绑定](guide/template-syntax#class-binding)更新模板,把它绑定到 `isSelected` 方法上。\n如果该方法返回 `true`,此绑定就会添加 CSS 类 `selected`,否则就移除它。\n在 `<li>` 标记中找到它,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENTHEUSERNAVIGATESFROMTHEHEROESLISTTOTHEMAGNETAHEROANDBACKMAGNETAAPPEARSSELECTED:", "original": "When the user navigates from the heroes list to the \"Magneta\" hero and back, \"Magneta\" appears selected:", "translation": "当用户从英雄列表导航到英雄“Magneta”并返回时,“Magneta”看起来是选中的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEOPTIONALFOOROUTEPARAMETERISHARMLESSANDCONTINUESTOBEIGNORED", "original": "The optional `foo` route parameter is harmless and continues to be ignored.", "translation": "这儿可选的 `foo` 路由参数人畜无害,并继续被忽略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ADDINGANIMATIONSTOTHEROUTEDCOMPONENT", "original": "### Adding animations to the routed component", "translation": "### 为路由组件添加动画", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEHEROESFEATUREMODULEISALMOSTCOMPLETEBUTWHATISAFEATUREWITHOUTSOMESMOOTHTRANSITIONS", "original": "The heroes feature module is almost complete, but what is a feature without some smooth transitions?", "translation": "这个“英雄”特性模块就要完成了,但这个特性还没有平滑的转场效果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISSECTIONSHOWSYOUHOWTOADDSOMEANIMATIONSGUIDEANIMATIONSTOTHEHERODETAILCOMPONENT", "original": "This section shows you how to add some [animations](guide/animations)\nto the `HeroDetailComponent`.", "translation": "在这一节,你将为*英雄详情*组件添加一些[动画](guide/animations)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "FIRSTIMPORTBROWSERANIMATIONSMODULE:", "original": "First import `BrowserAnimationsModule`:", "translation": "首先导入 `BrowserAnimationsModule`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEANANIMATIONSTSFILEINTHEROOTSRCAPPFOLDERTHECONTENTSLOOKLIKETHIS:", "original": "Create an `animations.ts` file in the root `src/app/` folder. The contents look like this:", "translation": "在根目录 `src/app/` 下创建一个 `animations.ts`。内容如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISFILEDOESTHEFOLLOWING:", "original": "This file does the following:", "translation": "该文件做了如下工作:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTSTHEANIMATIONSYMBOLSTHATBUILDTHEANIMATIONTRIGGERSCONTROLSTATEANDMANAGETRANSITIONSBETWEENSTATES", "original": "* Imports the animation symbols that build the animation triggers, control state, and manage transitions between states.", "translation": "导入动画符号以构建动画触发器、控制状态并管理状态之间的过渡。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EXPORTSACONSTANTNAMEDSLIDEINDOWNANIMATIONSETTOANANIMATIONTRIGGERNAMEDROUTEANIMATIONANIMATEDCOMPONENTSWILLREFERTOTHISNAME", "original": "* Exports a constant named `slideInDownAnimation` set to an animation trigger named *`routeAnimation`*;\nanimated components will refer to this name.", "translation": "导出了一个名叫 `slideInDownAnimation` 的常量,并把它设置为一个名叫*`routeAnimation` 的动画触发器。带动画的组件将会引用这个名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SPECIFIESTHEWILDCARDSTATETHATMATCHESANYANIMATIONSTATETHATTHEROUTECOMPONENTISIN", "original": "* Specifies the _wildcard state_ , `*`, that matches any animation state that the route component is in.", "translation": "指定了一个*通配符状态* —— `*`,它匹配该路由组件存在时的任何动画状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DEFINESTWOTRANSITIONSONETOEASETHECOMPONENTINFROMTHELEFTOFTHESCREENASITENTERSTHEAPPLICATIONVIEW:ENTERTHEOTHERTOANIMATETHECOMPONENTDOWNASITLEAVESTHEAPPLICATIONVIEW:LEAVE", "original": "* Defines two *transitions*, one to ease the component in from the left of the screen as it enters the application view (`:enter`),\nthe other to animate the component down as it leaves the application view (`:leave`).", "translation": "定义两个*过渡效果*,其中一个(`:enter`)在组件进入应用视图时让它从屏幕左侧缓动进入(ease-in),另一个(`:leave`)在组件离开应用视图时让它向下飞出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCOULDCREATEMORETRIGGERSWITHDIFFERENTTRANSITIONSFOROTHERROUTECOMPONENTSTHISTRIGGERISSUFFICIENTFORTHECURRENTMILESTONE", "original": "You could create more triggers with different transitions for other route components. This trigger is sufficient for the current milestone.", "translation": "你可以为其它路由组件用不同的转场效果创建更多触发器。现在这个触发器已经足够当前的里程碑用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BACKINTHEHERODETAILCOMPONENTIMPORTTHESLIDEINDOWNANIMATIONFROMANIMATIONSTSADDTHEHOSTBINDINGDECORATORTOTHEIMPORTSFROMANGULARCOREYOULLNEEDITINAMOMENT", "original": "Back in the `HeroDetailComponent`, import the `slideInDownAnimation` from `'./animations.ts`.\nAdd the `HostBinding` decorator to the imports from `@angular/core`; you'll need it in a moment.", "translation": "返回 `HeroDetailComponent`,从 `'./animations.ts` 中导入 `slideInDownAnimation`。\n从 `@angular/core` 中导入 `HostBinding` 装饰器,你很快就会用到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDANANIMATIONSARRAYTOTHECOMPONENTMETADATASTHATCONTAINSTHESLIDEINDOWNANIMATION", "original": "Add an `animations` array to the `@Component` metadata's that contains the `slideInDownAnimation`.", "translation": "把一个包含 `slideInDownAnimation` 的 `animations` 数组添加到 `@Component` 的元数据中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THENADDTHREEHOSTBINDINGPROPERTIESTOTHECLASSTOSETTHEANIMATIONANDSTYLESFORTHEROUTECOMPONENTSELEMENT", "original": "Then add three `@HostBinding` properties to the class to set the animation and styles for the route component's element.", "translation": "然后把三个 `@HostBinding` 属性添加到类中以设置这个路由组件元素的动画和样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTEANIMATIONPASSEDTOTHEFIRSTHOSTBINDINGMATCHESTHENAMEOFTHESLIDEINDOWNANIMATIONTRIGGERROUTEANIMATIONSETTHEROUTEANIMATIONPROPERTYTOTRUEBECAUSEYOUONLYCAREABOUTTHE:ENTERAND:LEAVESTATES", "original": "The `'@routeAnimation'` passed to the first `@HostBinding` matches\nthe name of the `slideInDownAnimation` _trigger_, `routeAnimation`.\nSet the `routeAnimation` property to `true` because you only care about the `:enter` and `:leave` states.", "translation": "传给了第一个 `@HostBinding` 的 `'@routeAnimation'` 匹配了 `slideInDownAnimation`*触发器*的名字 `routeAnimation`。\n把 `routeAnimation` 属性设置为 `true`,因为你只关心 `:enter` 和 `:leave` 这两个状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEOTHERTWOHOSTBINDINGPROPERTIESSTYLETHEDISPLAYANDPOSITIONOFTHECOMPONENT", "original": "The other two `@HostBinding` properties style the display and position of the component.", "translation": "另外两个 `@HostBinding` 属性指定组件的外观和位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEHERODETAILCOMPONENTWILLEASEINFROMTHELEFTWHENROUTEDTOANDWILLSLIDEDOWNWHENNAVIGATINGAWAY", "original": "The `HeroDetailComponent` will ease in from the left when routed to and will slide down when navigating away.", "translation": "当进入该路由时,`HeroDetailComponent` 将会从左侧缓动进入屏幕,而离开路由时,将会向下划出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "APPLYINGROUTEANIMATIONSTOINDIVIDUALCOMPONENTSWORKSFORASIMPLEDEMOBUTINAREALLIFEAPPITISBETTERTOANIMATEROUTESBASEDONROUTEPATHS", "original": "Applying route animations to individual components works for a simple demo, but in a real life app,\nit is better to animate routes based on _route paths_.", "translation": "在这样简单的演示程序中,可以把路由动画应用到独立的组件中,但是在真实的应用中,最好能基于*路由路径*应用路由动画。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###MILESTONE3WRAPUP", "original": "### Milestone 3 wrap up", "translation": "### 里程碑#3 的总结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVELEARNEDHOWTODOTHEFOLLOWING:", "original": "You've learned how to do the following:", "translation": "你学到了如何:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ORGANIZETHEAPPINTOFEATUREAREAS", "original": "* Organize the app into *feature areas*.", "translation": "把应用组织成*特性区*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NAVIGATEIMPERATIVELYFROMONECOMPONENTTOANOTHER", "original": "* Navigate imperatively from one component to another.", "translation": "命令式的从一个组件导航到另一个", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PASSINFORMATIONALONGINROUTEPARAMETERSANDSUBSCRIBETOTHEMINTHECOMPONENT", "original": "* Pass information along in route parameters and subscribe to them in the component.", "translation": "通过路由参数传递信息,并在组件中订阅它们", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTTHEFEATUREAREANGMODULEINTOTHEAPPMODULE", "original": "* Import the feature area NgModule into the `AppModule`.", "translation": "把这个特性分区模块导入根模块 `AppModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "APPLYANIMATIONSTOTHEROUTECOMPONENT", "original": "* Apply animations to the route component.", "translation": "把动画应用到路由组件上", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AFTERTHESECHANGESTHEFOLDERSTRUCTURELOOKSLIKETHIS:", "original": "After these changes, the folder structure looks like this:", "translation": "做完这些修改之后,目录结构是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HEREARETHERELEVANTFILESFORTHISVERSIONOFTHESAMPLEAPPLICATION", "original": "Here are the relevant files for this version of the sample application.", "translation": "这里是当前版本的范例程序相关文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##MILESTONE4:CRISISCENTERFEATURE", "original": "## Milestone 4: Crisis center feature", "translation": "## 里程碑#4:危机中心", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITSTIMETOADDREALFEATURESTOTHEAPPSCURRENTPLACEHOLDERCRISISCENTER", "original": "It's time to add real features to the app's current placeholder crisis center.", "translation": "是时候往该应用的危机中心(现在是占位符)中添加一些真实的特性了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BEGINBYIMITATINGTHEHEROESFEATURE:", "original": "Begin by imitating the heroes feature:", "translation": "先从模仿“英雄管理”中的特性开始:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "DELETETHEPLACEHOLDERCRISISCENTERFILE", "original": "* Delete the placeholder crisis center file.", "translation": "删除危机中心的占位文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEANAPPCRISISCENTERFOLDER", "original": "* Create an `app/crisis-center` folder.", "translation": "创建 `app/crisis-center` 文件夹。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "COPYTHEFILESFROMAPPHEROESINTOTHENEWCRISISCENTERFOLDER", "original": "* Copy the files from `app/heroes` into the new crisis center folder.", "translation": "把 `app/heroes` 中的文件复制到新的危机中心文件夹。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHENEWFILESCHANGEEVERYMENTIONOFHEROTOCRISISANDHEROESTOCRISES", "original": "* In the new files, change every mention of \"hero\" to \"crisis\", and \"heroes\" to \"crises\".", "translation": "在这些新文件中,把每一个对“hero”替换为“crisis”,并把“heroes”替换为“crises”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOULLTURNTHECRISISSERVICEINTOAPURVEYOROFMOCKCRISESINSTEADOFMOCKHEROES:", "original": "You'll turn the `CrisisService` into a purveyor of mock crises instead of mock heroes:", "translation": "你将会把 `CrisisService` 转换成模拟的危机列表,而不再是模拟的英雄列表:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THERESULTINGCRISISCENTERISAFOUNDATIONFORINTRODUCINGANEWCONCEPTMDASHCHILDROUTINGYOUCANLEAVEHEROESINITSCURRENTSTATEASACONTRASTWITHTHECRISISCENTERANDDECIDELATERIFTHEDIFFERENCESAREWORTHWHILE", "original": "The resulting crisis center is a foundation for introducing a new concept—**child routing**.\nYou can leave *Heroes* in its current state as a contrast with the *Crisis Center*\nand decide later if the differences are worthwhile.", "translation": "最终的危机中心可以作为引入**子路由**这个新概念的基础。\n你可以把*英雄管理*保持在当前状态,以便和*危机中心*进行对比,以后再根据这些差异是否有价值来决定后续行动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INKEEPINGWITHTHEAHREFHTTPS:BLOG8THLIGHTCOMUNCLEBOB20140508SINGLEREPONSIBILITYPRINCIPLEHTMLTITLESEPARATIONOFCONCERNSSEPARATIONOFCONCERNSPRINCIPLEACHANGESTOTHECRISISCENTERWONTAFFECTTHEAPPMODULEORANYOTHERFEATURESCOMPONENT", "original": "In keeping with the\n<a href=\"https://blog.8thlight.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html\" title=\"Separation of Concerns\">*Separation of Concerns* principle</a>,\nchanges to the *Crisis Center* won't affect the `AppModule` or\nany other feature's component.", "translation": "遵循<a href=\"https://blog.8thlight.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html\" target=\"_blank\" title=\"Separation of Concerns\">*关注点分离(Separation of Concerns)*原则</a>,\n对*危机中心*的修改不会影响 `AppModule` 或其它特性模块中的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###ACRISISCENTERWITHCHILDROUTES", "original": "### A crisis center with child routes", "translation": "### 带有子路由的危机中心", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISSECTIONSHOWSYOUHOWTOORGANIZETHECRISISCENTERTOCONFORMTOTHEFOLLOWINGRECOMMENDEDPATTERNFORANGULARAPPLICATIONS:", "original": "This section shows you how to organize the crisis center\nto conform to the following recommended pattern for Angular applications:", "translation": "本节会展示如何组织危机中心,来满足 Angular 应用所推荐的模式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHFEATUREAREARESIDESINITSOWNFOLDER", "original": "* Each feature area resides in its own folder.", "translation": "把每个特性放在自己的目录中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHFEATUREHASITSOWNANGULARFEATUREMODULE", "original": "* Each feature has its own Angular feature module.", "translation": "每个特性都有自己的 Angular 特性模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHAREAHASITSOWNAREAROOTCOMPONENT", "original": "* Each area has its own area root component.", "translation": "每个特性区都有自己的根组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHAREAROOTCOMPONENTHASITSOWNROUTEROUTLETANDCHILDROUTES", "original": "* Each area root component has its own router outlet and child routes.", "translation": "每个特性区的根组件中都有自己的路由出口及其子路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "FEATUREAREAROUTESRARELYIFEVERCROSSWITHROUTESOFOTHERFEATURES", "original": "* Feature area routes rarely (if ever) cross with routes of other features.", "translation": "特性区的路由很少(或完全不)与其它特性区的路由交叉。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFYOURAPPHADMANYFEATUREAREASTHEAPPCOMPONENTTREESMIGHTLOOKLIKETHIS:", "original": "If your app had many feature areas, the app component trees might look like this:", "translation": "如果你还有更多特性区,它们的组件树是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CHILDROUTINGCOMPONENT", "original": "### Child routing component", "translation": "### 子路由组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDTHEFOLLOWINGCRISISCENTERCOMPONENTTSTOTHECRISISCENTERFOLDER:", "original": "Add the following `crisis-center.component.ts` to the `crisis-center` folder:", "translation": "往 `crisis-center` 目录下添加下列 `crisis-center.component.ts` 文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECRISISCENTERCOMPONENTHASTHEFOLLOWINGINCOMMONWITHTHEAPPCOMPONENT:", "original": "The `CrisisCenterComponent` has the following in common with the `AppComponent`:", "translation": "`CrisisCenterComponent` 和 `AppComponent` 有下列共同点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITISTHEROOTOFTHECRISISCENTERAREAJUSTASAPPCOMPONENTISTHEROOTOFTHEENTIREAPPLICATION", "original": "* It is the *root* of the crisis center area,\njust as `AppComponent` is the root of the entire application.", "translation": "它是危机中心特性区的*根*,正如 `AppComponent` 是整个应用的根。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITISASHELLFORTHECRISISMANAGEMENTFEATUREAREAJUSTASTHEAPPCOMPONENTISASHELLTOMANAGETHEHIGHLEVELWORKFLOW", "original": "* It is a *shell* for the crisis management feature area,\njust as the `AppComponent` is a shell to manage the high-level workflow.", "translation": "它是危机管理特性区的*壳*,正如 `AppComponent` 是管理高层工作流的壳。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LIKEMOSTSHELLSTHECRISISCENTERCOMPONENTCLASSISVERYSIMPLESIMPLEREVENTHANAPPCOMPONENT:ITHASNOBUSINESSLOGICANDITSTEMPLATEHASNOLINKSJUSTATITLEANDROUTEROUTLETFORTHECRISISCENTERCHILDVIEWS", "original": "Like most shells, the `CrisisCenterComponent` class is very simple, simpler even than `AppComponent`:\nit has no business logic, and its template has no links, just a title and\n`<router-outlet>` for the crisis center child views.", "translation": "就像大多数的壳一样,`CrisisCenterComponent` 类也非常简单,甚至比 `AppComponent` 更简单:\n它没有业务逻辑,它的模板中没有链接,只有一个标题和用于放置危机中心的子视图的 `<router-outlet>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UNLIKEAPPCOMPONENTANDMOSTOTHERCOMPONENTSITLACKSASELECTORITDOESNTNEEDONESINCEYOUDONTEMBEDTHISCOMPONENTINAPARENTTEMPLATEINSTEADYOUUSETHEROUTERTONAVIGATETOIT", "original": "Unlike `AppComponent`, and most other components, it _lacks a selector_.\nIt doesn't _need_ one since you don't *embed* this component in a parent template,\ninstead you use the router to *navigate* to it.", "translation": "与 `AppComponent` 和大多数其它组件不同的是,它甚至都*没有指定选择器 `selector`*。\n它不*需要*选择器,因为你不会把这个组件嵌入到某个父模板中,而是使用路由器*导航*到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CHILDROUTECONFIGURATION", "original": "### Child route configuration", "translation": "### 子路由配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASAHOSTPAGEFORTHECRISISCENTERFEATUREADDTHEFOLLOWINGCRISISCENTERHOMECOMPONENTTSTOTHECRISISCENTERFOLDER", "original": "As a host page for the \"Crisis Center\" feature, add the following `crisis-center-home.component.ts` to the `crisis-center` folder.", "translation": "把下面这个 `crisis-center-home.component.ts` 添加到 `crisis-center` 目录下,作为 \"危机中心\" 特性区的宿主页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEACRISISCENTERROUTINGMODULETSFILEASYOUDIDTHEHEROESROUTINGMODULETSFILETHISTIMEYOUDEFINECHILDROUTESWITHINTHEPARENTCRISISCENTERROUTE", "original": "Create a `crisis-center-routing.module.ts` file as you did the `heroes-routing.module.ts` file.\nThis time, you define **child routes** *within* the parent `crisis-center` route.", "translation": "像 `heroes-routing.module.ts` 文件一样,你也创建一个 `crisis-center-routing.module.ts`。\n但这次,你要把**子路由**定义在父路由 `crisis-center` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOTICETHATTHEPARENTCRISISCENTERROUTEHASACHILDRENPROPERTYWITHASINGLEROUTECONTAININGTHECRISISLISTCOMPONENTTHECRISISLISTCOMPONENTROUTEALSOHASACHILDRENARRAYWITHTWOROUTES", "original": "Notice that the parent `crisis-center` route has a `children` property\nwith a single route containing the `CrisisListComponent`. The `CrisisListComponent` route\nalso has a `children` array with two routes.", "translation": "注意,父路由 `crisis-center` 有一个 `children` 属性,它有一个包含 `CrisisListComponent` 的路由。\n`CrisisListModule` 路由还有一个带两个路由的 `children` 数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESETWOROUTESNAVIGATETOTHECRISISCENTERCHILDCOMPONENTSCRISISCENTERHOMECOMPONENTANDCRISISDETAILCOMPONENTRESPECTIVELY", "original": "These two routes navigate to the crisis center child components,\n`CrisisCenterHomeComponent` and `CrisisDetailComponent`, respectively.", "translation": "这两个路由导航到了*危机中心*的两个子组件:`CrisisCenterHomeComponent` 和 `CrisisDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEREAREIMPORTANTDIFFERENCESINTHEWAYTHEROUTERTREATSTHESECHILDROUTES", "original": "There are *important differences* in the way the router treats these _child routes_.", "translation": "对这些路由的处理中有一些*重要的不同*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERDISPLAYSTHECOMPONENTSOFTHESEROUTESINTHEROUTEROUTLETOFTHECRISISCENTERCOMPONENTNOTINTHEROUTEROUTLETOFTHEAPPCOMPONENTSHELL", "original": "The router displays the components of these routes in the `RouterOutlet`\nof the `CrisisCenterComponent`, not in the `RouterOutlet` of the `AppComponent` shell.", "translation": "路由器会把这些路由对应的组件放在 `CrisisCenterComponent` 的 `RouterOutlet` 中,而不是 `AppComponent` 壳组件中的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECRISISLISTCOMPONENTCONTAINSTHECRISISLISTANDAROUTEROUTLETTODISPLAYTHECRISISCENTERHOMEANDCRISISDETAILROUTECOMPONENTS", "original": "The `CrisisListComponent` contains the crisis list and a `RouterOutlet` to\ndisplay the `Crisis Center Home` and `Crisis Detail` route components.", "translation": "`CrisisListComponent` 包含危机列表和一个 `RouterOutlet`,用以显示 `Crisis Center Home` 和 `Crisis Detail` 这两个路由组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECRISISDETAILROUTEISACHILDOFTHECRISISLISTSINCETHEROUTERREUSESCOMPONENTS#REUSEBYDEFAULTTHECRISISDETAILCOMPONENTWILLBEREUSEDASYOUSELECTDIFFERENTCRISESINCONTRASTBACKINTHEHERODETAILROUTETHECOMPONENTWASRECREATEDEACHTIMEYOUSELECTEDADIFFERENTHERO", "original": "The `Crisis Detail` route is a child of the `Crisis List`. Since the router [reuses components](#reuse)\nby default, the `Crisis Detail` component will be re-used as you select different crises.\nIn contrast, back in the `Hero Detail` route, the component was recreated each time you selected a different hero.", "translation": "`Crisis Detail` 路由是 `Crisis List` 的子路由。由于路由器默认会[复用组件](#reuse),因此当你选择了另一个危机时,`CrisisDetailComponent` 会被复用。 \n作为对比,回到 `Hero Detail` 路由时,每当你选择了不同的英雄时,该组件都会被重新创建。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ATTHETOPLEVELPATHSTHATBEGINWITHREFERTOTHEROOTOFTHEAPPLICATIONBUTCHILDROUTESEXTENDTHEPATHOFTHEPARENTROUTEWITHEACHSTEPDOWNTHEROUTETREEYOUADDASLASHFOLLOWEDBYTHEROUTEPATHUNLESSTHEPATHISEMPTY", "original": "At the top level, paths that begin with `/` refer to the root of the application.\nBut child routes *extend* the path of the parent route.\nWith each step down the route tree,\nyou add a slash followed by the route path, unless the path is _empty_.", "translation": "在顶级,以 `/` 开头的路径指向的总是应用的根。\n但这里是子路由。\n它们是在父路由路径的基础上做出的扩展。\n在路由树中每深入一步,你就会在该路由的路径上添加一个斜线 `/`(除非该路由的路径是*空的*)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "APPLYTHATLOGICTONAVIGATIONWITHINTHECRISISCENTERFORWHICHTHEPARENTPATHISCRISISCENTER", "original": "Apply that logic to navigation within the crisis center for which the parent path is `/crisis-center`.", "translation": "如果把该逻辑应用到危机中心中的导航,那么父路径就是 `/crisis-center`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TONAVIGATETOTHECRISISCENTERHOMECOMPONENTTHEFULLURLISCRISISCENTERCRISISCENTER", "original": "* To navigate to the `CrisisCenterHomeComponent`, the full URL is `/crisis-center` (`/crisis-center` + `''` + `''`).", "translation": "要导航到 `CrisisCenterHomeComponent`,完整的 URL 是 `/crisis-center` (`/crisis-center` + `''` + `''`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TONAVIGATETOTHECRISISDETAILCOMPONENTFORACRISISWITHID2THEFULLURLISCRISISCENTER2CRISISCENTER2", "original": "* To navigate to the `CrisisDetailComponent` for a crisis with `id=2`, the full URL is\n`/crisis-center/2` (`/crisis-center` + `''` + `'/2'`).", "translation": "要导航到 `CrisisDetailComponent` 以展示 `id=2` 的危机,完整的 URL 是 `/crisis-center/2` (`/crisis-center` + `''` + `'/2'`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEABSOLUTEURLFORTHELATTEREXAMPLEINCLUDINGTHELOCALHOSTORIGINIS", "original": "The absolute URL for the latter example, including the `localhost` origin, is", "translation": "本例子中包含站点部分的绝对 URL,就是:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HERESTHECOMPLETECRISISCENTERROUTINGMODULETSFILEWITHITSIMPORTS", "original": "Here's the complete `crisis-center-routing.module.ts` file with its imports.", "translation": "这里是完整的 `crisis-center.routing.ts` 及其导入语句。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###IMPORTCRISISCENTERMODULEINTOTHEAPPMODULEROUTES", "original": "### Import crisis center module into the *AppModule* routes", "translation": "### 把危机中心模块导入到 `AppModule` 的路由中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASWITHTHEHEROESMODULEYOUMUSTADDTHECRISISCENTERMODULETOTHEIMPORTSARRAYOFTHEAPPMODULEBEFORETHEAPPROUTINGMODULE:", "original": "As with the `HeroesModule`, you must add the `CrisisCenterModule` to the `imports` array of the `AppModule`\n_before_ the `AppRoutingModule`:", "translation": "就像 `HeroesModule` 模块中一样,你必须把 `CrisisCenterModule` 添加到 `AppModule` 的 `imports` 数组中,就在 `AppRoutingModule` 前面:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "REMOVETHEINITIALCRISISCENTERROUTEFROMTHEAPPROUTINGMODULETSTHEFEATUREROUTESARENOWPROVIDEDBYTHEHEROESMODULEANDTHECRISISCENTERMODULES", "original": "Remove the initial crisis center route from the `app-routing.module.ts`.\nThe feature routes are now provided by the `HeroesModule` and the `CrisisCenter` modules.", "translation": "从 `app.routing.ts` 中移除危机中心的初始路由。\n这些特性路由现在是由 `HeroesModule` 和 `CrisisCenter` 特性模块提供的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPROUTINGMODULETSFILERETAINSTHETOPLEVELAPPLICATIONROUTESSUCHASTHEDEFAULTANDWILDCARDROUTES", "original": "The `app-routing.module.ts` file retains the top-level application routes such as the default and wildcard routes.", "translation": "`app-routing.module.ts` 文件中只有应用的顶级路由,比如默认路由和通配符路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###RELATIVENAVIGATION", "original": "### Relative navigation", "translation": "### 相对导航", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHILEBUILDINGOUTTHECRISISCENTERFEATUREYOUNAVIGATEDTOTHECRISISDETAILROUTEUSINGANABSOLUTEPATHTHATBEGINSWITHASLASH", "original": "While building out the crisis center feature, you navigated to the\ncrisis detail route using an **absolute path** that begins with a _slash_.", "translation": "虽然构建出了危机中心特性区,你却仍在使用以斜杠开头的**绝对路径**来导航到危机详情的路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERMATCHESSUCHABSOLUTEPATHSTOROUTESSTARTINGFROMTHETOPOFTHEROUTECONFIGURATION", "original": "The router matches such _absolute_ paths to routes starting from the top of the route configuration.", "translation": "路由器会从路由配置的顶层来匹配像这样的*绝对路径*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCOULDCONTINUETOUSEABSOLUTEPATHSLIKETHISTONAVIGATEINSIDETHECRISISCENTERFEATUREBUTTHATPINSTHELINKSTOTHEPARENTROUTINGSTRUCTUREIFYOUCHANGEDTHEPARENTCRISISCENTERPATHYOUWOULDHAVETOCHANGETHELINKPARAMETERSARRAY", "original": "You could continue to use absolute paths like this to navigate inside the *Crisis Center*\nfeature, but that pins the links to the parent routing structure.\nIf you changed the parent `/crisis-center` path, you would have to change the link parameters array.", "translation": "你固然可以继续像*危机中心*特性区一样使用绝对路径,但是那样会把链接钉死在特定的父路由结构上。\n如果你修改了父路径 `/crisis-center`,那就不得不修改每一个链接参数数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANFREETHELINKSFROMTHISDEPENDENCYBYDEFININGPATHSTHATARERELATIVETOTHECURRENTURLSEGMENTNAVIGATIONWITHINTHEFEATUREAREAREMAINSINTACTEVENIFYOUCHANGETHEPARENTROUTEPATHTOTHEFEATURE", "original": "You can free the links from this dependency by defining paths that are **relative** to the current URL segment.\nNavigation _within_ the feature area remains intact even if you change the parent route path to the feature.", "translation": "通过改成定义*相对于*当前 URL 的路径,你可以把链接从这种依赖中解放出来。\n当你修改了该特性区的父路由路径时,该特性区*内部*的导航仍然完好无损。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HERESANEXAMPLE:", "original": "Here's an example:", "translation": "例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERSUPPORTSDIRECTORYLIKESYNTAXINALINKPARAMETERSLISTTOHELPGUIDEROUTENAMELOOKUP:", "original": "The router supports directory-like syntax in a _link parameters list_ to help guide route name lookup:", "translation": "路由器支持在*链接参数数组*中使用“目录式”语法来为查询路由名提供帮助:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ORNOLEADINGSLASHISRELATIVETOTHECURRENTLEVEL", "original": "`./` or `no leading slash` is relative to the current level.", "translation": "`./` 或 ` 无前导斜线 ` 形式是相对于当前级别的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TOGOUPONELEVELINTHEROUTEPATH", "original": "`../` to go up one level in the route path.", "translation": "`../` 会回到当前路由路径的上一级。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANCOMBINERELATIVENAVIGATIONSYNTAXWITHANANCESTORPATHIFYOUMUSTNAVIGATETOASIBLINGROUTEYOUCOULDUSETHESIBLINGCONVENTIONTOGOUPONELEVELTHENOVERANDDOWNTHESIBLINGROUTEPATH", "original": "You can combine relative navigation syntax with an ancestor path.\nIf you must navigate to a sibling route, you could use the `../<sibling>` convention to go up\none level, then over and down the sibling route path.", "translation": "你可以把相对导航语法和一个祖先路径组合起来用。\n如果不得不导航到一个兄弟路由,你可以用 `../<sibling>` 来回到上一级,然后进入兄弟路由路径中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TONAVIGATEARELATIVEPATHWITHTHEROUTERNAVIGATEMETHODYOUMUSTSUPPLYTHEACTIVATEDROUTETOGIVETHEROUTERKNOWLEDGEOFWHEREYOUAREINTHECURRENTROUTETREE", "original": "To navigate a relative path with the `Router.navigate` method, you must supply the `ActivatedRoute`\nto give the router knowledge of where you are in the current route tree.", "translation": "用 `Router.navigate` 方法导航到相对路径时,你必须提供当前的 `ActivatedRoute`,来让路由器知道你现在位于路由树中的什么位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AFTERTHELINKPARAMETERSARRAYADDANOBJECTWITHARELATIVETOPROPERTYSETTOTHEACTIVATEDROUTETHEROUTERTHENCALCULATESTHETARGETURLBASEDONTHEACTIVEROUTESLOCATION", "original": "After the _link parameters array_, add an object with a `relativeTo` property set to the `ActivatedRoute`.\nThe router then calculates the target URL based on the active route's location.", "translation": "在*链接参数数组*中,添加一个带有 `relativeTo` 属性的对象,并把它设置为当前的 `ActivatedRoute`。\n这样路由器就会基于当前激活路由的位置来计算出目标 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALWAYSSPECIFYTHECOMPLETEABSOLUTEPATHWHENCALLINGROUTERSNAVIGATEBYURLMETHOD", "original": "**Always** specify the complete _absolute_ path when calling router's `navigateByUrl` method.", "translation": "当调用路由器的 `navigateByUrl` 时,**总是**要指定完整的*绝对路径*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###NAVIGATETOCRISISLISTWITHARELATIVEURL", "original": "### Navigate to crisis list with a relative URL", "translation": "### 使用相对 URL 导航到危机列表", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVEALREADYINJECTEDTHEACTIVATEDROUTETHATYOUNEEDTOCOMPOSETHERELATIVENAVIGATIONPATH", "original": "You've already injected the `ActivatedRoute` that you need to compose the relative navigation path.", "translation": "你已经注入过了 `ActivatedRoute`,你需要把它来和相对导航路径组合在一起。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENUSINGAROUTERLINKTONAVIGATEINSTEADOFTHEROUTERSERVICEYOUDUSETHESAMELINKPARAMETERSARRAYBUTYOUWOULDNTPROVIDETHEOBJECTWITHTHERELATIVETOPROPERTYTHEACTIVATEDROUTEISIMPLICITINAROUTERLINKDIRECTIVE", "original": "When using a `RouterLink` to navigate instead of the `Router` service, you'd use the _same_\nlink parameters array, but you wouldn't provide the object with the `relativeTo` property.\nThe `ActivatedRoute` is implicit in a `RouterLink` directive.", "translation": "如果用 `RouterLink` 来代替 `Router` 服务进行导航,就要使用*相同*的链接参数数组,不过不再需要提供 `relativeTo` 属性。\n`ActivatedRoute` 已经隐含在了 `RouterLink` 指令中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UPDATETHEGOTOCRISESMETHODOFTHECRISISDETAILCOMPONENTTONAVIGATEBACKTOTHECRISISCENTERLISTUSINGRELATIVEPATHNAVIGATION", "original": "Update the `gotoCrises` method of the `CrisisDetailComponent` to navigate back to the *Crisis Center* list using relative path navigation.", "translation": "修改 `CrisisDetailComponent` 的 `gotoCrises` 方法,来使用相对路径返回*危机中心*列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOTICETHATTHEPATHGOESUPALEVELUSINGTHESYNTAXIFTHECURRENTCRISISIDIS3THERESULTINGPATHBACKTOTHECRISISLISTISCRISISCENTERID3FOOFOO", "original": "Notice that the path goes up a level using the `../` syntax.\nIf the current crisis `id` is `3`, the resulting path back to the crisis list is `/crisis-center/;id=3;foo=foo`.", "translation": "注意这个路径使用了 `../` 语法返回上一级。\n如果当前危机的 `id` 是 `3`,那么最终返回到的路径就是 `/crisis-center/;id=3;foo=foo`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###DISPLAYINGMULTIPLEROUTESINNAMEDOUTLETS", "original": "### Displaying multiple routes in named outlets", "translation": "### 用命名出口(outlet)显示多重路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUDECIDETOGIVEUSERSAWAYTOCONTACTTHECRISISCENTERWHENAUSERCLICKSACONTACTBUTTONYOUWANTTODISPLAYAMESSAGEINAPOPUPVIEW", "original": "You decide to give users a way to contact the crisis center.\nWhen a user clicks a \"Contact\" button, you want to display a message in a popup view.", "translation": "你决定给用户提供一种方式来联系危机中心。\n当用户点击“Contact”按钮时,你要在一个弹出框中显示一条消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPOPUPSHOULDSTAYOPENEVENWHENSWITCHINGBETWEENPAGESINTHEAPPLICATIONUNTILTHEUSERCLOSESITBYSENDINGTHEMESSAGEORCANCELINGCLEARLYYOUCANTPUTTHEPOPUPINTHESAMEOUTLETASTHEOTHERPAGES", "original": "The popup should stay open, even when switching between pages in the application, until the user closes it\nby sending the message or canceling.\nClearly you can't put the popup in the same outlet as the other pages.", "translation": "即使在应用中的不同页面之间切换,这个弹出框也应该始终保持打开状态,直到用户发送了消息或者手动取消。\n显然,你不能把这个弹出框跟其它放到页面放到同一个路由出口中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UNTILNOWYOUVEDEFINEDASINGLEOUTLETANDYOUVENESTEDCHILDROUTESUNDERTHATOUTLETTOGROUPROUTESTOGETHERTHEROUTERONLYSUPPORTSONEPRIMARYUNNAMEDOUTLETPERTEMPLATE", "original": "Until now, you've defined a single outlet and you've nested child routes\nunder that outlet to group routes together.\nThe router only supports one primary _unnamed_ outlet per template.", "translation": "迄今为止,你只定义过单路由出口,并且在其中嵌套了子路由以便对路由分组。\n在每个模板中,路由器只能支持一个*无名*主路由出口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ATEMPLATECANALSOHAVEANYNUMBEROFNAMEDOUTLETSEACHNAMEDOUTLETHASITSOWNSETOFROUTESWITHTHEIROWNCOMPONENTSMULTIPLEOUTLETSCANBEDISPLAYINGDIFFERENTCONTENTDETERMINEDBYDIFFERENTROUTESALLATTHESAMETIME", "original": "A template can also have any number of _named_ outlets.\nEach named outlet has its own set of routes with their own components.\nMultiple outlets can be displaying different content, determined by different routes, all at the same time.", "translation": "模板还可以有多个*命名的*路由出口。\n每个命名出口都自己有一组带组件的路由。\n多重出口可以在同一时间根据不同的路由来显示不同的内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDANOUTLETNAMEDPOPUPINTHEAPPCOMPONENTDIRECTLYBELOWTHEUNNAMEDOUTLET", "original": "Add an outlet named \"popup\" in the `AppComponent`, directly below the unnamed outlet.", "translation": "在 `AppComponent` 中添加一个名叫“popup”的出口,就在无名出口的下方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THATSWHEREAPOPUPWILLGOONCEYOULEARNHOWTOROUTEAPOPUPCOMPONENTTOIT", "original": "That's where a popup will go, once you learn how to route a popup component to it.", "translation": "一旦你学会了如何把一个弹出框组件路由到该出口,那里就是将会出现弹出框的地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####SECONDARYROUTES", "original": "#### Secondary routes", "translation": "#### 第二路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NAMEDOUTLETSARETHETARGETSOFSECONDARYROUTES", "original": "Named outlets are the targets of _secondary routes_.", "translation": "命名出口是*第二路由*的目标。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SECONDARYROUTESLOOKLIKEPRIMARYROUTESANDYOUCONFIGURETHEMTHESAMEWAYTHEYDIFFERINAFEWKEYRESPECTS", "original": "Secondary routes look like primary routes and you configure them the same way.\nThey differ in a few key respects.", "translation": "第二路由很像主路由,配置方式也一样。它们只有一些关键的不同点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEYAREINDEPENDENTOFEACHOTHER", "original": "* They are independent of each other.", "translation": "它们彼此互不依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEYWORKINCOMBINATIONWITHOTHERROUTES", "original": "* They work in combination with other routes.", "translation": "它们与其它路由组合使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEYAREDISPLAYEDINNAMEDOUTLETS", "original": "* They are displayed in named outlets.", "translation": "它们显示在命名出口中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEANEWCOMPONENTNAMEDCOMPOSEMESSAGECOMPONENTINSRCAPPCOMPOSEMESSAGECOMPONENTTSITDISPLAYSASIMPLEFORMWITHAHEADERANINPUTBOXFORTHEMESSAGEANDTWOBUTTONSSENDANDCANCEL", "original": "Create a new component named `ComposeMessageComponent` in `src/app/compose-message.component.ts`.\nIt displays a simple form with a header, an input box for the message,\nand two buttons, \"Send\" and \"Cancel\".", "translation": "在 `src/app/compose-message.component.ts` 中创建一个名叫 `ComposeMessageComponent` 的新组件。\n它显示一个简单的表单,包括一个头、一个消息输入框和两个按钮:“Send”和“Cancel”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HERESTHECOMPONENTANDITSTEMPLATE:", "original": "Here's the component and its template:", "translation": "下面是该组件及其模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITLOOKSABOUTTHESAMEASANYOTHERCOMPONENTYOUVESEENINTHISGUIDETHEREARETWONOTEWORTHYDIFFERENCES", "original": "It looks about the same as any other component you've seen in this guide.\nThere are two noteworthy differences.", "translation": "它看起来几乎和你以前见过其它组件一样,但有两个值得注意的区别。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOTETHATTHESENDMETHODSIMULATESLATENCYBYWAITINGASECONDBEFORESENDINGTHEMESSAGEANDCLOSINGTHEPOPUP", "original": "Note that the `send()` method simulates latency by waiting a second before \"sending\" the message and closing the popup.", "translation": "主要 `send()` 方法在发送消息和关闭弹出框之前通过等待模拟了一秒钟的延迟。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECLOSEPOPUPMETHODCLOSESTHEPOPUPVIEWBYNAVIGATINGTOTHEPOPUPOUTLETWITHANULLTHATSAPECULIARITYCOVEREDBELOW#CLEARSECONDARYROUTES", "original": "The `closePopup()` method closes the popup view by navigating to the popup outlet with a `null`.\nThat's a peculiarity covered [below](#clear-secondary-routes).", "translation": "`closePopup()` 方法用把 `popup` 出口导航到 `null` 的方式关闭了弹出框。\n这个奇怪的用法在[稍后的部分](guide/router#clear-secondary-routes)有讲解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASWITHOTHERAPPLICATIONCOMPONENTSYOUADDTHECOMPOSEMESSAGECOMPONENTTOTHEDECLARATIONSOFANNGMODULEDOSOINTHEAPPMODULE", "original": "As with other application components, you add the `ComposeMessageComponent` to the `declarations` of an `NgModule`.\nDo so in the `AppModule`.", "translation": "像其它组件一样,你还要把 `ComposeMessageComponent` 添加到 `AppModule` 的 `declarations` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####ADDASECONDARYROUTE", "original": "#### Add a secondary route", "translation": "#### 添加第二路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "OPENTHEAPPROUTINGMODULEANDADDANEWCOMPOSEROUTETOTHEAPPROUTES", "original": "Open the `AppRoutingModule` and add a new `compose` route to the `appRoutes`.", "translation": "打开 `AppRoutingModule`,并把一个新的 `compose` 路由添加到 `appRoutes` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPATHANDCOMPONENTPROPERTIESSHOULDBEFAMILIARTHERESANEWPROPERTYOUTLETSETTOPOPUPTHISROUTENOWTARGETSTHEPOPUPOUTLETANDTHECOMPOSEMESSAGECOMPONENTWILLDISPLAYTHERE", "original": "The `path` and `component` properties should be familiar.\nThere's a new property, `outlet`, set to `'popup'`.\nThis route now targets the popup outlet and the `ComposeMessageComponent` will display there.", "translation": "对 `path` 和 `component` 属性应该很熟悉了吧。\n注意这个新的属性 `outlet` 被设置成了 `'popup'`。\n这个路由现在指向了 `popup` 出口,而 `ComposeMessageComponent` 也将显示在那里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEUSERNEEDSAWAYTOOPENTHEPOPUPOPENTHEAPPCOMPONENTANDADDACONTACTLINK", "original": "The user needs a way to open the popup.\nOpen the `AppComponent` and add a \"Contact\" link.", "translation": "用户需要某种途径来打开这个弹出框。\n打开 `AppComponent`,并添加一个“Contact”链接。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALTHOUGHTHECOMPOSEROUTEISPINNEDTOTHEPOPUPOUTLETTHATSNOTSUFFICIENTFORWIRINGTHEROUTETOAROUTERLINKDIRECTIVEYOUHAVETOSPECIFYTHENAMEDOUTLETINALINKPARAMETERSARRAYANDBINDITTOTHEROUTERLINKWITHAPROPERTYBINDING", "original": "Although the `compose` route is pinned to the \"popup\" outlet, that's not sufficient for wiring the route to a `RouterLink` directive.\nYou have to specify the named outlet in a _link parameters array_ and bind it to the `RouterLink` with a property binding.", "translation": "虽然 `compose` 路由被钉死在了 `popup` 出口上,但这仍然不足以向 `RouterLink` 指令表明要加载该路由。\n你还要在*链接参数数组*中指定这个命名出口,并通过属性绑定的形式把它绑定到 `RouterLink` 上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THELINKPARAMETERSARRAYCONTAINSANOBJECTWITHASINGLEOUTLETSPROPERTYWHOSEVALUEISANOTHEROBJECTKEYEDBYONEORMOREOUTLETNAMESINTHISCASETHEREISONLYTHEPOPUPOUTLETPROPERTYANDITSVALUEISANOTHERLINKPARAMETERSARRAYTHATSPECIFIESTHECOMPOSEROUTE", "original": "The _link parameters array_ contains an object with a single `outlets` property whose value\nis another object keyed by one (or more) outlet names.\nIn this case there is only the \"popup\" outlet property and its value is another _link parameters array_ that specifies the `compose` route.", "translation": "*链接参数数组*包含一个只有一个 `outlets` 属性的对象,它的值是另一个对象,这个对象以一个或多个路由的出口名作为属性名。\n在这里,它只有一个出口名“popup”,它的值则是另一个*链接参数数组*,用于指定 `compose` 路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUAREINEFFECTSAYINGWHENTHEUSERCLICKSTHISLINKDISPLAYTHECOMPONENTASSOCIATEDWITHTHECOMPOSEROUTEINTHEPOPUPOUTLET", "original": "You are in effect saying, _when the user clicks this link, display the component associated with the `compose` route in the `popup` outlet_.", "translation": "意思是,当用户点击此链接时,在路由出口 `popup` 中显示与 `compose` 路由相关联的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISOUTLETSOBJECTWITHINANOUTEROBJECTWASCOMPLETELYUNNECESSARYWHENTHEREWASONLYONEROUTEANDONEUNNAMEDOUTLETTOTHINKABOUT", "original": "This `outlets` object within an outer object was completely unnecessary\nwhen there was only one route and one _unnamed_ outlet to think about.", "translation": "当有且只有一个*无名*出口时,外部对象中的这个 `outlets` 对象并不是必须的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERASSUMEDTHATYOURROUTESPECIFICATIONTARGETEDTHEUNNAMEDPRIMARYOUTLETANDCREATEDTHESEOBJECTSFORYOU", "original": "The router assumed that your route specification targeted the _unnamed_ primary outlet\nand created these objects for you.", "translation": "路由器假设这个路由指向了*无名*的主出口,并为你创建这些对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ROUTINGTOANAMEDOUTLETHASREVEALEDAPREVIOUSLYHIDDENROUTERTRUTH:YOUCANTARGETMULTIPLEOUTLETSWITHMULTIPLEROUTESINTHESAMEROUTERLINKDIRECTIVE", "original": "Routing to a named outlet has revealed a previously hidden router truth:\nyou can target multiple outlets with multiple routes in the same `RouterLink` directive.", "translation": "路由到一个命名出口就会揭示一个以前被隐藏的真相:\n你可以在同一个 `RouterLink` 指令中为多个路由出口指定多个路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOURENOTACTUALLYDOINGTHATHEREBUTTOTARGETANAMEDOUTLETYOUMUSTUSETHERICHERMOREVERBOSESYNTAX", "original": "You're not actually doing that here.\nBut to target a named outlet, you must use the richer, more verbose syntax.", "translation": "这里你实际上没能这样做。要想指向命名出口,你就得使用一种更强大也更啰嗦的语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####SECONDARYROUTENAVIGATION:MERGINGROUTESDURINGNAVIGATION", "original": "#### Secondary route navigation: merging routes during navigation", "translation": "#### 第二路由导航:在导航期间合并路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NAVIGATETOTHECRISISCENTERANDCLICKCONTACTYOUSHOULDSEESOMETHINGLIKETHEFOLLOWINGURLINTHEBROWSERADDRESSBAR", "original": "Navigate to the _Crisis Center_ and click \"Contact\".\nyou should see something like the following URL in the browser address bar.", "translation": "导航到*危机中心*并点击“Contact”,你将会在浏览器的地址栏看到如下 URL:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEINTERESTINGPARTOFTHEURLFOLLOWSTHE:", "original": "The interesting part of the URL follows the `...`:", "translation": "这个 URL 中有意思的部分是 `...` 后面的这些:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECRISISCENTERISTHEPRIMARYNAVIGATION", "original": "* The `crisis-center` is the primary navigation.", "translation": "`crisis-center` 是主导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PARENTHESESSURROUNDTHESECONDARYROUTE", "original": "* Parentheses surround the secondary route.", "translation": "圆括号包裹的部分是第二路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESECONDARYROUTECONSISTSOFANOUTLETNAMEPOPUPACOLONSEPARATORANDTHESECONDARYROUTEPATHCOMPOSE", "original": "* The secondary route consists of an outlet name (`popup`), a `colon` separator, and the secondary route path (`compose`).", "translation": "第二路由包括一个出口名称(`popup`)、一个冒号分隔符和第二路由的路径(`compose`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CLICKTHEHEROESLINKANDLOOKATTHEURLAGAIN", "original": "Click the _Heroes_ link and look at the URL again.", "translation": "点击 *Heroes* 链接,并再次查看 URL:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPRIMARYNAVIGATIONPARTHASCHANGEDTHESECONDARYROUTEISTHESAME", "original": "The primary navigation part has changed; the secondary route is the same.", "translation": "主导航的部分变化了,而第二路由没有变。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERISKEEPINGTRACKOFTWOSEPARATEBRANCHESINANAVIGATIONTREEANDGENERATINGAREPRESENTATIONOFTHATTREEINTHEURL", "original": "The router is keeping track of two separate branches in a navigation tree and generating a representation of that tree in the URL.", "translation": "路由器在导航树中对两个独立的分支保持追踪,并在 URL 中对这棵树进行表达。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANADDMANYMOREOUTLETSANDROUTESATTHETOPLEVELANDINNESTEDLEVELSCREATINGANAVIGATIONTREEWITHMANYBRANCHESTHEROUTERWILLGENERATETHEURLTOGOWITHIT", "original": "You can add many more outlets and routes, at the top level and in nested levels, creating a navigation tree with many branches.\nThe router will generate the URL to go with it.", "translation": "你还可以添加更多出口和更多路由(无论是在顶层还是在嵌套的子层)来创建一个带有多个分支的导航树。\n路由器将会生成相应的 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANTELLTHEROUTERTONAVIGATEANENTIRETREEATONCEBYFILLINGOUTTHEOUTLETSOBJECTMENTIONEDABOVETHENPASSTHATOBJECTINSIDEALINKPARAMETERSARRAYTOTHEROUTERNAVIGATEMETHOD", "original": "You can tell the router to navigate an entire tree at once by filling out the `outlets` object mentioned above.\nThen pass that object inside a _link parameters array_ to the `router.navigate` method.", "translation": "通过像前面那样填充 `outlets` 对象,你可以告诉路由器立即导航到一棵完整的树。\n然后把这个对象通过一个*链接参数数组*传给 `router.navigate` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EXPERIMENTWITHTHESEPOSSIBILITIESATYOURLEISURE", "original": "Experiment with these possibilities at your leisure.", "translation": "有空的时候你可以自行试验这些可能性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####CLEARINGSECONDARYROUTES", "original": "#### Clearing secondary routes", "translation": "#### 清除第二路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASYOUVELEARNEDACOMPONENTINANOUTLETPERSISTSUNTILYOUNAVIGATEAWAYTOANEWCOMPONENTSECONDARYOUTLETSARENODIFFERENTINTHISREGARD", "original": "As you've learned, a component in an outlet persists until you navigate away to a new component.\nSecondary outlets are no different in this regard.", "translation": "正如你刚刚学到的,除非导航到新的组件,否则路由出口中的组件会始终存在。\n这里涉及到的第二出口也同样如此。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EACHSECONDARYOUTLETHASITSOWNNAVIGATIONINDEPENDENTOFTHENAVIGATIONDRIVINGTHEPRIMARYOUTLETCHANGINGACURRENTROUTETHATDISPLAYSINTHEPRIMARYOUTLETHASNOEFFECTONTHEPOPUPOUTLETTHATSWHYTHEPOPUPSTAYSVISIBLEASYOUNAVIGATEAMONGTHECRISESANDHEROES", "original": "Each secondary outlet has its own navigation, independent of the navigation driving the primary outlet.\nChanging a current route that displays in the primary outlet has no effect on the popup outlet.\nThat's why the popup stays visible as you navigate among the crises and heroes.", "translation": "每个第二出口都有自己独立的导航,跟主出口的导航彼此独立。\n修改主出口中的当前路由并不会影响到 `popup` 出口中的。\n这就是为什么在危机中心和英雄管理之间导航时,弹出框始终都是可见的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CLICKINGTHESENDORCANCELBUTTONSDOESCLEARTHEPOPUPVIEWTOSEEHOWLOOKATTHECLOSEPOPUPMETHODAGAIN:", "original": "Clicking the \"send\" or \"cancel\" buttons _does_ clear the popup view.\nTo see how, look at the `closePopup()` method again:", "translation": "点击“send”或“cancel”按钮,则*会*清除弹出框视图。\n为何如此?再看看 `closePopup()` 方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITNAVIGATESIMPERATIVELYWITHTHEROUTERNAVIGATEMETHODPASSINGINALINKPARAMETERSARRAY#LINKPARAMETERSARRAY", "original": "It navigates imperatively with the `Router.navigate()` method, passing in a [link parameters array](#link-parameters-array).", "translation": "它使用 `Router.navigate()` 方法进行强制导航,并传入了一个[链接参数数组](guide/router#link-parameters-array)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LIKETHEARRAYBOUNDTOTHECONTACTROUTERLINKINTHEAPPCOMPONENTTHISONEINCLUDESANOBJECTWITHANOUTLETSPROPERTYTHEOUTLETSPROPERTYVALUEISANOTHEROBJECTWITHOUTLETNAMESFORKEYSTHEONLYNAMEDOUTLETISPOPUP", "original": "Like the array bound to the _Contact_ `RouterLink` in the `AppComponent`,\nthis one includes an object with an `outlets` property.\nThe `outlets` property value is another object with outlet names for keys.\nThe only named outlet is `'popup'`.", "translation": "就像在 `AppComponent` 中绑定到的 *Contact* `RouterLink` 一样,它也包含了一个带 `outlets` 属性的对象。\n`outlets` 属性的值是另一个对象,该对象用一些出口名称作为属性名。\n唯一的命名出口是 `'popup'`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISTIMETHEVALUEOFPOPUPISNULLTHATSNOTAROUTEBUTITISALEGITIMATEVALUESETTINGTHEPOPUPROUTEROUTLETTONULLCLEARSTHEOUTLETANDREMOVESTHESECONDARYPOPUPROUTEFROMTHECURRENTURL", "original": "This time, the value of `'popup'` is `null`. That's not a route, but it is a legitimate value.\nSetting the popup `RouterOutlet` to `null` clears the outlet and removes\nthe secondary popup route from the current URL.", "translation": "但这次,`'popup'` 的值是 `null`。`null` 不是一个路由,但却是一个合法的值。\n把 `popup` 这个 `RouterOutlet` 设置为 `null` 会清除该出口,并且从当前 URL 中移除第二路由 `popup`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##MILESTONE5:ROUTEGUARDS", "original": "## Milestone 5: Route guards", "translation": "## 里程碑 5:路由守卫", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ATTHEMOMENTANYUSERCANNAVIGATEANYWHEREINTHEAPPLICATIONANYTIMETHATSNOTALWAYSTHERIGHTTHINGTODO", "original": "At the moment, *any* user can navigate *anywhere* in the application *anytime*.\nThat's not always the right thing to do.", "translation": "现在,*任何用户*都能在*任何时候*导航到*任何地方*。\n但有时候这样是不对的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PERHAPSTHEUSERISNOTAUTHORIZEDTONAVIGATETOTHETARGETCOMPONENT", "original": "* Perhaps the user is not authorized to navigate to the target component.", "translation": "该用户可能无权导航到目标组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MAYBETHEUSERMUSTLOGINAUTHENTICATEFIRST", "original": "* Maybe the user must login (*authenticate*) first.", "translation": "可能用户得先登录(认证)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MAYBEYOUSHOULDFETCHSOMEDATABEFOREYOUDISPLAYTHETARGETCOMPONENT", "original": "* Maybe you should fetch some data before you display the target component.", "translation": "在显示目标组件前,你可能得先获取某些数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUMIGHTWANTTOSAVEPENDINGCHANGESBEFORELEAVINGACOMPONENT", "original": "* You might want to save pending changes before leaving a component.", "translation": "在离开组件前,你可能要先保存修改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUMIGHTASKTHEUSERIFITSOKTODISCARDPENDINGCHANGESRATHERTHANSAVETHEM", "original": "* You might ask the user if it's OK to discard pending changes rather than save them.", "translation": "你可能要询问用户:你是否要放弃本次更改,而不用保存它们?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANADDGUARDSTOTHEROUTECONFIGURATIONTOHANDLETHESESCENARIOS", "original": "You can add _guards_ to the route configuration to handle these scenarios.", "translation": "你可以往路由配置中添加***守卫***,来处理这些场景。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AGUARDSRETURNVALUECONTROLSTHEROUTERSBEHAVIOR:", "original": "A guard's return value controls the router's behavior:", "translation": "守卫返回一个值,以控制路由器的行为:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFITRETURNSTRUETHENAVIGATIONPROCESSCONTINUES", "original": "* If it returns `true`, the navigation process continues.", "translation": "如果它返回 `true`,导航过程会继续", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFITRETURNSFALSETHENAVIGATIONPROCESSSTOPSANDTHEUSERSTAYSPUT", "original": "* If it returns `false`, the navigation process stops and the user stays put.", "translation": "如果它返回 `false`,导航过程会终止,且用户会留在原地。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEGUARDCANALSOTELLTHEROUTERTONAVIGATEELSEWHEREEFFECTIVELYCANCELINGTHECURRENTNAVIGATION", "original": "The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation.", "translation": "守卫还可以告诉路由器导航到别处,这样也取消当前的导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEGUARDMIGHTRETURNITSBOOLEANANSWERSYNCHRONOUSLYBUTINMANYCASESTHEGUARDCANTPRODUCEANANSWERSYNCHRONOUSLYTHEGUARDCOULDASKTHEUSERAQUESTIONSAVECHANGESTOTHESERVERORFETCHFRESHDATATHESEAREALLASYNCHRONOUSOPERATIONS", "original": "The guard *might* return its boolean answer synchronously.\nBut in many cases, the guard can't produce an answer synchronously.\nThe guard could ask the user a question, save changes to the server, or fetch fresh data.\nThese are all asynchronous operations.", "translation": "守卫*可以*用同步的方式返回一个布尔值。但在很多情况下,守卫无法用同步的方式给出答案。\n守卫可能会向用户问一个问题、把更改保存到服务器,或者获取新数据,而这些都是异步操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ACCORDINGLYAROUTINGGUARDCANRETURNANOBSERVABLEBOOLEANORAPROMISEBOOLEANANDTHEROUTERWILLWAITFORTHEOBSERVABLETORESOLVETOTRUEORFALSE", "original": "Accordingly, a routing guard can return an `Observable<boolean>` or a `Promise<boolean>` and the\nrouter will wait for the observable to resolve to `true` or `false`.", "translation": "因此,路由的守卫可以返回一个 `Observable<boolean>` 或 `Promise<boolean>`,并且路由器会等待这个可观察对象被解析为 `true` 或 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERSUPPORTSMULTIPLEGUARDINTERFACES:", "original": "The router supports multiple guard interfaces:", "translation": "路由器可以支持多种守卫接口:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CANACTIVATEAPIROUTERCANACTIVATETOMEDIATENAVIGATIONTOAROUTE", "original": "* [`CanActivate`](api/router/CanActivate) to mediate navigation *to* a route.", "translation": "用[`CanActivate`](api/router/CanActivate)来处理导航*到*某路由的情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CANACTIVATECHILDAPIROUTERCANACTIVATECHILDTOMEDIATENAVIGATIONTOACHILDROUTE", "original": "* [`CanActivateChild`](api/router/CanActivateChild) to mediate navigation *to* a child route.", "translation": "用[`CanActivateChild`](api/router/CanActivateChild)来处理导航*到*某子路由的情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CANDEACTIVATEAPIROUTERCANDEACTIVATETOMEDIATENAVIGATIONAWAYFROMTHECURRENTROUTE", "original": "* [`CanDeactivate`](api/router/CanDeactivate) to mediate navigation *away* from the current route.", "translation": "用[`CanDeactivate`](api/router/CanDeactivate)来处理从当前路由*离开*的情况.", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RESOLVEAPIROUTERRESOLVETOPERFORMROUTEDATARETRIEVALBEFOREROUTEACTIVATION", "original": "* [`Resolve`](api/router/Resolve) to perform route data retrieval *before* route activation.", "translation": "用[`Resolve`](api/router/Resolve)在路由激活*之前*获取路由数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CANLOADAPIROUTERCANLOADTOMEDIATENAVIGATIONTOAFEATUREMODULELOADEDASYNCHRONOUSLY", "original": "* [`CanLoad`](api/router/CanLoad) to mediate navigation *to* a feature module loaded _asynchronously_.", "translation": "用[`CanLoad`](api/router/CanLoad)来处理*异步*导航到某特性模块的情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANHAVEMULTIPLEGUARDSATEVERYLEVELOFAROUTINGHIERARCHYTHEROUTERCHECKSTHECANDEACTIVATEANDCANACTIVATECHILDGUARDSFIRSTFROMTHEDEEPESTCHILDROUTETOTHETOPTHENITCHECKSTHECANACTIVATEGUARDSFROMTHETOPDOWNTOTHEDEEPESTCHILDROUTEIFTHEFEATUREMODULEISLOADEDASYNCHRONOUSLYTHECANLOADGUARDISCHECKEDBEFORETHEMODULEISLOADEDIFANYGUARDRETURNSFALSEPENDINGGUARDSTHATHAVENOTCOMPLETEDWILLBECANCELEDANDTHEENTIRENAVIGATIONISCANCELED", "original": "You can have multiple guards at every level of a routing hierarchy.\nThe router checks the `CanDeactivate` and `CanActivateChild` guards first, from the deepest child route to the top.\nThen it checks the `CanActivate` guards from the top down to the deepest child route. If the feature module\nis loaded asynchronously, the `CanLoad` guard is checked before the module is loaded.\nIf _any_ guard returns false, pending guards that have not completed will be canceled,\nand the entire navigation is canceled.", "translation": "在分层路由的每个级别上,你都可以设置多个守卫。\n路由器会先按照从最深的子路由由下往上检查的顺序来检查 `CanDeactivate()` 和 `CanActivateChild()` 守卫。\n然后它会按照从上到下的顺序检查 `CanActivate()` 守卫。\n如果特性模块是异步加载的,在加载它之前还会检查 `CanLoad()` 守卫。\n如果*任何*一个守卫返回 `false`,其它尚未完成的守卫会被取消,这样整个导航就被取消了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEREARESEVERALEXAMPLESOVERTHENEXTFEWSECTIONS", "original": "There are several examples over the next few sections.", "translation": "接下来的小节中有一些例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CANACTIVATE:REQUIRINGAUTHENTICATION", "original": "### _CanActivate_: requiring authentication", "translation": "### *CanActivate*: 要求认证", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "APPLICATIONSOFTENRESTRICTACCESSTOAFEATUREAREABASEDONWHOTHEUSERISYOUCOULDPERMITACCESSONLYTOAUTHENTICATEDUSERSORTOUSERSWITHASPECIFICROLEYOUMIGHTBLOCKORLIMITACCESSUNTILTHEUSERSACCOUNTISACTIVATED", "original": "Applications often restrict access to a feature area based on who the user is.\nYou could permit access only to authenticated users or to users with a specific role.\nYou might block or limit access until the user's account is activated.", "translation": "应用程序通常会根据访问者来决定是否授予某个特性区的访问权。\n你可以只对已认证过的用户或具有特定角色的用户授予访问权,还可以阻止或限制用户访问权,直到用户账户激活为止。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECANACTIVATEGUARDISTHETOOLTOMANAGETHESENAVIGATIONBUSINESSRULES", "original": "The `CanActivate` guard is the tool to manage these navigation business rules.", "translation": "`CanActivate` 守卫是一个管理这些导航类业务规则的工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####ADDANADMINFEATUREMODULE", "original": "#### Add an admin feature module", "translation": "#### 添加一个“管理”特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHISNEXTSECTIONYOULLEXTENDTHECRISISCENTERWITHSOMENEWADMINISTRATIVEFEATURESTHOSEFEATURESARENTDEFINEDYETBUTYOUCANSTARTBYADDINGANEWFEATUREMODULENAMEDADMINMODULE", "original": "In this next section, you'll extend the crisis center with some new *administrative* features.\nThose features aren't defined yet.\nBut you can start by adding a new feature module named `AdminModule`.", "translation": "在下一节,你将会使用一些新的*管理*特性来扩展危机中心。\n那些特性尚未定义,但是你可以先从添加一个名叫 `AdminModule` 的特性模块开始。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEANADMINFOLDERWITHAFEATUREMODULEFILEAROUTINGCONFIGURATIONFILEANDSUPPORTINGCOMPONENTS", "original": "Create an `admin` folder with a feature module file, a routing configuration file, and supporting components.", "translation": "创建一个 `admin` 目录,它带有一个特性模块文件、一个路由配置文件和一些支持性组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEADMINFEATUREFILESTRUCTURELOOKSLIKETHIS:", "original": "The admin feature file structure looks like this:", "translation": "管理特性区的文件是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEADMINFEATUREMODULECONTAINSTHEADMINCOMPONENTUSEDFORROUTINGWITHINTHEFEATUREMODULEADASHBOARDROUTEANDTWOUNFINISHEDCOMPONENTSTOMANAGECRISESANDHEROES", "original": "The admin feature module contains the `AdminComponent` used for routing within the\nfeature module, a dashboard route and two unfinished components to manage crises and heroes.", "translation": "管理特性模块包含 `AdminComponent`,它用于在特性模块内的仪表盘路由以及两个尚未完成的用于管理危机和英雄的组件之间进行路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SINCETHEADMINDASHBOARDROUTERLINKISANEMPTYPATHROUTEINTHEADMINCOMPONENTITISCONSIDEREDAMATCHTOANYROUTEWITHINTHEADMINFEATUREAREAYOUONLYWANTTHEDASHBOARDLINKTOBEACTIVEWHENTHEUSERVISITSTHATROUTEADDINGANADDITIONALBINDINGTOTHEDASHBOARDROUTERLINKROUTERLINKACTIVEOPTIONSEXACT:TRUEMARKSTHELINKASACTIVEWHENTHEUSERNAVIGATESTOTHEADMINURLANDNOTWHENNAVIGATINGTOANYOFTHECHILDROUTES", "original": "Since the admin dashboard `RouterLink` is an empty path route in the `AdminComponent`, it\nis considered a match to any route within the admin feature area.\nYou only want the `Dashboard` link to be active when the user visits that route.\nAdding an additional binding to the `Dashboard` routerLink,\n`[routerLinkActiveOptions]=\"{ exact: true }\"`, marks the `./` link as active when\nthe user navigates to the `/admin` URL and not when navigating to any of the child routes.", "translation": "由于 `AdminModule` 中 `AdminComponent` 中的 `RouterLink` 是一个空路径的路由,所以它会匹配到管理特性区的任何路由。\n但你只有在访问 `Dashboard` 路由时才希望该链接被激活。\n往 `Dashboard` 这个 routerLink 上添加另一个绑定 `[routerLinkActiveOptions]=\"{ exact: true }\"`,\n这样就只有当用户导航到 `/admin` 这个 URL 时才会激活它,而不会在导航到它的某个子路由时。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEINITIALADMINROUTINGCONFIGURATION:", "original": "The initial admin routing configuration:", "translation": "最初的管理路由配置如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###COMPONENTLESSROUTE:GROUPINGROUTESWITHOUTACOMPONENT", "original": "### Component-less route: grouping routes without a component", "translation": "### 无组件路由: 不借助组件对路由进行分组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LOOKINGATTHECHILDROUTEUNDERTHEADMINCOMPONENTTHEREISAPATHANDACHILDRENPROPERTYBUTITSNOTUSINGACOMPONENTYOUHAVENTMADEAMISTAKEINTHECONFIGURATIONYOUVEDEFINEDACOMPONENTLESSROUTE", "original": "Looking at the child route under the `AdminComponent`, there is a `path` and a `children`\nproperty but it's not using a `component`.\nYou haven't made a mistake in the configuration.\nYou've defined a _component-less_ route.", "translation": "来看 `AdminComponent` 下的子路由,这里有一个带 **path** 和 **children** 的子路由,\n但它没有使用 **component**。这并不是配置中的失误,而是在使用**无组件**路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEGOALISTOGROUPTHECRISISCENTERMANAGEMENTROUTESUNDERTHEADMINPATHYOUDONTNEEDACOMPONENTTODOITACOMPONENTLESSROUTEMAKESITEASIERTOGUARDCHILDROUTES#CANACTIVATECHILDGUARD", "original": "The goal is to group the `Crisis Center` management routes under the `admin` path.\nYou don't need a component to do it.\nA _component-less_ route makes it easier to [guard child routes](#can-activate-child-guard).", "translation": "这里的目标是对 `admin` 路径下的 ` 危机中心 ` 管理类路由进行分组,但并不需要另一个仅用来分组路由的组件。\n一个*无组件*的路由能让[守卫子路由](guide/router#can-activate-child-guard)变得更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NEXTIMPORTTHEADMINMODULEINTOAPPMODULETSANDADDITTOTHEIMPORTSARRAYTOREGISTERTHEADMINROUTES", "original": "Next, import the `AdminModule` into `app.module.ts` and add it to the `imports` array\nto register the admin routes.", "translation": "接下来,把 `AdminModule` 导入到 `app.module.ts` 中,并把它加入 `imports` 数组中来注册这些管理类路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDANADMINLINKTOTHEAPPCOMPONENTSHELLSOTHATUSERSCANGETTOTHISFEATURE", "original": "Add an \"Admin\" link to the `AppComponent` shell so that users can get to this feature.", "translation": "然后往壳组件 `AppComponent` 中添加一个链接,让用户能点击它,以访问该特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####GUARDTHEADMINFEATURE", "original": "#### Guard the admin feature", "translation": "#### 守护“管理特性”区", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CURRENTLYEVERYROUTEWITHINTHECRISISCENTERISOPENTOEVERYONETHENEWADMINFEATURESHOULDBEACCESSIBLEONLYTOAUTHENTICATEDUSERS", "original": "Currently every route within the *Crisis Center* is open to everyone.\nThe new *admin* feature should be accessible only to authenticated users.", "translation": "现在“危机中心”的每个路由都是对所有人开放的。这些新的*管理特性*应该只能被已登录用户访问。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCOULDHIDETHELINKUNTILTHEUSERLOGSINBUTTHATSTRICKYANDDIFFICULTTOMAINTAIN", "original": "You could hide the link until the user logs in. But that's tricky and difficult to maintain.", "translation": "你可以在用户登录之前隐藏这些链接,但这样会有点复杂并难以维护。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INSTEADYOULLWRITEACANACTIVATEGUARDMETHODTOREDIRECTANONYMOUSUSERSTOTHELOGINPAGEWHENTHEYTRYTOENTERTHEADMINAREA", "original": "Instead you'll write a `canActivate()` guard method to redirect anonymous users to the\nlogin page when they try to enter the admin area.", "translation": "你可以换种方式:写一个 `CanActivate()` 守卫,将正在尝试访问管理组件匿名用户重定向到登录页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISISAGENERALPURPOSEGUARDMDASHYOUCANIMAGINEOTHERFEATURESTHATREQUIREAUTHENTICATEDUSERSMDASHSOYOUCREATEANAUTHGUARDSERVICETSINTHEAPPLICATIONROOTFOLDER", "original": "This is a general purpose guard—you can imagine other features\nthat require authenticated users—so you create an\n`auth-guard.service.ts` in the application root folder.", "translation": "这是一种具有通用性的守护目标(通常会有其它特性需要登录用户才能访问),所以你要在应用的根目录下创建一个 `auth-guard.ts` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ATTHEMOMENTYOUREINTERESTEDINSEEINGHOWGUARDSWORKSOTHEFIRSTVERSIONDOESNOTHINGUSEFULITSIMPLYLOGSTOCONSOLEANDRETURNSTRUEIMMEDIATELYALLOWINGNAVIGATIONTOPROCEED:", "original": "At the moment you're interested in seeing how guards work so the first version does nothing useful.\nIt simply logs to console and `returns` true immediately, allowing navigation to proceed:", "translation": "此刻,你的兴趣在于看看守卫是如何工作的,所以第一个版本没做什么有用的事情。它只是往控制台写日志,并且立即返回 `true`,让导航继续:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NEXTOPENADMINROUTINGMODULETSIMPORTTHEAUTHGUARDCLASSANDUPDATETHEADMINROUTEWITHACANACTIVATEGUARDPROPERTYTHATREFERENCESIT:", "original": "Next, open `admin-routing.module.ts `, import the `AuthGuard` class, and\nupdate the admin route with a `canActivate` guard property that references it:", "translation": "接下来,打开 `crisis-center.routes.ts`,导入 `AuthGuard` 类,修改管理路由并通过 `CanActivate()` 守卫来引用 `AuthGuard`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEADMINFEATUREISNOWPROTECTEDBYTHEGUARDALBEITPROTECTEDPOORLY", "original": "The admin feature is now protected by the guard, albeit protected poorly.", "translation": "管理特性区现在受此守卫保护了,不过这样的保护还不够。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####TEACHAUTHGUARDTOAUTHENTICATE", "original": "#### Teach *AuthGuard* to authenticate", "translation": "#### 教 *AuthGuard* 进行认证", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MAKETHEAUTHGUARDATLEASTPRETENDTOAUTHENTICATE", "original": "Make the `AuthGuard` at least pretend to authenticate.", "translation": "先让 `AuthGuard` 至少能“假装”进行认证。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAUTHGUARDSHOULDCALLANAPPLICATIONSERVICETHATCANLOGINAUSERANDRETAININFORMATIONABOUTTHECURRENTUSERHERESADEMOAUTHSERVICE:", "original": "The `AuthGuard` should call an application service that can login a user and retain information about the current user.\nHere's a demo `AuthService`:", "translation": "`AuthGuard` 可以调用应用中的一项服务,该服务能让用户登录,并且保存当前用户的信息。下面是一个 `AuthService` 的示范:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALTHOUGHITDOESNTACTUALLYLOGINITHASWHATYOUNEEDFORTHISDISCUSSIONITHASANISLOGGEDINFLAGTOTELLYOUWHETHERTHEUSERISAUTHENTICATEDITSLOGINMETHODSIMULATESANAPICALLTOANEXTERNALSERVICEBYRETURNINGANOBSERVABLETHATRESOLVESSUCCESSFULLYAFTERASHORTPAUSETHEREDIRECTURLPROPERTYWILLSTORETHEATTEMPTEDURLSOYOUCANNAVIGATETOITAFTERAUTHENTICATING", "original": "Although it doesn't actually log in, it has what you need for this discussion.\nIt has an `isLoggedIn` flag to tell you whether the user is authenticated.\nIts `login` method simulates an API call to an external service by returning an\nObservable that resolves successfully after a short pause.\nThe `redirectUrl` property will store the attempted URL so you can navigate to it after authenticating.", "translation": "虽然它不会真的进行登录,但足够让你进行这个讨论了。\n它有一个 `isLoggedIn` 标志,用来标识是否用户已经登录过了。\n它的 `login` 方法会仿真一个对外部服务的 API 调用,返回一个可观察对象(observable)。在短暂的停顿之后,这个可观察对象就会解析成功。\n`redirectUrl` 属性将会保存在 URL 中,以便认证完之后导航到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "REVISETHEAUTHGUARDTOCALLIT", "original": "Revise the `AuthGuard` to call it.", "translation": "这就修改 `AuthGuard` 来调用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOTICETHATYOUINJECTTHEAUTHSERVICEANDTHEROUTERINTHECONSTRUCTORYOUHAVENTPROVIDEDTHEAUTHSERVICEYETBUTITSGOODTOKNOWTHATYOUCANINJECTHELPFULSERVICESINTOROUTINGGUARDS", "original": "Notice that you *inject* the `AuthService` and the `Router` in the constructor.\nYou haven't provided the `AuthService` yet but it's good to know that you can inject helpful services into routing guards.", "translation": "注意,你把 `AuthService` 和 `Router` 服务*注入到*构造函数中。\n你还没有提供 `AuthService`,这里要说明的是:可以往路由守卫中注入有用的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISGUARDRETURNSASYNCHRONOUSBOOLEANRESULTIFTHEUSERISLOGGEDINITRETURNSTRUEANDTHENAVIGATIONCONTINUES", "original": "This guard returns a synchronous boolean result.\nIf the user is logged in, it returns true and the navigation continues.", "translation": "该守卫返回一个同步的布尔值。如果用户已经登录,它就返回 `true`,导航会继续。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEACTIVATEDROUTESNAPSHOTCONTAINSTHEFUTUREROUTETHATWILLBEACTIVATEDANDTHEROUTERSTATESNAPSHOTCONTAINSTHEFUTUREROUTERSTATEOFTHEAPPLICATIONSHOULDYOUPASSTHROUGHTHEGUARDCHECK", "original": "The `ActivatedRouteSnapshot` contains the _future_ route that will be activated and the `RouterStateSnapshot`\ncontains the _future_ `RouterState` of the application, should you pass through the guard check.", "translation": "这个 `ActivatedRouteSnapshot` 包含了*即将*被激活的路由,而 `RouterStateSnapshot` 包含了该应用*即将*到达的状态。\n你应该通过守卫进行检查。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFTHEUSERISNOTLOGGEDINYOUSTORETHEATTEMPTEDURLTHEUSERCAMEFROMUSINGTHEROUTERSTATESNAPSHOTURLANDTELLTHEROUTERTONAVIGATETOALOGINPAGEMDASHAPAGEYOUHAVENTCREATEDYETTHISSECONDARYNAVIGATIONAUTOMATICALLYCANCELSTHECURRENTNAVIGATIONCHECKLOGINRETURNSFALSEJUSTTOBECLEARABOUTTHAT", "original": "If the user is not logged in, you store the attempted URL the user came from using the `RouterStateSnapshot.url` and\ntell the router to navigate to a login page—a page you haven't created yet.\nThis secondary navigation automatically cancels the current navigation; `checkLogin()` returns\n`false` just to be clear about that.", "translation": "如果用户还没有登录,你就会用 `RouterStateSnapshot.url` 保存用户来自的 URL 并让路由器导航到登录页(你尚未创建该页)。\n这间接导致路由器自动中止了这次导航,`checkLogin()` 返回 `false` 并不是必须的,但这样可以更清楚的表达意图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####ADDTHELOGINCOMPONENT", "original": "#### Add the *LoginComponent*", "translation": "#### 添加 *LoginComponent*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUNEEDALOGINCOMPONENTFORTHEUSERTOLOGINTOTHEAPPAFTERLOGGINGINYOULLREDIRECTTOTHESTOREDURLIFAVAILABLEORUSETHEDEFAULTURLTHEREISNOTHINGNEWABOUTTHISCOMPONENTORTHEWAYYOUWIREITINTOTHEROUTERCONFIGURATION", "original": "You need a `LoginComponent` for the user to log in to the app. After logging in, you'll redirect\nto the stored URL if available, or use the default URL.\nThere is nothing new about this component or the way you wire it into the router configuration.", "translation": "你需要一个 `LoginComponent` 来让用户登录进这个应用。在登录之后,你就会跳转到前面保存的 URL,如果没有,就跳转到默认 URL。\n 该组件没有什么新内容,你把它放进路由配置的方式也没什么新意。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "REGISTERALOGINROUTEINTHELOGINROUTINGMODULETSANDADDTHENECESSARYPROVIDERSTOTHEPROVIDERSARRAYINAPPMODULETSIMPORTTHELOGINCOMPONENTANDADDITTOTHEAPPMODULEDECLARATIONSIMPORTANDADDTHELOGINROUTINGMODULETOTHEAPPMODULEIMPORTSASWELL", "original": "Register a `/login` route in the `login-routing.module.ts` and add the necessary providers to the `providers`\narray. In `app.module.ts`, import the `LoginComponent` and add it to the `AppModule` `declarations`.\nImport and add the `LoginRoutingModule` to the `AppModule` imports as well.", "translation": "在 `login-routing.module.ts` 中注册一个 `/login` 路由,并把必要的提供商添加 `providers` 数组中。\n在 `app.module.ts` 中,导入 `LoginComponent` 并把它加入根模块的 `declarations` 中。\n同时在 `AppModule` 中导入并添加 `LoginRoutingModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "GUARDSANDTHESERVICEPROVIDERSTHEYREQUIREMUSTBEPROVIDEDATTHEMODULELEVELTHISALLOWSTHEROUTERACCESSTORETRIEVETHESESERVICESFROMTHEINJECTORDURINGTHENAVIGATIONPROCESSTHESAMERULEAPPLIESFORFEATUREMODULESLOADEDASYNCHRONOUSLY#ASYNCHRONOUSROUTING", "original": "Guards and the service providers they require _must_ be provided at the module-level. This allows\nthe Router access to retrieve these services from the `Injector` during the navigation process.\nThe same rule applies for feature modules loaded [asynchronously](#asynchronous-routing).", "translation": "它们所需的守卫和服务提供商**必须**在模块一级提供。这让路由器在导航过程中可以通过 `Injector` 来取得这些服务。\n 同样的规则也适用于[异步加载](guide/router#asynchronous-routing)的特性模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CANACTIVATECHILD:GUARDINGCHILDROUTES", "original": "### _CanActivateChild_: guarding child routes", "translation": "### `CanActivateChild`:保护子路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANALSOPROTECTCHILDROUTESWITHTHECANACTIVATECHILDGUARDTHECANACTIVATECHILDGUARDISSIMILARTOTHECANACTIVATEGUARDTHEKEYDIFFERENCEISTHATITRUNSBEFOREANYCHILDROUTEISACTIVATED", "original": "You can also protect child routes with the `CanActivateChild` guard.\nThe `CanActivateChild` guard is similar to the `CanActivate` guard.\nThe key difference is that it runs _before_ any child route is activated.", "translation": "你还可以使用 `CanActivateChild` 守卫来保护子路由。\n`CanActivateChild` 守卫和 `CanActivate` 守卫很像。\n它们的区别在于,`CanActivateChild` 会在*任何子路由*被激活之前运行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUPROTECTEDTHEADMINFEATUREMODULEFROMUNAUTHORIZEDACCESSYOUSHOULDALSOPROTECTCHILDROUTESWITHINTHEFEATUREMODULE", "original": "You protected the admin feature module from unauthorized access.\nYou should also protect child routes _within_ the feature module.", "translation": "你要保护管理特性模块,防止它被非授权访问,还要保护这个特性模块*内部*的那些子路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "EXTENDTHEAUTHGUARDTOPROTECTWHENNAVIGATINGBETWEENTHEADMINROUTESOPENAUTHGUARDSERVICETSANDADDTHECANACTIVATECHILDINTERFACETOTHEIMPORTEDTOKENSFROMTHEROUTERPACKAGE", "original": "Extend the `AuthGuard` to protect when navigating between the `admin` routes.\nOpen `auth-guard.service.ts` and add the `CanActivateChild` interface to the imported tokens from the router package.", "translation": "扩展 `AuthGuard` 以便在 `admin` 路由之间导航时提供保护。\n打开 `auth-guard.service.ts` 并从路由库中导入 `CanActivateChild` 接口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NEXTIMPLEMENTTHECANACTIVATECHILDMETHODWHICHTAKESTHESAMEARGUMENTSASTHECANACTIVATEMETHOD:ANACTIVATEDROUTESNAPSHOTANDROUTERSTATESNAPSHOTTHECANACTIVATECHILDMETHODCANRETURNANOBSERVABLEBOOLEANORPROMISEBOOLEANFORASYNCCHECKSANDABOOLEANFORSYNCCHECKSTHISONERETURNSABOOLEAN:", "original": "Next, implement the `canActivateChild()` method which takes the same arguments as the `canActivate()` method:\nan `ActivatedRouteSnapshot` and `RouterStateSnapshot`.\nThe `canActivateChild()` method can return an `Observable<boolean>` or `Promise<boolean>` for\nasync checks and a `boolean` for sync checks.\nThis one returns a `boolean`:", "translation": "接下来,实现 `CanActivateChild` 方法,它所接收的参数与 `CanActivate` 方法一样:一个 `ActivatedRouteSnapshot` 和一个 `RouterStateSnapshot`。\n`CanActivateChild` 方法可以返回 `Observable<boolean>` 或 `Promise<boolean>` 来支持异步检查,或 `boolean` 来支持同步检查。\n这里返回的是 `boolean`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDTHESAMEAUTHGUARDTOTHECOMPONENTLESSADMINROUTETOPROTECTALLOTHERCHILDROUTESATONETIMEINSTEADOFADDINGTHEAUTHGUARDTOEACHROUTEINDIVIDUALLY", "original": "Add the same `AuthGuard` to the `component-less` admin route to protect all other child routes at one time\ninstead of adding the `AuthGuard` to each route individually.", "translation": "同样把这个 `AuthGuard` 添加到“无组件的”管理路由,来同时保护它的所有子路由,而不是为每个路由单独添加这个 `AuthGuard`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CANDEACTIVATE:HANDLINGUNSAVEDCHANGES", "original": "### _CanDeactivate_: handling unsaved changes", "translation": "### *CanDeactivate*:处理未保存的更改", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BACKINTHEHEROESWORKFLOWTHEAPPACCEPTSEVERYCHANGETOAHEROIMMEDIATELYWITHOUTHESITATIONORVALIDATION", "original": "Back in the \"Heroes\" workflow, the app accepts every change to a hero immediately without hesitation or validation.", "translation": "回到“Heroes”工作流,该应用毫不犹豫的接受对英雄的任何修改,不作任何校验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHEREALWORLDYOUMIGHTHAVETOACCUMULATETHEUSERSCHANGESYOUMIGHTHAVETOVALIDATEACROSSFIELDSYOUMIGHTHAVETOVALIDATEONTHESERVERYOUMIGHTHAVETOHOLDCHANGESINAPENDINGSTATEUNTILTHEUSERCONFIRMSTHEMASAGROUPORCANCELSANDREVERTSALLCHANGES", "original": "In the real world, you might have to accumulate the users changes.\nYou might have to validate across fields.\nYou might have to validate on the server.\nYou might have to hold changes in a pending state until the user confirms them *as a group* or\ncancels and reverts all changes.", "translation": "在现实世界中,你得先把用户的改动积累起来。\n你可能不得不进行跨字段的校验,可能要找服务器进行校验,可能得把这些改动保存成一种待定状态,直到用户或者把这些改动*作为一组*进行确认或撤销所有改动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHATDOYOUDOABOUTUNAPPROVEDUNSAVEDCHANGESWHENTHEUSERNAVIGATESAWAYYOUCANTJUSTLEAVEANDRISKLOSINGTHEUSERSCHANGESTHATWOULDBEATERRIBLEEXPERIENCE", "original": "What do you do about unapproved, unsaved changes when the user navigates away?\nYou can't just leave and risk losing the user's changes; that would be a terrible experience.", "translation": "当用户要导航到外面时,该怎么处理这些既没有审核通过又没有保存过的改动呢?\n 你不能马上离开,不在乎丢失这些改动的风险,那显然是一种糟糕的用户体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITSBETTERTOPAUSEANDLETTHEUSERDECIDEWHATTODOIFTHEUSERCANCELSYOULLSTAYPUTANDALLOWMORECHANGESIFTHEUSERAPPROVESTHEAPPCANSAVE", "original": "It's better to pause and let the user decide what to do.\nIf the user cancels, you'll stay put and allow more changes.\nIf the user approves, the app can save.", "translation": "最好能暂停,并让用户决定该怎么做。\n如果用户选择了取消,你就留下来,并允许更多改动。\n如果用户选择了确认,那就进行保存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUSTILLMIGHTDELAYNAVIGATIONUNTILTHESAVESUCCEEDSIFYOULETTHEUSERMOVETOTHENEXTSCREENIMMEDIATELYANDTHESAVEWERETOFAILPERHAPSTHEDATAARERULEDINVALIDYOUWOULDLOSETHECONTEXTOFTHEERROR", "original": "You still might delay navigation until the save succeeds.\nIf you let the user move to the next screen immediately and\nthe save were to fail (perhaps the data are ruled invalid), you would lose the context of the error.", "translation": "在保存成功之前,你还可以继续推迟导航。如果你让用户立即移到下一个界面,而保存却失败了(可能因为数据不符合有效性规则),你就会丢失该错误的上下文环境。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANTBLOCKWHILEWAITINGFORTHESERVERMDASHTHATSNOTPOSSIBLEINABROWSERYOUNEEDTOSTOPTHENAVIGATIONWHILEYOUWAITASYNCHRONOUSLYFORTHESERVERTORETURNWITHITSANSWER", "original": "You can't block while waiting for the server—that's not possible in a browser.\nYou need to stop the navigation while you wait, asynchronously, for the server\nto return with its answer.", "translation": "在等待服务器的答复时,你没法阻塞它 —— 这在浏览器中是不可能的。\n 你只能用异步的方式在等待服务器答复之前先停止导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUNEEDTHECANDEACTIVATEGUARD", "original": "You need the `CanDeactivate` guard.", "translation": "你需要 `CanDeactivate` 守卫。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CANCELANDSAVE", "original": "### Cancel and save", "translation": "### 取消与保存", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESAMPLEAPPLICATIONDOESNTTALKTOASERVERFORTUNATELYYOUHAVEANOTHERWAYTODEMONSTRATEANASYNCHRONOUSROUTERHOOK", "original": "The sample application doesn't talk to a server.\nFortunately, you have another way to demonstrate an asynchronous router hook.", "translation": "这个范例应用不会与服务器通讯。\n幸运的是,你有另一种方式来演示异步的路由器钩子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "USERSUPDATECRISISINFORMATIONINTHECRISISDETAILCOMPONENTUNLIKETHEHERODETAILCOMPONENTTHEUSERCHANGESDONOTUPDATETHECRISISENTITYIMMEDIATELYINSTEADTHEAPPUPDATESTHEENTITYWHENTHEUSERPRESSESTHESAVEBUTTONANDDISCARDSTHECHANGESWHENTHEUSERPRESSESTHECANCELBUTTON", "original": "Users update crisis information in the `CrisisDetailComponent`.\nUnlike the `HeroDetailComponent`, the user changes do not update the crisis entity immediately.\nInstead, the app updates the entity when the user presses the *Save* button and\ndiscards the changes when the user presses the *Cancel* button.", "translation": "用户在 `CrisisDetailComponent` 中更新危机信息。\n与 `HeroDetailComponent` 不同,用户的改动不会立即更新危机的实体对象。当用户按下了 *Save* 按钮时,应用就更新这个实体对象;如果按了 *Cancel* 按钮,那就放弃这些更改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BOTHBUTTONSNAVIGATEBACKTOTHECRISISLISTAFTERSAVEORCANCEL", "original": "Both buttons navigate back to the crisis list after save or cancel.", "translation": "这两个按钮都会在保存或取消之后导航回危机列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHATIFTHEUSERTRIESTONAVIGATEAWAYWITHOUTSAVINGORCANCELINGTHEUSERCOULDPUSHTHEBROWSERBACKBUTTONORCLICKTHEHEROESLINKBOTHACTIONSTRIGGERANAVIGATIONSHOULDTHEAPPSAVEORCANCELAUTOMATICALLY", "original": "What if the user tries to navigate away without saving or canceling?\nThe user could push the browser back button or click the heroes link.\nBoth actions trigger a navigation.\nShould the app save or cancel automatically?", "translation": "如果用户尝试不保存或撤销就导航到外面该怎么办?\n 用户可以按浏览器的后退按钮,或点击英雄的链接。\n 这些操作都会触发导航。本应用应该自动保存或取消吗?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISDEMODOESNEITHERINSTEADITASKSTHEUSERTOMAKETHATCHOICEEXPLICITLYINACONFIRMATIONDIALOGBOXTHATWAITSASYNCHRONOUSLYFORTHEUSERSANSWER", "original": "This demo does neither. Instead, it asks the user to make that choice explicitly\nin a confirmation dialog box that *waits asynchronously for the user's\nanswer*.", "translation": "都不行。应用应该弹出一个确认对话框来要求用户明确做出选择,该对话框会*用异步的方式等用户做出选择*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCOULDWAITFORTHEUSERSANSWERWITHSYNCHRONOUSBLOCKINGCODETHEAPPWILLBEMORERESPONSIVEMDASHANDCANDOOTHERWORKMDASHBYWAITINGFORTHEUSERSANSWERASYNCHRONOUSLYWAITINGFORTHEUSERASYNCHRONOUSLYISLIKEWAITINGFORTHESERVERASYNCHRONOUSLY", "original": "You could wait for the user's answer with synchronous, blocking code.\nThe app will be more responsive—and can do other work—by\nwaiting for the user's answer asynchronously. Waiting for the user asynchronously\nis like waiting for the server asynchronously.", "translation": "你也能用同步的方式等用户的答复,阻塞代码。但如果能用异步的方式等待用户的答复,应用就会响应性更好,也能同时做别的事。异步等待用户的答复和等待服务器的答复是类似的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEDIALOGSERVICEPROVIDEDINTHEAPPMODULEFORAPPWIDEUSEDOESTHEASKING", "original": "The `DialogService`, provided in the `AppModule` for app-wide use, does the asking.", "translation": "`DialogService`(为了在应用级使用,已经注入到了 `AppModule`)就可以做到这些。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITRETURNSANOBSERVABLETHATRESOLVESWHENTHEUSEREVENTUALLYDECIDESWHATTODO:EITHERTODISCARDCHANGESANDNAVIGATEAWAYTRUEORTOPRESERVETHEPENDINGCHANGESANDSTAYINTHECRISISEDITORFALSE", "original": "It returns an `Observable` that *resolves* when the user eventually decides what to do: either\nto discard changes and navigate away (`true`) or to preserve the pending changes and stay in the crisis editor (`false`).", "translation": "它返回[promise](http://exploringjs.com/es6/ch_promises.html),当用户最终决定了如何去做时,它就会被*解析* —— 或者决定放弃更改直接导航离开(`true`),或者保留未完成的修改,留在危机编辑器中(`false`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATEAGUARDTHATCHECKSFORTHEPRESENCEOFACANDEACTIVATEMETHODINACOMPONENTMDASHANYCOMPONENTTHECRISISDETAILCOMPONENTWILLHAVETHISMETHODBUTTHEGUARDDOESNTHAVETOKNOWTHATTHEGUARDSHOULDNTKNOWTHEDETAILSOFANYCOMPONENTSDEACTIVATIONMETHODITNEEDONLYDETECTTHATTHECOMPONENTHASACANDEACTIVATEMETHODANDCALLITTHISAPPROACHMAKESTHEGUARDREUSABLE", "original": "Create a _guard_ that checks for the presence of a `canDeactivate()` method in a component—any component.\nThe `CrisisDetailComponent` will have this method.\nBut the guard doesn't have to know that.\nThe guard shouldn't know the details of any component's deactivation method.\nIt need only detect that the component has a `canDeactivate()` method and call it.\nThis approach makes the guard reusable.", "translation": "创建了一个 `Guard`,它将检查这个(任意)组件中是否有 `canDeactivate()` 函数。\n`CrisisDetailComponent` 就会有这个方法。\n但是该守卫并不需要知道 `CrisisDetailComponent` 确认退出激活状态的详情。\n它只需要检查该组件是否有一个 `canDeactivate()` 方法,并调用它。\n这就让该守卫可以复用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALTERNATIVELYYOUCOULDMAKEACOMPONENTSPECIFICCANDEACTIVATEGUARDFORTHECRISISDETAILCOMPONENTTHECANDEACTIVATEMETHODPROVIDESYOUWITHTHECURRENTINSTANCEOFTHECOMPONENTTHECURRENTACTIVATEDROUTEANDROUTERSTATESNAPSHOTINCASEYOUNEEDEDTOACCESSSOMEEXTERNALINFORMATIONTHISWOULDBEUSEFULIFYOUONLYWANTEDTOUSETHISGUARDFORTHISCOMPONENTANDNEEDEDTOGETTHECOMPONENTSPROPERTIESORCONFIRMWHETHERTHEROUTERSHOULDALLOWNAVIGATIONAWAYFROMIT", "original": "Alternatively, you could make a component-specific `CanDeactivate` guard for the `CrisisDetailComponent`.\nThe `canDeactivate()` method provides you with the current\ninstance of the `component`, the current `ActivatedRoute`,\nand `RouterStateSnapshot` in case you needed to access\nsome external information. This would be useful if you only\nwanted to use this guard for this component and needed to get\nthe component's properties or confirm whether the router should allow navigation away from it.", "translation": "另外,你也可以为 `CrisisDetailComponent` 创建一个特定的 `CanDeactivate` 守卫。\n在需要访问外部信息时,`canDeactivate()` 方法为你提供了组件、`ActivatedRoute` 和 `RouterStateSnapshot` 的当前实例。\n如果只想为这个组件使用该守卫,并且需要获取该组件属性或确认路由器是否允许从该组件导航出去时,这会非常有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LOOKINGBACKATTHECRISISDETAILCOMPONENTITIMPLEMENTSTHECONFIRMATIONWORKFLOWFORUNSAVEDCHANGES", "original": "Looking back at the `CrisisDetailComponent`, it implements the confirmation workflow for unsaved changes.", "translation": "看看 `CrisisDetailComponent` 组件,它已经实现了对未保存的更改进行确认的工作流。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOTICETHATTHECANDEACTIVATEMETHODCANRETURNSYNCHRONOUSLYITRETURNSTRUEIMMEDIATELYIFTHEREISNOCRISISORTHEREARENOPENDINGCHANGESBUTITCANALSORETURNAPROMISEORANOBSERVABLEANDTHEROUTERWILLWAITFORTHATTORESOLVETOTRUTHYNAVIGATEORFALSYSTAYPUT", "original": "Notice that the `canDeactivate()` method *can* return synchronously;\nit returns `true` immediately if there is no crisis or there are no pending changes.\nBut it can also return a `Promise` or an `Observable` and the router will wait for that\nto resolve to truthy (navigate) or falsy (stay put).", "translation": "注意,`canDeactivate` 方法*可以*同步返回,如果没有危机,或者没有未定的修改,它就立即返回 `true`。但是它也可以返回一个承诺(`Promise`)或可观察对象(`Observable`),路由器将等待它们被解析为真值(继续导航)或假值(留下)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDTHEGUARDTOTHECRISISDETAILROUTEINCRISISCENTERROUTINGMODULETSUSINGTHECANDEACTIVATEARRAYPROPERTY", "original": "Add the `Guard` to the crisis detail route in `crisis-center-routing.module.ts` using the `canDeactivate` array property.", "translation": "往 `crisis-center.routing.module.ts` 的危机详情路由中用 `canDeactivate` 数组添加一个 `Guard`(守卫)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDTHEGUARDTOTHEMAINAPPROUTINGMODULEPROVIDERSARRAYSOTHEROUTERCANINJECTITDURINGTHENAVIGATIONPROCESS", "original": "Add the `Guard` to the main `AppRoutingModule` `providers` array so the\n`Router` can inject it during the navigation process.", "translation": "还要把这个 `Guard` 添加到 `AppRoutingModule` 的 `providers` 中去,以便 `Router` 可以在导航过程中注入它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWYOUHAVEGIVENTHEUSERASAFEGUARDAGAINSTUNSAVEDCHANGES", "original": "Now you have given the user a safeguard against unsaved changes.", "translation": "现在,你已经给了用户一个能保护未保存更改的安全守卫。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###RESOLVE:PREFETCHINGCOMPONENTDATA", "original": "### _Resolve_: pre-fetching component data", "translation": "### _Resolve_: 预先获取组件数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHEHERODETAILANDCRISISDETAILTHEAPPWAITEDUNTILTHEROUTEWASACTIVATEDTOFETCHTHERESPECTIVEHEROORCRISIS", "original": "In the `Hero Detail` and `Crisis Detail`, the app waited until the route was activated to fetch the respective hero or crisis.", "translation": "在 `Hero Detail` 和 `Crisis Detail` 中,它们等待路由读取完对应的英雄和危机。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISWORKEDWELLBUTTHERESABETTERWAYIFYOUWEREUSINGAREALWORLDAPITHEREMIGHTBESOMEDELAYBEFORETHEDATATODISPLAYISRETURNEDFROMTHESERVERYOUDONTWANTTODISPLAYABLANKCOMPONENTWHILEWAITINGFORTHEDATA", "original": "This worked well, but there's a better way.\nIf you were using a real world API, there might be some delay before the data to display is returned from the server.\nYou don't want to display a blank component while waiting for the data.", "translation": "这种方式没有问题,但是它们还有进步的空间。\n 如果你在使用真实 api,很有可能数据返回有延迟,导致无法即时显示。\n 在这种情况下,直到数据到达前,显示一个空的组件不是最好的用户体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITSPREFERABLETOPREFETCHDATAFROMTHESERVERSOITSREADYTHEMOMENTTHEROUTEISACTIVATEDTHISALSOALLOWSYOUTOHANDLEERRORSBEFOREROUTINGTOTHECOMPONENTTHERESNOPOINTINNAVIGATINGTOACRISISDETAILFORANIDTHATDOESNTHAVEARECORDITDBEBETTERTOSENDTHEUSERBACKTOTHECRISISLISTTHATSHOWSONLYVALIDCRISISCENTERS", "original": "It's preferable to pre-fetch data from the server so it's ready the\nmoment the route is activated. This also allows you to handle errors before routing to the component.\nThere's no point in navigating to a crisis detail for an `id` that doesn't have a record.\nIt'd be better to send the user back to the `Crisis List` that shows only valid crisis centers.", "translation": "最好预先从服务器上获取完数据,这样在路由激活的那一刻数据就准备好了。\n还要在路由到此组件之前处理好错误。\n但当某个 `id` 无法对应到一个危机详情时,就没办法处理它。\n这时最好把用户带回到“危机列表”中,那里显示了所有有效的“危机”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INSUMMARYYOUWANTTODELAYRENDERINGTHEROUTEDCOMPONENTUNTILALLNECESSARYDATAHAVEBEENFETCHED", "original": "In summary, you want to delay rendering the routed component until all necessary data have been fetched.", "translation": "总之,你希望的是只有当所有必要数据都已经拿到之后,才渲染这个路由组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUNEEDARESOLVER", "original": "You need a *resolver*.", "translation": "你需要 `Resolve` 守卫。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###FETCHDATABEFORENAVIGATING", "original": "### Fetch data before navigating", "translation": "### 导航前预先加载路由信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ATTHEMOMENTTHECRISISDETAILCOMPONENTRETRIEVESTHESELECTEDCRISISIFTHECRISISISNOTFOUNDITNAVIGATESBACKTOTHECRISISLISTVIEW", "original": "At the moment, the `CrisisDetailComponent` retrieves the selected crisis.\nIf the crisis is not found, it navigates back to the crisis list view.", "translation": "目前,`CrisisDetailComponent` 会接收选中的危机。\n如果该危机没有找到,它就会导航回危机列表视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEEXPERIENCEMIGHTBEBETTERIFALLOFTHISWEREHANDLEDFIRSTBEFORETHEROUTEISACTIVATEDACRISISDETAILRESOLVERSERVICECOULDRETRIEVEACRISISORNAVIGATEAWAYIFTHECRISISDOESNOTEXISTBEFOREACTIVATINGTHEROUTEANDCREATINGTHECRISISDETAILCOMPONENT", "original": "The experience might be better if all of this were handled first, before the route is activated.\nA `CrisisDetailResolver` service could retrieve a `Crisis` or navigate away if the `Crisis` does not exist\n_before_ activating the route and creating the `CrisisDetailComponent`.", "translation": "如果能在该路由将要激活时提前处理了这个问题,那么用户体验会更好。\n`CrisisDetailResolver` 服务可以接收一个 `Crisis`,而如果这个 `Crisis` 不存在,就会在激活该路由并创建 `CrisisDetailComponent` 之前先行离开。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CREATETHECRISISDETAILRESOLVERSERVICETSFILEWITHINTHECRISISCENTERFEATUREAREA", "original": "Create the `crisis-detail-resolver.service.ts` file within the `Crisis Center` feature area.", "translation": "在“危机中心”特性区中创建 `crisis-detail-resolver.service.ts` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TAKETHERELEVANTPARTSOFTHECRISISRETRIEVALLOGICINCRISISDETAILCOMPONENTNGONINITANDMOVETHEMINTOTHECRISISDETAILRESOLVERIMPORTTHECRISISMODELCRISISSERVICEANDTHEROUTERSOYOUCANNAVIGATEELSEWHEREIFYOUCANTFETCHTHECRISIS", "original": "Take the relevant parts of the crisis retrieval logic in `CrisisDetailComponent.ngOnInit`\nand move them into the `CrisisDetailResolver`.\nImport the `Crisis` model, `CrisisService`, and the `Router`\nso you can navigate elsewhere if you can't fetch the crisis.", "translation": "在 `CrisisDetailComponent.ngOnInit` 中拿到相关的危机检索逻辑,并且把它们移到 `CrisisDetailResolver` 中。\n导入 `Crisis` 模型、`CrisisService` 和 `Router` 以便让你可以在找不到指定的危机时导航到别处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BEEXPLICITIMPLEMENTTHERESOLVEINTERFACEWITHATYPEOFCRISIS", "original": "Be explicit. Implement the `Resolve` interface with a type of `Crisis`.", "translation": "为了更明确一点,可以实现一个带有 `Crisis` 类型的 `Resolve` 接口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INJECTTHECRISISSERVICEANDROUTERANDIMPLEMENTTHERESOLVEMETHODTHATMETHODCOULDRETURNAPROMISEANOBSERVABLEORASYNCHRONOUSRETURNVALUE", "original": "Inject the `CrisisService` and `Router` and implement the `resolve()` method.\nThat method could return a `Promise`, an `Observable`, or a synchronous return value.", "translation": "注入 `CrisisService` 和 `Router`,并实现 `resolve()` 方法。\n该方法可以返回一个 `Promise`、一个 `Observable` 来支持异步方式,或者直接返回一个值来支持同步方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECRISISSERVICEGETCRISISMETHODRETURNSANOBSERVABLERETURNTHATOBSERVABLETOPREVENTTHEROUTEFROMLOADINGUNTILTHEDATAISFETCHEDTHEROUTERGUARDSREQUIREANOBSERVABLETOCOMPLETEMEANINGITHASEMITTEDALLOFITSVALUESYOUUSETHETAKEOPERATORWITHANARGUMENTOF1TOENSURETHATTHEOBSERVABLECOMPLETESAFTERRETRIEVINGTHEFIRSTVALUEFROMTHEOBSERVABLERETURNEDBYTHEGETCRISISMETHODIFITDOESNTRETURNAVALIDCRISISNAVIGATETHEUSERBACKTOTHECRISISLISTCOMPONENTCANCELINGTHEPREVIOUSINFLIGHTNAVIGATIONTOTHECRISISDETAILCOMPONENT", "original": "The `CrisisService.getCrisis` method returns an Observable.\nReturn that observable to prevent the route from loading until the data is fetched.\nThe `Router` guards require an Observable to `complete`, meaning it has emitted all\nof its values. You use the `take` operator with an argument of `1` to ensure that the\nObservable completes after retrieving the first value from the Observable returned by the\n`getCrisis` method.\nIf it doesn't return a valid `Crisis`, navigate the user back to the `CrisisListComponent`,\ncanceling the previous in-flight navigation to the `CrisisDetailComponent`.", "translation": "`CrisisService.getCrisis` 方法返回了一个 `Promise`。\n返回 `Promise` 可以阻止路由被加载,直到数据获取完毕。\n如果它没有返回一个有效的 `Crisis`,就把用户导航回 `CrisisListComponent`,并取消以前到 `CrisisDetailComponent` 尚未完成的导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IMPORTTHISRESOLVERINTHECRISISCENTERROUTINGMODULETSANDADDARESOLVEOBJECTTOTHECRISISDETAILCOMPONENTROUTECONFIGURATION", "original": "Import this resolver in the `crisis-center-routing.module.ts`\nand add a `resolve` object to the `CrisisDetailComponent` route configuration.", "translation": "把这个解析器(resolver)导入到 `crisis-center-routing.module.ts` 中,并往 `CrisisDetailComponent` 的路由配置中添加一个 `resolve` 对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "REMEMBERTOADDTHECRISISDETAILRESOLVERSERVICETOTHECRISISCENTERROUTINGMODULESPROVIDERSARRAY", "original": "Remember to add the `CrisisDetailResolver` service to the `CrisisCenterRoutingModule`'s `providers` array.", "translation": "别忘了把 `CrisisDetailResolver` 服务添加到 `CrisisCenterRoutingModule` 的 `providers` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THECRISISDETAILCOMPONENTSHOULDNOLONGERFETCHTHECRISISUPDATETHECRISISDETAILCOMPONENTTOGETTHECRISISFROMTHEACTIVATEDROUTEDATACRISISPROPERTYINSTEADTHATSWHEREYOUSAIDITSHOULDBEWHENYOURECONFIGUREDTHEROUTEITWILLBETHEREWHENTHECRISISDETAILCOMPONENTASKFORIT", "original": "The `CrisisDetailComponent` should no longer fetch the crisis.\nUpdate the `CrisisDetailComponent` to get the crisis from the `ActivatedRoute.data.crisis` property instead;\nthat's where you said it should be when you re-configured the route.\nIt will be there when the `CrisisDetailComponent` ask for it.", "translation": "`CrisisDetailComponent` 不应该再去获取这个危机的详情。\n把 `CrisisDetailComponent` 改成从 `ActivatedRoute.data.crisis` 属性中获取危机详情,这正是你重新配置路由的恰当时机。\n当 `CrisisDetailComponent` 要求取得危机详情时,它就已经在那里了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THREECRITICALPOINTS", "original": "**Three critical points**", "translation": "**两个关键点**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1THEROUTERSRESOLVEINTERFACEISOPTIONALTHECRISISDETAILRESOLVERDOESNTINHERITFROMABASECLASSTHEROUTERLOOKSFORTHATMETHODANDCALLSITIFFOUND", "original": "1. The router's `Resolve` interface is optional.\nThe `CrisisDetailResolver` doesn't inherit from a base class.\nThe router looks for that method and calls it if found.", "translation": "路由器的这个 `Resolve` 接口是可选的。`CrisisDetailResolver` 没有继承自某个基类。路由器只要找到了这个方法,就会调用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1RELYONTHEROUTERTOCALLTHERESOLVERDONTWORRYABOUTALLTHEWAYSTHATTHEUSERCOULDNAVIGATEAWAYTHATSTHEROUTERSJOBWRITETHISCLASSANDLETTHEROUTERTAKEITFROMTHERE", "original": "1. Rely on the router to call the resolver.\nDon't worry about all the ways that the user could navigate away.\nThat's the router's job. Write this class and let the router take it from there.", "translation": "要依赖路由器调用此守卫。不必关心用户用哪种方式导航离开,这是路由器的工作。你只要写出这个类,等路由器从那里取出它就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1THEOBSERVABLEPROVIDEDTOTHEROUTERMUSTCOMPLETEIFTHEOBSERVABLEDOESNOTCOMPLETETHENAVIGATIONWILLNOTCONTINUE", "original": "1. The Observable provided to the Router _must_ complete.\nIf the Observable does not complete, the navigation will not continue.", "translation": "由路由器提供的 Observable *必须* 完成(complete),否则导航不会继续。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THERELEVANTCRISISCENTERCODEFORTHISMILESTONEFOLLOWS", "original": "The relevant *Crisis Center* code for this milestone follows.", "translation": "本里程碑中与*危机中心*有关的代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###QUERYPARAMETERSANDFRAGMENTS", "original": "### Query parameters and fragments", "translation": "### 查询参数及片段", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHEROUTEPARAMETERS#OPTIONALROUTEPARAMETERSEXAMPLEYOUONLYDEALTWITHPARAMETERSSPECIFICTOTHEROUTEBUTWHATIFYOUWANTEDOPTIONALPARAMETERSAVAILABLETOALLROUTESTHISISWHEREQUERYPARAMETERSCOMEINTOPLAY", "original": "In the [route parameters](#optional-route-parameters) example, you only dealt with parameters specific to\nthe route, but what if you wanted optional parameters available to all routes?\nThis is where query parameters come into play.", "translation": "在这个[查询参数](guide/router#query-parameters)例子中,你只为路由指定了参数,但是该如何定义一些所有路由中都可用的可选参数呢?\n这就该“查询参数”登场了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "FRAGMENTSHTTPS:ENWIKIPEDIAORGWIKIFRAGMENTIDENTIFIERREFERTOCERTAINELEMENTSONTHEPAGEIDENTIFIEDWITHANIDATTRIBUTE", "original": "[Fragments](https://en.wikipedia.org/wiki/Fragment_identifier) refer to certain elements on the page\nidentified with an `id` attribute.", "translation": "[片段](https://en.wikipedia.org/wiki/Fragment_identifier)可以引用页面中带有特定 `id` 属性的元素.", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UPDATETHEAUTHGUARDTOPROVIDEASESSIONIDQUERYTHATWILLREMAINAFTERNAVIGATINGTOANOTHERROUTE", "original": "Update the `AuthGuard` to provide a `session_id` query that will remain after navigating to another route.", "translation": "修改 `AuthGuard` 以提供 `session_id` 查询参数,在导航到其它路由后,它还会存在。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDANANCHORELEMENTSOYOUCANJUMPTOACERTAINPOINTONTHEPAGE", "original": "Add an `anchor` element so you can jump to a certain point on the page.", "translation": "再添加一个锚点(`A`)元素,来让你能跳转到页面中的正确位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDTHENAVIGATIONEXTRASOBJECTTOTHEROUTERNAVIGATEMETHODTHATNAVIGATESYOUTOTHELOGINROUTE", "original": "Add the `NavigationExtras` object to the `router.navigate` method that navigates you to the `/login` route.", "translation": "为 `router.navigate` 方法添加一个 `NavigationExtras` 对象,用来导航到 `/login` 路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANALSOPRESERVEQUERYPARAMETERSANDFRAGMENTSACROSSNAVIGATIONSWITHOUTHAVINGTOPROVIDETHEMAGAINWHENNAVIGATINGINTHELOGINCOMPONENTYOULLADDANOBJECTASTHESECONDARGUMENTINTHEROUTERNAVIGATEFUNCTIONANDPROVIDETHEQUERYPARAMSHANDLINGANDPRESERVEFRAGMENTTOPASSALONGTHECURRENTQUERYPARAMETERSANDFRAGMENTTOTHENEXTROUTE", "original": "You can also preserve query parameters and fragments across navigations without having to provide them\nagain when navigating. In the `LoginComponent`, you'll add an *object* as the\nsecond argument in the `router.navigate` function\nand provide the `queryParamsHandling` and `preserveFragment` to pass along the current query parameters\nand fragment to the next route.", "translation": "还可以再导航之间**保留**查询参数和片段,而无需再次再导航中提供。在 `LoginComponent` 中的 `router.navigate` 方法中,添加第二个参数,该**对象**提供了 `preserveQueryParams` 和 `preserveFragment`,用于传递到当前的查询参数中并为下一个路由提供片段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEQUERYPARAMSHANDLINGFEATUREALSOPROVIDESAMERGEOPTIONWHICHWILLPRESERVEANDCOMBINETHECURRENTQUERYPARAMETERSWITHANYPROVIDEDQUERYPARAMETERSWHENNAVIGATING", "original": "The `queryParamsHandling` feature also provides a `merge` option, which will preserve and combine the current query parameters with any provided query parameters\nwhen navigating.", "translation": "`queryParamsHandling` 特性还提供了 `merge` 选项,它将会在导航时保留当前的查询参数,并与其它查询参数合并。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SINCEYOULLBENAVIGATINGTOTHEADMINDASHBOARDROUTEAFTERLOGGINGINYOULLUPDATEITTOHANDLETHEQUERYPARAMETERSANDFRAGMENT", "original": "Since you'll be navigating to the *Admin Dashboard* route after logging in, you'll update it to handle the\nquery parameters and fragment.", "translation": "由于要在登录后导航到*危机管理*特征区的路由,所以你还得修改它,来处理这些全局查询参数和片段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "QUERYPARAMETERSANDFRAGMENTSAREALSOAVAILABLETHROUGHTHEACTIVATEDROUTESERVICEJUSTLIKEROUTEPARAMETERSTHEQUERYPARAMETERSANDFRAGMENTSAREPROVIDEDASANOBSERVABLETHEUPDATEDCRISISADMINCOMPONENTFEEDSTHEOBSERVABLEDIRECTLYINTOTHETEMPLATEUSINGTHEASYNCPIPE", "original": "*Query parameters* and *fragments* are also available through the `ActivatedRoute` service.\nJust like *route parameters*, the query parameters and fragments are provided as an `Observable`.\nThe updated *Crisis Admin* component feeds the `Observable` directly into the template using the `AsyncPipe`.", "translation": "*查询参数*和*片段*可通过 `Router` 服务的 `routerState` 属性使用。和*路由参数*类似,全局查询参数和片段也是 `Observable` 对象。\n 在修改过的*英雄管理*组件中,你将借助 `AsyncPipe` 直接把 `Observable` 传给模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWYOUCANCLICKONTHEADMINBUTTONWHICHTAKESYOUTOTHELOGINPAGEWITHTHEPROVIDEDQUERYPARAMMAPANDFRAGMENTAFTERYOUCLICKTHELOGINBUTTONNOTICETHATYOUHAVEBEENREDIRECTEDTOTHEADMINDASHBOARDPAGEWITHTHEQUERYPARAMETERSANDFRAGMENTSTILLINTACTINTHEADDRESSBAR", "original": "Now, you can click on the *Admin* button, which takes you to the *Login*\npage with the provided `queryParamMap` and `fragment`. After you click the login button, notice that\nyou have been redirected to the `Admin Dashboard` page with the query parameters and fragment still intact in the address bar.", "translation": "按照下列步骤试验下:点击*Crisis Admin*按钮,它会带着你提供的 `queryParamMap` 和 `fragment` 跳转到登录页。\n点击登录按钮,你就会被重定向到 `Admin Dashboard` 页。\n注意,它仍然带着上一步提供的 `queryParamMap` 和 `fragment`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANUSETHESEPERSISTENTBITSOFINFORMATIONFORTHINGSTHATNEEDTOBEPROVIDEDACROSSPAGESLIKEAUTHENTICATIONTOKENSORSESSIONIDS", "original": "You can use these persistent bits of information for things that need to be provided across pages like\nauthentication tokens or session ids.", "translation": "你可以用这些持久化信息来携带需要为每个页面都提供的信息,如认证令牌或会话的 ID 等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEQUERYPARAMSANDFRAGMENTCANALSOBEPRESERVEDUSINGAROUTERLINKWITHTHEQUERYPARAMSHANDLINGANDPRESERVEFRAGMENTBINDINGSRESPECTIVELY", "original": "The `query params` and `fragment` can also be preserved using a `RouterLink` with\nthe `queryParamsHandling` and `preserveFragment` bindings respectively.", "translation": "“查询参数”和“片段”也可以分别用 `RouterLink` 中的 **preserveQueryParams** 和 **preserveFragment** 保存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##MILESTONE6:ASYNCHRONOUSROUTING", "original": "## Milestone 6: Asynchronous routing", "translation": "## 里程碑 6:异步路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ASYOUVEWORKEDTHROUGHTHEMILESTONESTHEAPPLICATIONHASNATURALLYGOTTENLARGERASYOUCONTINUETOBUILDOUTFEATUREAREASTHEOVERALLAPPLICATIONSIZEWILLCONTINUETOGROWATSOMEPOINTYOULLREACHATIPPINGPOINTWHERETHEAPPLICATIONTAKESLONGTIMETOLOAD", "original": "As you've worked through the milestones, the application has naturally gotten larger.\nAs you continue to build out feature areas, the overall application size will continue to grow.\nAt some point you'll reach a tipping point where the application takes long time to load.", "translation": "完成上面的里程碑后,应用程序很自然的长大了。在继续构建特征区的过程中,应用的尺寸将会变得更大。在某一个时间点,你将达到一个顶点,应用将会需要过多的时间来加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HOWDOYOUCOMBATTHISPROBLEMWITHASYNCHRONOUSROUTINGWHICHLOADSFEATUREMODULESLAZILYONREQUESTLAZYLOADINGHASMULTIPLEBENEFITS", "original": "How do you combat this problem? With asynchronous routing, which loads feature modules _lazily_, on request.\nLazy loading has multiple benefits.", "translation": "如何才能解决这个问题呢?通过引进异步路由,可以获得在请求时才**惰性**加载特性模块的能力。\n惰性加载有多个优点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANLOADFEATUREAREASONLYWHENREQUESTEDBYTHEUSER", "original": "* You can load feature areas only when requested by the user.", "translation": "你可以只在用户请求时才加载某些特性区。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANSPEEDUPLOADTIMEFORUSERSTHATONLYVISITCERTAINAREASOFTHEAPPLICATION", "original": "* You can speed up load time for users that only visit certain areas of the application.", "translation": "对于那些只访问应用程序某些区域的用户,这样能加快加载速度。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANCONTINUEEXPANDINGLAZYLOADEDFEATUREAREASWITHOUTINCREASINGTHESIZEOFTHEINITIALLOADBUNDLE", "original": "* You can continue expanding lazy loaded feature areas without increasing the size of the initial load bundle.", "translation": "你可以持续扩充惰性加载特性区的功能,而不用增加初始加载的包体积。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUREALREADYMADEPARTWAYTHEREBYORGANIZINGTHEAPPLICATIONINTOMODULESMDASHAPPMODULEHEROESMODULEADMINMODULEANDCRISISCENTERMODULEMDASHYOUHAVENATURALCANDIDATESFORLAZYLOADING", "original": "You're already made part way there.\nBy organizing the application into modules—`AppModule`,\n`HeroesModule`, `AdminModule` and `CrisisCenterModule`—you\nhave natural candidates for lazy loading.", "translation": "你已经完成了一部分。通过把应用组织成一些模块:`AppModule`、`HeroesModule`、`AdminModule` 和 `CrisisCenterModule`,\n你已经有了可用于实现惰性加载的候选者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SOMEMODULESLIKEAPPMODULEMUSTBELOADEDFROMTHESTARTBUTOTHERSCANANDSHOULDBELAZYLOADEDTHEADMINMODULEFOREXAMPLEISNEEDEDBYAFEWAUTHORIZEDUSERSSOYOUSHOULDONLYLOADITWHENREQUESTEDBYTHERIGHTPEOPLE", "original": "Some modules, like `AppModule`, must be loaded from the start.\nBut others can and should be lazy loaded.\nThe `AdminModule`, for example, is needed by a few authorized users, so\nyou should only load it when requested by the right people.", "translation": "有些模块(比如 `AppModule`)必须在启动时加载,但其它的都可以而且应该惰性加载。\n比如 `AdminModule` 就只有少数已认证的用户才需要它,所以你应该只有在正确的人请求它时才加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###LAZYLOADINGROUTECONFIGURATION", "original": "### Lazy Loading route configuration", "translation": "### 惰性加载路由配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "CHANGETHEADMINPATHINTHEADMINROUTINGMODULETSFROMADMINTOANEMPTYSTRINGTHEEMPTYPATH", "original": "Change the `admin` **path** in the `admin-routing.module.ts` from `'admin'` to an empty string, `''`, the _empty path_.", "translation": "把 `admin-routing.module.ts` 中的 `admin` 路径从 `'admin'` 改为空路径 `''`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERSUPPORTSEMPTYPATHROUTESUSETHEMTOGROUPROUTESTOGETHERWITHOUTADDINGANYADDITIONALPATHSEGMENTSTOTHEURLUSERSWILLSTILLVISITADMINANDTHEADMINCOMPONENTSTILLSERVESASTHEROUTINGCOMPONENTCONTAININGCHILDROUTES", "original": "The `Router` supports *empty path* routes;\nuse them to group routes together without adding any additional path segments to the URL.\nUsers will still visit `/admin` and the `AdminComponent` still serves as the *Routing Component* containing child routes.", "translation": "`Router` 支持*空路径*路由,可以使用它们来分组路由,而不用往 URL 中添加额外的路径片段。\n用户仍旧访问 `/admin`,并且 `AdminComponent` 仍然作为用来包含子路由的*路由组件*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "OPENTHEAPPROUTINGMODULEANDADDANEWADMINROUTETOITSAPPROUTESARRAY", "original": "Open the `AppRoutingModule` and add a new `admin` route to its `appRoutes` array.", "translation": "打开 `AppRoutingModule`,并把一个新的 `admin` 路由添加到它的 `appRoutes` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "GIVEITALOADCHILDRENPROPERTYNOTACHILDRENPROPERTYSETTOTHEADDRESSOFTHEADMINMODULETHEADDRESSISTHEADMINMODULEFILELOCATIONRELATIVETOTHEAPPROOTFOLLOWEDBYA#SEPARATORFOLLOWEDBYTHENAMEOFTHEEXPORTEDMODULECLASSADMINMODULE", "original": "Give it a `loadChildren` property (not a `children` property!), set to the address of the `AdminModule`.\nThe address is the `AdminModule` file location (relative to the app root),\nfollowed by a `#` separator,\nfollowed by the name of the exported module class, `AdminModule`.", "translation": "给它一个 `loadChildren` 属性(注意不是 `children` 属性),把它设置为 `AdminModule` 的地址。\n该地址是 `AdminModule` 的文件路径(相对于 `app` 目录的),加上一个 `#` 分隔符,再加上导出模块的类名 `AdminModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENTHEROUTERNAVIGATESTOTHISROUTEITUSESTHELOADCHILDRENSTRINGTODYNAMICALLYLOADTHEADMINMODULETHENITADDSTHEADMINMODULEROUTESTOITSCURRENTROUTECONFIGURATIONFINALLYITLOADSTHEREQUESTEDROUTETOTHEDESTINATIONADMINCOMPONENT", "original": "When the router navigates to this route, it uses the `loadChildren` string to dynamically load the `AdminModule`.\nThen it adds the `AdminModule` routes to its current route configuration.\nFinally, it loads the requested route to the destination admin component.", "translation": "当路由器导航到这个路由时,它会用 `loadChildren` 字符串来动态加载 `AdminModule`,然后把 `AdminModule` 添加到当前的路由配置中,\n最后,它把所请求的路由加载到目标 `admin` 组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THELAZYLOADINGANDRECONFIGURATIONHAPPENJUSTONCEWHENTHEROUTEISFIRSTREQUESTEDTHEMODULEANDROUTESAREAVAILABLEIMMEDIATELYFORSUBSEQUENTREQUESTS", "original": "The lazy loading and re-configuration happen just once, when the route is _first_ requested;\nthe module and routes are available immediately for subsequent requests.", "translation": "惰性加载和重新配置工作只会发生一次,也就是在该路由*首次*被请求时。在后续的请求中,该模块和路由都是立即可用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANGULARPROVIDESABUILTINMODULELOADERTHATSUPPORTSSYSTEMJSTOLOADMODULESASYNCHRONOUSLYIFYOUWEREUSINGANOTHERBUNDLINGTOOLSUCHASWEBPACKYOUWOULDUSETHEWEBPACKMECHANISMFORASYNCHRONOUSLYLOADINGMODULES", "original": "Angular provides a built-in module loader that supports SystemJS to load modules asynchronously. If you were\nusing another bundling tool, such as Webpack, you would use the Webpack mechanism for asynchronously loading modules.", "translation": "Angular 提供一个内置模块加载器,支持**`SystemJS`**来异步加载模块。如果你使用其它捆绑工具比如 **Webpack**,则使用 Webpack 的机制来异步加载模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TAKETHEFINALSTEPANDDETACHTHEADMINFEATURESETFROMTHEMAINAPPLICATIONTHEROOTAPPMODULEMUSTNEITHERLOADNORREFERENCETHEADMINMODULEORITSFILES", "original": "Take the final step and detach the admin feature set from the main application.\nThe root `AppModule` must neither load nor reference the `AdminModule` or its files.", "translation": "最后一步是把管理特性区从主应用中完全分离开。\n根模块 `AppModule` 既不能加载也不能引用 `AdminModule` 及其文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INAPPMODULETSREMOVETHEADMINMODULEIMPORTSTATEMENTFROMTHETOPOFTHEFILEANDREMOVETHEADMINMODULEFROMTHENGMODULESIMPORTSARRAY", "original": "In `app.module.ts`, remove the `AdminModule` import statement from the top of the file\nand remove the `AdminModule` from the NgModule's `imports` array.", "translation": "在 `app.module.ts` 中,从顶部移除 `AdminModule` 的导入语句,并且从 Angular 模块的 `imports` 数组中移除 `AdminModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CANLOADGUARD:GUARDINGUNAUTHORIZEDLOADINGOFFEATUREMODULES", "original": "### _CanLoad_ Guard: guarding unauthorized loading of feature modules", "translation": "### `CanLoad` 守卫:保护对特性模块的未授权加载", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUREALREADYPROTECTINGTHEADMINMODULEWITHACANACTIVATEGUARDTHATPREVENTSUNAUTHORIZEDUSERSFROMACCESSINGTHEADMINFEATUREAREAITREDIRECTSTOTHELOGINPAGEIFTHEUSERISNOTAUTHORIZED", "original": "You're already protecting the `AdminModule` with a `CanActivate` guard that prevents unauthorized users from\naccessing the admin feature area.\nIt redirects to the login page if the user is not authorized.", "translation": "你已经使用 `CanActivate` 保护 `AdminModule` 了,它会阻止未授权用户访问管理特性区。如果用户未登录,它就会跳转到登录页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BUTTHEROUTERISSTILLLOADINGTHEADMINMODULEEVENIFTHEUSERCANTVISITANYOFITSCOMPONENTSIDEALLYYOUDONLYLOADTHEADMINMODULEIFTHEUSERISLOGGEDIN", "original": "But the router is still loading the `AdminModule` even if the user can't visit any of its components.\nIdeally, you'd only load the `AdminModule` if the user is logged in.", "translation": "但是路由器仍然会加载 `AdminModule` —— 即使用户无法访问它的任何一个组件。\n理想的方式是,只有在用户已登录的情况下你才加载 `AdminModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDACANLOADGUARDTHATONLYLOADSTHEADMINMODULEONCETHEUSERISLOGGEDINANDATTEMPTSTOACCESSTHEADMINFEATUREAREA", "original": "Add a **`CanLoad`** guard that only loads the `AdminModule` once the user is logged in _and_ attempts to access the admin feature area.", "translation": "添加一个**`CanLoad`**守卫,它只在用户已登录*并且*尝试访问管理特性区的时候,才加载 `AdminModule` 一次。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEEXISTINGAUTHGUARDALREADYHASTHEESSENTIALLOGICINITSCHECKLOGINMETHODTOSUPPORTTHECANLOADGUARD", "original": "The existing `AuthGuard` already has the essential logic in\nits `checkLogin()` method to support the `CanLoad` guard.", "translation": "现有的 `AuthGuard` 的 `checkLogin()` 方法中已经有了支持 `CanLoad` 守卫的基础逻辑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "OPENAUTHGUARDSERVICETSIMPORTTHECANLOADINTERFACEFROMANGULARROUTERADDITTOTHEAUTHGUARDCLASSSIMPLEMENTSLISTTHENIMPLEMENTCANLOADASFOLLOWS:", "original": "Open `auth-guard.service.ts`.\nImport the `CanLoad` interface from `@angular/router`.\nAdd it to the `AuthGuard` class's `implements` list.\nThen implement `canLoad()` as follows:", "translation": "打开 `auth-guard.service.ts`,从 `@angular/router` 中导入 `CanLoad` 接口。\n把它添加到 `AuthGuard` 类的 `implements` 列表中。\n然后实现 `canLoad`,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERSETSTHECANLOADMETHODSROUTEPARAMETERTOTHEINTENDEDDESTINATIONURLTHECHECKLOGINMETHODREDIRECTSTOTHATURLONCETHEUSERHASLOGGEDIN", "original": "The router sets the `canLoad()` method's `route` parameter to the intended destination URL.\nThe `checkLogin()` method redirects to that URL once the user has logged in.", "translation": "路由器会把 `canLoad()` 方法的 `route` 参数设置为准备访问的目标 URL。\n如果用户已经登录了,`checkLogin()` 方法就会重定向到那个 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWIMPORTTHEAUTHGUARDINTOTHEAPPROUTINGMODULEANDADDTHEAUTHGUARDTOTHECANLOADARRAYPROPERTYFORTHEADMINROUTETHECOMPLETEDADMINROUTELOOKSLIKETHIS:", "original": "Now import the `AuthGuard` into the `AppRoutingModule` and add the `AuthGuard` to the `canLoad`\narray property for the `admin` route.\nThe completed admin route looks like this:", "translation": "现在,把 `AuthGuard` 导入到 `AppRoutingModule` 中,并把 `AuthGuard` 添加到 `admin` 路由的 `canLoad` 数组中。\n完整的 `admin` 路由是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###PRELOADING:BACKGROUNDLOADINGOFFEATUREAREAS", "original": "### Preloading: background loading of feature areas", "translation": "### 预加载:特性区的后台加载", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVELEARNEDHOWTOLOADMODULESONDEMANDYOUCANALSOLOADMODULESASYNCHRONOUSLYWITHPRELOADING", "original": "You've learned how to load modules on-demand.\nYou can also load modules asynchronously with _preloading_.", "translation": "你已经学会了如何按需加载模块,接下来再看看如何使用*预加载*技术异步加载模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISMAYSEEMLIKEWHATTHEAPPHASBEENDOINGALLALONGNOTQUITETHEAPPMODULEISLOADEDWHENTHEAPPLICATIONSTARTSTHATSEAGERLOADINGNOWTHEADMINMODULELOADSONLYWHENTHEUSERCLICKSONALINKTHATSLAZYLOADING", "original": "This may seem like what the app has been doing all along. Not quite.\nThe `AppModule` is loaded when the application starts; that's _eager_ loading.\nNow the `AdminModule` loads only when the user clicks on a link; that's _lazy_ loading.", "translation": "看起来好像应用一直都是这么做的,但其实并非如此。\n`AppModule` 在应用启动时就被加载了,它是*立即*加载的。\n而 `AdminModule` 只有当用户点击某个链接时才会加载,它是*惰性*加载的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PRELOADINGISSOMETHINGINBETWEENCONSIDERTHECRISISCENTERITISNTTHEFIRSTVIEWTHATAUSERSEESBYDEFAULTTHEHEROESARETHEFIRSTVIEWFORTHESMALLESTINITIALPAYLOADANDFASTESTLAUNCHTIMEYOUSHOULDEAGERLYLOADTHEAPPMODULEANDTHEHEROESMODULE", "original": "_Preloading_ is something in between.\nConsider the _Crisis Center_.\nIt isn't the first view that a user sees.\nBy default, the _Heroes_ are the first view.\nFor the smallest initial payload and fastest launch time,\nyou should eagerly load the `AppModule` and the `HeroesModule`.", "translation": "*预加载*是介于两者之间的一种方式。\n来看看*危机中心*。\n用户第一眼不会看到它。\n默认情况下,*英雄管理*才是第一视图。\n为了获得尽可能小的初始加载体积和最快的加载速度,你应该对 `AppModule` 和 `HeroesModule` 进行立即加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCOULDLAZYLOADTHECRISISCENTERBUTYOUREALMOSTCERTAINTHATTHEUSERWILLVISITTHECRISISCENTERWITHINMINUTESOFLAUNCHINGTHEAPPIDEALLYTHEAPPWOULDLAUNCHWITHJUSTTHEAPPMODULEANDTHEHEROESMODULELOADEDANDTHENALMOSTIMMEDIATELYLOADTHECRISISCENTERMODULEINTHEBACKGROUNDBYTHETIMETHEUSERNAVIGATESTOTHECRISISCENTERITSMODULEWILLHAVEBEENLOADEDANDREADYTOGO", "original": "You could lazy load the _Crisis Center_.\nBut you're almost certain that the user will visit the _Crisis Center_ within minutes of launching the app.\nIdeally, the app would launch with just the `AppModule` and the `HeroesModule` loaded\nand then, almost immediately, load the `CrisisCenterModule` in the background.\nBy the time the user navigates to the _Crisis Center_, its module will have been loaded and ready to go.", "translation": "你可以惰性加载*危机中心*。\n但是,你几乎可以肯定用户会在启动应用之后的几分钟内访问*危机中心*。\n理想情况下,应用启动时应该只加载 `AppModule` 和 `HeroesModule`,然后几乎立即开始后台加载 `CrisisCenterModule`。\n在用户浏览到*危机中心*之前,该模块应该已经加载完毕,可供访问了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THATSPRELOADING", "original": "That's _preloading_.", "translation": "这就是*预加载*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####HOWPRELOADINGWORKS", "original": "#### How preloading works", "translation": "#### 预加载的工作原理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "AFTEREACHSUCCESSFULNAVIGATIONTHEROUTERLOOKSINITSCONFIGURATIONFORANUNLOADEDMODULETHATITCANPRELOADWHETHERITPRELOADSAMODULEANDWHICHMODULESITPRELOADSDEPENDSUPONTHEPRELOADSTRATEGY", "original": "After each _successful_ navigation, the router looks in its configuration for an unloaded module that it can preload.\nWhether it preloads a module, and which modules it preloads, depends upon the *preload strategy*.", "translation": "在每次*成功的*导航后,路由器会在自己的配置中查找尚未加载并且可以预加载的模块。\n是否加载某个模块,以及要加载哪些模块,取决于*预加载策略*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTEROFFERSTWOPRELOADINGSTRATEGIESOUTOFTHEBOX:", "original": "The `Router` offers two preloading strategies out of the box:", "translation": "`Router` 内置了两种预加载策略:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOPRELOADINGATALLWHICHISTHEDEFAULTLAZYLOADEDFEATUREAREASARESTILLLOADEDONDEMAND", "original": "* No preloading at all which is the default. Lazy loaded feature areas are still loaded on demand.", "translation": "完全不预加载,这是默认值。惰性加载的特性区仍然会按需加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PRELOADINGOFALLLAZYLOADEDFEATUREAREAS", "original": "* Preloading of all lazy loaded feature areas.", "translation": "预加载所有惰性加载的特性区。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "OUTOFTHEBOXTHEROUTEREITHERNEVERPRELOADSORPRELOADSEVERYLAZYLOADMODULETHEROUTERALSOSUPPORTSCUSTOMPRELOADINGSTRATEGIES#CUSTOMPRELOADINGFORFINECONTROLOVERWHICHMODULESTOPRELOADANDWHEN", "original": "Out of the box, the router either never preloads, or preloads every lazy load module.\nThe `Router` also supports [custom preloading strategies](#custom-preloading) for\nfine control over which modules to preload and when.", "translation": "默认情况下,路由器或者完全不预加载或者预加载每个惰性加载模块。\n路由器还支持[自定义预加载策略](guide/router#custom-preloading),以便完全控制要预加载哪些模块以及何时加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHISNEXTSECTIONYOULLUPDATETHECRISISCENTERMODULETOLOADLAZILYBYDEFAULTANDUSETHEPRELOADALLMODULESSTRATEGYTOLOADITANDALLOTHERLAZYLOADEDMODULESASSOONASPOSSIBLE", "original": "In this next section, you'll update the `CrisisCenterModule` to load lazily\nby default and use the `PreloadAllModules` strategy\nto load it (and _all other_ lazy loaded modules) as soon as possible.", "translation": "在下一节,你将会把 `CrisisCenterModule` 改为默认惰性加载的,并使用 `PreloadAllModules` 策略来尽快加载它(以及*所有其它*惰性加载模块)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####LAZYLOADTHECRISISCENTER", "original": "#### Lazy load the _crisis center_", "translation": "#### 惰性加载*危机中心*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "UPDATETHEROUTECONFIGURATIONTOLAZYLOADTHECRISISCENTERMODULETAKETHESAMESTEPSYOUUSEDTOCONFIGUREADMINMODULEFORLAZYLOAD", "original": "Update the route configuration to lazy load the `CrisisCenterModule`.\nTake the same steps you used to configure `AdminModule` for lazy load.", "translation": "修改路由配置,来惰性加载 `CrisisCenterModule`。修改的步骤和配置惰性加载 `AdminModule` 时一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1CHANGETHECRISISCENTERPATHINTHECRISISCENTERROUTINGMODULETOANEMPTYSTRING", "original": "1. Change the `crisis-center` path in the `CrisisCenterRoutingModule` to an empty string.", "translation": "把 `CrisisCenterRoutingModule` 中的路径从 `crisis-center` 改为空字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1ADDACRISISCENTERROUTETOTHEAPPROUTINGMODULE", "original": "1. Add a `crisis-center` route to the `AppRoutingModule`.", "translation": "往 `AppRoutingModule` 中添加一个 `crisis-center` 路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1SETTHELOADCHILDRENSTRINGTOLOADTHECRISISCENTERMODULE", "original": "1. Set the `loadChildren` string to load the `CrisisCenterModule`.", "translation": "设置 `loadChildren` 字符串来加载 `CrisisCenterModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1REMOVEALLMENTIONOFTHECRISISCENTERMODULEFROMAPPMODULETS", "original": "1. Remove all mention of the `CrisisCenterModule` from `app.module.ts`.", "translation": "从 `app.module.ts` 中移除所有对 `CrisisCenterModule` 的引用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HEREARETHEUPDATEDMODULESBEFOREENABLINGPRELOAD:", "original": "Here are the updated modules _before enabling preload_:", "translation": "下面是打开预加载之前的模块修改版:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCOULDTRYTHISNOWANDCONFIRMTHATTHECRISISCENTERMODULELOADSAFTERYOUCLICKTHECRISISCENTERBUTTON", "original": "You could try this now and confirm that the `CrisisCenterModule` loads after you click the \"Crisis Center\" button.", "translation": "你可以现在尝试它,并确认在点击了“Crisis Center”按钮之后加载了 `CrisisCenterModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TOENABLEPRELOADINGOFALLLAZYLOADEDMODULESIMPORTTHEPRELOADALLMODULESTOKENFROMTHEANGULARROUTERPACKAGE", "original": "To enable preloading of all lazy loaded modules, import the `PreloadAllModules` token from the Angular router package.", "translation": "要为所有惰性加载模块启用预加载功能,请从 Angular 的路由模块中导入 `PreloadAllModules`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESECONDARGUMENTINTHEROUTERMODULEFORROOTMETHODTAKESANOBJECTFORADDITIONALCONFIGURATIONOPTIONSTHEPRELOADINGSTRATEGYISONEOFTHOSEOPTIONSADDTHEPRELOADALLMODULESTOKENTOTHEFORROOTCALL:", "original": "The second argument in the `RouterModule.forRoot` method takes an object for additional configuration options.\nThe `preloadingStrategy` is one of those options.\nAdd the `PreloadAllModules` token to the `forRoot` call:", "translation": "`RouterModule.forRoot` 方法的第二个参数接受一个附加配置选项对象。\n`preloadingStrategy` 就是其中之一。\n把 `PreloadAllModules` 添加到 `forRoot` 调用中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISTELLSTHEROUTERPRELOADERTOIMMEDIATELYLOADALLLAZYLOADEDROUTESROUTESWITHALOADCHILDRENPROPERTY", "original": "This tells the `Router` preloader to immediately load _all_ lazy loaded routes (routes with a `loadChildren` property).", "translation": "这会让 `Router` 预加载器立即加载*所有*惰性加载路由(带 `loadChildren` 属性的路由)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENYOUVISITHTTP:LOCALHOST:3000THEHEROESROUTELOADSIMMEDIATELYUPONLAUNCHANDTHEROUTERSTARTSLOADINGTHECRISISCENTERMODULERIGHTAFTERTHEHEROESMODULELOADS", "original": "When you visit `http://localhost:3000`, the `/heroes` route loads immediately upon launch\nand the router starts loading the `CrisisCenterModule` right after the `HeroesModule` loads.", "translation": "当访问 `http://localhost:3000` 时,`/heroes` 路由立即随之启动,并且路由器在加载了 `HeroesModule` 之后立即开始加载 `CrisisCenterModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SURPRISINGLYTHEADMINMODULEDOESNOTPRELOADSOMETHINGISBLOCKINGIT", "original": "Surprisingly, the `AdminModule` does _not_ preload. Something is blocking it.", "translation": "意外的是,`AdminModule`*没有*预加载,有什么东西阻塞了它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####CANLOADBLOCKSPRELOAD", "original": "#### CanLoad blocks preload", "translation": "#### CanLoad 会阻塞预加载", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPRELOADALLMODULESSTRATEGYDOESNOTLOADFEATUREAREASPROTECTEDBYACANLOAD#CANLOADGUARDGUARDTHISISBYDESIGN", "original": "The `PreloadAllModules` strategy does not load feature areas protected by a [CanLoad](#can-load-guard) guard.\nThis is by design.", "translation": "`PreloadAllModules` 策略不会加载被[CanLoad](guide/router#can-load-guard)守卫所保护的特性区。这是刻意设计的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUADDEDACANLOADGUARDTOTHEROUTEINTHEADMINMODULEAFEWSTEPSBACKTOBLOCKLOADINGOFTHATMODULEUNTILTHEUSERISAUTHORIZEDTHATCANLOADGUARDTAKESPRECEDENCEOVERTHEPRELOADSTRATEGY", "original": "You added a `CanLoad` guard to the route in the `AdminModule` a few steps back\nto block loading of that module until the user is authorized.\nThat `CanLoad` guard takes precedence over the preload strategy.", "translation": "你几步之前刚刚给 `AdminModule` 中的路由添加了 `CanLoad` 守卫,以阻塞加载那个模块,直到用户认证结束。\n`CanLoad` 守卫的优先级高于预加载策略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFYOUWANTTOPRELOADAMODULEANDGUARDAGAINSTUNAUTHORIZEDACCESSDROPTHECANLOADGUARDMETHODANDRELYONTHECANACTIVATE#CANACTIVATEGUARDGUARDALONE", "original": "If you want to preload a module _and_ guard against unauthorized access,\ndrop the `canLoad()` guard method and rely on the [canActivate()](#can-activate-guard) guard alone.", "translation": "如果你要加载一个模块*并且*保护它防止未授权访问,请移除 `canLoad` 守卫,只单独依赖[CanActivate](guide/router#can-activate-guard)守卫。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CUSTOMPRELOADINGSTRATEGY", "original": "### Custom Preloading Strategy", "translation": "### 自定义预加载策略", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PRELOADINGEVERYLAZYLOADEDMODULESWORKSWELLINMANYSITUATIONSBUTITISNTALWAYSTHERIGHTCHOICEESPECIALLYONMOBILEDEVICESANDOVERLOWBANDWIDTHCONNECTIONSYOUMAYCHOOSETOPRELOADONLYCERTAINFEATUREMODULESBASEDONUSERMETRICSANDOTHERBUSINESSANDTECHNICALFACTORS", "original": "Preloading every lazy loaded modules works well in many situations,\nbut it isn't always the right choice, especially on mobile devices and over low bandwidth connections.\nYou may choose to preload only certain feature modules, based on user metrics and other business and technical factors.", "translation": "在大多数场景下,预加载每个惰性加载模块就很好了,但是有时候它却并不是正确的选择,特别是在移动设备和低带宽连接下。\n你可能出于用户的测量和其它商业和技术因素而选择只对某些特性模块进行预加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANCONTROLWHATANDHOWTHEROUTERPRELOADSWITHACUSTOMPRELOADINGSTRATEGY", "original": "You can control what and how the router preloads with a custom preloading strategy.", "translation": "使用自定义预加载策略,你可以控制路由器预加载哪些路由以及如何加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHISSECTIONYOULLADDACUSTOMSTRATEGYTHATONLYPRELOADSROUTESWHOSEDATAPRELOADFLAGISSETTOTRUERECALLTHATYOUCANADDANYTHINGTOTHEDATAPROPERTYOFAROUTE", "original": "In this section, you'll add a custom strategy that _only_ preloads routes whose `data.preload` flag is set to `true`.\nRecall that you can add anything to the `data` property of a route.", "translation": "在这一节,你将添加一个自定义策略,它*只*预加载那些 `data.preload` 标志为 `true` 的路由。\n回忆一下,你可以往路由的 `data` 属性中添加任何东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SETTHEDATAPRELOADFLAGINTHECRISISCENTERROUTEINTHEAPPROUTINGMODULE", "original": "Set the `data.preload` flag in the `crisis-center` route in the `AppRoutingModule`.", "translation": "在 `AppRoutingModule` 的 `crisis-center` 路由中设置 `data.preload` 标志。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ADDANEWFILETOTHEPROJECTCALLEDSELECTIVEPRELOADINGSTRATEGYTSANDDEFINEASELECTIVEPRELOADINGSTRATEGYSERVICECLASSASFOLLOWS:", "original": "Add a new file to the project called `selective-preloading-strategy.ts`\nand define a `SelectivePreloadingStrategy` service class as follows:", "translation": "往项目中添加一个新的名叫 `selective-preloading-strategy.ts` 的文件,并在其中定义一个服务类 `SelectivePreloadingStrategy`,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SELECTIVEPRELOADINGSTRATEGYIMPLEMENTSTHEPRELOADINGSTRATEGYWHICHHASONEMETHODPRELOAD", "original": "`SelectivePreloadingStrategy` implements the `PreloadingStrategy`, which has one method, `preload`.", "translation": "`SelectivePreloadingStrategy` 实现了 `PreloadingStrategy`,它只有一个方法 `preload`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERCALLSTHEPRELOADMETHODWITHTWOARGUMENTS:", "original": "The router calls the `preload` method with two arguments:", "translation": "路由器会用两个参数调用调用 `preload` 方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1THEROUTETOCONSIDER", "original": "1. The route to consider.", "translation": "要加载的路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1ALOADERFUNCTIONTHATCANLOADTHEROUTEDMODULEASYNCHRONOUSLY", "original": "1. A loader function that can load the routed module asynchronously.", "translation": "一个加载器(loader)函数,它能异步加载带路由的模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ANIMPLEMENTATIONOFPRELOADMUSTRETURNANOBSERVABLEIFTHEROUTESHOULDPRELOADITRETURNSTHEOBSERVABLERETURNEDBYCALLINGTHELOADERFUNCTIONIFTHEROUTESHOULDNOTPRELOADITRETURNSANOBSERVABLEOFNULL", "original": "An implementation of `preload`must return an `Observable`.\nIf the route should preload, it returns the observable returned by calling the loader function.\nIf the route should _not_ preload, it returns an `Observable` of `null`.", "translation": "`preload` 的实现必须返回一个 `Observable`。\n如果该路由应该预加载,它就会返回调用加载器函数所返回的 `Observable`。\n如果该路由*不*应该预加载,它就返回一个 `null` 值的 `Observable` 对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INTHISSAMPLETHEPRELOADMETHODLOADSTHEROUTEIFTHEROUTESDATAPRELOADFLAGISTRUTHY", "original": "In this sample, the `preload` method loads the route if the route's `data.preload` flag is truthy.", "translation": "在这个例子中,`preload` 方法只有在路由的 `data.preload` 标识为真时才会加载该路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ITALSOHASASIDEEFFECTSELECTIVEPRELOADINGSTRATEGYLOGSTHEPATHOFASELECTEDROUTEINITSPUBLICPRELOADEDMODULESARRAY", "original": "It also has a side-effect.\n`SelectivePreloadingStrategy` logs the `path` of a selected route in its public `preloadedModules` array.", "translation": "它还有一个副作用。\n`SelectivePreloadingStrategy` 会把所选路由的 `path` 记录在它的公共数组 `preloadedModules` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SHORTLYYOULLEXTENDTHEADMINDASHBOARDCOMPONENTTOINJECTTHISSERVICEANDDISPLAYITSPRELOADEDMODULESARRAY", "original": "Shortly, you'll extend the `AdminDashboardComponent` to inject this service and display its `preloadedModules` array.", "translation": "很快,你就会扩展 `AdminDashboardComponent` 来注入该服务,并且显示它的 `preloadedModules` 数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BUTFIRSTMAKEAFEWCHANGESTOTHEAPPROUTINGMODULE", "original": "But first, make a few changes to the `AppRoutingModule`.", "translation": "但是首先,要对 `AppRoutingModule` 做少量修改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1IMPORTSELECTIVEPRELOADINGSTRATEGYINTOAPPROUTINGMODULE", "original": "1. Import `SelectivePreloadingStrategy` into `AppRoutingModule`.", "translation": "把 `SelectivePreloadingStrategy` 导入到 `AppRoutingModule` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1REPLACETHEPRELOADALLMODULESSTRATEGYINTHECALLTOFORROOTWITHTHISSELECTIVEPRELOADINGSTRATEGY", "original": "1. Replace the `PreloadAllModules` strategy in the call to `forRoot` with this `SelectivePreloadingStrategy`.", "translation": "把 `PreloadAllModules` 策略替换成对 `forRoot` 的调用,并且传入这个 `SelectivePreloadingStrategy`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1ADDTHESELECTIVEPRELOADINGSTRATEGYSTRATEGYTOTHEAPPROUTINGMODULEPROVIDERSARRAYSOITCANBEINJECTEDELSEWHEREINTHEAPP", "original": "1. Add the `SelectivePreloadingStrategy` strategy to the `AppRoutingModule` providers array so it can be injected\nelsewhere in the app.", "translation": "把 `SelectivePreloadingStrategy` 策略添加到 `AppRoutingModule` 的 `providers` 数组中,以便它可以注入到应用中的任何地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "NOWEDITTHEADMINDASHBOARDCOMPONENTTODISPLAYTHELOGOFPRELOADEDROUTES", "original": "Now edit the `AdminDashboardComponent` to display the log of preloaded routes.", "translation": "现在,编辑 `AdminDashboardComponent` 以显示这些预加载路由的日志。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1IMPORTTHESELECTIVEPRELOADINGSTRATEGYITSASERVICE", "original": "1. Import the `SelectivePreloadingStrategy` (it's a service).", "translation": "导入 `SelectivePreloadingStrategy`(它是一个服务)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1INJECTITINTOTHEDASHBOARDSCONSTRUCTOR", "original": "1. Inject it into the dashboard's constructor.", "translation": "把它注入到仪表盘的构造函数中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1UPDATETHETEMPLATETODISPLAYTHESTRATEGYSERVICESPRELOADEDMODULESARRAY", "original": "1. Update the template to display the strategy service's `preloadedModules` array.", "translation": "修改模板来显示这个策略服务的 `preloadedModules` 数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENYOUREDONEITLOOKSLIKETHIS", "original": "When you're done it looks like this.", "translation": "当完成时,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ONCETHEAPPLICATIONLOADSTHEINITIALROUTETHECRISISCENTERMODULEISPRELOADEDVERIFYTHISBYLOGGINGINTOTHEADMINFEATUREAREAANDNOTINGTHATTHECRISISCENTERISLISTEDINTHEPRELOADEDMODULESITSALSOLOGGEDTOTHEBROWSERSCONSOLE", "original": "Once the application loads the initial route, the `CrisisCenterModule` is preloaded.\nVerify this by logging in to the `Admin` feature area and noting that the `crisis-center` is listed in the `Preloaded Modules`.\nIt's also logged to the browser's console.", "translation": "一旦应用加载完了初始路由,`CrisisCenterModule` 也被预加载了。\n通过 `Admin` 特性区中的记录就可以验证它,“Preloaded Modules”中没有列出 `crisis-center`。\n它也被记录到了浏览器的控制台。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##MIGRATINGURLSWITHREDIRECTS", "original": "## Migrating URLs with Redirects", "translation": "## 使用重定向迁移 URL", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVESETUPTHEROUTESFORNAVIGATINGAROUNDYOURAPPLICATIONYOUVEUSEDNAVIGATIONIMPERATIVELYANDDECLARATIVELYTOMANYDIFFERENTROUTESBUTLIKEANYAPPLICATIONREQUIREMENTSCHANGEOVERTIMEYOUVESETUPLINKSANDNAVIGATIONTOHEROESANDHERO:IDFROMTHEHEROLISTCOMPONENTANDHERODETAILCOMPONENTCOMPONENTSIFTHEREWASAREQUIREMENTTHATLINKSTOHEROESBECOMESUPERHEROESYOUSTILLWANTTHEPREVIOUSURLSTONAVIGATECORRECTLYYOUALSODONTWANTTOGOANDUPDATEEVERYLINKINYOURAPPLICATIONSOREDIRECTSMAKESREFACTORINGROUTESTRIVIAL", "original": "You've setup the routes for navigating around your application. You've used navigation imperatively and declaratively to many different routes. But like any application, requirements change over time. You've setup links and navigation to `/heroes` and `/hero/:id` from the `HeroListComponent` and `HeroDetailComponent` components. If there was a requirement that links to `heroes` become `superheroes`, you still want the previous URLs to navigate correctly. You also don't want to go and update every link in your application, so redirects makes refactoring routes trivial.", "translation": "你已经设置好了路由,并且用命令式和声明式的方式导航到了很多不同的路由。但是,任何应用的需求都会随着时间而改变。\n你把链接 `/heroes` 和 `hero/:id` 指向了 `HeroListComponent` 和 `HeroDetailComponent` 组件。\n如果有这样一个需求,要把链接 `heroes` 变成 `superheroes`,你仍然希望以前的 URL 能正常导航。\n但你也不想在应用中找到并修改每一个链接,这时候,重定向就可以省去这些琐碎的重构工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###CHANGINGHEROESTOSUPERHEROES", "original": "### Changing /heroes to /superheroes", "translation": "### 把 `/heroes` 修改为 `/superheros`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LETSTAKETHEHEROROUTESANDMIGRATETHEMTONEWURLSTHEROUTERCHECKSFORREDIRECTSINYOURCONFIGURATIONBEFORENAVIGATINGSOEACHREDIRECTISTRIGGEREDWHENNEEDEDTOSUPPORTTHISCHANGEYOULLADDREDIRECTSFROMTHEOLDROUTESTOTHENEWROUTESINTHEHEROESROUTINGMODULE", "original": "Let's take the `Hero` routes and migrate them to new URLs. The `Router` checks for redirects in your configuration before navigating, so each redirect is triggered when needed. To support this change, you'll add redirects from the old routes to the new routes in the `heroes-routing.module`.", "translation": "先取得 `Hero` 路由,并把它们迁移到新的 URL。`Router`(路由器)会在开始导航之前先在配置中检查所有重定向语句,以便将来按需触发重定向。要支持这种修改,你就要在 `heroes-routing.module` 文件中把老的路由重定向到新的路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOULLNOTICETWODIFFERENTTYPESOFREDIRECTSTHEFIRSTCHANGEISFROMHEROESTOSUPERHEROESWITHOUTANYPARAMETERSTHISISASTRAIGHTFORWARDREDIRECTUNLIKETHECHANGEFROMHERO:IDTOSUPERHERO:IDWHICHINCLUDESTHE:IDROUTEPARAMETERROUTERREDIRECTSALSOUSEPOWERFULPATTERNMATCHINGSOTHEROUTERINSPECTSTHEURLANDREPLACESROUTEPARAMETERSINTHEPATHWITHTHEIRAPPROPRIATEDESTINATIONPREVIOUSLYYOUNAVIGATEDTOAURLSUCHASHERO15WITHAROUTEPARAMETERIDOF15", "original": "You'll notice two different types of redirects. The first change is from `/heroes` to `/superheroes` without any parameters. This is a straightforward redirect, unlike the change from `/hero/:id` to `/superhero/:id`, which includes the `:id` route parameter. Router redirects also use powerful pattern matching, so the `Router` inspects the URL and replaces route parameters in the `path` with their appropriate destination. Previously, you navigated to a URL such as `/hero/15` with a route parameter `id` of `15`.", "translation": "注意,这里有两种类型的重定向。第一种是不带参数的从 `/heroes` 重定向到 `/superheroes`。这是一种非常直观的重定向。第二种是从 `/hero/:id` 重定向到 `/superhero/:id`,它还要包含一个 `:id` 路由参数。\n路由器重定向时使用强大的模式匹配功能,这样,路由器就会检查 URL,并且把 `path` 中带的路由参数替换成相应的目标形式。以前,你导航到形如 `/hero/15` 的 URL 时,带了一个路由参数 `id`,它的值是 `15`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERALSOSUPPORTSQUERYPARAMETERS#QUERYPARAMETERSANDTHEFRAGMENT#FRAGMENTWHENUSINGREDIRECTS", "original": "The `Router` also supports [query parameters](#query-parameters) and the [fragment](#fragment) when using redirects.", "translation": "在重定向的时候,路由器还支持[查询参数](#query-parameters)和[片段(fragment)](#fragment)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENUSINGABSOLUTEREDIRECTSTHEROUTERWILLUSETHEQUERYPARAMETERSANDTHEFRAGMENTFROMTHEREDIRECTTOINTHEROUTECONFIG", "original": "* When using absolute redirects, the `Router` will use the query parameters and the fragment from the redirectTo in the route config.", "translation": "当使用绝对地址重定向时,路由器将会使用路由配置的 `redirectTo` 属性中规定的查询参数和片段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENUSINGRELATIVEREDIRECTSTHEROUTERUSETHEQUERYPARAMSANDTHEFRAGMENTFROMTHESOURCEURL", "original": "* When using relative redirects, the `Router` use the query params and the fragment from the source URL.", "translation": "当使用相对地址重定向时,路由器将会使用源地址(跳转前的地址)中的查询参数和片段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "BEFOREUPDATINGTHEAPPROUTINGMODULETSYOULLNEEDTOCONSIDERANIMPORTANTRULECURRENTLYOUREMPTYPATHROUTEREDIRECTSTOHEROESWHICHREDIRECTSTOSUPERHEROESTHISWONTWORKANDISBYDESIGNASTHEROUTERHANDLESREDIRECTSONCEATEACHLEVELOFROUTINGCONFIGURATIONTHISPREVENTSCHAININGOFREDIRECTSWHICHCANLEADTOENDLESSREDIRECTLOOPS", "original": "Before updating the `app-routing.module.ts`, you'll need to consider an important rule. Currently, our empty path route redirects to `/heroes`, which redirects to `/superheroes`. This _won't_ work and is by design as the `Router` handles redirects once at each level of routing configuration. This prevents chaining of redirects, which can lead to endless redirect loops.", "translation": "在修改 `app-routing.module.ts` 之前,你要先考虑一条重要的规则。\n目前,你把空路径路由重定向到了 `/heroes`,它又被重定向到了 `/superheroes`。这样*不行*,从设计上就不行。\n因为路由器在每一层的路由配置中只会处理一次重定向。这样可以防止出现无限循环的重定向。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SOINSTEADYOULLUPDATETHEEMPTYPATHROUTEINAPPROUTINGMODULETSTOREDIRECTTOSUPERHEROES", "original": "So instead, you'll update the empty path route in `app-routing.module.ts` to redirect to `/superheroes`.", "translation": "所以,你要在 `app-routing.module.ts` 中修改空路径路由,让它重定向到 `/superheroes`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SINCEROUTERLINKSARENTTIEDTOROUTECONFIGURATIONYOULLNEEDTOUPDATETHEASSOCIATEDROUTERLINKSSOTHEYREMAINACTIVEWHENTHENEWROUTEISACTIVEYOULLUPDATETHEAPPCOMPONENTTSTEMPLATEFORTHEHEROESROUTERLINK", "original": "Since `RouterLink`s aren't tied to route configuration, you'll need to update the associated router links so they remain active when the new route is active. You'll update the `app.component.ts` template for the `/heroes` routerLink.", "translation": "由于 `RouterLink` 指令没有关联到路由配置,所以你需要修改相关的路由链接,以便在新的路由激活时,它们也能保持激活状态。你要修改 `app.component.ts` 模板中的 `/heroes` 路由链接。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WITHTHEREDIRECTSSETUPALLPREVIOUSROUTESNOWPOINTTOTHEIRNEWDESTINATIONSANDBOTHURLSSTILLFUNCTIONASINTENDED", "original": "With the redirects setup, all previous routes now point to their new destinations and both URLs still function as intended.", "translation": "当这些重定向设置好之后,所有以前的路由都指向了它们的新目标,并且每个 URL 也仍然能正常工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##INSPECTTHEROUTERSCONFIGURATION", "original": "## Inspect the router's configuration", "translation": "## 审查路由器配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUPUTALOTOFEFFORTINTOCONFIGURINGTHEROUTERINSEVERALROUTINGMODULEFILESANDWERECAREFULTOLISTTHEMINTHEPROPERORDER#ROUTINGMODULEORDERAREROUTESACTUALLYEVALUATEDASYOUPLANNEDHOWISTHEROUTERREALLYCONFIGURED", "original": "You put a lot of effort into configuring the router in several routing module files\nand were careful to list them [in the proper order](#routing-module-order).\nAre routes actually evaluated as you planned?\nHow is the router really configured?", "translation": "你把大量的精力投入到在一系列路由模块文件里配置路由器上,并且小心的[以合适的顺序](guide/router#routing-module-order)列出它们。\n这些路由是否真的如同你预想的那样执行了?\n路由器的真实配置是怎样的?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANINSPECTTHEROUTERSCURRENTCONFIGURATIONANYTIMEBYINJECTINGITANDEXAMININGITSCONFIGPROPERTYFOREXAMPLEUPDATETHEAPPMODULEASFOLLOWSANDLOOKINTHEBROWSERCONSOLEWINDOWTOSEETHEFINISHEDROUTECONFIGURATION", "original": "You can inspect the router's current configuration any time by injecting it and\nexamining its `config` property.\nFor example, update the `AppModule` as follows and look in the browser console window\nto see the finished route configuration.", "translation": "通过注入它(Router)并检查它的 `config` 属性,你可以随时审查路由器的当前配置。\n例如,把 `AppModule` 修改为这样,并在浏览器的控制台窗口中查看最终的路由配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##WRAPUPANDFINALAPP", "original": "## Wrap up and final app", "translation": "## 总结与最终的应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVECOVEREDALOTOFGROUNDINTHISGUIDEANDTHEAPPLICATIONISTOOBIGTOREPRINTHEREPLEASEVISITTHELIVEEXAMPLETITLEROUTERSAMPLEINSTACKBLITZLIVEEXAMPLEWHEREYOUCANDOWNLOADTHEFINALSOURCECODE", "original": "You've covered a lot of ground in this guide and the application is too big to reprint here.\nPlease visit the <live-example title=\"Router Sample in Stackblitz\"></live-example>\nwhere you can download the final source code.", "translation": "本章中涉及到了很多背景知识,而且本应用程序也太大了,所以没法在这里显示。请访问<live-example title=\"Router Sample in Stackblitz\"></live-example>,在那里你可以下载最终的源码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "##APPENDICES", "original": "## Appendices", "translation": "## 附录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEBALANCEOFTHISGUIDEISASETOFAPPENDICESTHATELABORATESOMEOFTHEPOINTSYOUCOVEREDQUICKLYABOVE", "original": "The balance of this guide is a set of appendices that\nelaborate some of the points you covered quickly above.", "translation": "本章剩下的部分是一组附录,它详尽阐述了那些曾匆匆带过的知识点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEAPPENDIXMATERIALISNTESSENTIALCONTINUEDREADINGISFORTHECURIOUS", "original": "The appendix material isn't essential. Continued reading is for the curious.", "translation": "该附件中的内容不是必须的,感兴趣的人才需要阅读它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###APPENDIX:LINKPARAMETERSARRAY", "original": "### Appendix: link parameters array", "translation": "### 附录:链接参数数组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALINKPARAMETERSARRAYHOLDSTHEFOLLOWINGINGREDIENTSFORROUTERNAVIGATION:", "original": "A link parameters array holds the following ingredients for router navigation:", "translation": "链接参数数组保存路由导航时所需的成分:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPATHOFTHEROUTETOTHEDESTINATIONCOMPONENT", "original": "* The *path* of the route to the destination component.", "translation": "指向目标组件的那个路由的*路径(path)*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "REQUIREDANDOPTIONALROUTEPARAMETERSTHATGOINTOTHEROUTEURL", "original": "* Required and optional route parameters that go into the route URL.", "translation": "必备路由参数和可选路由参数,它们将进入该路由的 URL", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANBINDTHEROUTERLINKDIRECTIVETOSUCHANARRAYLIKETHIS:", "original": "You can bind the `RouterLink` directive to such an array like this:", "translation": "你可以把 `RouterLink` 指令绑定到一个数组,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUVEWRITTENATWOELEMENTARRAYWHENSPECIFYINGAROUTEPARAMETERLIKETHIS:", "original": "You've written a two element array when specifying a route parameter like this:", "translation": "在指定路由参数时,你写过一个双元素的数组,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANPROVIDEOPTIONALROUTEPARAMETERSINANOBJECTLIKETHIS:", "original": "You can provide optional route parameters in an object like this:", "translation": "你可以在对象中提供可选的路由参数,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESETHREEEXAMPLESCOVERTHENEEDFORANAPPWITHONELEVELROUTINGTHEMOMENTYOUADDACHILDROUTERSUCHASTHECRISISCENTERYOUCREATENEWLINKARRAYPOSSIBILITIES", "original": "These three examples cover the need for an app with one level routing.\nThe moment you add a child router, such as the crisis center, you create new link array possibilities.", "translation": "这三个例子涵盖了你在单级路由的应用中所需的一切。在你添加一个像*危机中心*一样的子路由时,你可以创建新链接数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RECALLTHATYOUSPECIFIEDADEFAULTCHILDROUTEFORTHECRISISCENTERSOTHISSIMPLEROUTERLINKISFINE", "original": "Recall that you specified a default child route for the crisis center so this simple `RouterLink` is fine.", "translation": "回忆一下,你曾为*危机中心*指定过一个默认的子路由,以便能使用这种简单的 `RouterLink`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "PARSEITOUT", "original": "Parse it out.", "translation": "分解一下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEFIRSTITEMINTHEARRAYIDENTIFIESTHEPARENTROUTECRISISCENTER", "original": "* The first item in the array identifies the parent route (`/crisis-center`).", "translation": "数组中的第一个条目标记出了父路由(`/crisis-center`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEREARENOPARAMETERSFORTHISPARENTROUTESOYOUREDONEWITHIT", "original": "* There are no parameters for this parent route so you're done with it.", "translation": "这个父路由没有参数,因此这步已经完成了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEREISNODEFAULTFORTHECHILDROUTESOYOUNEEDTOPICKONE", "original": "* There is no default for the child route so you need to pick one.", "translation": "没有默认的子路由,因此你得选取一个。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOURENAVIGATINGTOTHECRISISLISTCOMPONENTWHOSEROUTEPATHISBUTYOUDONTNEEDTOEXPLICITLYADDTHESLASH", "original": "* You're navigating to the `CrisisListComponent`, whose route path is `/`, but you don't need to explicitly add the slash.", "translation": "你决定跳转到 `CrisisListComponent`,它的路由路径是'/',但你不用显式的添加它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "VOILCRISISCENTER", "original": "* Voilà! `['/crisis-center']`.", "translation": "哇!`['/crisis-center']`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "TAKEITASTEPFURTHERCONSIDERTHEFOLLOWINGROUTERLINKTHATNAVIGATESFROMTHEROOTOFTHEAPPLICATIONDOWNTOTHEDRAGONCRISIS:", "original": "Take it a step further. Consider the following router link that\nnavigates from the root of the application down to the *Dragon Crisis*:", "translation": "更进一步。这次要构建一个从根组件往下导航到“巨龙危机”时的链接参数数组:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEFIRSTITEMINTHEARRAYIDENTIFIESTHEPARENTROUTECRISISCENTER", "original": "* The first item in the array identifies the parent route (`/crisis-center`).", "translation": "数组中的第一个条目标记出了父路由(`/crisis-center`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEREARENOPARAMETERSFORTHISPARENTROUTESOYOUREDONEWITHIT", "original": "* There are no parameters for this parent route so you're done with it.", "translation": "这个父路由没有参数,因此这步已经完成了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THESECONDITEMIDENTIFIESTHECHILDROUTEDETAILSABOUTAPARTICULARCRISIS:ID", "original": "* The second item identifies the child route details about a particular crisis (`/:id`).", "translation": "数组中的第二个条目('/:id')用来标记出到指定危机的详情页的子路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEDETAILSCHILDROUTEREQUIRESANIDROUTEPARAMETER", "original": "* The details child route requires an `id` route parameter.", "translation": "详细的子路由需要一个 `id` 路由参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUADDEDTHEIDOFTHEDRAGONCRISISASTHESECONDITEMINTHEARRAY1", "original": "* You added the `id` of the *Dragon Crisis* as the second item in the array (`1`).", "translation": "你把*巨龙危机*的 `id` 添加为该数组中的第二个条目(`1`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THERESULTINGPATHISCRISISCENTER1", "original": "* The resulting path is `/crisis-center/1`.", "translation": "最终生成的路径是 `/crisis-center/1`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "IFYOUWANTEDTOYOUCOULDREDEFINETHEAPPCOMPONENTTEMPLATEWITHCRISISCENTERROUTESEXCLUSIVELY:", "original": "If you wanted to, you could redefine the `AppComponent` template with *Crisis Center* routes exclusively:", "translation": "只要想,你也可以用*危机中心*路由单独重定义 `AppComponent` 的模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "INSUMYOUCANWRITEAPPLICATIONSWITHONETWOORMORELEVELSOFROUTINGTHELINKPARAMETERSARRAYAFFORDSTHEFLEXIBILITYTOREPRESENTANYROUTINGDEPTHANDANYLEGALSEQUENCEOFROUTEPATHSREQUIREDROUTERPARAMETERSANDOPTIONALROUTEPARAMETEROBJECTS", "original": "In sum, you can write applications with one, two or more levels of routing.\nThe link parameters array affords the flexibility to represent any routing depth and\nany legal sequence of route paths, (required) router parameters, and (optional) route parameter objects.", "translation": "总结:你可以用一级、两级或多级路由来写应用程序。\n 链接参数数组提供了用来表示任意深度路由的链接参数数组以及任意合法的路由参数序列、必须的路由器参数以及可选的路由参数对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "###APPENDIX:LOCATIONSTRATEGYANDBROWSERURLSTYLES", "original": "### Appendix: *LocationStrategy* and browser URL styles", "translation": "### 附录:*LocationStrategy* 以及浏览器 URL 样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHENTHEROUTERNAVIGATESTOANEWCOMPONENTVIEWITUPDATESTHEBROWSERSLOCATIONANDHISTORYWITHAURLFORTHATVIEWTHISISASTRICTLYLOCALURLTHEBROWSERSHOULDNTSENDTHISURLTOTHESERVERANDSHOULDNOTRELOADTHEPAGE", "original": "When the router navigates to a new component view, it updates the browser's location and history\nwith a URL for that view.\nThis is a strictly local URL. The browser shouldn't send this URL to the server\nand should not reload the page.", "translation": "当路由器导航到一个新的组件视图时,它会用该视图的 URL 来更新浏览器的当前地址以及历史。\n严格来说,这个 URL 其实是本地的,浏览器不会把该 URL 发给服务器,并且不会重新加载此页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "MODERNHTML5BROWSERSSUPPORTAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIHISTORYAPI#ADDINGANDMODIFYINGHISTORYENTRIESTITLEHTML5BROWSERHISTORYPUSHSTATEHISTORYPUSHSTATEAATECHNIQUETHATCHANGESABROWSERSLOCATIONANDHISTORYWITHOUTTRIGGERINGASERVERPAGEREQUESTTHEROUTERCANCOMPOSEANATURALURLTHATISINDISTINGUISHABLEFROMONETHATWOULDOTHERWISEREQUIREAPAGELOAD", "original": "Modern HTML5 browsers support\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries\" title=\"HTML5 browser history push-state\">history.pushState</a>,\na technique that changes a browser's location and history without triggering a server page request.\nThe router can compose a \"natural\" URL that is indistinguishable from\none that would otherwise require a page load.", "translation": "现代 HTML 5 浏览器支持[history.pushState](https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries) API,\n这是一项可以改变浏览器的当前地址和历史,却又不会触发服务端页面请求的技术。\n路由器可以合成出一个“自然的”URL,它看起来和那些需要进行页面加载的 URL 没什么区别。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "HERESTHECRISISCENTERURLINTHISHTML5PUSHSTATESTYLE:", "original": "Here's the *Crisis Center* URL in this \"HTML5 pushState\" style:", "translation": "下面是*危机中心*的 URL 在“HTML 5 pushState”风格下的样子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "OLDERBROWSERSSENDPAGEREQUESTSTOTHESERVERWHENTHELOCATIONURLCHANGESUNLESSTHECHANGEOCCURSAFTERA#CALLEDTHEHASHROUTERSCANTAKEADVANTAGEOFTHISEXCEPTIONBYCOMPOSINGINAPPLICATIONROUTEURLSWITHHASHESHERESAHASHURLTHATROUTESTOTHECRISISCENTER", "original": "Older browsers send page requests to the server when the location URL changes\n_unless_ the change occurs after a \"#\" (called the \"hash\").\nRouters can take advantage of this exception by composing in-application route\nURLs with hashes. Here's a \"hash URL\" that routes to the *Crisis Center*.", "translation": "老旧的浏览器在当前地址的 URL 变化时总会往服务器发送页面请求……唯一的例外规则是:当这些变化位于“#”(被称为“hash”)后面时不会发送。通过把应用内的路由 URL 拼接在 `#` 之后,路由器可以获得这条“例外规则”带来的优点。下面是到*危机中心*路由的“hash URL”:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERSUPPORTSBOTHSTYLESWITHTWOLOCATIONSTRATEGYPROVIDERS:", "original": "The router supports both styles with two `LocationStrategy` providers:", "translation": "路由器通过两种 `LocationStrategy` 提供商来支持所有这些风格:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1PATHLOCATIONSTRATEGYMDASHTHEDEFAULTHTML5PUSHSTATESTYLE", "original": "1. `PathLocationStrategy`—the default \"HTML5 pushState\" style.", "translation": "`PathLocationStrategy` - 默认的策略,支持“HTML 5 pushState”风格。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1HASHLOCATIONSTRATEGYMDASHTHEHASHURLSTYLE", "original": "1. `HashLocationStrategy`—the \"hash URL\" style.", "translation": "`HashLocationStrategy` - 支持“hash URL”风格。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEROUTERMODULEFORROOTFUNCTIONSETSTHELOCATIONSTRATEGYTOTHEPATHLOCATIONSTRATEGYMAKINGITTHEDEFAULTSTRATEGYYOUCANSWITCHTOTHEHASHLOCATIONSTRATEGYWITHANOVERRIDEDURINGTHEBOOTSTRAPPINGPROCESSIFYOUPREFERIT", "original": "The `RouterModule.forRoot` function sets the `LocationStrategy` to the `PathLocationStrategy`,\nmaking it the default strategy.\nYou can switch to the `HashLocationStrategy` with an override during the bootstrapping process if you prefer it.", "translation": "`RouterModule.forRoot` 函数把 `LocationStrategy` 设置成了 `PathLocationStrategy`,使其成为了默认策略。\n你可以在启动过程中改写(override)它,来切换到 `HashLocationStrategy` 风格 —— 如果你更喜欢这种。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "LEARNABOUTPROVIDERSANDTHEBOOTSTRAPPROCESSINTHEDEPENDENCYINJECTIONGUIDEGUIDEDEPENDENCYINJECTION#BOOTSTRAP", "original": "Learn about providers and the bootstrap process in the\n[Dependency Injection guide](guide/dependency-injection#bootstrap).", "translation": "要学习关于“提供商”和启动过程的更多知识,参见[依赖注入](guide/dependency-injection#bootstrap)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####WHICHSTRATEGYISBEST", "original": "#### Which strategy is best?", "translation": "#### 哪种策略更好?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUMUSTCHOOSEASTRATEGYANDYOUNEEDTOMAKETHERIGHTCALLEARLYINTHEPROJECTITWONTBEEASYTOCHANGELATERONCETHEAPPLICATIONISINPRODUCTIONANDTHEREARELOTSOFAPPLICATIONURLREFERENCESINTHEWILD", "original": "You must choose a strategy and you need to make the right call early in the project.\nIt won't be easy to change later once the application is in production\nand there are lots of application URL references in the wild.", "translation": "你必须选择一种策略,并且在项目的早期就这么干。一旦该应用进入了生产阶段,要改起来可就不容易了,因为外面已经有了大量对应用 URL 的引用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "ALMOSTALLANGULARPROJECTSSHOULDUSETHEDEFAULTHTML5STYLEITPRODUCESURLSTHATAREEASIERFORUSERSTOUNDERSTANDANDITPRESERVESTHEOPTIONTODOSERVERSIDERENDERINGLATER", "original": "Almost all Angular projects should use the default HTML5 style.\nIt produces URLs that are easier for users to understand.\nAnd it preserves the option to do _server-side rendering_ later.", "translation": "几乎所有的 Angular 项目都会使用默认的 HTML 5 风格。它生成的 URL 更易于被用户理解,它也为将来做**服务端渲染**预留了空间。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "RENDERINGCRITICALPAGESONTHESERVERISATECHNIQUETHATCANGREATLYIMPROVEPERCEIVEDRESPONSIVENESSWHENTHEAPPFIRSTLOADSANAPPTHATWOULDOTHERWISETAKETENORMORESECONDSTOSTARTCOULDBERENDEREDONTHESERVERANDDELIVEREDTOTHEUSERSDEVICEINLESSTHANASECOND", "original": "Rendering critical pages on the server is a technique that can greatly improve\nperceived responsiveness when the app first loads.\nAn app that would otherwise take ten or more seconds to start\ncould be rendered on the server and delivered to the user's device\nin less than a second.", "translation": "在服务器端渲染指定的页面,是一项可以在该应用首次加载时大幅提升响应速度的技术。那些原本需要十秒甚至更长时间加载的应用,可以预先在服务端渲染好,并在少于一秒的时间内完整呈现在用户的设备上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THISOPTIONISONLYAVAILABLEIFAPPLICATIONURLSLOOKLIKENORMALWEBURLSWITHOUTHASHES#INTHEMIDDLE", "original": "This option is only available if application URLs look like normal web URLs\nwithout hashes (#) in the middle.", "translation": "只有当应用的 URL 看起来像是标准的 Web URL,中间没有 hash(#)时,这个选项才能生效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "STICKWITHTHEDEFAULTUNLESSYOUHAVEACOMPELLINGREASONTORESORTTOHASHROUTES", "original": "Stick with the default unless you have a compelling reason to\nresort to hash routes.", "translation": "除非你有强烈的理由不得不使用 hash 路由,否则就应该坚决使用默认的 HTML 5 路由风格。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####HTML5URLSANDTHELTBASEHREF", "original": "#### HTML5 URLs and the *<base href>*", "translation": "#### HTML 5 URL 与*<base href>*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WHILETHEROUTERUSESTHEAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIHISTORYAPI#ADDINGANDMODIFYINGHISTORYENTRIESTITLEBROWSERHISTORYPUSHSTATEHTML5PUSHSTATEASTYLEBYDEFAULTYOUMUSTCONFIGURETHATSTRATEGYWITHABASEHREF", "original": "While the router uses the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries\" title=\"Browser history push-state\">HTML5 pushState</a>\nstyle by default, you *must* configure that strategy with a **base href**.", "translation": "由于路由器默认使用“<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries\" target=\"_blank\" title=\"Browser history push-state\">HTML 5 pushState</a>”风格,所以你*必须*用一个**base href**来配置该策略(Strategy)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THEPREFERREDWAYTOCONFIGURETHESTRATEGYISTOADDAAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBHTMLELEMENTBASETITLEBASEHREFLTBASEHREFGTELEMENTATAGINTHEHEADOFTHEINDEXHTML", "original": "The preferred way to configure the strategy is to add a\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base\" title=\"base href\"><base href> element</a>\ntag in the `<head>` of the `index.html`.", "translation": "配置该策略的首选方式是往 `index.html` 的 `<head>` 中添加一个[<base href> element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "WITHOUTTHATTAGTHEBROWSERMAYNOTBEABLETOLOADRESOURCESIMAGESCSSSCRIPTSWHENDEEPLINKINGINTOTHEAPPBADTHINGSCOULDHAPPENWHENSOMEONEPASTESANAPPLICATIONLINKINTOTHEBROWSERSADDRESSBARORCLICKSSUCHALINKINANEMAIL", "original": "Without that tag, the browser may not be able to load resources\n(images, CSS, scripts) when \"deep linking\" into the app.\nBad things could happen when someone pastes an application link into the\nbrowser's address bar or clicks such a link in an email.", "translation": "如果没有此标签,当通过“深链接”进入该应用时,浏览器就不能加载资源(图片、CSS、脚本)。如果有人把应用的链接粘贴进浏览器的地址栏或从邮件中点击应用的链接时,这种问题就发生。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "SOMEDEVELOPERSMAYNOTBEABLETOADDTHEBASEELEMENTPERHAPSBECAUSETHEYDONTHAVEACCESSTOHEADORTHEINDEXHTML", "original": "Some developers may not be able to add the `<base>` element, perhaps because they don't have\naccess to `<head>` or the `index.html`.", "translation": "有些开发人员可能无法添加 `<base>` 元素,这可能是因为它们没有访问 `<head>` 或 `index.html` 的权限。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "THOSEDEVELOPERSMAYSTILLUSEHTML5URLSBYTAKINGTWOREMEDIALSTEPS:", "original": "Those developers may still use HTML5 URLs by taking two remedial steps:", "translation": "它们仍然可以使用 HTML 5 格式的 URL,但要采取两个步骤进行补救:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1PROVIDETHEROUTERWITHANAPPROPRIATEAPPBASEHREFVALUE", "original": "1. Provide the router with an appropriate [APP_BASE_HREF][] value.", "translation": "用适当的[APP_BASE_HREF][]值提供(provide)路由器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "1USEROOTURLSFORALLWEBRESOURCES:CSSIMAGESSCRIPTSANDTEMPLATEHTMLFILES", "original": "1. Use _root URLs_ for all web resources: CSS, images, scripts, and template HTML files.", "translation": "对所有 Web 资源使用**绝对地址**:CSS、图片、脚本、模板 HTML。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "####HASHLOCATIONSTRATEGY", "original": "#### *HashLocationStrategy*", "translation": "#### *HashLocationStrategy* 策略", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "YOUCANGOOLDSCHOOLWITHTHEHASHLOCATIONSTRATEGYBYPROVIDINGTHEUSEHASH:TRUEINANOBJECTASTHESECONDARGUMENTOFTHEROUTERMODULEFORROOTINTHEAPPMODULE", "original": "You can go old-school with the `HashLocationStrategy` by\nproviding the `useHash: true` in an object as the second argument of the `RouterModule.forRoot`\nin the `AppModule`.", "translation": "你可以在根模块的 `RouterModule.forRoot` 的第二个参数中传入一个带有 `useHash: true` 的对象,以回到基于 `HashLocationStrategy` 的传统方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/router.md" }, { + "key": "#THERXJSLIBRARY", "original": "# The RxJS library", "translation": "# RxJS 库", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "REACTIVEPROGRAMMINGISANASYNCHRONOUSPROGRAMMINGPARADIGMCONCERNEDWITHDATASTREAMSANDTHEPROPAGATIONOFCHANGEWIKIPEDIAHTTPS:ENWIKIPEDIAORGWIKIREACTIVEPROGRAMMINGRXJSREACTIVEEXTENSIONSFORJAVASCRIPTISALIBRARYFORREACTIVEPROGRAMMINGUSINGOBSERVABLESTHATMAKESITEASIERTOCOMPOSEASYNCHRONOUSORCALLBACKBASEDCODERXJSDOCSHTTP:REACTIVEXIORXJS", "original": "Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change ([Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)). RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using observables that makes it easier to compose asynchronous or callback-based code ([RxJS Docs](http://reactivex.io/rxjs/)).", "translation": "响应式编程是一种面向数据流和变更传播的异步编程范式([Wikipedia](https://zh.wikipedia.org/wiki/%E5%93%8D%E5%BA%94%E5%BC%8F%E7%BC%96%E7%A8%8B))。RxJS(响应式扩展的 JavaScript 版)是一个使用可观察对象进行响应式编程的库,它让组合异步代码和基于回调的代码变得更简单 ([RxJS Docs](http://reactivex.io/rxjs/))。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "RXJSPROVIDESANIMPLEMENTATIONOFTHEOBSERVABLETYPEWHICHISNEEDEDUNTILTHETYPEBECOMESPARTOFTHELANGUAGEANDUNTILBROWSERSSUPPORTITTHELIBRARYALSOPROVIDESUTILITYFUNCTIONSFORCREATINGANDWORKINGWITHOBSERVABLESTHESEUTILITYFUNCTIONSCANBEUSEDFOR:", "original": "RxJS provides an implementation of the `Observable` type, which is needed until the type becomes part of the language and until browsers support it. The library also provides utility functions for creating and working with observables. These utility functions can be used for:", "translation": "RxJS 提供了一种对 `Observable` 类型的实现,直到 `Observable` 成为了 JavaScript 语言的一部分并且浏览器支持它之前,它都是必要的。这个库还提供了一些工具函数,用于创建和使用可观察对象。这些工具函数可用于:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "CONVERTINGEXISTINGCODEFORASYNCOPERATIONSINTOOBSERVABLES", "original": "* Converting existing code for async operations into observables", "translation": "把现有的异步代码转换成可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "ITERATINGTHROUGHTHEVALUESINASTREAM", "original": "* Iterating through the values in a stream", "translation": "迭代流中的各个值", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "MAPPINGVALUESTODIFFERENTTYPES", "original": "* Mapping values to different types", "translation": "把这些值映射成其它类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "FILTERINGSTREAMS", "original": "* Filtering streams", "translation": "对流进行过滤", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "COMPOSINGMULTIPLESTREAMS", "original": "* Composing multiple streams", "translation": "组合多个流", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "##OBSERVABLECREATIONFUNCTIONS", "original": "## Observable creation functions", "translation": "## 创建可观察对象的函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "RXJSOFFERSANUMBEROFFUNCTIONSTHATCANBEUSEDTOCREATENEWOBSERVABLESTHESEFUNCTIONSCANSIMPLIFYTHEPROCESSOFCREATINGOBSERVABLESFROMTHINGSSUCHASEVENTSTIMERSPROMISESANDSOONFOREXAMPLE:", "original": "RxJS offers a number of functions that can be used to create new observables. These functions can simplify the process of creating observables from things such as events, timers, promises, and so on. For example:", "translation": "RxJS 提供了一些用来创建可观察对象的函数。这些函数可以简化根据某些东西创建可观察对象的过程,比如事件、定时器、承诺等等。比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "##OPERATORS", "original": "## Operators", "translation": "## 操作符", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "OPERATORSAREFUNCTIONSTHATBUILDONTHEOBSERVABLESFOUNDATIONTOENABLESOPHISTICATEDMANIPULATIONOFCOLLECTIONSFOREXAMPLERXJSDEFINESOPERATORSSUCHASMAPFILTERCONCATANDFLATMAP", "original": "Operators are functions that build on the observables foundation to enable sophisticated manipulation of collections. For example, RxJS defines operators such as `map()`, `filter()`, `concat()`, and `flatMap()`.", "translation": "操作符是基于可观察对象构建的一些对集合进行复杂操作的函数。RxJS 定义了一些操作符,比如 `map()`、`filter()`、`concat()` 和 `flatMap()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "OPERATORSTAKECONFIGURATIONOPTIONSANDTHEYRETURNAFUNCTIONTHATTAKESASOURCEOBSERVABLEWHENEXECUTINGTHISRETURNEDFUNCTIONTHEOPERATOROBSERVESTHESOURCEOBSERVABLESEMITTEDVALUESTRANSFORMSTHEMANDRETURNSANEWOBSERVABLEOFTHOSETRANSFORMEDVALUESHEREISASIMPLEEXAMPLE:", "original": "Operators take configuration options, and they return a function that takes a source observable. When executing this returned function, the operator observes the source observable’s emitted values, transforms them, and returns a new observable of those transformed values. Here is a simple example:", "translation": "操作符接受一些配置项,然后返回一个以来源可观察对象为参数的函数。当执行这个返回的函数时,这个操作符会观察来源可观察对象中发出的值,转换它们,并返回由转换后的值组成的新的可观察对象。下面是一个简单的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "YOUCANUSEPIPESTOLINKOPERATORSTOGETHERPIPESLETYOUCOMBINEMULTIPLEFUNCTIONSINTOASINGLEFUNCTIONTHEPIPEFUNCTIONTAKESASITSARGUMENTSTHEFUNCTIONSYOUWANTTOCOMBINEANDRETURNSANEWFUNCTIONTHATWHENEXECUTEDRUNSTHECOMPOSEDFUNCTIONSINSEQUENCE", "original": "You can use _pipes_ to link operators together. Pipes let you combine multiple functions into a single function. The `pipe()` function takes as its arguments the functions you want to combine, and returns a new function that, when executed, runs the composed functions in sequence.", "translation": "你可以使用*管道*来把这些操作符链接起来。管道让你可以把多个由操作符返回的函数组合成一个。`pipe()` 函数以你要组合的这些函数作为参数,并且返回一个新的函数,当执行这个新函数时,就会顺序执行那些被组合进去的函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "ASETOFOPERATORSAPPLIEDTOANOBSERVABLEISARECIPEMDASHTHATISASETOFINSTRUCTIONSFORPRODUCINGTHEVALUESYOUREINTERESTEDINBYITSELFTHERECIPEDOESNTDOANYTHINGYOUNEEDTOCALLSUBSCRIBETOPRODUCEARESULTTHROUGHTHERECIPE", "original": "A set of operators applied to an observable is a recipe—that is, a set of instructions for producing the values you’re interested in. By itself, the recipe doesn’t do anything. You need to call `subscribe()` to produce a result through the recipe.", "translation": "应用于某个可观察对象上的一组操作符就像一个菜谱 —— 也就是说,对你感兴趣的这些值进行处理的一组操作步骤。这个菜谱本身不会做任何事。你需要调用 `subscribe()` 来通过这个菜谱生成一个结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "HERESANEXAMPLE:", "original": "Here’s an example:", "translation": "例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "THEPIPEFUNCTIONISALSOAMETHODONTHERXJSOBSERVABLESOYOUUSETHISSHORTERFORMTODEFINETHESAMEOPERATION:", "original": "The `pipe()` function is also a method on the RxJS `Observable`, so you use this shorter form to define the same operation:", "translation": "`pipe()` 函数也同时是 RxJS 的 `Observable` 上的一个方法,所以你可以用下列简写形式来达到同样的效果:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "###COMMONOPERATORS", "original": "### Common operators", "translation": "### 常用操作符", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "RXJSPROVIDESMANYOPERATORSOVER150OFTHEMBUTONLYAHANDFULAREUSEDFREQUENTLYHEREISALISTOFCOMMONOPERATORSFORUSAGEEXAMPLESSEERXJS5OPERATORSBYEXAMPLEHTTPS:GITHUBCOMBTRONCONELEARNRXJSBLOBMASTEROPERATORSCOMPLETEMDINRXJSDOCUMENTATION", "original": "RxJS provides many operators (over 150 of them), but only a handful are used frequently. Here is a list of common operators; for usage examples, see [RxJS 5 Operators By Example](https://github.com/btroncone/learn-rxjs/blob/master/operators/complete.md) in RxJS documentation.", "translation": "RxJS 提供了很多操作符(超过 150 个),不过只有少数是常用的。\n下面是一个常用操作符的列表,要查看用法范例,参见 RxJS 文档中的 [RxJS 5 操作符范例](https://github.com/btroncone/learn-rxjs/blob/master/operators/complete.md)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "NOTETHATFORANGULARAPPSWEPREFERCOMBININGOPERATORSWITHPIPESRATHERTHANCHAININGCHAININGISUSEDINMANYRXJSEXAMPLES", "original": "Note that, for Angular apps, we prefer combining operators with pipes, rather than chaining. Chaining is used in many RxJS examples.", "translation": "注意,对于 Angular 应用来说,我们提倡使用管道来组合操作符,而不是使用链式写法。链式写法仍然在很多 RxJS 中使用着。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "AREAOPERATORS::CREATIONFROMFROMPROMISEFROMEVENTOFCOMBINATIONCOMBINELATESTCONCATMERGESTARTWITHWITHLATESTFROMZIPFILTERINGDEBOUNCETIMEDISTINCTUNTILCHANGEDFILTERTAKETAKEUNTILTRANSFORMATIONBUFFERTIMECONCATMAPMAPMERGEMAPSCANSWITCHMAPUTILITYTAPMULTICASTINGSHARE", + "original": "| Area | Operators |\n| :------------ | :---------- |\n| Creation | `from`, `fromPromise`,`fromEvent`, `of` |\n| Combination | `combineLatest`, `concat`, `merge`, `startWith` , `withLatestFrom`, `zip` |\n| Filtering | `debounceTime`, `distinctUntilChanged`, `filter`, `take`, `takeUntil` |\n| Transformation | `bufferTime`, `concatMap`, `map`, `mergeMap`, `scan`, `switchMap` |\n| Utility | `tap` |\n| Multicasting | `share` |", + "translation": "| <t>Area</t><t>类别</t> | <t>Operators</t><t>操作</t> |\n| :------------ | :---------- |\n| <t>Creation</t><t>创建</t> | `from`, `fromPromise`,`fromEvent`, `of` |\n| <t>Combination</t><t>组合</t> | `combineLatest`, `concat`, `merge`, `startWith` , `withLatestFrom`, `zip` |\n| <t>Filtering</t><t>过滤</t> | `debounceTime`, `distinctUntilChanged`, `filter`, `take`, `takeUntil` |\n| <t>Transformation</t><t>转换</t> | `bufferTime`, `concatMap`, `map`, `mergeMap`, `scan`, `switchMap` |\n| <t>Utility</t><t>工具</t> | `tap` |\n| <t>Multicasting</t><t>多播</t> | `share` |", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" + }, + { + "key": "##ERRORHANDLING", "original": "## Error handling", "translation": "## 错误处理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "INADDITIONTOTHEERRORHANDLERTHATYOUPROVIDEONSUBSCRIPTIONRXJSPROVIDESTHECATCHERROROPERATORTHATLETSYOUHANDLEKNOWNERRORSINTHEOBSERVABLERECIPE", "original": "In addition to the `error()` handler that you provide on subscription, RxJS provides the `catchError` operator that lets you handle known errors in the observable recipe.", "translation": "除了可以在订阅时提供 `error()` 处理器外,RxJS 还提供了 `catchError` 操作符,它允许你在管道中处理已知错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "FORINSTANCESUPPOSEYOUHAVEANOBSERVABLETHATMAKESANAPIREQUESTANDMAPSTOTHERESPONSEFROMTHESERVERIFTHESERVERRETURNSANERRORORTHEVALUEDOESNTEXISTANERRORISPRODUCEDIFYOUCATCHTHISERRORANDSUPPLYADEFAULTVALUEYOURSTREAMCONTINUESTOPROCESSVALUESRATHERTHANERRORINGOUT", "original": "For instance, suppose you have an observable that makes an API request and maps to the response from the server. If the server returns an error or the value doesn’t exist, an error is produced. If you catch this error and supply a default value, your stream continues to process values rather than erroring out.", "translation": "假设你有一个可观察对象,它发起 API 请求,然后对服务器返回的响应进行映射。如果服务器返回了错误或值不存在,就会生成一个错误。如果你捕获这个错误并提供了一个默认值,流就会继续处理这些值,而不会报错。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "HERESANEXAMPLEOFUSINGTHECATCHERROROPERATORTODOTHIS:", "original": "Here's an example of using the `catchError` operator to do this:", "translation": "下面是使用 `catchError` 操作符实现这种效果的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "###RETRYFAILEDOBSERVABLE", "original": "### Retry failed observable", "translation": "### 重试失败的可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "WHERETHECATCHERROROPERATORPROVIDESASIMPLEPATHOFRECOVERYTHERETRYOPERATORLETSYOURETRYAFAILEDREQUEST", "original": "Where the `catchError` operator provides a simple path of recovery, the `retry` operator lets you retry a failed request.", "translation": "`catchError` 提供了一种简单的方式进行恢复,而 `retry` 操作符让你可以尝试失败的请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "USETHERETRYOPERATORBEFORETHECATCHERROROPERATORITRESUBSCRIBESTOTHEORIGINALSOURCEOBSERVABLEWHICHCANTHENRERUNTHEFULLSEQUENCEOFACTIONSTHATRESULTEDINTHEERRORIFTHISINCLUDESANHTTPREQUESTITWILLRETRYTHATHTTPREQUEST", "original": "Use the `retry` operator before the `catchError` operator. It resubscribes to the original source observable, which can then re-run the full sequence of actions that resulted in the error. If this includes an HTTP request, it will retry that HTTP request.", "translation": "可以在 `catchError` 之前使用 `retry` 操作符。它会订阅到原始的来源可观察对象,它可以重新运行导致结果出错的动作序列。如果其中包含 HTTP 请求,它就会重新发起那个 HTTP 请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "THEFOLLOWINGCONVERTSTHEPREVIOUSEXAMPLETORETRYTHEREQUESTBEFORECATCHINGTHEERROR:", "original": "The following converts the previous example to retry the request before catching the error:", "translation": "下列代码为前面的例子加上了捕获错误前重发请求的逻辑:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "DONOTRETRYAUTHENTICATIONREQUESTSSINCETHESESHOULDONLYBEINITIATEDBYUSERACTIONWEDONTWANTTOLOCKOUTUSERACCOUNTSWITHREPEATEDLOGINREQUESTSTHATTHEUSERHASNOTINITIATED", "original": "Do not retry **authentication** requests, since these should only be initiated by user action. We don't want to lock out user accounts with repeated login requests that the user has not initiated.", "translation": "不要重试**登录认证**请求,这些请求只应该由用户操作触发。我们肯定不会希望自动重复发送登录请求导致用户的账号被锁定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "##NAMINGCONVENTIONSFOROBSERVABLES", "original": "## Naming conventions for observables", "translation": "## 可观察对象的命名约定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "BECAUSEANGULARAPPLICATIONSAREMOSTLYWRITTENINTYPESCRIPTYOUWILLTYPICALLYKNOWWHENAVARIABLEISANOBSERVABLEALTHOUGHTHEANGULARFRAMEWORKDOESNOTENFORCEANAMINGCONVENTIONFOROBSERVABLESYOUWILLOFTENSEEOBSERVABLESNAMEDWITHATRAILINGSIGN", "original": "Because Angular applications are mostly written in TypeScript, you will typically know when a variable is an observable. Although the Angular framework does not enforce a naming convention for observables, you will often see observables named with a trailing “$” sign.", "translation": "由于 Angular 的应用几乎都是用 TypeScript 写的,你通常会希望知道某个变量是否可观察对象。虽然 Angular 框架并没有针对可观察对象的强制性命名约定,不过你经常会看到可观察对象的名字以“$”符号结尾。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "THISCANBEUSEFULWHENSCANNINGTHROUGHCODEANDLOOKINGFOROBSERVABLEVALUESALSOIFYOUWANTAPROPERTYTOSTORETHEMOSTRECENTVALUEFROMANOBSERVABLEITCANBECONVENIENTTOSIMPLYUSETHESAMENAMEWITHORWITHOUTTHE", "original": "This can be useful when scanning through code and looking for observable values. Also, if you want a property to store the most recent value from an observable, it can be convenient to simply use the same name with or without the “$”.", "translation": "这在快速浏览代码并查找可观察对象值时会非常有用。同样的,如果你希望用某个属性来存储来自可观察对象的最近一个值,它的命名惯例是与可观察对象同名,但不带“$”后缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "FOREXAMPLE:", "original": "For example:", "translation": "比如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/rx-library.md" }, { + "key": "#SECURITY", "original": "# Security", "translation": "# 安全", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "THISPAGEDESCRIBESANGULARSBUILTINPROTECTIONSAGAINSTCOMMONWEBAPPLICATIONVULNERABILITIESANDATTACKSSUCHASCROSSSITESCRIPTINGATTACKSITDOESNTCOVERAPPLICATIONLEVELSECURITYSUCHASAUTHENTICATIONWHOISTHISUSERANDAUTHORIZATIONWHATCANTHISUSERDO", "original": "This page describes Angular's built-in\nprotections against common web-application vulnerabilities and attacks such as cross-site\nscripting attacks. It doesn't cover application-level security, such as authentication (_Who is\nthis user?_) and authorization (_What can this user do?_).", "translation": "Web 应用程序的安全涉及到很多方面。针对常见的漏洞和攻击,比如跨站脚本攻击,Angular 提供了一些内置的保护措施。本章将讨论这些内置保护措施,但不会涉及应用级安全,比如用户认证(*这个用户是谁?*)和授权(*这个用户能做什么?*)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "FORMOREINFORMATIONABOUTTHEATTACKSANDMITIGATIONSDESCRIBEDBELOWSEEOWASPGUIDEPROJECTHTTPS:WWWOWASPORGINDEXPHPCATEGORY:OWASPGUIDEPROJECT", "original": "For more information about the attacks and mitigations described below, see [OWASP Guide Project](https://www.owasp.org/index.php/Category:OWASP_Guide_Project).", "translation": "要了解更多攻防信息,参见[开放式 Web 应用程序安全项目(OWASP)](https://www.owasp.org/index.php/Category:OWASP_Guide_Project)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "YOUCANRUNTHELIVEEXAMPLELIVEEXAMPLEINSTACKBLITZANDDOWNLOADTHECODEFROMTHERE", "original": "You can run the <live-example></live-example> in Stackblitz and download the code from there.", - "translation": "运行<live-example></live-example>来试用本页的代码。", + "translation": "你可以运行<live-example></live-example>,在 Stackblitz 中试用并下载本页的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "H2IDREPORTISSUESREPORTINGVULNERABILITIESH2", "original": "<h2 id='report-issues'>Reporting vulnerabilities</h2>", "translation": "<h2 id='report-issues'>举报漏洞</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "TOREPORTVULNERABILITIESINANGULARITSELFEMAILUSATSECURITYANGULARIOMAILTO:SECURITYANGULARIO", "original": "To report vulnerabilities in Angular itself, email us at [security@angular.io](mailto:security@angular.io).", "translation": "给我们([security@angular.io](mailto:security@angular.io))发邮件,报告 Angular 本身的漏洞。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "FORMOREINFORMATIONABOUTHOWGOOGLEHANDLESSECURITYISSUESSEEGOOGLESSECURITYPHILOSOPHYHTTPS:WWWGOOGLECOMABOUTAPPSECURITY", "original": "For more information about how Google handles security issues, see [Google's security\nphilosophy](https://www.google.com/about/appsecurity/).", "translation": "要了解关于“谷歌如何处理安全问题”的更多信息,参见[谷歌的安全哲学](https://www.google.com/about/appsecurity/)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "H2IDBESTPRACTICESBESTPRACTICESH2", "original": "<h2 id='best-practices'>Best practices</h2>", "translation": "<h2 id='best-practices'>最佳实践</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "KEEPCURRENTWITHTHELATESTANGULARLIBRARYRELEASESWEREGULARLYUPDATETHEANGULARLIBRARIESANDTHESEUPDATESMAYFIXSECURITYDEFECTSDISCOVEREDINPREVIOUSVERSIONSCHECKTHEANGULARCHANGELOGHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERCHANGELOGMDFORSECURITYRELATEDUPDATES", "original": "* **Keep current with the latest Angular library releases.**\nWe regularly update the Angular libraries, and these updates may fix security defects discovered in\nprevious versions. Check the Angular [change\nlog](https://github.com/angular/angular/blob/master/CHANGELOG.md) for security-related updates.", "translation": "**及时把 Angular 包更新到最新版本。**\n我们会频繁的更新 Angular 库,这些更新可能会修复之前版本中发现的安全漏洞。查看 Angular 的[更新记录](https://github.com/angular/angular/blob/master/CHANGELOG.md),了解与安全有关的更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "DONTMODIFYYOURCOPYOFANGULARPRIVATECUSTOMIZEDVERSIONSOFANGULARTENDTOFALLBEHINDTHECURRENTVERSIONANDMAYNOTINCLUDEIMPORTANTSECURITYFIXESANDENHANCEMENTSINSTEADSHAREYOURANGULARIMPROVEMENTSWITHTHECOMMUNITYANDMAKEAPULLREQUEST", "original": "* **Don't modify your copy of Angular.**\nPrivate, customized versions of Angular tend to fall behind the current version and may not include\nimportant security fixes and enhancements. Instead, share your Angular improvements with the\ncommunity and make a pull request.", "translation": "**不要修改你的 Angular 副本。**\n私有的、定制版的 Angular 往往跟不上最新版本,这可能导致你忽略重要的安全修复与增强。反之,应该在社区共享你对 Angular 所做的改进并创建 Pull Request。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "AVOIDANGULARAPISMARKEDINTHEDOCUMENTATIONASSECURITYRISKFORMOREINFORMATIONSEETHETRUSTINGSAFEVALUESGUIDESECURITY#BYPASSSECURITYAPISSECTIONOFTHISPAGE", "original": "* **Avoid Angular APIs marked in the documentation as “_Security Risk_.”**\nFor more information, see the [Trusting safe values](guide/security#bypass-security-apis) section of this page.", "translation": "**避免使用本文档中带“[*安全风险*](guide/security#bypass-security-apis)”标记的 Angular API。** \n 要了解更多信息,请参阅本章的[信任那些安全的值](guide/security#bypass-security-apis)部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "H2IDXSSPREVENTINGCROSSSITESCRIPTINGXSSH2", "original": "<h2 id='xss'>Preventing cross-site scripting (XSS)</h2>", "translation": "<h2 id='xss'>防范跨站脚本(XSS)攻击</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "CROSSSITESCRIPTINGXSSHTTPS:ENWIKIPEDIAORGWIKICROSSSITESCRIPTINGENABLESATTACKERSTOINJECTMALICIOUSCODEINTOWEBPAGESSUCHCODECANTHENFOREXAMPLESTEALUSERDATAINPARTICULARLOGINDATAORPERFORMACTIONSTOIMPERSONATETHEUSERTHISISONEOFTHEMOSTCOMMONATTACKSONTHEWEB", "original": "[Cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) enables attackers\nto inject malicious code into web pages. Such code can then, for example, steal user data (in\nparticular, login data) or perform actions to impersonate the user. This is one of the most\ncommon attacks on the web.", "translation": "[跨站脚本(XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting)允许攻击者将恶意代码注入到页面中。这些代码可以偷取用户数据\n(特别是它们的登录数据),还可以冒充用户执行操作。它是 Web 上最常见的攻击方式之一。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "TOBLOCKXSSATTACKSYOUMUSTPREVENTMALICIOUSCODEFROMENTERINGTHEDOMDOCUMENTOBJECTMODELFOREXAMPLEIFATTACKERSCANTRICKYOUINTOINSERTINGASCRIPTTAGINTHEDOMTHEYCANRUNARBITRARYCODEONYOURWEBSITETHEATTACKISNTLIMITEDTOSCRIPTTAGSMDASHMANYELEMENTSANDPROPERTIESINTHEDOMALLOWCODEEXECUTIONFOREXAMPLEIMGONERRORANDAHREFJAVASCRIPT:IFATTACKERCONTROLLEDDATAENTERSTHEDOMEXPECTSECURITYVULNERABILITIES", "original": "To block XSS attacks, you must prevent malicious code from entering the DOM (Document Object Model). For example, if\nattackers can trick you into inserting a `<script>` tag in the DOM, they can run arbitrary code on\nyour website. The attack isn't limited to `<script>` tags—many elements and properties in the\nDOM allow code execution, for example, `<img onerror=\"...\">` and `<a href=\"javascript:...\">`. If\nattacker-controlled data enters the DOM, expect security vulnerabilities.", "translation": "为了防范 XSS 攻击,你必须阻止恶意代码进入 DOM。比如,如果某个攻击者能骗你把 `<script>` 标签插入到 DOM,就可以在你的网站上运行任何代码。\n除了 `<script>`,攻击者还可以使用很多 DOM 元素和属性来执行代码,比如 `<img onerror=\"...\">`、`<a href=\"javascript:...\">`。\n如果攻击者所控制的数据混进了 DOM,就会导致安全漏洞。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "###ANGULARSCROSSSITESCRIPTINGSECURITYMODEL", "original": "### Angular’s cross-site scripting security model", "translation": "### Angular 的“跨站脚本安全模型”", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "TOSYSTEMATICALLYBLOCKXSSBUGSANGULARTREATSALLVALUESASUNTRUSTEDBYDEFAULTWHENAVALUEISINSERTEDINTOTHEDOMFROMATEMPLATEVIAPROPERTYATTRIBUTESTYLECLASSBINDINGORINTERPOLATIONANGULARSANITIZESANDESCAPESUNTRUSTEDVALUES", "original": "To systematically block XSS bugs, Angular treats all values as untrusted by default. When a value\nis inserted into the DOM from a template, via property, attribute, style, class binding, or interpolation,\nAngular sanitizes and escapes untrusted values.", "translation": "为了系统性的防范 XSS 问题,Angular 默认把所有值都当做不可信任的。\n当值从模板中以属性(Property)、DOM 元素属性(Attribte)、CSS 类绑定或插值表达式等途径插入到 DOM 中的时候,\nAngular 将对这些值进行无害化处理(Sanitize),对不可信的值进行编码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ANGULARTEMPLATESARETHESAMEASEXECUTABLECODE:HTMLATTRIBUTESANDBINDINGEXPRESSIONSBUTNOTTHEVALUESBOUNDINTEMPLATESARETRUSTEDTOBESAFETHISMEANSTHATAPPLICATIONSMUSTPREVENTVALUESTHATANATTACKERCANCONTROLFROMEVERMAKINGITINTOTHESOURCECODEOFATEMPLATENEVERGENERATETEMPLATESOURCECODEBYCONCATENATINGUSERINPUTANDTEMPLATESTOPREVENTTHESEVULNERABILITIESUSETHEOFFLINETEMPLATECOMPILERGUIDESECURITY#OFFLINETEMPLATECOMPILERALSOKNOWNASTEMPLATEINJECTION", "original": "_Angular templates are the same as executable code_: HTML, attributes, and binding expressions\n(but not the values bound) in templates are trusted to be safe. This means that applications must\nprevent values that an attacker can control from ever making it into the source code of a\ntemplate. Never generate template source code by concatenating user input and templates.\nTo prevent these vulnerabilities, use\nthe [offline template compiler](guide/security#offline-template-compiler), also known as _template injection_.", "translation": "**Angular 的模板同样是可执行的**:模板中的 HTML、Attribute 和绑定表达式(还没有绑定到值的时候)会被当做可信任的。\n这意味着应用必须防止把可能被攻击者控制的值直接编入模板的源码中。永远不要根据用户的输入和原始模板动态生成模板源码!\n使用[离线模板编译器](guide/security#offline-template-compiler)是防范这类“模板注入”漏洞的有效途径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "###SANITIZATIONANDSECURITYCONTEXTS", "original": "### Sanitization and security contexts", "translation": "### 无害化处理与安全环境", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "SANITIZATIONISTHEINSPECTIONOFANUNTRUSTEDVALUETURNINGITINTOAVALUETHATSSAFETOINSERTINTOTHEDOMINMANYCASESSANITIZATIONDOESNTCHANGEAVALUEATALLSANITIZATIONDEPENDSONCONTEXT:AVALUETHATSHARMLESSINCSSISPOTENTIALLYDANGEROUSINAURL", "original": "_Sanitization_ is the inspection of an untrusted value, turning it into a value that's safe to insert into\nthe DOM. In many cases, sanitization doesn't change a value at all. Sanitization depends on context:\na value that's harmless in CSS is potentially dangerous in a URL.", "translation": "无害化处理会审查不可信的值,并将它们转换成可以安全插入到 DOM 的形式。多数情况下,这些值并不会在处理过程中发生任何变化。\n无害化处理的方式取决于所在的环境:一个在 CSS 里面无害的值,可能在 URL 里很危险。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ANGULARDEFINESTHEFOLLOWINGSECURITYCONTEXTS:", "original": "Angular defines the following security contexts:", "translation": "Angular 定义了四个安全环境 - HTML,样式,URL,和资源 URL:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "HTMLISUSEDWHENINTERPRETINGAVALUEASHTMLFOREXAMPLEWHENBINDINGTOINNERHTML", "original": "* **HTML** is used when interpreting a value as HTML, for example, when binding to `innerHtml`.", "translation": "**HTML**:值需要被解释为 HTML 时使用,比如当绑定到 `innerHTML` 时。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "STYLEISUSEDWHENBINDINGCSSINTOTHESTYLEPROPERTY", "original": "* **Style** is used when binding CSS into the `style` property.", "translation": "**样式**:值需要作为 CSS 绑定到 `style` 属性时使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "URLISUSEDFORURLPROPERTIESSUCHASAHREF", "original": "* **URL** is used for URL properties, such as `<a href>`.", "translation": "**URL**:值需要被用作 URL 属性时使用,比如 `<a href>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "RESOURCEURLISAURLTHATWILLBELOADEDANDEXECUTEDASCODEFOREXAMPLEINSCRIPTSRC", "original": "* **Resource URL** is a URL that will be loaded and executed as code, for example, in `<script src>`.", "translation": "**资源 URL**:值需要被当做代码而加载并执行时使用,比如 `<script src>` 中的 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ANGULARSANITIZESUNTRUSTEDVALUESFORHTMLSTYLESANDURLSSANITIZINGRESOURCEURLSISNTPOSSIBLEBECAUSETHEYCONTAINARBITRARYCODEINDEVELOPMENTMODEANGULARPRINTSACONSOLEWARNINGWHENITHASTOCHANGEAVALUEDURINGSANITIZATION", "original": "Angular sanitizes untrusted values for HTML, styles, and URLs; sanitizing resource URLs isn't\npossible because they contain arbitrary code. In development mode, Angular prints a console warning\nwhen it has to change a value during sanitization.", "translation": "Angular 会对前三项中种不可信的值进行无害化处理。但 Angular 无法对第四种资源 URL 进行无害化,因为它们可能包含任何代码。在开发模式下,\n如果 Angular 在进行无害化处理时需要被迫改变一个值,它就会在控制台上输出一个警告。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "###SANITIZATIONEXAMPLE", "original": "### Sanitization example", "translation": "### 无害化示例", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "THEFOLLOWINGTEMPLATEBINDSTHEVALUEOFHTMLSNIPPETONCEBYINTERPOLATINGITINTOANELEMENTSCONTENTANDONCEBYBINDINGITTOTHEINNERHTMLPROPERTYOFANELEMENT:", "original": "The following template binds the value of `htmlSnippet`, once by interpolating it into an element's\ncontent, and once by binding it to the `innerHTML` property of an element:", "translation": "下面的例子绑定了 `htmlSnippet` 的值,一次把它放进插值表达式里,另一次把它绑定到元素的 `innerHTML` 属性上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "INTERPOLATEDCONTENTISALWAYSESCAPEDMDASHTHEHTMLISNTINTERPRETEDANDTHEBROWSERDISPLAYSANGLEBRACKETSINTHEELEMENTSTEXTCONTENT", "original": "Interpolated content is always escaped—the HTML isn't interpreted and the browser displays\nangle brackets in the element's text content.", "translation": "插值表达式的内容总会被编码 - 其中的 HTML 不会被解释,所以浏览器会在元素的文本内容中显示尖括号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "FORTHEHTMLTOBEINTERPRETEDBINDITTOANHTMLPROPERTYSUCHASINNERHTMLBUTBINDINGAVALUETHATANATTACKERMIGHTCONTROLINTOINNERHTMLNORMALLYCAUSESANXSSVULNERABILITYFOREXAMPLECODECONTAINEDINASCRIPTTAGISEXECUTED:", "original": "For the HTML to be interpreted, bind it to an HTML property such as `innerHTML`. But binding\na value that an attacker might control into `innerHTML` normally causes an XSS\nvulnerability. For example, code contained in a `<script>` tag is executed:", "translation": "如果希望这段 HTML 被正常解释,就必须绑定到一个 HTML 属性上,比如 `innerHTML`。但是如果把一个可能被攻击者控制的值绑定到 `innerHTML` 就会导致 XSS 漏洞。\n比如,包含在 `<script>` 标签的代码就会被执行:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ANGULARRECOGNIZESTHEVALUEASUNSAFEANDAUTOMATICALLYSANITIZESITWHICHREMOVESTHESCRIPTTAGBUTKEEPSSAFECONTENTSUCHASTHETEXTCONTENTOFTHESCRIPTTAGANDTHEBELEMENT", "original": "Angular recognizes the value as unsafe and automatically sanitizes it, which removes the `<script>`\ntag but keeps safe content such as the text content of the `<script>` tag and the `<b>` element.", "translation": "Angular 认为这些值是不安全的,并自动进行无害化处理。它会移除 `<script>` 标签,但保留安全的内容,比如该片段中的文本内容或 `<b>` 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "###AVOIDDIRECTUSEOFTHEDOMAPIS", "original": "### Avoid direct use of the DOM APIs", "translation": "### 避免直接使用 DOM API", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "THEBUILTINBROWSERDOMAPISDONTAUTOMATICALLYPROTECTYOUFROMSECURITYVULNERABILITIESFOREXAMPLEDOCUMENTTHENODEAVAILABLETHROUGHELEMENTREFANDMANYTHIRDPARTYAPISCONTAINUNSAFEMETHODSAVOIDDIRECTLYINTERACTINGWITHTHEDOMANDINSTEADUSEANGULARTEMPLATESWHEREPOSSIBLE", "original": "The built-in browser DOM APIs don't automatically protect you from security vulnerabilities.\nFor example, `document`, the node available through `ElementRef`, and many third-party APIs\ncontain unsafe methods. Avoid directly interacting with the DOM and instead use Angular\ntemplates where possible.", "translation": "浏览器内置的 DOM API 不会自动针对安全漏洞进行防护。比如,`document`(它可以通过 `ElementRef` 访问)以及其它第三方 API 都可能包含不安全的方法。\n要避免直接与 DOM 交互,只要可能,就尽量使用 Angular 模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "###CONTENTSECURITYPOLICY", "original": "### Content security policy", "translation": "### 内容安全策略", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "CONTENTSECURITYPOLICYCSPISADEFENSEINDEPTHTECHNIQUETOPREVENTXSSTOENABLECSPCONFIGUREYOURWEBSERVERTORETURNANAPPROPRIATECONTENTSECURITYPOLICYHTTPHEADERREADMOREABOUTCONTENTSECURITYPOLICYATANINTRODUCTIONTOCONTENTSECURITYPOLICYHTTP:WWWHTML5ROCKSCOMENTUTORIALSSECURITYCONTENTSECURITYPOLICYONTHEHTML5ROCKSWEBSITE", "original": "Content Security Policy (CSP) is a defense-in-depth\ntechnique to prevent XSS. To enable CSP, configure your web server to return an appropriate\n`Content-Security-Policy` HTTP header. Read more about content security policy at\n[An Introduction to Content Security Policy](http://www.html5rocks.com/en/tutorials/security/content-security-policy/)\non the HTML5Rocks website.", "translation": "[内容安全策略(CSP)](https://developer.mozilla.org/en-)是用来防范 XSS 的纵深防御技术。\n要打开 CSP,请配置你的 Web 服务器,让它返回合适的 HTTP 头 `Content_Security_Policy`。\n要了解关于内容安全策略的更多信息,请参阅 HTML5Rocks 上的[内容安全策略简介](http://www.html5rocks.com/en/tutorials/security/content-security-policy/)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "###USETHEOFFLINETEMPLATECOMPILER", "original": "### Use the offline template compiler", "translation": "### 使用离线模板编译器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "THEOFFLINETEMPLATECOMPILERPREVENTSAWHOLECLASSOFVULNERABILITIESCALLEDTEMPLATEINJECTIONANDGREATLYIMPROVESAPPLICATIONPERFORMANCEUSETHEOFFLINETEMPLATECOMPILERINPRODUCTIONDEPLOYMENTSDONTDYNAMICALLYGENERATETEMPLATESANGULARTRUSTSTEMPLATECODESOGENERATINGTEMPLATESINPARTICULARTEMPLATESCONTAININGUSERDATACIRCUMVENTSANGULARSBUILTINPROTECTIONSFORINFORMATIONABOUTDYNAMICALLYCONSTRUCTINGFORMSINASAFEWAYSEETHEDYNAMICFORMSGUIDEDYNAMICFORMGUIDEPAGE", "original": "The offline template compiler prevents a whole class of vulnerabilities called template injection,\nand greatly improves application performance. Use the offline template compiler in production\ndeployments; don't dynamically generate templates. Angular trusts template code, so generating\ntemplates, in particular templates containing user data, circumvents Angular's built-in protections.\nFor information about dynamically constructing forms in a safe way, see the\n[Dynamic Forms](guide/dynamic-form) guide page.", "translation": "离线模板编译器阻止了一整套被称为“模板注入”的漏洞,并能显著增强应用程序的性能。尽量在产品发布时使用离线模板编译器,\n而不要动态生成模板(比如在代码中拼接字符串生成模板)。由于 Angular 会信任模板本身的代码,所以,动态生成的模板 —— 特别是包含用户数据的模板 —— 会绕过 Angular 自带的保护机制。\n要了解如何用安全的方式动态创建表单,请参见[动态表单](guide/dynamic-form)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "###SERVERSIDEXSSPROTECTION", "original": "### Server-side XSS protection", "translation": "### 服务器端 XSS 保护", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "HTMLCONSTRUCTEDONTHESERVERISVULNERABLETOINJECTIONATTACKSINJECTINGTEMPLATECODEINTOANANGULARAPPLICATIONISTHESAMEASINJECTINGEXECUTABLECODEINTOTHEAPPLICATION:ITGIVESTHEATTACKERFULLCONTROLOVERTHEAPPLICATIONTOPREVENTTHISUSEATEMPLATINGLANGUAGETHATAUTOMATICALLYESCAPESVALUESTOPREVENTXSSVULNERABILITIESONTHESERVERDONTGENERATEANGULARTEMPLATESONTHESERVERSIDEUSINGATEMPLATINGLANGUAGEDOINGTHISCARRIESAHIGHRISKOFINTRODUCINGTEMPLATEINJECTIONVULNERABILITIES", "original": "HTML constructed on the server is vulnerable to injection attacks. Injecting template code into an\nAngular application is the same as injecting executable code into the\napplication: it gives the attacker full control over the application. To prevent this,\nuse a templating language that automatically escapes values to prevent XSS vulnerabilities on\nthe server. Don't generate Angular templates on the server side using a templating language; doing this\ncarries a high risk of introducing template-injection vulnerabilities.", "translation": "服务器端构造的 HTML 很容易受到注入攻击。当需要在服务器端生成 HTML 时(比如 Angular 应用的初始页面),\n 务必使用一个能够自动进行无害化处理以防范 XSS 漏洞的后端模板语言。不要在服务器端使用模板语言生成 Angular 模板,\n 这样会带来很高的“模板注入”风险。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "H2IDBYPASSSECURITYAPISTRUSTINGSAFEVALUESH2", "original": "<h2 id='bypass-security-apis'>Trusting safe values</h2>", "translation": "<h2 id='bypass-security-apis'>信任安全值</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "SOMETIMESAPPLICATIONSGENUINELYNEEDTOINCLUDEEXECUTABLECODEDISPLAYANIFRAMEFROMSOMEURLORCONSTRUCTPOTENTIALLYDANGEROUSURLSTOPREVENTAUTOMATICSANITIZATIONINANYOFTHESESITUATIONSYOUCANTELLANGULARTHATYOUINSPECTEDAVALUECHECKEDHOWITWASGENERATEDANDMADESUREITWILLALWAYSBESECUREBUTBECAREFULIFYOUTRUSTAVALUETHATMIGHTBEMALICIOUSYOUAREINTRODUCINGASECURITYVULNERABILITYINTOYOURAPPLICATIONIFINDOUBTFINDAPROFESSIONALSECURITYREVIEWER", "original": "Sometimes applications genuinely need to include executable code, display an `<iframe>` from some\nURL, or construct potentially dangerous URLs. To prevent automatic sanitization in any of these\nsituations, you can tell Angular that you inspected a value, checked how it was generated, and made\nsure it will always be secure. But *be careful*. If you trust a value that might be malicious, you\nare introducing a security vulnerability into your application. If in doubt, find a professional\nsecurity reviewer.", "translation": "有时候,应用程序确实需要包含可执行的代码,比如使用 URL 显示 `<iframe>`,或者构造出有潜在危险的 URL。\n 为了防止在这种情况下被自动无害化,你可以告诉 Angular:我已经审查了这个值,检查了它是怎么生成的,并确信它总是安全的。\n 但是**千万要小心**!如果你信任了一个可能是恶意的值,就会在应用中引入一个安全漏洞。如果你有疑问,请找一个安全专家复查下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "TOMARKAVALUEASTRUSTEDINJECTDOMSANITIZERANDCALLONEOFTHEFOLLOWINGMETHODS:", "original": "To mark a value as trusted, inject `DomSanitizer` and call one of the\nfollowing methods:", "translation": "注入 `DomSanitizer` 服务,然后调用下面的方法之一,你就可以把一个值标记为可信任的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "REMEMBERWHETHERAVALUEISSAFEDEPENDSONCONTEXTSOCHOOSETHERIGHTCONTEXTFORYOURINTENDEDUSEOFTHEVALUEIMAGINETHATTHEFOLLOWINGTEMPLATENEEDSTOBINDAURLTOAJAVASCRIPT:ALERTCALL:", "original": "Remember, whether a value is safe depends on context, so choose the right context for\nyour intended use of the value. Imagine that the following template needs to bind a URL to a\n`javascript:alert(...)` call:", "translation": "记住,一个值是否安全取决于它所在的环境,所以你要为这个值按预定的用法选择正确的环境。假设下面的模板需要把 `javascript.alert(...)` 方法绑定到 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "NORMALLYANGULARAUTOMATICALLYSANITIZESTHEURLDISABLESTHEDANGEROUSCODEANDINDEVELOPMENTMODELOGSTHISACTIONTOTHECONSOLETOPREVENTTHISMARKTHEURLVALUEASATRUSTEDURLUSINGTHEBYPASSSECURITYTRUSTURLCALL:", "original": "Normally, Angular automatically sanitizes the URL, disables the dangerous code, and\nin development mode, logs this action to the console. To prevent\nthis, mark the URL value as a trusted URL using the `bypassSecurityTrustUrl` call:", "translation": "通常,Angular 会自动无害化这个 URL 并禁止危险的代码。为了防止这种行为,可以调用 `bypassSecurityTrustUrl` 把这个 URL 值标记为一个可信任的 URL:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "IFYOUNEEDTOCONVERTUSERINPUTINTOATRUSTEDVALUEUSEACONTROLLERMETHODTHEFOLLOWINGTEMPLATEALLOWSUSERSTOENTERAYOUTUBEVIDEOIDANDLOADTHECORRESPONDINGVIDEOINANIFRAMETHEIFRAMESRCATTRIBUTEISARESOURCEURLSECURITYCONTEXTBECAUSEANUNTRUSTEDSOURCECANFOREXAMPLESMUGGLEINFILEDOWNLOADSTHATUNSUSPECTINGUSERSCOULDEXECUTESOCALLAMETHODONTHECONTROLLERTOCONSTRUCTATRUSTEDVIDEOURLWHICHCAUSESANGULARTOALLOWBINDINGINTOIFRAMESRC:", "original": "If you need to convert user input into a trusted value, use a\ncontroller method. The following template allows users to enter a YouTube video ID and load the\ncorresponding video in an `<iframe>`. The `<iframe src>` attribute is a resource URL security\ncontext, because an untrusted source can, for example, smuggle in file downloads that unsuspecting users\ncould execute. So call a method on the controller to construct a trusted video URL, which causes\nAngular to allow binding into `<iframe src>`:", "translation": "如果需要把用户输入转换为一个可信任的值,可以在控制器方法中处理。下面的模板允许用户输入一个 YouTube 视频的 ID,\n 然后把相应的视频加载到 `<iframe>` 中。`<iframe src>` 是一个“资源 URL”的安全环境,因为不可信的源码可能作为文件下载到本地,被毫无防备的用户执行。\n 所以要调用一个控制器方法来构造一个新的、可信任的视频 URL,然后把它绑定到 `<iframe src>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "H2IDHTTPHTTPLEVELVULNERABILITIESH2", "original": "<h2 id='http'>HTTP-level vulnerabilities</h2>", "translation": "<h2 id='http'>HTTP 级别的漏洞</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ANGULARHASBUILTINSUPPORTTOHELPPREVENTTWOCOMMONHTTPVULNERABILITIESCROSSSITEREQUESTFORGERYCSRFORXSRFANDCROSSSITESCRIPTINCLUSIONXSSIBOTHOFTHESEMUSTBEMITIGATEDPRIMARILYONTHESERVERSIDEBUTANGULARPROVIDESHELPERSTOMAKEINTEGRATIONONTHECLIENTSIDEEASIER", "original": "Angular has built-in support to help prevent two common HTTP vulnerabilities, cross-site request\nforgery (CSRF or XSRF) and cross-site script inclusion (XSSI). Both of these must be mitigated primarily\non the server side, but Angular provides helpers to make integration on the client side easier.", "translation": "Angular 内置了一些支持来防范两个常见的 HTTP 漏洞:跨站请求伪造(XSRF)和跨站脚本包含(XSSI)。\n 这两个漏洞主要在服务器端防范,但是 Angular 也自带了一些辅助特性,可以让客户端的集成变得更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "H3IDXSRFCROSSSITEREQUESTFORGERYH3", "original": "<h3 id='xsrf'>Cross-site request forgery</h3>", "translation": "<h3 id='xsrf'>跨站请求伪造(XSRF)</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "INACROSSSITEREQUESTFORGERYCSRFORXSRFANATTACKERTRICKSTHEUSERINTOVISITINGADIFFERENTWEBPAGESUCHASEVILCOMWITHMALIGNANTCODETHATSECRETLYSENDSAMALICIOUSREQUESTTOTHEAPPLICATIONSWEBSERVERSUCHASEXAMPLEBANKCOM", "original": "In a cross-site request forgery (CSRF or XSRF), an attacker tricks the user into visiting\na different web page (such as `evil.com`) with malignant code that secretly sends a malicious request\nto the application's web server (such as `example-bank.com`).", "translation": "在跨站请求伪造(XSRF 或 CSFR)中,攻击者欺骗用户,让他们访问一个假冒页面(例如 `evil.com`),\n该页面带有恶意代码,秘密的向你的应用程序服务器发送恶意请求(例如 `example-bank.com`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ASSUMETHEUSERISLOGGEDINTOTHEAPPLICATIONATEXAMPLEBANKCOMTHEUSEROPENSANEMAILANDCLICKSALINKTOEVILCOMWHICHOPENSINANEWTAB", "original": "Assume the user is logged into the application at `example-bank.com`.\nThe user opens an email and clicks a link to `evil.com`, which opens in a new tab.", "translation": "假设用户已经在 `example-bank.com` 登录。用户打开一个邮件,点击里面的链接,在新页面中打开 `evil.com`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "THEEVILCOMPAGEIMMEDIATELYSENDSAMALICIOUSREQUESTTOEXAMPLEBANKCOMPERHAPSITSAREQUESTTOTRANSFERMONEYFROMTHEUSERSACCOUNTTOTHEATTACKERSACCOUNTTHEBROWSERAUTOMATICALLYSENDSTHEEXAMPLEBANKCOMCOOKIESINCLUDINGTHEAUTHENTICATIONCOOKIEWITHTHISREQUEST", "original": "The `evil.com` page immediately sends a malicious request to `example-bank.com`.\nPerhaps it's a request to transfer money from the user's account to the attacker's account.\nThe browser automatically sends the `example-bank.com` cookies (including the authentication cookie) with this request.", "translation": "该 `evil.com` 页面立刻发送恶意请求到 `example-bank.com`。这个请求可能是从用户账户转账到攻击者的账户。\n与该请求一起,浏览器自动发出 `example-bank.com` 的 cookie。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "IFTHEEXAMPLEBANKCOMSERVERLACKSXSRFPROTECTIONITCANTTELLTHEDIFFERENCEBETWEENALEGITIMATEREQUESTFROMTHEAPPLICATIONANDTHEFORGEDREQUESTFROMEVILCOM", "original": "If the `example-bank.com` server lacks XSRF protection, it can't tell the difference between a legitimate\nrequest from the application and the forged request from `evil.com`.", "translation": "如果 `example-bank.com` 服务器缺乏 XSRF 保护,就无法辨识请求是从应用程序发来的合法请求还是从 `evil.com` 来的假请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "TOPREVENTTHISTHEAPPLICATIONMUSTENSURETHATAUSERREQUESTORIGINATESFROMTHEREALAPPLICATIONNOTFROMADIFFERENTSITETHESERVERANDCLIENTMUSTCOOPERATETOTHWARTTHISATTACK", "original": "To prevent this, the application must ensure that a user request originates from the real\napplication, not from a different site.\nThe server and client must cooperate to thwart this attack.", "translation": "为了防止这种情况,你必须确保每个用户的请求都是从你自己的应用中发出的,而不是从另一个网站发出的。\n 客户端和服务器必须合作来抵挡这种攻击。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "INACOMMONANTIXSRFTECHNIQUETHEAPPLICATIONSERVERSENDSARANDOMLYGENERATEDAUTHENTICATIONTOKENINACOOKIETHECLIENTCODEREADSTHECOOKIEANDADDSACUSTOMREQUESTHEADERWITHTHETOKENINALLSUBSEQUENTREQUESTSTHESERVERCOMPARESTHERECEIVEDCOOKIEVALUETOTHEREQUESTHEADERVALUEANDREJECTSTHEREQUESTIFTHEVALUESAREMISSINGORDONTMATCH", "original": "In a common anti-XSRF technique, the application server sends a randomly\ngenerated authentication token in a cookie.\nThe client code reads the cookie and adds a custom request header with the token in all subsequent requests.\nThe server compares the received cookie value to the request header value and rejects the request if the values are missing or don't match.", "translation": "常见的反 XSRF 技术是服务器随机生成一个用户认证令牌到 cookie 中。\n 客户端代码获取这个 cookie,并用它为接下来所有的请求添加自定义请求页头。\n 服务器比较收到的 cookie 值与请求页头的值,如果它们不匹配,便拒绝请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "THISTECHNIQUEISEFFECTIVEBECAUSEALLBROWSERSIMPLEMENTTHESAMEORIGINPOLICYONLYCODEFROMTHEWEBSITEONWHICHCOOKIESARESETCANREADTHECOOKIESFROMTHATSITEANDSETCUSTOMHEADERSONREQUESTSTOTHATSITETHATMEANSONLYYOURAPPLICATIONCANREADTHISCOOKIETOKENANDSETTHECUSTOMHEADERTHEMALICIOUSCODEONEVILCOMCANT", "original": "This technique is effective because all browsers implement the _same origin policy_. Only code from the website\non which cookies are set can read the cookies from that site and set custom headers on requests to that site.\nThat means only your application can read this cookie token and set the custom header. The malicious code on `evil.com` can't.", "translation": "这个技术之所以有效,是因为所有浏览器都实现了*同源策略*。只有设置 cookie 的网站的代码可以访问该站的 cookie,并为该站的请求设置自定义页头。\n 这就是说,只有你的应用程序可以获取这个 cookie 令牌和设置自定义页头。`evil.com` 的恶意代码不能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ANGULARSHTTPCLIENTHASBUILTINSUPPORTFORTHECLIENTSIDEHALFOFTHISTECHNIQUEREADABOUTITMOREINTHEHTTPCLIENTGUIDEGUIDEHTTP", "original": "Angular's `HttpClient` has built-in support for the client-side half of this technique. Read about it more in the [HttpClient guide](/guide/http).", "translation": "Angular 的 `HttpClient` 对这项技术的客户端部分提供了内置的支持要了解更多信息,参见 [HttpClient 部分](/guide/http)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "FORINFORMATIONABOUTCSRFATTHEOPENWEBAPPLICATIONSECURITYPROJECTOWASPSEEAHREFHTTPS:WWWOWASPORGINDEXPHPCROSSSITEREQUESTFORGERY28CSRF29CROSSSITEREQUESTFORGERYCSRFAANDAHREFHTTPS:WWWOWASPORGINDEXPHPCSRFPREVENTIONCHEATSHEETCROSSSITEREQUESTFORGERYCSRFPREVENTIONCHEATSHEETATHESTANFORDUNIVERSITYPAPERAHREFHTTPS:SECLABSTANFORDEDUWEBSECCSRFCSRFPDFROBUSTDEFENSESFORCROSSSITEREQUESTFORGERYAISARICHSOURCEOFDETAIL", "original": "For information about CSRF at the Open Web Application Security Project (OWASP), see\n<a href=\"https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29\">Cross-Site Request Forgery (CSRF)</a> and\n<a href=\"https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet\">Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet</a>.\nThe Stanford University paper\n<a href=\"https://seclab.stanford.edu/websec/csrf/csrf.pdf\">Robust Defenses for Cross-Site Request Forgery</a> is a rich source of detail.", "translation": "到开放式 Web 应用程序安全项目(OWASP)的[这里](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29)\n和[这里](https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet)学习更多关于跨站请求伪造(XSRF)的知识。\n这个[斯坦福大学论文](https://seclab.stanford.edu/websec/csrf/csrf.pdf)有详尽的细节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "SEEALSODAVESMITHSEASYTOUNDERSTANDAHREFHTTPS:WWWYOUTUBECOMWATCHV9INCZW6QTPYTITLECROSSSITEREQUESTFUNKERYSECURINGYOURANGULARAPPSFROMEVILDOERSTALKONXSRFATANGULARCONNECT2016A", "original": "See also Dave Smith's easy-to-understand\n<a href=\"https://www.youtube.com/watch?v=9inczw6qtpY\" title=\"Cross Site Request Funkery Securing Your Angular Apps From Evil Doers\">talk on XSRF at AngularConnect 2016</a>.", "translation": "参见 Dave Smith 在<a href=\"https://www.youtube.com/watch?v=9inczw6qtpY\" target=\"_blank\" title=\"Cross Site Request Funkery Securing Your Angular Apps From Evil Doers\">AngularConnect 2016 关于 XSRF 的演讲</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "H3IDXSSICROSSSITESCRIPTINCLUSIONXSSIH3", "original": "<h3 id='xssi'>Cross-site script inclusion (XSSI)</h3>", "translation": "<h3 id='xssi'>跨站脚本包含(XSSI)</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "CROSSSITESCRIPTINCLUSIONALSOKNOWNASJSONVULNERABILITYCANALLOWANATTACKERSWEBSITETOREADDATAFROMAJSONAPITHEATTACKWORKSONOLDERBROWSERSBYOVERRIDINGNATIVEJAVASCRIPTOBJECTCONSTRUCTORSANDTHENINCLUDINGANAPIURLUSINGASCRIPTTAG", "original": "Cross-site script inclusion, also known as JSON vulnerability, can allow an attacker's website to\nread data from a JSON API. The attack works on older browsers by overriding native JavaScript\nobject constructors, and then including an API URL using a `<script>` tag.", "translation": "跨站脚本包含,也被称为 Json 漏洞,它可以允许一个攻击者的网站从 JSON API 读取数据。这种攻击发生在老的浏览器上,\n它重写原生 JavaScript 对象的构造函数,然后使用 `<script>` 标签包含一个 API 的 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "THISATTACKISONLYSUCCESSFULIFTHERETURNEDJSONISEXECUTABLEASJAVASCRIPTSERVERSCANPREVENTANATTACKBYPREFIXINGALLJSONRESPONSESTOMAKETHEMNONEXECUTABLEBYCONVENTIONUSINGTHEWELLKNOWNSTRINGN", "original": "This attack is only successful if the returned JSON is executable as JavaScript. Servers can\nprevent an attack by prefixing all JSON responses to make them non-executable, by convention, using the\nwell-known string `\")]}',\\n\"`.", "translation": "只有在返回的 JSON 能像 JavaScript 一样可以被执行时,这种攻击才会生效。所以服务端会约定给所有 JSON 响应体加上前缀 `\")]}',\\n\"`,来把它们标记为不可执行的,\n以防范这种攻击。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ANGULARSHTTPCLIENTLIBRARYRECOGNIZESTHISCONVENTIONANDAUTOMATICALLYSTRIPSTHESTRINGNFROMALLRESPONSESBEFOREFURTHERPARSING", "original": "Angular's `HttpClient` library recognizes this convention and automatically strips the string\n`\")]}',\\n\"` from all responses before further parsing.", "translation": "Angular 的 `Http` 库会识别这种约定,并在进一步解析之前,自动把字符串 `\")]}',\\n\"` 从所有响应中去掉。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "FORMOREINFORMATIONSEETHEXSSISECTIONOFTHISGOOGLEWEBSECURITYBLOGPOSTHTTPS:SECURITYGOOGLEBLOGCOM201105WEBSITESECURITYFORWEBMASTERSHTML", "original": "For more information, see the XSSI section of this [Google web security blog\npost](https://security.googleblog.com/2011/05/website-security-for-webmasters.html).", "translation": "要学习更多这方面的知识,请参见[谷歌 Web 安全博客文章](https://security.googleblog.com/2011/05/website-security-for-webmasters.html)的 XSSI 小节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "H2IDCODEREVIEWAUDITINGANGULARAPPLICATIONSH2", "original": "<h2 id='code-review'>Auditing Angular applications</h2>", "translation": "<h2 id='code-review'>审计 Angular 应用程序</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "ANGULARAPPLICATIONSMUSTFOLLOWTHESAMESECURITYPRINCIPLESASREGULARWEBAPPLICATIONSANDMUSTBEAUDITEDASSUCHANGULARSPECIFICAPISTHATSHOULDBEAUDITEDINASECURITYREVIEWSUCHASTHEBYPASSSECURITYTRUSTGUIDESECURITY#BYPASSSECURITYAPISMETHODSAREMARKEDINTHEDOCUMENTATIONASSECURITYSENSITIVE", "original": "Angular applications must follow the same security principles as regular web applications, and\nmust be audited as such. Angular-specific APIs that should be audited in a security review,\nsuch as the [_bypassSecurityTrust_](guide/security#bypass-security-apis) methods, are marked in the documentation\nas security sensitive.", "translation": "Angular 应用应该遵循和常规 Web 应用一样的安全原则并按照这些原则进行审计。Angular 中某些应该在安全评审中被审计的 API(\n比如[_bypassSecurityTrust_](guide/security#bypass-security-apis) API)都在文档中被明确标记为安全性敏感的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/security.md" }, { + "key": "#SERVICEWORKERCOMMUNICATION", "original": "# Service worker communication", "translation": "# 与 Service Worker 通讯", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "IMPORTINGSERVICEWORKERMODULEINTOYOURAPPMODULEDOESNTJUSTREGISTERTHESERVICEWORKERITALSOPROVIDESAFEWSERVICESYOUCANUSETOINTERACTWITHTHESERVICEWORKERANDCONTROLTHECACHINGOFYOURAPP", "original": "Importing `ServiceWorkerModule` into your `AppModule` doesn't just register the service worker, it also provides a few services you can use to interact with the service worker and control the caching of your app.", "translation": "把 `ServiceWorkerModule` 导入到你的 `AppModule` 中不仅会注册 Service Worker,还会提供一些服务,让你能和 Service Worker 通讯,并控制你的应用缓存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWING:", "original": "A basic understanding of the following:", "translation": "对下列知识有基本的了解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "GETTINGSTARTEDWITHSERVICEWORKERSGUIDESERVICEWORKERGETTINGSTARTED", "original": "* [Getting Started with Service Workers](guide/service-worker-getting-started).", - "translation": "[Service Worker 快速起步](guide/service-worker-getting-started).", + "translation": "[Service Worker 快速起步](guide/service-worker-getting-started)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "##SWUPDATESERVICE", "original": "## `SwUpdate` service", "translation": "## `SwUpdate` 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "THESWUPDATESERVICEGIVESYOUACCESSTOEVENTSTHATINDICATEWHENTHESERVICEWORKERHASDISCOVEREDANAVAILABLEUPDATEFORYOURAPPORWHENITHASACTIVATEDSUCHANUPDATEMDASHMEANINGITISNOWSERVINGCONTENTFROMTHATUPDATETOYOURAPP", "original": "The `SwUpdate` service gives you access to events that indicate when the service worker has discovered an available update for your app or when it has activated such an update—meaning it is now serving content from that update to your app.", "translation": "`SwUpdate` 服务让你能访问一些事件,这些事件会指出 Service Worker 何时发现了可用的更新或者一个更新何时可以被激活 —— 这意味着它现在可以通过更新后的版本提供服务了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "THESWUPDATESERVICESUPPORTSFOURSEPARATEOPERATIONS:", "original": "The `SwUpdate` service supports four separate operations:", "translation": "`SwUpdate` 服务支持四个独立的操作:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "GETTINGNOTIFIEDOFAVAILABLEUPDATESTHESEARENEWVERSIONSOFTHEAPPTOBELOADEDIFTHEPAGEISREFRESHED", "original": "* Getting notified of *available* updates. These are new versions of the app to be loaded if the page is refreshed.", "translation": "获取出现*可用*更新的通知。如果要刷新页面,这些就是可加载的新版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "GETTINGNOTIFIEDOFUPDATEACTIVATIONTHISISWHENTHESERVICEWORKERSTARTSSERVINGANEWVERSIONOFTHEAPPIMMEDIATELY", "original": "* Getting notified of update *activation*. This is when the service worker starts serving a new version of the app immediately.", "translation": "获取更新*被激活*的通知。这时候 Service Worker 就可以立即使用这些新版本提供服务了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "ASKINGTHESERVICEWORKERTOCHECKTHESERVERFORNEWUPDATES", "original": "* Asking the service worker to check the server for new updates.", "translation": "要求 Service Worker 向服务器查询是否有新版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "ASKINGTHESERVICEWORKERTOACTIVATETHELATESTVERSIONOFTHEAPPFORTHECURRENTTAB", "original": "* Asking the service worker to activate the latest version of the app for the current tab.", "translation": "要求 Service Worker 为当前页面激活该应用的最新版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "###AVAILABLEANDACTIVATEDUPDATES", "original": "### Available and activated updates", "translation": "### 有可用更新及已激活更新", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "THETWOUPDATEEVENTSAVAILABLEANDACTIVATEDAREOBSERVABLEPROPERTIESOFSWUPDATE:", "original": "The two update events, `available` and `activated`, are `Observable` properties of `SwUpdate`:", "translation": "这两个更新事件 `available` 和 `activated`,都是 `SwUpdate` 的 `Observable` 属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "YOUCANUSETHESEEVENTSTONOTIFYTHEUSEROFAPENDINGUPDATEORTOREFRESHTHEIRPAGESWHENTHECODETHEYARERUNNINGISOUTOFDATE", "original": "You can use these events to notify the user of a pending update or to refresh their pages when the code they are running is out of date.", "translation": "你可以使用这些事件来通知用户有一个待做更新或当它们运行的代码已经过期时刷新页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "###CHECKINGFORUPDATES", "original": "### Checking for updates", "translation": "### 检查更新", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "ITSPOSSIBLETOASKTHESERVICEWORKERTOCHECKIFANYUPDATESHAVEBEENDEPLOYEDTOTHESERVERYOUMIGHTCHOOSETODOTHISIFYOUHAVEASITETHATCHANGESFREQUENTLYORWANTUPDATESTOHAPPENONASCHEDULE", "original": "It's possible to ask the service worker to check if any updates have been deployed to the server. You might choose to do this if you have a site that changes frequently or want updates to happen on a schedule.", "translation": "可以要求 Service Worker 检查是否有任何更新已经发布到了服务器上。如果你的站点更新非常频繁,或者希望它按照计划进行定时更新,你就可以用它来实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "DOTHISWITHTHECHECKFORUPDATEMETHOD:", "original": "Do this with the `checkForUpdate()` method:", "translation": "通过调用 `checkForUpdate()` 方法来实现:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "THISMETHODRETURNSAPROMISEWHICHINDICATESTHATTHEUPDATECHECKHASCOMPLETEDSUCCESSFULLYTHOUGHITDOESNOTINDICATEWHETHERANUPDATEWASDISCOVEREDASARESULTOFTHECHECKEVENIFONEISFOUNDTHESERVICEWORKERMUSTSTILLSUCCESSFULLYDOWNLOADTHECHANGEDFILESWHICHCANFAILIFSUCCESSFULTHEAVAILABLEEVENTWILLINDICATEAVAILABILITYOFANEWVERSIONOFTHEAPP", "original": "This method returns a `Promise` which indicates that the update check has completed successfully, though it does not indicate whether an update was discovered as a result of the check. Even if one is found, the service worker must still successfully download the changed files, which can fail. If successful, the `available` event will indicate availability of a new version of the app.", "translation": "该方法返回一个用来表示检查更新已经成功完成的 `Promise`,不过它不会指出是否确实发现了一个更新。\n即使找到了一个,Service Worker 还必须成功下载更新过的文件,而这可能会失败。如果成功了,就会通过一个 `available` 事件来表明当前应用有一个可用的新版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "###FORCINGUPDATEACTIVATION", "original": "### Forcing update activation", "translation": "### 强制激活更新", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "IFTHECURRENTTABNEEDSTOBEUPDATEDTOTHELATESTAPPVERSIONIMMEDIATELYITCANASKTODOSOWITHTHEACTIVATEUPDATEMETHOD:", "original": "If the current tab needs to be updated to the latest app version immediately, it can ask to do so with the `activateUpdate()` method:", "translation": "如果当前页需要立即更新到最新的应用版本,可以通过 `activateUpdate()` 方法来要求立即这么做:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "DOINGTHISCOULDBREAKLAZYLOADINGINTOCURRENTLYRUNNINGAPPSESPECIALLYIFTHELAZYLOADEDCHUNKSUSEFILENAMESWITHHASHESWHICHCHANGEEVERYVERSION", "original": "Doing this could break lazy-loading into currently running apps, especially if the lazy-loaded chunks use filenames with hashes, which change every version.", "translation": "这可能会让惰性加载的模块进入当前正在运行的应用中,特别是如果惰性加载的模块文件名中使用了哈希时,这将会改变每一个版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "##MOREONANGULARSERVICEWORKERS", "original": "## More on Angular service workers", - "translation": "## 关于 Angular Service Worker 的更多知识", + "translation": "## 关于 Angular Service Worker 的更多信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", - "translation": "你可能对下列内容感兴趣:", + "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "SERVICEWORKERINPRODUCTIONGUIDESERVICEWORKERDEVOPS", "original": "* [Service Worker in Production](guide/service-worker-devops).", - "translation": "[产品环境下的 Service Worker](guide/service-worker-devops).", + "translation": "[生产环境下的 Service Worker](guide/service-worker-devops)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-communications.md" }, { + "key": "#SERVICEWORKERCONFIGURATION", "original": "# Service worker configuration", "translation": "# Service Worker 配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWING:", "original": "A basic understanding of the following:", "translation": "对下列知识有基本的了解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "SERVICEWORKERINPRODUCTIONGUIDESERVICEWORKERDEVOPS", "original": "* [Service Worker in Production](guide/service-worker-devops).", - "translation": "[产品环境下的 Service Worker](guide/service-worker-devops).", + "translation": "[生产环境下的 Service Worker](guide/service-worker-devops)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THESRCNGSWCONFIGJSONCONFIGURATIONFILESPECIFIESWHICHFILESANDDATAURLSTHEANGULARSERVICEWORKERSHOULDCACHEANDHOWITSHOULDUPDATETHECACHEDFILESANDDATATHECLIPROCESSESTHECONFIGURATIONFILEDURINGNGBUILDPRODMANUALLYYOUCANPROCESSITWITHTHENGSWCONFIGTOOL:", "original": "The `src/ngsw-config.json` configuration file specifies which files and data URLs the Angular \nservice worker should cache and how it should update the cached files and data. The \nCLI processes the configuration file during `ng build --prod`. Manually, you can process \nit with the `ngsw-config` tool:", "translation": "配置文件 `src/ngsw-config.json` 指定了 Angular Service Worker 应该缓存哪些文件和数据的 URL,以及如何更新缓存的文件和数据。\nCLI 会在 `ng build --prod` 期间处理配置文件。\n如果想手动处理,你可以使用 `ngsw-config` 工具:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THECONFIGURATIONFILEUSESTHEJSONFORMATALLFILEPATHSMUSTBEGINWITHWHICHISTHEDEPLOYMENTDIRECTORYMDASHUSUALLYDISTINCLIPROJECTS", "original": "The configuration file uses the JSON format. All file paths must begin with `/`, which is the deployment directory—usually `dist` in CLI projects.", "translation": "该配置文件使用 JSON 格式。\n所有文件路径都必须以 `/` 开头,也就是部署目录 —— 在 CLI 项目中的它通常是 `dist`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "PATTERNSUSEALIMITEDGLOBFORMAT:", "original": "Patterns use a limited glob format:", "translation": "它的模式使用受限的 glob 格式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "MATCHES0ORMOREPATHSEGMENTS", "original": "* `**` matches 0 or more path segments.", "translation": "`**` 匹配 0 到多段路径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "MATCHESEXACTLYONEPATHSEGMENTORFILENAMESEGMENT", "original": "* `*` matches exactly one path segment or filename segment.", "translation": "`*` 只匹配一段路径或文件名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THEPREFIXMARKSTHEPATTERNASBEINGNEGATIVEMEANINGTHATONLYFILESTHATDONTMATCHTHEPATTERNWILLBEINCLUDED", "original": "* The `!` prefix marks the pattern as being negative, meaning that only files that don't match the pattern will be included.", "translation": "`!` 前缀表示该模式是反的,也就是说只包含与该模式不匹配的文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "EXAMPLEPATTERNS:", "original": "Example patterns:", "translation": "范例模式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "HTMLSPECIFIESALLHTMLFILES", "original": "* `/**/*.html` specifies all HTML files.", "translation": "`/**/*.html` 指定所有 HTML 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "HTMLSPECIFIESONLYHTMLFILESINTHEROOT", "original": "* `/*.html` specifies only HTML files in the root.", "translation": "`/*.html` 仅指定根目录下的 HTML 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "MAPEXCLUDEALLSOURCEMAPS", "original": "* `!/**/*.map` exclude all sourcemaps.", "translation": "`!/**/*.map` 排除了所有源码映射文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "EACHSECTIONOFTHECONFIGURATIONFILEISDESCRIBEDBELOW", "original": "Each section of the configuration file is described below.", "translation": "下面讲讲配置文件中的每一节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THISSECTIONENABLESYOUTOPASSANYDATAYOUWANTTHATDESCRIBESTHISPARTICULARVERSIONOFTHEAPPTHESWUPDATESERVICEINCLUDESTHATDATAINTHEUPDATENOTIFICATIONSMANYAPPSUSETHISSECTIONTOPROVIDEADDITIONALINFORMATIONFORTHEDISPLAYOFUIPOPUPSNOTIFYINGUSERSOFTHEAVAILABLEUPDATE", "original": "This section enables you to pass any data you want that describes this particular version of the app.\nThe `SwUpdate` service includes that data in the update notifications. Many apps use this section to provide additional information for the display of UI popups, notifying users of the available update.", "translation": "本节允许你传递用来描述这个特定应用版本的任何数据。\n`SwUpdate` 服务会在更新通知中包含这些数据。\n许多应用会使用本节来提供 UI 弹窗时要显示的附加信息,以通知用户有可用的更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "SPECIFIESTHEFILETHATSERVESASTHEINDEXPAGETOSATISFYNAVIGATIONREQUESTSUSUALLYTHISISINDEXHTML", "original": "Specifies the file that serves as the index page to satisfy navigation requests. Usually this is `/index.html`.", "translation": "指定用来充当索引页的文件以满足导航请求。通常是`/index.html`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "ASSETSARERESOURCESTHATAREPARTOFTHEAPPVERSIONTHATUPDATEALONGWITHTHEAPPTHEYCANINCLUDERESOURCESLOADEDFROMTHEPAGESORIGINASWELLASTHIRDPARTYRESOURCESLOADEDFROMCDNSANDOTHEREXTERNALURLSASNOTALLSUCHEXTERNALURLSMAYBEKNOWNATBUILDTIMEURLPATTERNSCANBEMATCHED", "original": "*Assets* are resources that are part of the app version that update along with the app. They can include resources loaded from the page's origin as well as third-party resources loaded from CDNs and other external URLs. As not all such external URLs may be known at build time, URL patterns can be matched.", "translation": "*资产(Assets)*是与应用一起更新的应用版本的一部分。\n它们可以包含从页面的同源地址加载的资源以及从 CDN 和其它外部 URL 加载的第三方资源。\n由于在构建时可能没法提前知道所有这些外部 URL,因此也可以指定 URL 的模式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THISFIELDCONTAINSANARRAYOFASSETGROUPSEACHOFWHICHDEFINESASETOFASSETRESOURCESANDTHEPOLICYBYWHICHTHEYARECACHED", "original": "This field contains an array of asset groups, each of which defines a set of asset resources and the policy by which they are cached.", "translation": "该字段包含一个资产组的数组,每个资产组中会定义一组资产资源和它们的缓存策略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "EACHASSETGROUPSPECIFIESBOTHAGROUPOFRESOURCESANDAPOLICYTHATGOVERNSTHEMTHISPOLICYDETERMINESWHENTHERESOURCESAREFETCHEDANDWHATHAPPENSWHENCHANGESAREDETECTED", "original": "Each asset group specifies both a group of resources and a policy that governs them. This policy determines when the resources are fetched and what happens when changes are detected.", "translation": "每个资产组都会指定一组资源和一个管理它们的策略。\n此策略用来决定何时获取资源以及当检测到更改时该怎么做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "ASSETGROUPSFOLLOWTHETYPESCRIPTINTERFACESHOWNHERE:", "original": "Asset groups follow the Typescript interface shown here:", "translation": "这些资产组会遵循下面的 Typescript 接口:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "ANAMEISMANDATORYITIDENTIFIESTHISPARTICULARGROUPOFASSETSBETWEENVERSIONSOFTHECONFIGURATION", "original": "A `name` is mandatory. It identifies this particular group of assets between versions of the configuration.", "translation": "`name` 是强制性的。它用来标识该配置文件版本中这个特定的资产组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THEINSTALLMODEDETERMINESHOWTHESERESOURCESAREINITIALLYCACHEDTHEINSTALLMODECANBEEITHEROFTWOVALUES:", "original": "The `installMode` determines how these resources are initially cached. The `installMode` can be either of two values:", "translation": "`installMode` 决定了这些资源最初的缓存方式。`installMode` 可以取如下两个值之一:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "PREFETCHTELLSTHEANGULARSERVICEWORKERTOFETCHEVERYSINGLELISTEDRESOURCEWHILEITSCACHINGTHECURRENTVERSIONOFTHEAPPTHISISBANDWIDTHINTENSIVEBUTENSURESRESOURCESAREAVAILABLEWHENEVERTHEYREREQUESTEDEVENIFTHEBROWSERISCURRENTLYOFFLINE", "original": "* `prefetch` tells the Angular service worker to fetch every single listed resource while it's caching the current version of the app. This is bandwidth-intensive but ensures resources are available whenever they're requested, even if the browser is currently offline.", "translation": "`prefetch` 告诉 Angular Service Worker 在缓存当前版本的应用时要获取每一个列出的资源。\n 这是个带宽密集型的模式,但可以确保这些资源在请求时可用,即使浏览器正处于离线状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "LAZYDOESNOTCACHEANYOFTHERESOURCESUPFRONTINSTEADTHEANGULARSERVICEWORKERONLYCACHESRESOURCESFORWHICHITRECEIVESREQUESTSTHISISANONDEMANDCACHINGMODERESOURCESTHATARENEVERREQUESTEDWILLNOTBECACHEDTHISISUSEFULFORTHINGSLIKEIMAGESATDIFFERENTRESOLUTIONSSOTHESERVICEWORKERONLYCACHESTHECORRECTASSETSFORTHEPARTICULARSCREENANDORIENTATION", "original": "* `lazy` does not cache any of the resources up front. Instead, the Angular service worker only caches resources for which it receives requests. This is an on-demand caching mode. Resources that are never requested will not be cached. This is useful for things like images at different resolutions, so the service worker only caches the correct assets for the particular screen and orientation.", "translation": "`lazy` 不会预先缓存任何资源。相反,Angular Service Worker 只会缓存它收到请求的资源。\n 这是一种按需缓存模式。永远不会请求的资源也永远不会被缓存。\n 这对于像为不同分辨率提供的图片之类的资源很有用,那样 Service Worker 就只会为特定的屏幕和设备方向缓存正确的资源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "FORRESOURCESALREADYINTHECACHETHEUPDATEMODEDETERMINESTHECACHINGBEHAVIORWHENANEWVERSIONOFTHEAPPISDISCOVEREDANYRESOURCESINTHEGROUPTHATHAVECHANGEDSINCETHEPREVIOUSVERSIONAREUPDATEDINACCORDANCEWITHUPDATEMODE", "original": "For resources already in the cache, the `updateMode` determines the caching behavior when a new version of the app is discovered. Any resources in the group that have changed since the previous version are updated in accordance with `updateMode`.", "translation": "对于已经存在于缓存中的资源,`updateMode` 会决定在发现了新版本应用后的缓存行为。\n自上一版本以来更改过的所有组中资源都会根据 `updateMode` 进行更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "PREFETCHTELLSTHESERVICEWORKERTODOWNLOADANDCACHETHECHANGEDRESOURCESIMMEDIATELY", "original": "* `prefetch` tells the service worker to download and cache the changed resources immediately.", "translation": "`prefetch` 会告诉 Service Worker 立即下载并缓存更新过的资源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "LAZYTELLSTHESERVICEWORKERTONOTCACHETHOSERESOURCESINSTEADITTREATSTHEMASUNREQUESTEDANDWAITSUNTILTHEYREREQUESTEDAGAINBEFOREUPDATINGTHEMANUPDATEMODEOFLAZYISONLYVALIDIFTHEINSTALLMODEISALSOLAZY", "original": "* `lazy` tells the service worker to not cache those resources. Instead, it treats them as unrequested and waits until they're requested again before updating them. An `updateMode` of `lazy` is only valid if the `installMode` is also `lazy`.", "translation": "`lazy` 告诉 Service Worker 不要缓存这些资源,而是先把它们看作未被请求的,等到它们再次被请求时才进行更新。\n `lazy` 这个 `updateMode` 只有在 `installMode` 也同样是 `lazy` 时才有效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THISSECTIONDESCRIBESTHERESOURCESTOCACHEBROKENUPINTOTHREEGROUPS", "original": "This section describes the resources to cache, broken up into three groups.", "translation": "本节描述要缓存的资源,分为三组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "FILESLISTSPATTERNSTHATMATCHFILESINTHEDISTRIBUTIONDIRECTORYTHESECANBESINGLEFILESORGLOBLIKEPATTERNSTHATMATCHANUMBEROFFILES", "original": "* `files` lists patterns that match files in the distribution directory. These can be single files or glob-like patterns that match a number of files.", "translation": "`files` 列出了与 `dist` 目录中的文件相匹配的模式。它们可以是单个文件也可以是能匹配多个文件的类似 glob 的模式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "VERSIONEDFILESISLIKEFILESBUTSHOULDBEUSEDFORBUILDARTIFACTSTHATALREADYINCLUDEAHASHINTHEFILENAMEWHICHISUSEDFORCACHEBUSTINGTHEANGULARSERVICEWORKERCANOPTIMIZESOMEASPECTSOFITSOPERATIONIFITCANASSUMEFILECONTENTSAREIMMUTABLE", "original": "* `versionedFiles` is like `files` but should be used for build artifacts that already include a hash in the filename, which is used for cache busting. The Angular service worker can optimize some aspects of its operation if it can assume file contents are immutable.", "translation": "`versionedFiles` 和 `files` 相似,但是它用来对工件进行构建,这些工件已经在文件名中包含了一个散列,用于让其缓存失效。\n 如果 Angular Service Worker 能假定这些文件在文件名不变时其内容也不会变,那它就可以从某些方面优化这种操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "URLSINCLUDESBOTHURLSANDURLPATTERNSTHATWILLBEMATCHEDATRUNTIMETHESERESOURCESARENOTFETCHEDDIRECTLYANDDONOTHAVECONTENTHASHESBUTTHEYWILLBECACHEDACCORDINGTOTHEIRHTTPHEADERSTHISISMOSTUSEFULFORCDNSSUCHASTHEGOOGLEFONTSSERVICE", "original": "* `urls` includes both URLs and URL patterns that will be matched at runtime. These resources are not fetched directly and do not have content hashes, but they will be cached according to their HTTP headers. This is most useful for CDNs such as the Google Fonts service.", "translation": "`urls` 包括要在运行时进行匹配的 URL 和 URL 模式。\n 这些资源不是直接获取的,也没有内容散列,但它们会根据 HTTP 标头进行缓存。\n 这对于像 Google Fonts 服务这样的 CDN 非常有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "UNLIKEASSETRESOURCESDATAREQUESTSARENOTVERSIONEDALONGWITHTHEAPPTHEYRECACHEDACCORDINGTOMANUALLYCONFIGUREDPOLICIESTHATAREMOREUSEFULFORSITUATIONSSUCHASAPIREQUESTSANDOTHERDATADEPENDENCIES", "original": "Unlike asset resources, data requests are not versioned along with the app. They're cached according to manually-configured policies that are more useful for situations such as API requests and other data dependencies.", "translation": "与这些资产性(asset)资源不同,数据请求不会随应用一起版本化。\n它们会根据手动配置的策略进行缓存,这些策略对 API 请求和所依赖的其它数据等情况会更有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "DATAGROUPSFOLLOWTHISTYPESCRIPTINTERFACE:", "original": "Data groups follow this Typescript interface:", "translation": "数据组遵循下列 TypeScript 接口:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "SIMILARTOASSETGROUPSEVERYDATAGROUPHASANAMEWHICHUNIQUELYIDENTIFIESIT", "original": "Similar to `assetGroups`, every data group has a `name` which uniquely identifies it.", "translation": "和 `assetGroups` 下类似,每个数据组也都有一个 `name` ,用作它的唯一标识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "ALISTOFURLPATTERNSURLSTHATMATCHTHESEPATTERNSWILLBECACHEDACCORDINGTOTHISDATAGROUPSPOLICY", "original": "A list of URL patterns. URLs that match these patterns will be cached according to this data group's policy.", "translation": "一个 URL 模式的列表。匹配这些模式的 URL 将会根据该数据组的策略进行缓存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "OCCASIONALLYAPISCHANGEFORMATSINAWAYTHATISNOTBACKWARDCOMPATIBLEANEWVERSIONOFTHEAPPMAYNOTBECOMPATIBLEWITHTHEOLDAPIFORMATANDTHUSMAYNOTBECOMPATIBLEWITHEXISTINGCACHEDRESOURCESFROMTHATAPI", "original": "Occasionally APIs change formats in a way that is not backward-compatible. A new version of the app may not be compatible with the old API format and thus may not be compatible with existing cached resources from that API.", "translation": "API 有时可能会以不向后兼容的方式更改格式。\n新版本的应用可能与旧的 API 格式不兼容,因此也就与该 API 中目前已缓存的资源不兼容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "VERSIONPROVIDESAMECHANISMTOINDICATETHATTHERESOURCESBEINGCACHEDHAVEBEENUPDATEDINABACKWARDSINCOMPATIBLEWAYANDTHATTHEOLDCACHEENTRIESMDASHTHOSEFROMPREVIOUSVERSIONSMDASHSHOULDBEDISCARDED", "original": "`version` provides a mechanism to indicate that the resources being cached have been updated in a backwards-incompatible way, and that the old cache entries—those from previous versions—should be discarded.", "translation": "`version` 提供了一种机制,用于指出这些被缓存的资源已经通过不向后兼容的方式进行了更新,并且旧的缓存条目(即来自以前版本的缓存条目)应该被丢弃。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "VERSIONISANINTEGERFIELDANDDEFAULTSTO0", "original": "`version` is an integer field and defaults to `0`.", "translation": "`version` 是个整型字段,默认为 `0`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THISSECTIONDEFINESTHEPOLICYBYWHICHMATCHINGREQUESTSWILLBECACHED", "original": "This section defines the policy by which matching requests will be cached.", "translation": "本节定义了对匹配上的请求进行缓存时的策略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "REQUIREDTHEMAXIMUMNUMBEROFENTRIESORRESPONSESINTHECACHEOPENENDEDCACHESCANGROWINUNBOUNDEDWAYSANDEVENTUALLYEXCEEDSTORAGEQUOTASCALLINGFOREVICTION", "original": "(required) The maximum number of entries, or responses, in the cache. Open-ended caches can grow in unbounded ways and eventually exceed storage quotas, calling for eviction.", "translation": "(必需)缓存的最大条目数或响应数。开放式缓存可以无限增长,并最终超过存储配额,建议适时清理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "REQUIREDTHEMAXAGEPARAMETERINDICATESHOWLONGRESPONSESAREALLOWEDTOREMAININTHECACHEBEFOREBEINGCONSIDEREDINVALIDANDEVICTEDMAXAGEISADURATIONSTRINGUSINGTHEFOLLOWINGUNITSUFFIXES:", "original": "(required) The `maxAge` parameter indicates how long responses are allowed to remain in the cache before being considered invalid and evicted. `maxAge` is a duration string, using the following unit suffixes:", "translation": "(必需)`maxAge` 参数表示在响应因失效而要清除之前允许在缓存中留存的时间。`maxAge` 是一个表示持续时间的字符串,可使用以下单位作为后缀:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "D:DAYS", "original": "* `d`: days", "translation": "`d`:天数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "H:HOURS", "original": "* `h`: hours", "translation": "`h`:小时数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "M:MINUTES", "original": "* `m`: minutes", "translation": "`m`:分钟数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "S:SECONDS", "original": "* `s`: seconds", "translation": "`s`:秒数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "U:MILLISECONDS", "original": "* `u`: milliseconds", "translation": "`u`:微秒数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "FOREXAMPLETHESTRING3D12HWILLCACHECONTENTFORUPTOTHREEANDAHALFDAYS", "original": "For example, the string `3d12h` will cache content for up to three and a half days.", "translation": "比如,字符串 `3d12h` 规定此内容最多缓存三天半。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THISDURATIONSTRINGSPECIFIESTHENETWORKTIMEOUTTHENETWORKTIMEOUTISHOWLONGTHEANGULARSERVICEWORKERWILLWAITFORTHENETWORKTORESPONDBEFOREUSINGACACHEDRESPONSEIFCONFIGUREDTODOSO", "original": "This duration string specifies the network timeout. The network timeout is how long the Angular service worker will wait for the network to respond before using a cached response, if configured to do so.", "translation": "这个表示持续时间的字符串用于指定网络超时时间。\n如果配置了它,Angular Service Worker 在开始使用缓存之前就会先等待网络给出响应,这个等待时间就是网络超时时间。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "THEANGULARSERVICEWORKERCANUSEEITHEROFTWOCACHINGSTRATEGIESFORDATARESOURCES", "original": "The Angular service worker can use either of two caching strategies for data resources.", "translation": "Angular Service Worker 可以使用两种缓存策略之一来获取数据资源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "PERFORMANCETHEDEFAULTOPTIMIZESFORRESPONSESTHATAREASFASTASPOSSIBLEIFARESOURCEEXISTSINTHECACHETHECACHEDVERSIONISUSEDTHISALLOWSFORSOMESTALENESSDEPENDINGONTHEMAXAGEINEXCHANGEFORBETTERPERFORMANCETHISISSUITABLEFORRESOURCESTHATDONTCHANGEOFTENFOREXAMPLEUSERAVATARIMAGES", "original": "* `performance`, the default, optimizes for responses that are as fast as possible. If a resource exists in the cache, the cached version is used. This allows for some staleness, depending on the `maxAge`, in exchange for better performance. This is suitable for resources that don't change often; for example, user avatar images.", "translation": "`performance`,默认值,为尽快给出响应而优化。如果缓存中存在某个资源,则使用这个缓存版本。\n 它允许资源有一定的陈旧性(取决于 `maxAge`)以换取更好的性能。适用于那些不经常改变的资源,例如用户头像。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "FRESHNESSOPTIMIZESFORCURRENCYOFDATAPREFERENTIALLYFETCHINGREQUESTEDDATAFROMTHENETWORKONLYIFTHENETWORKTIMESOUTACCORDINGTOTIMEOUTDOESTHEREQUESTFALLBACKTOTHECACHETHISISUSEFULFORRESOURCESTHATCHANGEFREQUENTLYFOREXAMPLEACCOUNTBALANCES", "original": "* `freshness` optimizes for currency of data, preferentially fetching requested data from the network. Only if the network times out, according to `timeout`, does the request fall back to the cache. This is useful for resources that change frequently; for example, account balances.", "translation": "`freshness` 为数据的即时性而优化,优先从网络获取请求的数据。只有当网络超时时,请求才会根据 `timeout` 的设置回退到缓存中。这对于那些频繁变化的资源很有用,例如账户余额。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-config.md" }, { + "key": "#SERVICEWORKERINPRODUCTION", "original": "# Service worker in production", - "translation": "# 产品环境下的 Service Worker", + "translation": "# 生产环境下的 Service Worker", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THISPAGEISAREFERENCEFORDEPLOYINGANDSUPPORTINGPRODUCTIONAPPSTHATUSETHEANGULARSERVICEWORKERITEXPLAINSHOWTHEANGULARSERVICEWORKERFITSINTOTHELARGERPRODUCTIONENVIRONMENTTHESERVICEWORKERSBEHAVIORUNDERVARIOUSCONDITIONSANDAVAILABLERECOURSESANDFAILSAFES", "original": "This page is a reference for deploying and supporting production apps that use the Angular service worker. It explains how the Angular service worker fits into the larger production environment, the service worker's behavior under various conditions, and available recourses and fail-safes.", - "translation": "本页讲的是如何使用 Angular Service Worker 发布和支持产品环境下的应用。\n它解释了 Angular Service Worker 如何满足大规模产品环境的需求、Service Worker 在多种条件下有哪些行为以及有哪些可用的资源和故障保护机制。", + "translation": "本页讲的是如何使用 Angular Service Worker 发布和支持生产环境下的应用。\n它解释了 Angular Service Worker 如何满足大规模生产环境的需求、Service Worker 在多种条件下有哪些行为以及有哪些可用的资源和故障保护机制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWING:", "original": "A basic understanding of the following:", "translation": "对下列知识有基本的了解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "SERVICEWORKERCOMMUNICATIONGUIDESERVICEWORKERCOMMUNICATIONS", "original": "* [Service Worker Communication](guide/service-worker-communications).", "translation": "[与 Service Worker 通讯](guide/service-worker-communications).", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "##SERVICEWORKERANDCACHINGOFAPPRESOURCES", "original": "## Service worker and caching of app resources", "translation": "## Service Worker 与应用资源的缓存", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "CONCEPTUALLYYOUCANIMAGINETHEANGULARSERVICEWORKERASAFORWARDCACHEORACDNEDGETHATISINSTALLEDINTHEENDUSERSWEBBROWSERTHESERVICEWORKERSJOBISTOSATISFYREQUESTSMADEBYTHEANGULARAPPFORRESOURCESORDATAFROMALOCALCACHEWITHOUTNEEDINGTOWAITFORTHENETWORKLIKEANYCACHEITHASRULESFORHOWCONTENTISEXPIREDANDUPDATED", "original": "Conceptually, you can imagine the Angular service worker as a forward cache or a CDN edge that is installed in the end user's web browser. The service worker's job is to satisfy requests made by the Angular app for resources or data from a local cache, without needing to wait for the network. Like any cache, it has rules for how content is expired and updated.", "translation": "从概念上说,你可以把 Angular Service Worker 想象成一个转发式缓存或装在最终用户浏览器中的 CDN 边缘。\nService Worker 的工作是从本地缓存中满足 Angular 应用对资源或数据的请求,而不用等待网络。\n和所有缓存一样,它有一些规则来决定内容该如何过期或更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "###APPVERSIONS", "original": "### App versions", "translation": "### 应用的版本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "INTHECONTEXTOFANANGULARSERVICEWORKERAVERSIONISACOLLECTIONOFRESOURCESTHATREPRESENTASPECIFICBUILDOFTHEANGULARAPPWHENEVERANEWBUILDOFTHEAPPISDEPLOYEDTHESERVICEWORKERTREATSTHATBUILDASANEWVERSIONOFTHEAPPTHISISTRUEEVENIFONLYASINGLEFILEISUPDATEDATANYGIVENTIMETHESERVICEWORKERMAYHAVEMULTIPLEVERSIONSOFTHEAPPINITSCACHEANDITMAYBESERVINGTHEMSIMULTANEOUSLYFORMOREINFORMATIONSEETHEAPPTABSGUIDESERVICEWORKERDEVOPS#TABSSECTIONBELOW", "original": "In the context of an Angular service worker, a \"version\" is a collection of resources that represent a specific build of the Angular app. Whenever a new build of the app is deployed, the service worker treats that build as a new version of the app. This is true even if only a single file is updated. At any given time, the service worker may have multiple versions of the app in its cache and it may be serving them simultaneously. For more information, see the [App tabs](guide/service-worker-devops#tabs) section below.", "translation": "在 Angular Service Worker 的语境下,“版本”是指用来表示 Angular 应用的某一次构建成果的一组资源。\n当应用的一个新的构建发布时,Service Worker 就把它看做此应用的一个新版本。\n就算只修改了一个文件,也同样如此。\n在任何一个给定的时间,Service Worker 可能会在它的缓存中拥有此应用的多个版本,这几个版本也都能用于提供服务。\n要了解更多,参见稍后的 [App 选项卡](guide/service-worker-devops#tabs)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "TOPRESERVEAPPINTEGRITYTHEANGULARSERVICEWORKERGROUPSALLFILESINTOAVERSIONTOGETHERTHEFILESGROUPEDINTOAVERSIONUSUALLYINCLUDEHTMLJSANDCSSFILESGROUPINGOFTHESEFILESISESSENTIALFORINTEGRITYBECAUSEHTMLJSANDCSSFILESFREQUENTLYREFERTOEACHOTHERANDDEPENDONSPECIFICCONTENTFOREXAMPLEANINDEXHTMLFILEMIGHTHAVEASCRIPTTAGTHATREFERENCESBUNDLEJSANDITMIGHTATTEMPTTOCALLAFUNCTIONSTARTAPPFROMWITHINTHATSCRIPTANYTIMETHISVERSIONOFINDEXHTMLISSERVEDTHECORRESPONDINGBUNDLEJSMUSTBESERVEDWITHITFOREXAMPLEASSUMETHATTHESTARTAPPFUNCTIONISRENAMEDTORUNAPPINBOTHFILESINTHISSCENARIOITISNOTVALIDTOSERVETHEOLDINDEXHTMLWHICHCALLSSTARTAPPALONGWITHTHENEWBUNDLEWHICHDEFINESRUNAPP", "original": "To preserve app integrity, the Angular service worker groups all files into a version together. The files grouped into a version usually include HTML, JS, and CSS files. Grouping of these files is essential for integrity because HTML, JS, and CSS files frequently refer to each other and depend on specific content. For example, an `index.html` file might have a `<script>` tag that references `bundle.js` and it might attempt to call a function `startApp()` from within that script. Any time this version of `index.html` is served, the corresponding `bundle.js` must be served with it. For example, assume that the `startApp()` function is renamed to `runApp()` in both files. In this scenario, it is not valid to serve the old `index.html`, which calls `startApp()`, along with the new bundle, which defines `runApp()`.", "translation": "要保持应用的整体性,Angular Service Worker 会用所有的文件共同组成一个版本。\n组成版本的这些文件通常包括 HTML、JS 和 CSS 文件。把这些文件分成一组是至关重要的,因为它们会互相引用,并且依赖于一些特定内容。\n比如,`index.html` 文件可能有个引用 `bundle.js` 的 `<script>` 标签,它可能会试图从这个脚本中调用一个 `startApp()` 函数。\n任何时候,只要这个版本的 `index.html` 被提供了,与它对应的 `bundle.js` 也必须同时提供。\n这种情况下,使用调用了 `startApp()` 的老的 `index.html` 并同时使用定义了 `runApp()` 的新 bundle 就是无效的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THISFILEINTEGRITYISESPECIALLYIMPORTANTWHENLAZYLOADINGMODULESAJSBUNDLEMAYREFERENCEMANYLAZYCHUNKSANDTHEFILENAMESOFTHELAZYCHUNKSAREUNIQUETOTHEPARTICULARBUILDOFTHEAPPIFARUNNINGAPPATVERSIONXATTEMPTSTOLOADALAZYCHUNKBUTTHESERVERHASUPDATEDTOVERSIONX1ALREADYTHELAZYLOADINGOPERATIONWILLFAIL", "original": "This file integrity is especially important when lazy loading modules. \nA JS bundle may reference many lazy chunks, and the filenames of the \nlazy chunks are unique to the particular build of the app. If a running \napp at version `X` attempts to load a lazy chunk, but the server has \nupdated to version `X + 1` already, the lazy loading operation will fail.", "translation": "当使用惰性加载模块时,文件的整体性就显得格外重要。\n某个 JS 包可能引用很多惰性块,而这些惰性块的文件名在应用的每次特定的构建中都是唯一的。\n如果运行应用的 `X` 版本视图加载一个惰性块,但该块的服务器已经升级到了 `X + 1`版本,这次惰性加载操作就会失败。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEVERSIONIDENTIFIEROFTHEAPPISDETERMINEDBYTHECONTENTSOFALLRESOURCESANDITCHANGESIFANYOFTHEMCHANGEINPRACTICETHEVERSIONISDETERMINEDBYTHECONTENTSOFTHENGSWJSONFILEWHICHINCLUDESHASHESFORALLKNOWNCONTENTIFANYOFTHECACHEDFILESCHANGETHEFILESHASHWILLCHANGEINNGSWJSONCAUSINGTHEANGULARSERVICEWORKERTOTREATTHEACTIVESETOFFILESASANEWVERSION", "original": "The version identifier of the app is determined by the contents of all \nresources, and it changes if any of them change. In practice, the version \nis determined by the contents of the `ngsw.json` file, which includes \nhashes for all known content. If any of the cached files change, the file's \nhash will change in `ngsw.json`, causing the Angular service worker to \ntreat the active set of files as a new version.", "translation": "本应用的版本标识符由其所有资源的内容决定,如果它们中的任何一个发生了变化,则版本标识符也随之改变。 \n实际上,版本是由 `ngsw.json` 文件的内容决定的,包含了所有已知内容的哈希值。\n如果任何一个被缓存的文件发生了变化,则该文件的哈希也将在`ngsw.json`中随之变化,从而导致 Angular Service Worker 将这个活动文件的集合视为一个新版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "WITHTHEVERSIONINGBEHAVIOROFTHEANGULARSERVICEWORKERANAPPLICATIONSERVERCANENSURETHATTHEANGULARAPPALWAYSHASACONSISTENTSETOFFILES", "original": "With the versioning behavior of the Angular service worker, an application \nserver can ensure that the Angular app always has a consistent set of files.", "translation": "借助 Angular Service Worker 的这种版本控制行为,应用服务器就可以确保这个 Angular 应用中的这组文件始终保持一致。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####UPDATECHECKS", "original": "#### Update checks", "translation": "#### 更新检测", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "EVERYTIMETHEUSEROPENSORREFRESHESTHEAPPLICATIONTHEANGULARSERVICEWORKERCHECKSFORUPDATESTOTHEAPPBYLOOKINGFORUPDATESTOTHENGSWJSONMANIFESTIFANUPDATEISFOUNDITISDOWNLOADEDANDCACHEDAUTOMATICALLYANDWILLBESERVEDTHENEXTTIMETHEAPPLICATIONISLOADED", "original": "Every time the user opens or refreshes the application, the Angular service worker\nchecks for updates to the app by looking for updates to the `ngsw.json` manifest. If\nan update is found, it is downloaded and cached automatically, and will be served\nthe next time the application is loaded.", "translation": "每当用户打开或刷新应用程序时,Angular Service Worker 都会通过查看清单(manifest)文件 “ngsw.json” 的更新来检查该应用程序的更新。\n如果它找到了更新,就会自动下载并缓存这个版本,并在下次加载应用程序时提供。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "###RESOURCEINTEGRITY", "original": "### Resource integrity", "translation": "### 资源整体性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ONEOFTHEPOTENTIALSIDEEFFECTSOFLONGCACHINGISINADVERTENTLYCACHINGANINVALIDRESOURCEINANORMALHTTPCACHEAHARDREFRESHORCACHEEXPIRATIONLIMITSTHENEGATIVEEFFECTSOFCACHINGANINVALIDFILEASERVICEWORKERIGNORESSUCHCONSTRAINTSANDEFFECTIVELYLONGCACHESTHEENTIREAPPCONSEQUENTLYITISESSENTIALTHATTHESERVICEWORKERGETTHECORRECTCONTENT", "original": "One of the potential side effects of long caching is inadvertently \ncaching an invalid resource. In a normal HTTP cache, a hard refresh \nor cache expiration limits the negative effects of caching an invalid \nfile. A service worker ignores such constraints and effectively long \ncaches the entire app. Consequently, it is essential that the service worker \nget the correct content.", "translation": "长周期缓存的潜在副作用之一就是可能无意中缓存了无效的资源。\n在普通的HTTP缓存中,硬刷新或缓存过期限制了缓存这种无效文件导致的负面影响。\n而 Service Worker 会忽略这样的约束,事实上会对整个应用程序进行长期缓存。\n因此,让 Service Worker 获得正确的内容就显得至关重要。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "TOENSURERESOURCEINTEGRITYTHEANGULARSERVICEWORKERVALIDATESTHEHASHESOFALLRESOURCESFORWHICHITHASAHASHTYPICALLYFORACLIAPPTHISISEVERYTHINGINTHEDISTDIRECTORYCOVEREDBYTHEUSERSSRCNGSWCONFIGJSONCONFIGURATION", "original": "To ensure resource integrity, the Angular service worker validates \nthe hashes of all resources for which it has a hash. Typically for \na CLI app, this is everything in the `dist` directory covered by \nthe user's `src/ngsw-config.json` configuration.", "translation": "为了确保资源的整体性,Angular Service Worker 会验证所有带哈希的资源的哈希值。\n通常,对于 CLI 应用程序,用户的 `src/ngsw-config.json` 配置文件中会涵盖 `dist` 目录下的所有内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "IFAPARTICULARFILEFAILSVALIDATIONTHEANGULARSERVICEWORKERATTEMPTSTOREFETCHTHECONTENTUSINGACACHEBUSTINGURLPARAMETERTOELIMINATETHEEFFECTSOFBROWSERORINTERMEDIATECACHINGIFTHATCONTENTALSOFAILSVALIDATIONTHESERVICEWORKERCONSIDERSTHEENTIREVERSIONOFTHEAPPTOBEINVALIDANDITSTOPSSERVINGTHEAPPIFNECESSARYTHESERVICEWORKERENTERSASAFEMODEWHEREREQUESTSFALLBACKONTHENETWORKOPTINGNOTTOUSEITSCACHEIFTHERISKOFSERVINGINVALIDBROKENOROUTDATEDCONTENTISHIGH", "original": "If a particular file fails validation, the Angular service worker \nattempts to re-fetch the content using a \"cache-busting\" URL \nparameter to eliminate the effects of browser or intermediate \ncaching. If that content also fails validation, the service worker \nconsiders the entire version of the app to be invalid and it stops \nserving the app. If necessary, the service worker enters a safe mode \nwhere requests fall back on the network, opting not to use its cache \nif the risk of serving invalid, broken, or outdated content is high.", "translation": "如果某个特定的文件未能通过验证,Angular Service Worker 就会尝试用 “cache-busting” URL 为参数重新获取内容,以消除浏览器或中间缓存的影响。\n如果该内容也未能通过验证,则 Service Worker 会认为该应用的整个版本都无效,并停止用它提供服务。\n如有必要,Service Worker 会进入安全模式,这些请求将退化为直接访问网络。\n如果服务无效、损坏或内容过期的风险很高,则会选择不使用缓存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "HASHMISMATCHESCANOCCURFORAVARIETYOFREASONS:", "original": "Hash mismatches can occur for a variety of reasons:", "translation": "导致哈希值不匹配的原因有很多:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "CACHINGLAYERSINBETWEENTHEORIGINSERVERANDTHEENDUSERCOULDSERVESTALECONTENT", "original": "* Caching layers in between the origin server and the end user could serve stale content.", "translation": "在源服务器和最终用户之间缓存图层可能会提供陈旧的内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ANONATOMICDEPLOYMENTCOULDRESULTINTHEANGULARSERVICEWORKERHAVINGVISIBILITYOFPARTIALLYUPDATEDCONTENT", "original": "* A non-atomic deployment could result in the Angular service worker having visibility of partially updated content.", "translation": "非原子化的部署可能会导致 Angular Service Worker 看到部分更新后的内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ERRORSDURINGTHEBUILDPROCESSCOULDRESULTINUPDATEDRESOURCESWITHOUTNGSWJSONBEINGUPDATEDTHEREVERSECOULDALSOHAPPENRESULTINGINANUPDATEDNGSWJSONWITHOUTUPDATEDRESOURCES", "original": "* Errors during the build process could result in updated resources without `ngsw.json` being updated. The reverse could also happen resulting in an updated `ngsw.json` without updated resources.", "translation": "构建过程中的错误可能会导致更新了资源,却没有更新 `ngsw.json`。\n 反之,也可能发生没有更新资源,却更新了 `ngsw.json` 的情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####UNHASHEDCONTENT", "original": "#### Unhashed content", "translation": "#### 不带哈希的内容", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEONLYRESOURCESTHATHAVEHASHESINTHENGSWJSONMANIFESTARERESOURCESTHATWEREPRESENTINTHEDISTDIRECTORYATTHETIMETHEMANIFESTWASBUILTOTHERRESOURCESESPECIALLYTHOSELOADEDFROMCDNSHAVECONTENTTHATISUNKNOWNATBUILDTIMEORAREUPDATEDMOREFREQUENTLYTHANTHEAPPISDEPLOYED", "original": "The only resources that have hashes in the `ngsw.json` \nmanifest are resources that were present in the `dist` \ndirectory at the time the manifest was built. Other \nresources, especially those loaded from CDNs, have \ncontent that is unknown at build time or are updated \nmore frequently than the app is deployed.", "translation": "`ngsw.json` 清单中唯一带哈希值的资源就是构建清单时 `dist` 目录中的资源。\n而其他资源,特别是从 CDN 加载的资源,其内容在构建时是未知的,或者会比应用程序部署得更频繁。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "IFTHEANGULARSERVICEWORKERDOESNOTHAVEAHASHTOVALIDATEAGIVENRESOURCEITSTILLCACHESITSCONTENTSBUTITHONORSTHEHTTPCACHINGHEADERSBYUSINGAPOLICYOFSTALEWHILEREVALIDATETHATISWHENHTTPCACHINGHEADERSFORACACHEDRESOURCEINDICATETHATTHERESOURCEHASEXPIREDTHEANGULARSERVICEWORKERCONTINUESTOSERVETHECONTENTANDITATTEMPTSTOREFRESHTHERESOURCEINTHEBACKGROUNDTHISWAYBROKENUNHASHEDRESOURCESDONOTREMAININTHECACHEBEYONDTHEIRCONFIGUREDLIFETIMES", "original": "If the Angular service worker does not have a hash to validate \na given resource, it still caches its contents but it honors \nthe HTTP caching headers by using a policy of \"stale while \nrevalidate.\" That is, when HTTP caching headers for a cached \nresource indicate that the resource has expired, the Angular \nservice worker continues to serve the content and it attempts \nto refresh the resource in the background. This way, broken \nunhashed resources do not remain in the cache beyond their \nconfigured lifetimes.", "translation": "如果 Angular Service Worker 没有哈希可以验证给定的资源,它仍然会缓存它的内容,但会使用 “重新验证时失效” 的策略来承认HTTP缓存头。\n也就是说,当被缓存资源的 HTTP 缓存头指出该资源已过期时,Angular Service Worker 将继续提供内容,并尝试在后台刷新资源。\n这样,那些被破坏的非哈希资源留在缓存中的时间就不会超出为它配置的生命周期。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "###APPTABS", "original": "### App tabs", "translation": "### App 选项卡", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ITCANBEPROBLEMATICFORANAPPIFTHEVERSIONOFRESOURCESITSRECEIVINGCHANGESSUDDENLYORWITHOUTWARNINGSEETHEVERSIONSGUIDESERVICEWORKERDEVOPS#VERSIONSSECTIONABOVEFORADESCRIPTIONOFSUCHISSUES", "original": "It can be problematic for an app if the version of resources \nit's receiving changes suddenly or without warning. See the \n[Versions](guide/service-worker-devops#versions) section above \nfor a description of such issues.", "translation": "如果应用程序的资源版本突然发生了变化或没有给出警告,就可能会有问题。有关这些问题的描述,请参阅前面的 [版本](guide/service-worker-devops#versions) 部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEANGULARSERVICEWORKERPROVIDESAGUARANTEE:ARUNNINGAPPWILLCONTINUETORUNTHESAMEVERSIONOFTHEAPPIFANOTHERINSTANCEOFTHEAPPISOPENEDINANEWWEBBROWSERTABTHENTHEMOSTCURRENTVERSIONOFTHEAPPISSERVEDASARESULTTHATNEWTABCANBERUNNINGADIFFERENTVERSIONOFTHEAPPTHANTHEORIGINALTAB", "original": "The Angular service worker provides a guarantee: a running app \nwill continue to run the same version of the app. If another \ninstance of the app is opened in a new web browser tab, then \nthe most current version of the app is served. As a result, \nthat new tab can be running a different version of the app \nthan the original tab.", "translation": "Angular Service Worker 会保证:正在运行的应用程序会继续运行和当前应用相同的版本。\n而如果在新的 Web 浏览器选项卡中打开了该应用的另一个实例,则会提供该应用的最新版本。\n因此,这个新标签可以和原始标签同时运行不同版本的应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ITSIMPORTANTTONOTETHATTHISGUARANTEEISSTRONGERTHANTHATPROVIDEDBYTHENORMALWEBDEPLOYMENTMODELWITHOUTASERVICEWORKERTHEREISNOGUARANTEETHATCODELAZILYLOADEDLATERINARUNNINGAPPISFROMTHESAMEVERSIONASTHEINITIALCODEFORTHEAPP", "original": "It's important to note that this guarantee is **stronger** \nthan that provided by the normal web deployment model. Without \na service worker, there is no guarantee that code lazily loaded \nlater in a running app is from the same version as the initial \ncode for the app.", "translation": "值得注意的是,这种担保比普通的 Web 部署模型提供的担保还要**更强一点**。\n如果没有 Service Worker,则不能保证稍后在这个正在运行的应用中惰性加载的代码\n和其初始代码的版本是一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEREAREAFEWLIMITEDREASONSWHYTHEANGULARSERVICEWORKERMIGHTCHANGETHEVERSIONOFARUNNINGAPPSOMEOFTHEMAREERRORCONDITIONS:", "original": "There are a few limited reasons why the Angular service worker \nmight change the version of a running app. Some of them are \nerror conditions:", "translation": "Angular Service Worker 为什么可能会更改运行中的应用的版本有几个有限的原因。\n其中一些是因为出错了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THECURRENTVERSIONBECOMESINVALIDDUETOAFAILEDHASH", "original": "* The current version becomes invalid due to a failed hash.", "translation": "由于哈希验证失败,当前版本变成了无效的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ANUNRELATEDERRORCAUSESTHESERVICEWORKERTOENTERSAFEMODETHATISTEMPORARYDEACTIVATION", "original": "* An unrelated error causes the service worker to enter safe mode; that is, temporary deactivation.", "translation": "某个无关的错误导致 Service Worker 进入了安全模式,或者说,它被暂时禁用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEANGULARSERVICEWORKERISAWAREOFWHICHVERSIONSAREINUSEATANYGIVENMOMENTANDITCLEANSUPVERSIONSWHENNOTABISUSINGTHEM", "original": "The Angular service worker is aware of which versions are in \nuse at any given moment and it cleans up versions when \nno tab is using them.", "translation": "Angular Service Worker 能知道在任何指定的时刻正在使用哪些版本,\n并清除那些没有被任何选项卡使用的版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "OTHERREASONSTHEANGULARSERVICEWORKERMIGHTCHANGETHEVERSIONOFARUNNINGAPPARENORMALEVENTS:", "original": "Other reasons the Angular service worker might change the version \nof a running app are normal events:", "translation": "另一些可能导致 Angular Service Worker 在运行期间改变版本的因素是一些正常事件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEPAGEISRELOADEDREFRESHED", "original": "* The page is reloaded/refreshed.", "translation": "页面被重新加载/刷新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEPAGEREQUESTSANUPDATEBEIMMEDIATELYACTIVATEDVIATHESWUPDATESERVICE", "original": "* The page requests an update be immediately activated via the `SwUpdate` service.", "translation": "该页面通过 `SwUpdate` 服务请求立即激活这个更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "###SERVICEWORKERUPDATES", "original": "### Service worker updates", "translation": "### Service Worker 更新", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEANGULARSERVICEWORKERISASMALLSCRIPTTHATRUNSINWEBBROWSERSFROMTIMETOTIMETHESERVICEWORKERWILLBEUPDATEDWITHBUGFIXESANDFEATUREIMPROVEMENTS", "original": "The Angular service worker is a small script that runs in web browsers. \nFrom time to time, the service worker will be updated with bug \nfixes and feature improvements.", "translation": "Angular Service Worker 是一个运行在Web浏览器中的小脚本。\n有时,这个 Service Worker 也可能会需要更新,以修复错误和增强特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEANGULARSERVICEWORKERISDOWNLOADEDWHENTHEAPPISFIRSTOPENEDANDWHENTHEAPPISACCESSEDAFTERAPERIODOFINACTIVITYIFTHESERVICEWORKERHASCHANGEDTHESERVICEWORKERWILLBEUPDATEDINTHEBACKGROUND", "original": "The Angular service worker is downloaded when the app is first opened \nand when the app is accessed after a period of inactivity. If the \nservice worker has changed, the service worker will be updated in the background.", "translation": "首次打开应用时或在一段非活动时间之后再访问应用程序时,就会下载 Angular Service Worker。 如果 Service Worker 发生了变化,Service Worker 就会在后台进行更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "MOSTUPDATESTOTHEANGULARSERVICEWORKERARETRANSPARENTTOTHEAPPMDASHTHEOLDCACHESARESTILLVALIDANDCONTENTISSTILLSERVEDNORMALLYHOWEVEROCCASIONALLYABUGFIXORFEATUREINTHEANGULARSERVICEWORKERREQUIRESTHEINVALIDATIONOFOLDCACHESINTHISCASETHEAPPWILLBEREFRESHEDTRANSPARENTLYFROMTHENETWORK", "original": "Most updates to the Angular service worker are transparent to the \napp—the old caches are still valid and content is still served \nnormally. However, occasionally a bugfix or feature in the Angular \nservice worker requires the invalidation of old caches. In this case, \nthe app will be refreshed transparently from the network.", "translation": "Angular Service Worker 的大部分更新对应用程序来说都是透明的 - 旧缓存仍然有效,其内容仍然能正常使用。\n但是,在 Angular Service Worker 中可能偶尔会有错误修复或新功能,需要让旧的缓存失效。\n这时,应用程序就从会网络上透明地进行刷新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "##DEBUGGINGTHEANGULARSERVICEWORKER", "original": "## Debugging the Angular service worker", "translation": "## 调试 Angular Service Worker", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "OCCASIONALLYITMAYBENECESSARYTOEXAMINETHEANGULARSERVICEWORKERINARUNNINGSTATETOINVESTIGATEISSUESORTOENSURETHATITISOPERATINGASDESIGNEDBROWSERSPROVIDEBUILTINTOOLSFORDEBUGGINGSERVICEWORKERSANDTHEANGULARSERVICEWORKERITSELFINCLUDESUSEFULDEBUGGINGFEATURES", "original": "Occasionally, it may be necessary to examine the Angular service \nworker in a running state to investigate issues or to ensure that \nit is operating as designed. Browsers provide built-in tools for \ndebugging service workers and the Angular service worker itself \nincludes useful debugging features.", "translation": "偶尔,可能会需要检查运行中的 Angular Service Worker,以调查问题或确保它在按设计运行。\n浏览器提供了用于调试 Service Worker 的内置工具,而且 Angular Service Worker 本身也包含了一些有用的调试功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "###LOCATINGANDANALYZINGDEBUGGINGINFORMATION", "original": "### Locating and analyzing debugging information", "translation": "### 定位并分析调试信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEANGULARSERVICEWORKEREXPOSESDEBUGGINGINFORMATIONUNDERTHENGSWVIRTUALDIRECTORYCURRENTLYTHESINGLEEXPOSEDURLISNGSWSTATEHEREISANEXAMPLEOFTHISDEBUGPAGESCONTENTS:", "original": "The Angular service worker exposes debugging information under \nthe `ngsw/` virtual directory. Currently, the single exposed URL \nis `ngsw/state`. Here is an example of this debug page's contents:", "translation": "Angular Service Worker 会在虚拟目录 `ngsw/` 下暴露出调试信息。\n目前,它暴露的唯一的 URL 是 `ngsw/state`。\n下面是这个调试页面中的一段范例内容:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####DRIVERSTATE", "original": "#### Driver state", "translation": "#### 驱动程序的状态", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEFIRSTLINEINDICATESTHEDRIVERSTATE:", "original": "The first line indicates the driver state:", "translation": "第一行表示驱动程序的状态:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "NORMALINDICATESTHATTHESERVICEWORKERISOPERATINGNORMALLYANDISNOTINADEGRADEDSTATE", "original": "`NORMAL` indicates that the service worker is operating normally and is not in a degraded state.", "translation": "`NORMAL` 表示这个 Service Worker 正在正常运行,并且没有处于降级运行的状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEREARETWOPOSSIBLEDEGRADEDSTATES:", "original": "There are two possible degraded states:", "translation": "有两种可能的降级状态:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "EXISTINGCLIENTSONLY:THESERVICEWORKERDOESNOTHAVEACLEANCOPYOFTHELATESTKNOWNVERSIONOFTHEAPPOLDERCACHEDVERSIONSARESAFETOUSESOEXISTINGTABSCONTINUETORUNFROMCACHEBUTNEWLOADSOFTHEAPPWILLBESERVEDFROMTHENETWORK", "original": "* `EXISTING_CLIENTS_ONLY`: the service worker does not have a \nclean copy of the latest known version of the app. Older cached \nversions are safe to use, so existing tabs continue to run from \ncache, but new loads of the app will be served from the network.", "translation": "`EXISTING_CLIENTS_ONLY`:这个 Service Worker 没有该应用的最新已知版本的干净副本。\n 较旧的缓存版本可以被安全的使用,所以现有的选项卡将继续使用较旧的版本运行本应用,\n 但新的应用将从网络上加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "SAFEMODE:THESERVICEWORKERCANNOTGUARANTEETHESAFETYOFUSINGCACHEDDATAEITHERANUNEXPECTEDERROROCCURREDORALLCACHEDVERSIONSAREINVALIDALLTRAFFICWILLBESERVEDFROMTHENETWORKRUNNINGASLITTLESERVICEWORKERCODEASPOSSIBLE", "original": "* `SAFE_MODE`: the service worker cannot guarantee the safety of \nusing cached data. Either an unexpected error occurred or all \ncached versions are invalid. All traffic will be served from the \nnetwork, running as little service worker code as possible.", "translation": "`SAFE_MODE`:Service Worker 不能保证使用缓存数据的安全性。\n 发生了意外错误或所有缓存版本都无效。\n 这时所有的流量都将从网络提供,尽量少运行 Service Worker 中的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "INBOTHCASESTHEPARENTHETICALANNOTATIONPROVIDESTHEERRORTHATCAUSEDTHESERVICEWORKERTOENTERTHEDEGRADEDSTATE", "original": "In both cases, the parenthetical annotation provides the \nerror that caused the service worker to enter the degraded state.", "translation": "在这两种情况下,后面的括号注解中都会提供导致 Service Worker 进入降级状态的错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####LATESTMANIFESTHASH", "original": "#### Latest manifest hash", "translation": "#### 最新清单的哈希", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THISISTHESHA1HASHOFTHEMOSTUPTODATEVERSIONOFTHEAPPTHATTHESERVICEWORKERKNOWSABOUT", "original": "This is the SHA1 hash of the most up-to-date version of the app that the service worker knows about.", "translation": "这是 Service Worker 所知道的应用最新版本的 SHA1 哈希值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####LASTUPDATECHECK", "original": "#### Last update check", "translation": "#### 最后一次更新检查", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THISINDICATESTHELASTTIMETHESERVICEWORKERCHECKEDFORANEWVERSIONORUPDATEOFTHEAPPNEVERINDICATESTHATTHESERVICEWORKERHASNEVERCHECKEDFORANUPDATE", "original": "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.", "translation": "这表示 Service Worker 最后一次检查应用程序的新版本或更新的时间。“never” 表示 Service Worker 从未检查过更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "INTHISEXAMPLEDEBUGFILETHEUPDATECHECKISCURRENTLYSCHEDULEDASEXPLAINEDTHENEXTSECTION", "original": "In this example debug file, the update check is currently scheduled, as explained the next section.", "translation": "在这个调试文件范例中,这次更新检查目前是已排期的,如下一节所述。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####VERSION", "original": "#### Version", "translation": "#### 版本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "INTHISEXAMPLETHESERVICEWORKERHASONEVERSIONOFTHEAPPCACHEDANDBEINGUSEDTOSERVETWODIFFERENTTABSNOTETHATTHISVERSIONHASHISTHELATESTMANIFESTHASHLISTEDABOVEBOTHCLIENTSAREONTHELATESTVERSIONEACHCLIENTISLISTEDBYITSIDFROMTHECLIENTSAPIINTHEBROWSER", "original": "In this example, the service worker has one version of the app cached and \nbeing used to serve two different tabs. Note that this version hash \nis the \"latest manifest hash\" listed above. Both clients are on the \nlatest version. Each client is listed by its ID from the `Clients` \nAPI in the browser.", "translation": "在这个例子中,Service Worker 拥有一个版本的应用程序缓存并用它服务于两个不同的选项卡。\n请注意,这个版本哈希值是上面列出的“最新清单的哈希”。\n它的两个客户运行的都是最新版本。每个客户都用浏览器中 `Clients` API的 ID 列了出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####IDLETASKQUEUE", "original": "#### Idle task queue", "translation": "#### 空闲任务队列", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THEIDLETASKQUEUEISTHEQUEUEOFALLPENDINGTASKSTHATHAPPENINTHEBACKGROUNDINTHESERVICEWORKERIFTHEREAREANYTASKSINTHEQUEUETHEYARELISTEDWITHADESCRIPTIONINTHISEXAMPLETHESERVICEWORKERHASONESUCHTASKSCHEDULEDAPOSTINITIALIZATIONOPERATIONINVOLVINGANUPDATECHECKANDCLEANUPOFSTALECACHES", "original": "The Idle Task Queue is the queue of all pending tasks that happen \nin the background in the service worker. If there are any tasks \nin the queue, they are listed with a description. In this example, \nthe service worker has one such task scheduled, a post-initialization \noperation involving an update check and cleanup of stale caches.", "translation": "空闲任务队列是 Service Worker 中所有在后台发生的未决任务的队列。\n如果这个队列中存在任何任务,则列出它们的描述。\n在这个例子中,Service Worker 安排的任务是一个用于更新检查和清除过期缓存的后期初始化操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THELASTUPDATETICKRUNCOUNTERSGIVETHETIMESINCESPECIFICEVENTSHAPPENEDRELATEDTOTHEIDLEQUEUETHELASTUPDATERUNCOUNTERSHOWSTHELASTTIMEIDLETASKSWEREACTUALLYEXECUTEDLASTUPDATETICKSHOWSTHETIMESINCETHELASTEVENTAFTERWHICHTHEQUEUEMIGHTBEPROCESSED", "original": "The last update tick/run counters give the time since specific \nevents happened related to the idle queue. The \"Last update run\" \ncounter shows the last time idle tasks were actually executed. \n\"Last update tick\" shows the time since the last event after \nwhich the queue might be processed.", "translation": "最后的 tick/run 计数器给出了与特定事件发生有关的空闲队列中的时间。\n“Last update run” 计数器显示的是上次执行空闲任务的时间。\n“Last update tick” 显示的是自上次事件以来可能要处理的队列的时间。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "####DEBUGLOG", "original": "#### Debug log", "translation": "#### 调试日志", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ERRORSTHATOCCURWITHINTHESERVICEWORKERWILLBELOGGEDHERE", "original": "Errors that occur within the service worker will be logged here.", "translation": "在 Service Worker 中出现的任何错误都会记录在这里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "###DEVELOPERTOOLS", "original": "### Developer Tools", "translation": "### 开发者工具", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "BROWSERSSUCHASCHROMEPROVIDEDEVELOPERTOOLSFORINTERACTINGWITHSERVICEWORKERSSUCHTOOLSCANBEPOWERFULWHENUSEDPROPERLYBUTTHEREAREAFEWTHINGSTOKEEPINMIND", "original": "Browsers such as Chrome provide developer tools for interacting \nwith service workers. Such tools can be powerful when used properly, \nbut there are a few things to keep in mind.", "translation": "Chrome 等浏览器提供了能与 Service Worker 交互的开发者工具。\n这些工具在使用得当时非常强大,但也要牢记一些事情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "WHENUSINGDEVELOPERTOOLSTHESERVICEWORKERISKEPTRUNNINGINTHEBACKGROUNDANDNEVERRESTARTSTHISCANCAUSEBEHAVIORWITHDEVTOOLSOPENTODIFFERFROMBEHAVIORAUSERMIGHTEXPERIENCE", "original": "* When using developer tools, the service worker is kept running \nin the background and never restarts. This can cause behavior with Dev\nTools open to differ from behavior a user might experience.", "translation": "使用开发人员工具时,Service Worker 将继续在后台运行,并且不会重新启动。\n 这可能会导致开着 Dev Tools 时的行为与用户实际遇到的行为不一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "IFYOULOOKINTHECACHESTORAGEVIEWERTHECACHEISFREQUENTLYOUTOFDATERIGHTCLICKTHECACHESTORAGETITLEANDREFRESHTHECACHES", "original": "* If you look in the Cache Storage viewer, the cache is frequently \nout of date. Right click the Cache Storage title and refresh the caches.", "translation": "如果你查看缓存存储器的查看器,缓存就会经常过期。右键单击缓存存储器的标题并刷新缓存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "STOPPINGANDSTARTINGTHESERVICEWORKERINTHESERVICEWORKERPANETRIGGERSACHECKFORUPDATES", "original": "Stopping and starting the service worker in the Service Worker \npane triggers a check for updates.", "translation": "在 Service Worker 页停止并重新启动这个 Service Worker 将会触发一次更新检查。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "##SERVICEWORKERSAFETY", "original": "## Service Worker Safety", "translation": "## Service Worker 的安全性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "LIKEANYCOMPLEXSYSTEMBUGSORBROKENCONFIGURATIONSCANCAUSETHEANGULARSERVICEWORKERTOACTINUNFORESEENWAYSWHILEITSDESIGNATTEMPTSTOMINIMIZETHEIMPACTOFSUCHPROBLEMSTHEANGULARSERVICEWORKERCONTAINSSEVERALFAILSAFEMECHANISMSINCASEANADMINISTRATOREVERNEEDSTODEACTIVATETHESERVICEWORKERQUICKLY", "original": "Like any complex system, bugs or broken configurations can cause \nthe Angular service worker to act in unforeseen ways. While its \ndesign attempts to minimize the impact of such problems, the \nAngular service worker contains several failsafe mechanisms in case \nan administrator ever needs to deactivate the service worker quickly.", "translation": "像任何复杂的系统一样,错误或损坏的配置可能会导致 Angular Service Worker 以不可预知的方式工作。\n虽然它在设计时就尝试将此类问题的影响降至最低,但是,如果管理员需要快速停用 Service Worker,\nAngular Service Worker 也包含多种故障保护机制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "##FAILSAFE", "original": "## Fail-safe", "translation": "## 故障保护机制", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "TODEACTIVATETHESERVICEWORKERREMOVEORRENAMETHENGSWCONFIGJSONFILEWHENTHESERVICEWORKERSREQUESTFORNGSWJSONRETURNSA404THENTHESERVICEWORKERREMOVESALLOFITSCACHESANDDEREGISTERSITSELFESSENTIALLYSELFDESTRUCTING", "original": "To deactivate the service worker, remove or rename the \n`ngsw-config.json` file. When the service worker's request \nfor `ngsw.json` returns a `404`, then the service worker \nremoves all of its caches and de-registers itself, \nessentially self-destructing.", "translation": "要停用 Service Worker,请删除或重命名 `ngsw-config.json` 文件。\n当 Service Worker 对 `ngsw.json` 的请求返回 `404` 时,Service Worker 就会删除它的所有缓存并注销自己,本质上就是自毁。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ALSOINCLUDEDINTHEANGULARSERVICEWORKERNPMPACKAGEISASMALLSCRIPTSAFETYWORKERJSWHICHWHENLOADEDWILLUNREGISTERITSELFFROMTHEBROWSERTHISSCRIPTCANBEUSEDASALASTRESORTTOGETRIDOFUNWANTEDSERVICEWORKERSALREADYINSTALLEDONCLIENTPAGES", "original": "Also included in the `@angular/service-worker` NPM package is a small\nscript `safety-worker.js`, which when loaded will unregister itself\nfrom the browser. This script can be used as a last resort to get rid\nof unwanted service workers already installed on client pages.", "translation": "`@angular/service-worker` NPM 包中还包含一个小脚本`safety-worker.js`,当它被加载时就会把它自己从浏览器中注销。\n这个脚本可以作为终极武器来摆脱那些已经安装在客户端页面上的不想要的 Service Worker。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "ITSIMPORTANTTONOTETHATYOUCANNOTREGISTERTHISWORKERDIRECTLYASOLDCLIENTSWITHCACHEDSTATEMAYNOTSEEANEWINDEXHTMLWHICHINSTALLSTHEDIFFERENTWORKERSCRIPTINSTEADYOUMUSTSERVETHECONTENTSOFSAFETYWORKERJSATTHEURLOFTHESERVICEWORKERSCRIPTYOUARETRYINGTOUNREGISTERANDMUSTCONTINUETODOSOUNTILYOUARECERTAINALLUSERSHAVESUCCESSFULLYUNREGISTEREDTHEOLDWORKERFORMOSTSITESTHISMEANSTHATYOUSHOULDSERVETHESAFETYWORKERATTHEOLDSERVICEWORKERURLFOREVER", "original": "It's important to note that you cannot register this worker directly,\nas old clients with cached state may not see a new `index.html` which\ninstalls the different worker script. Instead, you must serve the\ncontents of `safety-worker.js` at the URL of the Service Worker script\nyou are trying to unregister, and must continue to do so until you are\ncertain all users have successfully unregistered the old worker. For\nmost sites, this means that you should serve the safety worker at the\nold Service Worker URL forever.", "translation": "要特别注意的是,你不能直接注册这个 Safety Worker,因为具有已缓存状态的旧客户端可能无法看到一个新的、用来安装 另一个 worker 脚本的 `index.html`。\n相反,你必须在想要注销的 Service Worker 脚本的 URL 中提供 `safety-worker.js` 的内容,\n而且必须持续这样做,直到确定所有用户都已成功注销了原有的 Worker。\n对大多数网站而言,这意味着你应该永远为旧的 Service Worker URL 提供 这个 Safety Worker。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "THISSCRIPTCANBEUSEDBOTHTODEACTIVATEANGULARSERVICEWORKERASWELLASANYOTHERSERVICEWORKERSWHICHMIGHTHAVEBEENSERVEDINTHEPASTONYOURSITE", "original": "This script can be used both to deactivate `@angular/service-worker`\nas well as any other Service Workers which might have been served in\nthe past on your site.", "translation": "这个脚本可以用来停用 `@angular/service-worker` 以及任何其它以前在你的站点上提供过的 Service Worker。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "##MOREONANGULARSERVICEWORKERS", "original": "## More on Angular service workers", - "translation": "## 关于 Angular Service Worker 的更多知识", + "translation": "## 关于 Angular Service Worker 的更多信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", - "translation": "你可能对下列内容感兴趣:", + "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "SERVICEWORKERCONFIGURATIONGUIDESERVICEWORKERCONFIG", "original": "* [Service Worker Configuration](guide/service-worker-config).", - "translation": "[Service Worker 配置](guide/service-worker-config).", + "translation": "[Service Worker 配置](guide/service-worker-config)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-devops.md" }, { + "key": "#GETTINGSTARTEDWITHSERVICEWORKERS", "original": "# Getting started with service workers", "translation": "# Service Worker 快速起步", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWING:", "original": "A basic understanding of the following:", "translation": "对下列知识有基本的了解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "INTRODUCTIONTOANGULARSERVICEWORKERSGUIDESERVICEWORKERINTRO", "original": "* [Introduction to Angular service workers](guide/service-worker-intro).", "translation": "[Angular Service Worker 简介](guide/service-worker-intro).", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "BEGINNINGINANGULAR500YOUCANEASILYENABLEANGULARSERVICEWORKERSUPPORTINANYCLIPROJECTTHISDOCUMENTEXPLAINSHOWTOENABLEANGULARSERVICEWORKERSUPPORTINNEWANDEXISTINGPROJECTSITTHENUSESASIMPLEEXAMPLETOSHOWYOUASERVICEWORKERINACTIONDEMONSTRATINGLOADINGANDBASICCACHING", "original": "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.", "translation": "从 Angular 5.0.0 开始,你就可以轻松为任何 CLI 项目启用 Angular Service Worker 的支持了。\n这个文档解释了你要如何在新项目和现有项目中启用 Angular Service Worker 的支持。\n然后使用一个简单的例子为你展示 Service Worker 实战,以演示加载和基本的缓存功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "##ADDINGASERVICEWORKERTOANEWAPPLICATION", "original": "## Adding a service worker to a new application", "translation": "## 为新项目添加 Service Worker", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "IFYOUREGENERATINGANEWCLIPROJECTYOUCANUSETHECLITOSETUPTHEANGULARSERVICEWORKERASPARTOFCREATINGTHEPROJECTTODOSOADDTHESERVICEWORKERFLAGTOTHENGNEWCOMMAND:", "original": "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:", "translation": "如果你正在生成一个新的 CLI 项目,可以 使用 CLI 在创建项目时就准备好 Angular Service Worker。\n只要在 `ng new` 命令中添加 `--service-worker` 标志就可以了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "THESERVICEWORKERFLAGTAKESCAREOFCONFIGURINGYOURAPPTOUSESERVICEWORKERSBYADDINGTHESERVICEWORKERPACKAGEALONGWITHSETTINGUPTHENECESSARYFILESTOSUPPORTSERVICEWORKERSFORINFORMATIONONTHEDETAILSSEETHEFOLLOWINGSECTIONWHICHCOVERSTHEPROCESSINDETAILASITSHOWSYOUHOWTOADDASERVICEWORKERMANUALLYTOANEXISTINGAPP", "original": "The `--service-worker` flag takes care of configuring your app to \nuse service workers by adding the `service-worker` package along \nwith setting up the necessary files to support service workers. \nFor information on the details, see the following section \nwhich covers the process in detail as it shows you how to add a \nservice worker manually to an existing app.", "translation": "`--service-worker` 标志会通过添加 `service-worker` 包及其它必须的文件,来帮你配置好 Service Worker。\n这个过程的细节和向现有项目中手动添加 Service Worker 的支持是一样的。要了解详情,参见下面的部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "##ADDINGASERVICEWORKERTOANEXISTINGAPP", "original": "## Adding a service worker to an existing app", "translation": "## 向现有工程中添加 Service Worker", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "TOADDASERVICEWORKERTOANEXISTINGAPP:", "original": "To add a service worker to an existing app:", "translation": "要把 Service Worker 添加到现有应用中,就要:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "1ADDTHESERVICEWORKERPACKAGE", "original": "1. Add the service worker package.", "translation": "添加 Service Worker 包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "2ENABLESERVICEWORKERBUILDSUPPORTINTHECLI", "original": "2. Enable service worker build support in the CLI.", "translation": "在 CLI 中启用 Service Worker 的构建支持。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "3IMPORTANDREGISTERTHESERVICEWORKER", "original": "3. Import and register the service worker.", "translation": "导入并注册这个 Service Worker。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "4CREATETHESERVICEWORKERCONFIGURATIONFILEWHICHSPECIFIESTHECACHINGBEHAVIORSANDOTHERSETTINGS", "original": "4. Create the service worker configuration file, which specifies the caching behaviors and other settings.", "translation": "创建 Service Worker 的配置文件,它指定了缓存行为和其它设置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "5BUILDTHEPROJECT", "original": "5. Build the project.", "translation": "构建该项目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###STEP1:ADDTHESERVICEWORKERPACKAGE", "original": "### Step 1: Add the service worker package", "translation": "### 步骤 1:添加 Service Worker 包", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "ADDTHEPACKAGEANGULARSERVICEWORKERUSINGTHEYARNUTILITYASSHOWNHERE:", "original": "Add the package `@angular/service-worker`, using the yarn utility as shown here:", "translation": "添加 `@angular/service-worker` 包,使用 yarn 工具时的用法如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###STEP2:ENABLESERVICEWORKERBUILDSUPPORTINTHECLI", "original": "### Step 2: Enable service worker build support in the CLI", "translation": "### 步骤 2:在 CLI 中启用 Service Worker 的构建支持", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "TOENABLETHEANGULARSERVICEWORKERTHECLIMUSTGENERATEANANGULARSERVICEWORKERMANIFESTATBUILDTIMETOCAUSETHECLITOGENERATETHEMANIFESTFORANEXISTINGPROJECTSETTHESERVICEWORKERFLAGTOTRUEINTHEPROJECTSANGULARCLIJSONFILEASSHOWNHERE:", "original": "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:", "translation": "要启用 Angular Service Worker,CLI 必须在构建时生成一个 Angular Service Worker 的 `manifest` 文件。\n要让 CLI 为现有项目生成 `manifest`,就要在该项目的 `.angular-cli.json` 文件中 `serviceWorker` 标识设置为 `true`。命令如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###STEP3:IMPORTANDREGISTERTHESERVICEWORKER", "original": "### Step 3: Import and register the service worker", "translation": "### 步骤 3:导入并注册 Service Worker", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "TOIMPORTANDREGISTERTHEANGULARSERVICEWORKER:", "original": "To import and register the Angular service worker:", "translation": "要导入并注册 Angular Service Worker 就要:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "ATTHETOPOFTHEROOTMODULESRCAPPAPPMODULETSIMPORTSERVICEWORKERMODULEANDENVIRONMENT", "original": "At the top of the root module, `src/app/app.module.ts`, import `ServiceWorkerModule` and `environment`.", "translation": "在根模块 `src/app/app.module.ts` 的顶部导入 `ServiceWorkerModule` 和 `environment`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "ADDSERVICEWORKERMODULETOTHENGMODULEIMPORTSARRAYUSETHEREGISTERHELPERTOTAKECAREOFREGISTERINGTHESERVICEWORKERTAKINGCARETODISABLETHESERVICEWORKERWHENNOTRUNNINGINPRODUCTIONMODE", "original": "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.", - "translation": "把 `ServiceWorkerModule` 添加到 `@NgModule` 的 `imports` 数组中。使用 `register()` 来帮助管理 Service Worker 的注册并在非产品环境下运行时禁用 Service Worker。", + "translation": "把 `ServiceWorkerModule` 添加到 `@NgModule` 的 `imports` 数组中。使用 `register()` 来帮助管理 Service Worker 的注册并在非生产环境下运行时禁用 Service Worker。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "THEFILENGSWWORKERJSISTHENAMEOFTHEPREBUILTSERVICEWORKERSCRIPTWHICHTHECLICOPIESINTODISTTODEPLOYALONGWITHYOURSERVER", "original": "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.", "translation": "`ngsw-worker.js` 文件是内置的 Service Worker 脚本的名字,CLI 会把它复制到 `dist/` 目录下,让它随你的服务器一起发布。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###STEP4:CREATETHECONFIGURATIONFILENGSWCONFIGJSON", "original": "### Step 4: Create the configuration file, `ngsw-config.json`", "translation": "### 步骤 4:创建配置文件 `ngsw-config.json`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "THEANGULARCLINEEDSASERVICEWORKERCONFIGURATIONFILECALLEDNGSWCONFIGJSONTHECONFIGURATIONFILECONTROLSHOWTHESERVICEWORKERCACHESFILESANDDATARESOURCES", "original": "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 \nresources.", "translation": "Angular CLI 需要一个名叫 `ngsw-config.json` 的 Service Worker 配置文件。\n这个配置文件会控制 Service Worker 如何缓存各个文件和数据资源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "YOUCANBEGINWITHTHEBOILERPLATEVERSIONFROMTHECLIWHICHCONFIGURESSENSIBLEDEFAULTSFORMOSTAPPLICATIONS", "original": "You can begin with the boilerplate version from the CLI, which configures sensible defaults for most applications.", "translation": "你可以从 CLI 创建的样板项目开始,它已经配置好了适合大多数应用的默认选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "ALTERNATELYSAVETHEFOLLOWINGASSRCNGSWCONFIGJSON:", "original": "Alternately, save the following as `src/ngsw-config.json`:", "translation": "另外,你也可以把下列内容保存为 `src/ngsw-config.json`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###STEP5:BUILDTHEPROJECT", "original": "### Step 5: Build the project", "translation": "### 步骤 5:构建本项目", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "FINALLYBUILDTHEPROJECT:", "original": "Finally, build the project:", "translation": "最后,构建本项目:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "THECLIPROJECTISNOWSETUPTOUSETHEANGULARSERVICEWORKER", "original": "The CLI project is now set up to use the Angular service worker.", "translation": "现在,这个 CLI 项目就可以使用 Angular Service Worker 了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "##SERVICEWORKERINACTION:ATOUR", "original": "## Service worker in action: a tour", "translation": "## Service Worker 实战:向导", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "THISSECTIONDEMONSTRATESASERVICEWORKERINACTIONUSINGANEXAMPLEAPPLICATION", "original": "This section demonstrates a service worker in action, \nusing an example application.", "translation": "本节用一个范例应用来演示一下 Service Worker 实战。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###SERVINGWITHHTTPSERVER", "original": "### Serving with `http-server`", "translation": "### 用 `http-server` 启动开发服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "BECAUSENGSERVEDOESNOTWORKWITHSERVICEWORKERSYOUMUSTUSEASEPERATEHTTPSERVERTOTESTYOURPROJECTLOCALLYYOUCANUSEANYHTTPSERVERTHEEXAMPLEBELOWUSESTHEHTTPSERVERHTTPS:WWWNPMJSCOMPACKAGEHTTPSERVERPACKAGEFROMNPMTOREDUCETHEPOSSIBILITYOFCONFLICTSTESTONADEDICATEDPORT", "original": "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.", "translation": "由于 `ng serve` 对 Service Worker 无效,所以必须用一个独立的 HTTP 服务器在本地测试你的项目。\n你可以使用任何 HTTP 服务器。下面这个例子使用来自 npm 中的 [http-server](https://www.npmjs.com/package/http-server) 包。\n为了减小端口冲突的可能性,我们在一个专用端口上进行测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "TOSERVEWITHHTTPSERVERCHANGETOTHEDIRECTORYCONTAININGYOURWEBFILESANDSTARTTHEWEBSERVER:", "original": "To serve with `http-server`, change to the directory containing your web files and start the web server:", "translation": "要想使用 `http-server` 服务器,进入包含这些 web 文件的目录,并启动开发服务器:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###INITIALLOAD", "original": "### Initial load", "translation": "### 最初的加载", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "WITHTHESERVERRUNNINGYOUCANPOINTYOURBROWSERATHTTP:LOCALHOST:8080YOURAPPLICATIONSHOULDLOADNORMALLY", "original": "With the server running, you can point your browser at http://localhost:8080/. Your application should load normally.", "translation": "在服务器运行起来之后,你可以在浏览器中访问 http://localhost:8080/。你的应用像通常一样加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "TIP:WHENTESTINGANGULARSERVICEWORKERSITSAGOODIDEATOUSEANINCOGNITOORPRIVATEWINDOWINYOURBROWSERTOENSURETHESERVICEWORKERDOESNTENDUPREADINGFROMAPREVIOUSLEFTOVERSTATEWHICHCANCAUSEUNEXPECTEDBEHAVIOR", "original": "**Tip:** When testing Angular service workers, it's a good idea to use an incognito or private window in your browser to ensure the service worker doesn't end up reading from a previous leftover state, which can cause unexpected behavior.", "translation": "**提示:** 当测试 Angular Service Worker 时,最好使用浏览器中的隐身或隐私窗口,以确保 Service Worker 不会从以前的残留状态中读取数据,否则可能导致意外的行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###SIMULATINGANETWORKISSUE", "original": "### Simulating a network issue", "translation": "### 模拟网络出问题", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "TOSIMULATEANETWORKISSUEDISABLENETWORKINTERACTIONFORYOURAPPLICATIONINCHROME:", "original": "To simulate a network issue, disable network interaction for your application. In Chrome:", "translation": "要想模拟网络出问题的情况,可以为你的应用禁用网络交互。在 Chrome 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "1SELECTTOOLSDEVELOPERTOOLSFROMTHECHROMEMENULOCATEDATTHETOPRIGHTCORNER", "original": "1. Select **Tools** > **Developer Tools** (from the Chrome menu located at the top right corner).", "translation": "选择 **Tools** > **Developer Tools** (从右上角的 Chrome 菜单)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "2GOTOTHENETWORKTAB", "original": "2. Go to the **Network tab**.", "translation": "进入 **Network 页**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "3CHECKTHEOFFLINEBOX", "original": "3. Check the **Offline box**.", "translation": "勾选 **Offline** 复选框。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "NOWTHEAPPHASNOACCESSTONETWORKINTERACTION", "original": "Now the app has no access to network interaction.", "translation": "现在,本应用不能再和网络进行交互了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "FORAPPLICATIONSTHATDONOTUSETHEANGULARSERVICEWORKERREFRESHINGNOWWOULDDISPLAYCHROMESINTERNETDISCONNECTEDPAGETHATSAYSTHEREISNOINTERNETCONNECTION", "original": "For applications that do not use the Angular service worker, refreshing now would display Chrome's Internet disconnected page that says \"There is no Internet connection\".", "translation": "对于那些不使用 Angular Service Worker 的应用,现在刷新将会显示 Chrome 的“网络中断”页,提示“没有可用的网络连接”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "WITHTHEADDITIONOFANANGULARSERVICEWORKERTHEAPPLICATIONBEHAVIORCHANGESONAREFRESHTHEPAGELOADSNORMALLY", "original": "With the addition of an Angular service worker, the application behavior changes. On a refresh, the page loads normally.", "translation": "有了 Angular Service Worker,本应用的行为就不一样了。刷新时,页面会正常加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "IFYOULOOKATTHENETWORKTABYOUCANVERIFYTHATTHESERVICEWORKERISACTIVE", "original": "If you look at the Network tab, you can verify that the service worker is active.", "translation": "如果你看看 Network 页,就会发现 Service Worker 是激活的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "NOTICETHATUNDERTHESIZECOLUMNTHEREQUESTSSTATEISFROMSERVICEWORKERTHISMEANSTHATTHERESOURCESARENOTBEINGLOADEDFROMTHENETWORKINSTEADTHEYAREBEINGLOADEDFROMTHESERVICEWORKERSCACHE", "original": "Notice that under the \"Size\" column, the requests state is `(from ServiceWorker)`. This means that the resources are not being loaded from the network. Instead, they are being loaded from the service worker's cache.", "translation": "注意,在 “Size” 列中,请求的状态是 `(from ServiceWorker)`。\n这表示该资源不是从网络上加载的,而是从 Service Worker 的缓存中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###WHATSBEINGCACHED", "original": "### What's being cached?", "translation": "### 什么被缓存了?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "NOTICETHATALLOFTHEFILESTHEBROWSERNEEDSTORENDERTHISAPPLICATIONARECACHEDTHENGSWCONFIGJSONBOILERPLATECONFIGURATIONISSETUPTOCACHETHESPECIFICRESOURCESUSEDBYTHECLI:", "original": "Notice that all of the files the browser needs to render this application are cached. The `ngsw-config.json` boilerplate configuration is set up to cache the specific resources used by the CLI:", "translation": "注意,浏览器要渲染的所有这些文件都被缓存了。\n`ngsw-config.json` 样板文件被配置成了要缓存 CLI 用到的那些文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "BUILDARTIFACTSJSANDCSSBUNDLES", "original": "* Build artifacts (JS and CSS bundles).", "translation": "构建结果(JS 和 CSS 包)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "ANYTHINGUNDERASSETS", "original": "* Anything under `assets`.", "translation": "`assets` 下的所有文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###MAKINGCHANGESTOYOURAPPLICATION", "original": "### Making changes to your application", "translation": "### 修改你的应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "NOWTHATYOUVESEENHOWSERVICEWORKERSCACHEYOURAPPLICATIONTHENEXTSTEPISUNDERSTANDINGHOWUPDATESWORK", "original": "Now that you've seen how service workers cache your application, the \nnext step is understanding how updates work.", "translation": "现在,你已经看到了 Service Worker 如何缓存你的应用,接下来的步骤讲它如何进行更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "1IFYOURETESTINGINANINCOGNITOWINDOWOPENASECONDBLANKTABTHISWILLKEEPTHEINCOGNITOANDTHECACHESTATEALIVEDURINGYOURTEST", "original": "1. If you're testing in an incognito window, open a second blank tab. This will keep the incognito and the cache state alive during your test.", "translation": "如果你正在隐身窗口中测试,请打开第二个空白页。这会让该隐身窗口和缓存的状态在测试期间持续活着。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "2CLOSETHEAPPLICATIONTABBUTNOTTHEWINDOWTHISSHOULDALSOCLOSETHEDEVELOPERTOOLS", "original": "2. Close the application tab, but not the window. This should also close the Developer Tools.", "translation": "关闭该应用的页面,而不是整个窗口。这也会同时关闭开发者工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "3SHUTDOWNHTTPSERVER", "original": "3. Shut down `http-server`.", "translation": "关闭 `http-server`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "4NEXTMAKEACHANGETOTHEAPPLICATIONANDWATCHTHESERVICEWORKERINSTALLTHEUPDATE", "original": "4. Next, make a change to the application, and watch the service worker install the update.", "translation": "接下来,对应用进行一些修改,并且观察 Service Worker 安装这些更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "5OPENSRCAPPAPPCOMPONENTHTMLFOREDITING", "original": "5. Open `src/app/app.component.html` for editing.", "translation": "打开 `src/app/app.component.html` 供编辑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "6CHANGETHETEXTWELCOMETOTITLETOBIENVENUETITLE", "original": "6. Change the text `Welcome to {{title}}!` to `Bienvenue à {{title}}!`.", "translation": "把文本 `Welcome to {{title}}!` 改为 `Bienvenue à {{title}}!`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "7BUILDANDRUNTHESERVERAGAIN:", "original": "7. Build and run the server again:", "translation": "再次构建并运行此服务器:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "###UPDATINGYOURAPPLICATIONINTHEBROWSER", "original": "### Updating your application in the browser", "translation": "### 在浏览器中更新你的应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "NOWLOOKATHOWTHEBROWSERANDSERVICEWORKERHANDLETHEUPDATEDAPPLICATION", "original": "Now look at how the browser and service worker handle the updated application.", "translation": "现在,看看浏览器和 Service Worker 如何处理这个更新后的应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "1OPENHTTP:LOCALHOST:8080AGAININTHESAMEWINDOWWHATHAPPENS", "original": "1. Open http://localhost:8080 again in the same window. What happens?", "translation": "再次在同一个窗口中打开 <http://localhost:8080>,发生了什么?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "WHATWENTWRONGNOTHINGACTUALLYTHEANGULARSERVICEWORKERISDOINGITSJOBANDSERVINGTHEVERSIONOFTHEAPPLICATIONTHATITHASINSTALLEDEVENTHOUGHTHEREISANUPDATEAVAILABLEINTHEINTERESTOFSPEEDTHESERVICEWORKERDOESNTWAITTOCHECKFORUPDATESBEFOREITSERVESTHEAPPLICATIONTHATITHASCACHED", "original": "What went wrong? Nothing, actually. The Angular service worker is doing its job and serving the version of the application that it has **installed**, even though there is an update available. In the interest of speed, the service worker doesn't wait to check for updates before it serves the application that it has cached.", "translation": "错在哪里?哪里也没错,真的。Angular Service Worker 正在做自己的工作,并且用它**已经安装过**的版本提供服务,虽然,已经有新版本可用了。由于更关注速度,所以 Service Worker 并不会在启动它已经缓存过的版本之前先等待检查更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "IFYOULOOKATTHEHTTPSERVERLOGSYOUCANSEETHESERVICEWORKERREQUESTINGNGSWJSONTHISISHOWTHESERVICEWORKERCHECKSFORUPDATES", "original": "If you look at the `http-server` logs, you can see the service worker requesting `/ngsw.json`. This is how the service worker checks for updates.", "translation": "如果你看看 `http-server` 的 log,就会发现 Service Worker 请求了 `/ngsw.json` 文件,这是 Service Worker 正在检查更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "2REFRESHTHEPAGE", "original": "2. Refresh the page.", "translation": "刷新页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "THESERVICEWORKERINSTALLEDTHEUPDATEDVERSIONOFYOURAPPINTHEBACKGROUNDANDTHENEXTTIMETHEPAGEISLOADEDORRELOADEDTHESERVICEWORKERSWITCHESTOTHELATESTVERSION", "original": "The service worker installed the updated version of your app *in the background*, and the next time the page is loaded or reloaded, the service worker switches to the latest version.", "translation": "Service Worker *在后台*安装好了这个更新后的版本,下次加载或刷新页面时,Service Worker 就切换到最新的版本了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "##MOREONANGULARSERVICEWORKERS", "original": "## More on Angular service workers", - "translation": "## 关于 Angular Service Worker 的更多知识", + "translation": "## 关于 Angular Service Worker 的更多信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", - "translation": "你可能对下列内容感兴趣:", + "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "COMMUNICATINGWITHSERVICEWORKERSGUIDESERVICEWORKERCOMMUNICATIONS", "original": "* [Communicating with service workers](guide/service-worker-communications).", - "translation": "[与 Service Worker 通讯](guide/service-worker-communications).", + "translation": "[与 Service Worker 通讯](guide/service-worker-communications)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-getting-started.md" }, { + "key": "#ANGULARSERVICEWORKERINTRODUCTION", "original": "# Angular service worker introduction", "translation": "# Angular 的 Service Worker 简介", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "SERVICEWORKERSAUGMENTTHETRADITIONALWEBDEPLOYMENTMODELANDEMPOWERAPPLICATIONSTODELIVERAUSEREXPERIENCEWITHTHERELIABILITYANDPERFORMANCEONPARWITHNATIVELYINSTALLEDCODE", "original": "Service workers augment the traditional web deployment model and empower applications to deliver a user experience with the reliability and performance on par with natively-installed code.", "translation": "Service Worker 可以增强传统的 Web 发布模式,并使应用程序能够提供可与本机代码媲美的高可靠、高性能的用户体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "ATITSSIMPLESTASERVICEWORKERISASCRIPTTHATRUNSINTHEWEBBROWSERANDMANAGESCACHINGFORANAPPLICATION", "original": "At its simplest, a service worker is a script that runs in the web browser and manages caching for an application.", "translation": "简单来说,Service Worker 就是一段运行在 Web 浏览器中,并为应用管理缓存的脚本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "SERVICEWORKERSFUNCTIONASANETWORKPROXYTHEYINTERCEPTALLOUTGOINGHTTPREQUESTSMADEBYTHEAPPLICATIONANDCANCHOOSEHOWTORESPONDTOTHEMFOREXAMPLETHEYCANQUERYALOCALCACHEANDDELIVERACACHEDRESPONSEIFONEISAVAILABLEPROXYINGISNTLIMITEDTOREQUESTSMADETHROUGHPROGRAMMATICAPISSUCHASFETCHITALSOINCLUDESRESOURCESREFERENCEDINHTMLANDEVENTHEINITIALREQUESTTOINDEXHTMLSERVICEWORKERBASEDCACHINGISTHUSCOMPLETELYPROGRAMMABLEANDDOESNTRELYONSERVERSPECIFIEDCACHINGHEADERS", "original": "Service workers function as a network proxy. They intercept all outgoing HTTP requests made by the application and can choose how to respond to them. For example, they can query a local cache and deliver a cached response if one is available. Proxying isn't limited to requests made through programmatic APIs, such as `fetch`; it also includes resources referenced in HTML and even the initial request to `index.html`. Service worker-based caching is thus completely programmable and doesn't rely on server-specified caching headers.", "translation": "Service Worker 的功能就像一个网络代理。它们会拦截所有由应用发出的 HTTP 请求,并选择如何给出响应。\n比如,它们可以查询局部缓存,如果有缓存的响应数据,就用它做出响应。\n这种代理行为不会局限于通过程序调用 API(比如`fetch`)发起的请求,还包括 HTML 中对资源的引用,甚至对 `index.html` 的首次请求。\n 基于 Service Worker 的缓存是完全可编程的,并且不依赖于服务端指定的那些控制缓存策略的头。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "UNLIKETHEOTHERSCRIPTSTHATMAKEUPANAPPLICATIONSUCHASTHEANGULARAPPBUNDLETHESERVICEWORKERISPRESERVEDAFTERTHEUSERCLOSESTHETABTHENEXTTIMETHATBROWSERLOADSTHEAPPLICATIONTHESERVICEWORKERLOADSFIRSTANDCANINTERCEPTEVERYREQUESTFORRESOURCESTOLOADTHEAPPLICATIONIFTHESERVICEWORKERISDESIGNEDTODOSOITCANCOMPLETELYSATISFYTHELOADINGOFTHEAPPLICATIONWITHOUTTHENEEDFORTHENETWORK", "original": "Unlike the other scripts that make up an application, such as the Angular app bundle, the service worker is preserved after the user closes the tab. The next time that browser loads the application, the service worker loads first, and can intercept every request for resources to load the application. If the service worker is designed to do so, it can *completely satisfy the loading of the application, without the need for the network*.", "translation": "不像应用中的其它脚本(如 Angular 的应用包),Service Worker 在用户关闭浏览器页标签时仍然会被保留。\n下次浏览器加载本应用时,Service Worker 会首先加载,然后拦截加载本应用时的对每一项资源的请求。\n如果这个 Service Worker 就是为此而设计的,它就能*完全满足应用加载时的需求,而不需要依赖网络*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "EVENACROSSAFASTRELIABLENETWORKROUNDTRIPDELAYSCANINTRODUCESIGNIFICANTLATENCYWHENLOADINGTHEAPPLICATIONUSINGASERVICEWORKERTOREDUCEDEPENDENCYONTHENETWORKCANSIGNIFICANTLYIMPROVETHEUSEREXPERIENCE", "original": "Even across a fast reliable network, round-trip delays can introduce significant latency when loading the application. Using a service worker to reduce dependency on the network can significantly improve the user experience.", "translation": "即使在快速可靠的网络中,往返延迟也可能在加载应用程序时产生显著的延迟。使用 Service Worker 来减少对网络的依赖可以显着改善用户体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "##SERVICEWORKERSINANGULAR", "original": "## Service workers in Angular", "translation": "## Angular 中的 Service Worker", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "ANGULARAPPLICATIONSASSINGLEPAGEAPPLICATIONSAREINAPRIMEPOSITIONTOBENEFITFROMTHEADVANTAGESOFSERVICEWORKERSSTARTINGWITHVERSION500ANGULARSHIPSWITHASERVICEWORKERIMPLEMENTATIONANGULARDEVELOPERSCANTAKEADVANTAGEOFTHISSERVICEWORKERANDBENEFITFROMTHEINCREASEDRELIABILITYANDPERFORMANCEITPROVIDESWITHOUTNEEDINGTOCODEAGAINSTLOWLEVELAPIS", "original": "Angular applications, as single-page applications, are in a prime position to benefit from the advantages of service workers. Starting with version 5.0.0, Angular ships with a service worker implementation. Angular developers can take advantage of this service worker and benefit from the increased reliability and performance it provides, without needing to code against low-level APIs.", "translation": "作为单页面应用,Angular 应用位于从 Service Worker 中受益的首要位置。\n从 Angular v5.0.0 开始,Angular 提供了一份 Service Worker 的实现。\nAngular 开发人员可以从这个 Service Worker 加强的可靠性和性能中获益,而不用再针对底层 API 写代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "ANGULARSSERVICEWORKERISDESIGNEDTOOPTIMIZETHEENDUSEREXPERIENCEOFUSINGANAPPLICATIONOVERASLOWORUNRELIABLENETWORKCONNECTIONWHILEALSOMINIMIZINGTHERISKSOFSERVINGOUTDATEDCONTENT", "original": "Angular's service worker is designed to optimize the end user experience of using an application over a slow or unreliable network connection, while also minimizing the risks of serving outdated content.", "translation": "Angular 的 Service Worker 的设计目标是优化那些使用慢速、不可靠网络的最终用户的体验,同时还要尽可能减小提供过期内容的风险。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "THEANGULARSERVICEWORKERSBEHAVIORFOLLOWSTHATDESIGNGOAL:", "original": "The Angular service worker's behavior follows that design goal:", "translation": "Angular 的 Service Worker 的行为遵循下列设计目标:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "CACHINGANAPPLICATIONISLIKEINSTALLINGANATIVEAPPLICATIONTHEAPPLICATIONISCACHEDASONEUNITANDALLFILESUPDATETOGETHER", "original": "* Caching an application is like installing a native application. The application is cached as one unit, and all files update together.", "translation": "像安装原生应用一样缓存应用。该应用作为整体被缓存,它的所有文件作为整体进行更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "ARUNNINGAPPLICATIONCONTINUESTORUNWITHTHESAMEVERSIONOFALLFILESITDOESNOTSUDDENLYSTARTRECEIVINGCACHEDFILESFROMANEWERVERSIONWHICHARELIKELYINCOMPATIBLE", "original": "* A running application continues to run with the same version of all files. It does not suddenly start receiving cached files from a newer version, which are likely incompatible.", "translation": "正在运行的应用使用所有文件的同一版本继续运行。不要突然开始接收来自新版本的、可能不兼容的缓存文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "WHENUSERSREFRESHTHEAPPLICATIONTHEYSEETHELATESTFULLYCACHEDVERSIONNEWTABSLOADTHELATESTCACHEDCODE", "original": "* When users refresh the application, they see the latest fully cached version. New tabs load the latest cached code.", "translation": "当用户刷新本应用时,他们会看到最新的被完全缓存的版本。新的页标签中会加载最新的缓存代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "UPDATESHAPPENINTHEBACKGROUNDRELATIVELYQUICKLYAFTERCHANGESAREPUBLISHEDTHEPREVIOUSVERSIONOFTHEAPPLICATIONISSERVEDUNTILANUPDATEISINSTALLEDANDREADY", "original": "* Updates happen in the background, relatively quickly after changes are published. The previous version of the application is served until an update is installed and ready.", "translation": "在更改发布之后,相对较快的在后台进行更新。在一次完整的更新完成之前,仍然使用应用的上一个版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "THESERVICEWORKERCONSERVESBANDWIDTHWHENPOSSIBLERESOURCESAREONLYDOWNLOADEDIFTHEYVECHANGED", "original": "* The service worker conserves bandwidth when possible. Resources are only downloaded if they've changed.", "translation": "只要有可能,Service Worker 就会尽量节省带宽。它只会下载那些发生了变化的资源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "TOSUPPORTTHESEBEHAVIORSTHEANGULARSERVICEWORKERLOADSAMANIFESTFILEFROMTHESERVERTHEMANIFESTDESCRIBESTHERESOURCESTOCACHEANDINCLUDESHASHESOFEVERYFILESCONTENTSWHENANUPDATETOTHEAPPLICATIONISDEPLOYEDTHECONTENTSOFTHEMANIFESTCHANGEINFORMINGTHESERVICEWORKERTHATANEWVERSIONOFTHEAPPLICATIONSHOULDBEDOWNLOADEDANDCACHEDTHISMANIFESTISGENERATEDFROMAUSERPROVIDEDCONFIGURATIONFILECALLEDNGSWCONFIGJSONBYUSINGABUILDTOOLSUCHASTHEANGULARCLI", "original": "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.", "translation": "要支持这些行为,Angular 的 Service Worker 会从服务器上下载一个 `manifest` 文件。\n这个 `manifest` 文件描述要缓存的资源,并包含每个文件内容的哈希值。\n当发布了应用的一个新版本时,`manifest` 的内容就会改变,通知 Service Worker 应该下载并缓存应用的一个新版本了。\n这个 manifest 是从用户使用 Angular CLI 等构建工具提供的一个名叫 `ngsw-config.json` 的文件中生成的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "INSTALLINGTHEANGULARSERVICEWORKERISASSIMPLEASINCLUDINGANNGMODULEINADDITIONTOREGISTERINGTHEANGULARSERVICEWORKERWITHTHEBROWSERTHISALSOMAKESAFEWSERVICESAVAILABLEFORINJECTIONWHICHINTERACTWITHTHESERVICEWORKERANDCANBEUSEDTOCONTROLITFOREXAMPLEANAPPLICATIONCANASKTOBENOTIFIEDWHENANEWUPDATEBECOMESAVAILABLEORANAPPLICATIONCANASKTHESERVICEWORKERTOCHECKTHESERVERFORAVAILABLEUPDATES", "original": "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.", "translation": "安装 Angular 的 Service Worker 就像引入一个 `NgModule` 一样简单。\n除了使用浏览器注册 Angular 的 Service Worker 之外,还要制作一些可供注入的服务,它们可以与 Service Worker 交互,并控制它。\n比如,应用可以要求当新的更新已经就绪时通知自己,或要求 Service Worker 检查服务器,看是否有可用的更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "##PREREQUISITES", "original": "## Prerequisites", "translation": "## 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "TOUSEANGULARSERVICEWORKERSYOUMUSTHAVETHEFOLLOWINGANGULARANDCLIVERSIONS:", "original": "To use Angular service workers, you must have the following Angular and CLI versions:", "translation": "要想使用 Angular Service Worker,你要使用下列 Angular 和 CLI 版本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "ANGULAR500ORLATER", "original": "* Angular 5.0.0 or later.", "translation": "Angular 5.0.0 或更高。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "ANGULARCLI160ORLATER", "original": "* Angular CLI 1.6.0 or later.", "translation": "Angular CLI 1.6.0 或更高。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "YOURAPPLICATIONMUSTRUNINAWEBBROWSERTHATSUPPORTSSERVICEWORKERSCURRENTLYTHELATESTVERSIONSOFCHROMEANDFIREFOXARESUPPORTEDTOLEARNABOUTOTHERBROWSERSTHATARESERVICEWORKERREADYSEETHECANIUSEHTTP:CANIUSECOM#FEATSERVICEWORKERSPAGE", "original": "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.", "translation": "你的应用必须运行在支持 Service Worker 的 Web 浏览器中。目前,Chrome 和 Firefox 的最新版本 都已经支持了。\n要想知道其它浏览器是否支持,参见 [Can I Use](http://caniuse.com/#feat=serviceworkers) 页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "##RELATEDRESOURCES", "original": "## Related resources", "translation": "## 相关资源", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "FORMOREINFORMATIONABOUTSERVICEWORKERSINGENERALSEESERVICEWORKERS:ANINTRODUCTIONHTTPS:DEVELOPERSGOOGLECOMWEBFUNDAMENTALSPRIMERSSERVICEWORKERS", "original": "For more information about service workers in general, see [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/).", "translation": "要了解更多关于 Service Worker 的普遍性信息,参见 [Service Worker 简介](https://developers.google.com/web/fundamentals/primers/service-workers/)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "FORMOREINFORMATIONABOUTBROWSERSUPPORTSEETHEBROWSERSUPPORTHTTPS:DEVELOPERSGOOGLECOMWEBFUNDAMENTALSPRIMERSSERVICEWORKERS#BROWSERSUPPORTSECTIONOFSERVICEWORKERS:ANINTRODUCTIONHTTPS:DEVELOPERSGOOGLECOMWEBFUNDAMENTALSPRIMERSSERVICEWORKERSJAKEARCHIBALDSISSERVICEWORKERREADYHTTPS:JAKEARCHIBALDGITHUBIOISSERVICEWORKERREADYANDCANIUSEHTTP:CANIUSECOM#FEATSERVICEWORKERS", "original": "For more information about browser support, see the [browser support](https://developers.google.com/web/fundamentals/primers/service-workers/#browser_support) section of [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/), Jake Archibald's [Is Serviceworker ready?](https://jakearchibald.github.io/isserviceworkerready/), and \n[Can I Use](http://caniuse.com/#feat=serviceworkers).", "translation": "要了解关于浏览器支持度的更多信息,参见 [Service Worker 简介](https://developers.google.com/web/fundamentals/primers/service-workers/) 中的[浏览器支持](https://developers.google.com/web/fundamentals/primers/service-workers/#browser_support)部分、Jake Archibald 写的[Serviceworker 好了吗?](https://jakearchibald.github.io/isserviceworkerready/)和 [Can I Use](http://caniuse.com/#feat=serviceworkers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "THEREMAINDEROFTHISANGULARDOCUMENTATIONSPECIFICALLYADDRESSESTHEANGULARIMPLEMENTATIONOFSERVICEWORKERS", "original": "The remainder of this Angular documentation specifically addresses the Angular implementation of service workers.", "translation": "本文档的其余部分会专注于讲 Angular 中的 Service Worker 实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "##MOREONANGULARSERVICEWORKERS", "original": "## More on Angular service workers", "translation": "## 关于 Angular Service Worker 的更多信息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "GETTINGSTARTEDWITHSERVICEWORKERSGUIDESERVICEWORKERGETTINGSTARTED", "original": "* [Getting Started with service workers](guide/service-worker-getting-started).", - "translation": "[Service Worker 快速起步](guide/service-worker-getting-started).", + "translation": "[Service Worker 快速起步](guide/service-worker-getting-started)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/service-worker-intro.md" }, { + "key": "#SETTHEDOCUMENTTITLE", "original": "# Set the Document Title", "translation": "# 设置文档标题", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "YOURAPPSHOULDBEABLETOMAKETHEBROWSERTITLEBARSAYWHATEVERYOUWANTITTOSAYTHISCOOKBOOKEXPLAINSHOWTODOIT", "original": "Your app should be able to make the browser title bar say whatever you want it to say.\nThis cookbook explains how to do it.", "translation": "应用程序应该能让浏览器标题栏显示你想让它显示的内容。本*烹饪宝典*解释怎么做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "SEETHELIVEEXAMPLENAMESETDOCUMENTTITLELIVEEXAMPLE", "original": "See the <live-example name=\"set-document-title\"></live-example>.", "translation": "参见<live-example name=\"set-document-title\"></live-example>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "##THEPROBLEMWITHLTTITLEGT", "original": "## The problem with *<title>*", "translation": "## *<title>*的问题", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "THEOBVIOUSAPPROACHISTOBINDAPROPERTYOFTHECOMPONENTTOTHEHTMLTITLELIKETHIS:", "original": "The obvious approach is to bind a property of the component to the HTML `<title>` like this:", "translation": "显而易见的方法是把组件的属性绑定到 HTML 的 `<title>` 标签上,像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "SORRYBUTTHATWONTWORKTHEROOTCOMPONENTOFTHEAPPLICATIONISANELEMENTCONTAINEDWITHINTHEBODYTAGTHEHTMLTITLEISINTHEDOCUMENTHEADOUTSIDETHEBODYMAKINGITINACCESSIBLETOANGULARDATABINDING", "original": "Sorry but that won't work.\nThe root component of the application is an element contained within the `<body>` tag.\nThe HTML `<title>` is in the document `<head>`, outside the body, making it inaccessible to Angular data binding.", "translation": "抱歉,这样不行。应用程序的根组件是一个包含在 `<body>` 标签里的元素。该 HTML 的 `<title>` 在文档的 `<head>` 元素里,在 `<body>` 之外,Angular 的数据绑定无法访问到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "YOUCOULDGRABTHEBROWSERDOCUMENTOBJECTANDSETTHETITLEMANUALLYTHATSDIRTYANDUNDERMINESYOURCHANCESOFRUNNINGTHEAPPOUTSIDEOFABROWSERSOMEDAY", "original": "You could grab the browser `document` object and set the title manually.\nThat's dirty and undermines your chances of running the app outside of a browser someday.", "translation": "可以从浏览器获得 `document` 对象,并且手动设置标题。但是这样看起来很脏,而且将无法在浏览器之外运行应用程序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "RUNNINGYOURAPPOUTSIDEABROWSERMEANSTHATYOUCANTAKEADVANTAGEOFSERVERSIDEPRERENDERINGFORNEARINSTANTFIRSTAPPRENDERTIMESANDFORSEOITMEANSYOUCOULDRUNFROMINSIDEAWEBWORKERTOIMPROVEYOURAPPSRESPONSIVENESSBYUSINGMULTIPLETHREADSANDITMEANSTHATYOUCOULDRUNYOURAPPINSIDEELECTRONJSORWINDOWSUNIVERSALTODELIVERITTOTHEDESKTOP", "original": "Running your app outside a browser means that you can take advantage of server-side\n pre-rendering for near-instant first app render times and for SEO. It means you could run from\n inside a Web Worker to improve your app's responsiveness by using multiple threads. And it\n means that you could run your app inside Electron.js or Windows Universal to deliver it to the desktop.", "translation": "在浏览器外运行应用程序意味着:利用服务器端预先渲染,为应用程序实现几乎实时的首次渲染,同时还能支持 SEO(搜索引擎优化)。\n意味着你可以在一个 Web Worker 中运行你的应用程序,通过多线程技术增强应用程序的响应性。\n还意味着你可以在 Electron.js 或者 Windows Universal 里面运行,发布到桌面环境。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "##USETHETITLESERVICE", "original": "## Use the `Title` service", "translation": "## 使用 `Title` 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "FORTUNATELYANGULARBRIDGESTHEGAPBYPROVIDINGATITLESERVICEASPARTOFTHEBROWSERPLATFORMTHETITLEAPIPLATFORMBROWSERTITLESERVICEISASIMPLECLASSTHATPROVIDESANAPIFORGETTINGANDSETTINGTHECURRENTHTMLDOCUMENTTITLE:", "original": "Fortunately, Angular bridges the gap by providing a `Title` service as part of the *Browser platform*.\nThe [Title](api/platform-browser/Title) service is a simple class that provides an API\nfor getting and setting the current HTML document title:", "translation": "幸运的是,Angular 在*浏览器平台*的包中,提供了一个 `Title` 服务,弥补了这种差异。\n[Title](api/platform-browser/Title)服务是一个简单的类,提供了一个 API,用来获取和设置当前 HTML 文档的标题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "GETTITLE:STRINGMDASHGETSTHETITLEOFTHECURRENTHTMLDOCUMENT", "original": "* `getTitle() : string`—Gets the title of the current HTML document.", "translation": "`getTitle(): string` —— 获取当前 HTML 文档的标题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "SETTITLENEWTITLE:STRINGMDASHSETSTHETITLEOFTHECURRENTHTMLDOCUMENT", "original": "* `setTitle( newTitle : string )`—Sets the title of the current HTML document.", "translation": "`setTitle( newTitle: string)` —— 设置当前 HTML 文档的标题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "YOUCANINJECTTHETITLESERVICEINTOTHEROOTAPPCOMPONENTANDEXPOSEABINDABLESETTITLEMETHODTHATCALLSIT:", "original": "You can inject the `Title` service into the root `AppComponent` and expose a bindable `setTitle` method that calls it:", "translation": "你可以把 `Title` 服务注入到根组件 `AppComponent`,并暴露出可供绑定的 `setTitle` 方法让别人来调用该服务:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "BINDTHATMETHODTOTHREEANCHORTAGSANDVOIL", "original": "Bind that method to three anchor tags and voilà!", "translation": "把这个方法绑定到三个 A 标签,瞧瞧!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "HERESTHECOMPLETESOLUTION:", "original": "Here's the complete solution:", "translation": "这里是完整的方案(代码)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "##WHYPROVIDETHETITLESERVICEINBOOTSTRAP", "original": "## Why provide the `Title` service in `bootstrap`", "translation": "## 为什么要在 *bootstrap* 里面提供这个 *Title* 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "GENERALLYYOUWANTTOPROVIDEAPPLICATIONWIDESERVICESINTHEROOTAPPLICATIONCOMPONENTAPPCOMPONENT", "original": "Generally you want to provide application-wide services in the root application component, `AppComponent`.", "translation": "你通常会在应用程序的根组件 `AppComponent` 中提供应用程序级的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "THISCOOKBOOKRECOMMENDSREGISTERINGTHETITLESERVICEDURINGBOOTSTRAPPINGALOCATIONYOURESERVEFORCONFIGURINGTHERUNTIMEANGULARENVIRONMENT", "original": "This cookbook recommends registering the title service during bootstrapping,\na location you reserve for configuring the runtime Angular environment.", "translation": "但这里,要在引导过程中注册这个 Title 服务,这个位置是为你设置 Angular 运行环境而保留的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "THATSEXACTLYWHATYOUREDOINGTHETITLESERVICEISPARTOFTHEANGULARBROWSERPLATFORMIFYOUBOOTSTRAPYOURAPPLICATIONINTOADIFFERENTPLATFORMYOULLHAVETOPROVIDEADIFFERENTTITLESERVICETHATUNDERSTANDSTHECONCEPTOFADOCUMENTTITLEFORTHATSPECIFICPLATFORMIDEALLYTHEAPPLICATIONITSELFNEITHERKNOWSNORCARESABOUTTHERUNTIMEENVIRONMENT", "original": "That's exactly what you're doing.\nThe `Title` service is part of the Angular *browser platform*.\nIf you bootstrap your application into a different platform,\nyou'll have to provide a different `Title` service that understands\nthe concept of a \"document title\" for that specific platform.\nIdeally, the application itself neither knows nor cares about the runtime environment.", "translation": "你的做法正是如此。这里的 `Title` 服务是 Angular*浏览器平台*的一部分。如果在其它平台上引导应用程序,就得提供另一个专为那个平台准备的 `Title` 服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/set-document-title.md" }, { + "key": "#ANATOMYOFTHESETUPPROJECT", "original": "# Anatomy of the Setup Project", "translation": "# 搭建项目环境", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THEDOCUMENTATIONSETUPGUIDESETUPPROCEDURESINSTALLALOTOFFILESMOSTOFTHEMCANBESAFELYIGNORED", "original": "The documentation [setup](guide/setup) procedures install a _lot_ of files.\nMost of them can be safely ignored.", "translation": "在[搭建](guide/setup)本地开发环境的过程中会安装*很多*文件。它们大部分都可以被忽略掉。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "APPLICATIONFILESINSIDETHESRCANDE2EFOLDERSMATTERMOSTTODEVELOPERS", "original": "Application files _inside the_ **`src/`** and **`e2e/`** folders matter most to developers.", "translation": "对程序员来讲最重要的是在 *`src/`* 和 *`e2e/`* 文件夹*之内*的应用文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "FILESOUTSIDETHOSEFOLDERSCONDITIONTHEDEVELOPMENTENVIRONMENTTHEYRARELYCHANGEANDYOUMAYNEVERVIEWORMODIFYTHEMIFYOUDOTHISPAGECANHELPYOUUNDERSTANDTHEIRPURPOSE", "original": "Files _outside_ those folders condition the development environment.\nThey rarely change and you may never view or modify them.\nIf you do, this page can help you understand their purpose.", "translation": "在这两个文件夹*之外*的文件为开发环境设定条件。\n这些文件很少会需要变动,你可能永远都不需要阅览或者修改它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "FILE", "original": "File", "translation": "文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "PURPOSE", "original": "Purpose", "translation": "用途", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "ANGULARAPPLICATIONFILESGOHERE", "original": "Angular application files go here.", "translation": "你的 Angular 应用文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "SHIPSWITHTHEHELLOANGULARSAMPLESAPPCOMPONENTAPPMODULEACOMPONENTUNITTESTAPPCOMPONENTSPECTSANDTHEBOOTSTRAPFILEMAINTS", "original": "Ships with the \"Hello Angular\" sample's\n `AppComponent`, `AppModule`, a component unit test (`app.component.spec.ts`), and\n the bootstrap file, `main.ts`.", "translation": "\"Hello Angular\" 这个例子中有 `AppComponent`、`AppModule`、 一个组件单元测试 (`app.component.spec.ts`) 以及引导文件 `main.ts`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "TRYTHELIVEEXAMPLENAMESETUPSAMPLEAPPLICATIONLIVEEXAMPLEANDTHELIVEEXAMPLENAMESETUPSTACKBLITZQUICKSTARTSPECSUNITTESTLIVEEXAMPLEASLIVEEXAMPLES", "original": "Try the <live-example name=\"setup\">sample application</live-example>\n and the <live-example name=\"setup\" stackblitz=\"quickstart-specs\">unit test</live-example>\n as _live examples_.", "translation": "在 live example 中试试<live-example name=\"setup\">范例程序</live-example>和<live-example name=\"setup\" stackblitz=\"quickstart-specs\">单元测试</live-example>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "ENDTOENDE2ETESTSOFTHEAPPLICATIONWRITTENINJASMINEANDRUNBYTHEAHREFHTTP:WWWPROTRACTORTESTORGTITLEPROTRACTOR:ENDTOENDTESTINGFORANGULARPROTRACTORAE2ETESTRUNNER", "original": "_End-to-end_ (e2e) tests of the application,\n written in Jasmine and run by the\n <a href=\"http://www.protractortest.org/\" title=\"Protractor: end-to-end testing for Angular\">protractor</a>\n e2e test runner.", "translation": "应用的*端对端*(e2e)测试,用 Jasmine 写成并用 <a href=\"http://www.protractortest.org/\" target=\"_blank\" title=\"Protractor:Angular 的端对端测试\">protractor</a> 端对端测试运行器测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "INITIALIZEDWITHANE2ETESTFORTHEHELLOANGULARSAMPLE", "original": "Initialized with an e2e test for the \"Hello Angular\" sample.", "translation": "初始化后,有个“Hello Angular” 的例子的端对端测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THENPMPACKAGESINSTALLEDWITHTHENPMINSTALLCOMMAND", "original": "The _npm_ packages installed with the `npm install` command.", "translation": "用 `npm install` 命令安装的 *npm* 包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "TOOLINGCONFIGURATIONFILESANDFOLDERSIGNORETHEMUNTILYOUHAVEACOMPELLINGREASONTODOOTHERWISE", "original": "Tooling configuration files and folders.\n Ignore them until you have a compelling reason to do otherwise.", "translation": "配置文件和文件夹的工具。\n 除非你有足够的理由,否则别动它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THEHISTORYOFCHANGESTOTHEQUICKSTARTREPOSITORYDELETEORIGNORE", "original": "The history of changes to the _QuickStart_ repository.\n Delete or ignore.", "translation": "*快速上手*库的更新历史。\n 删除或忽略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THEAPPLICATIONICONTHATAPPEARSINTHEBROWSERTAB", "original": "The application icon that appears in the browser tab.", "translation": "出现在浏览器标签上的应用图标。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THEAPPLICATIONHOSTPAGEITLOADSAFEWESSENTIALSCRIPTSINAPRESCRIBEDORDERTHENITBOOTSTHEAPPLICATIONPLACINGTHEROOTAPPCOMPONENTINTHECUSTOMMYAPPBODYTAG", "original": "The application host page.\n It loads a few essential scripts in a prescribed order.\n Then it boots the application, placing the root `AppComponent`\n in the custom `<my-app>` body tag.", "translation": "应用的宿主页面。\n 它以特定的顺序加载一些基本脚本。\n 然后它启动应用,将根 `AppComponent` 放置到自定义 `<my-app>` 标签里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THESAMEINDEXHTMLSATISFIESALLDOCUMENTATIONAPPLICATIONSAMPLES", "original": "The same `index.html` satisfies all documentation application samples.", "translation": "同一个 `index.html` 满足所有文档应用例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "CONFIGURATIONFORTHEAHREFHTTPS:KARMARUNNERGITHUBIO10INDEXHTMLTITLEKARMAUNITTESTRUNNERKARMAATESTRUNNERDESCRIBEDINTHETESTINGGUIDETESTINGGUIDE", "original": "Configuration for the <a href=\"https://karma-runner.github.io/1.0/index.html\" title=\"Karma unit test runner\">karma</a>\n test runner described in the [Testing](guide/testing) guide.", "translation": "在[测试](guide/testing)指南中提到的 <a href=\"https://karma-runner.github.io/1.0/index.html\" target=\"_blank\" title=\"Karma 测试运行器\">karma</a> 测试运行器的配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "SCRIPTTORUNAHREFHTTPS:KARMARUNNERGITHUBIO10INDEXHTMLTITLEKARMAUNITTESTRUNNERKARMAAWITHSYSTEMJSASDESCRIBEDINTHETESTINGGUIDETESTINGGUIDE", "original": "Script to run <a href=\"https://karma-runner.github.io/1.0/index.html\" title=\"Karma unit test runner\">karma</a>\n with SystemJS as described in the [Testing](guide/testing) guide.", "translation": "在[测试](guide/testing)指南中提到的 <a href=\"https://karma-runner.github.io/1.0/index.html\" target=\"_blank\" title=\"Karma 测试运行器\">karma</a> 测试运行器的脚本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "ALISTOFFILESTHATYOUCANDELETEIFYOUWANTTOPURGEYOURSETUPOFTHEORIGINALQUICKSTARTSEEDTESTINGANDGITMAINTENANCEARTIFACTSSEEINSTRUCTIONSINTHEOPTIONALDELETINGNONESSENTIALFILESGUIDESETUP#NONESSENTIALSETUP:DELETINGNONESSENTIALFILESSECTIONDOTHISONLYINTHEBEGINNINGTOAVOIDACCIDENTALLYDELETINGYOUROWNTESTSANDGITSETUP", "original": "A list of files that you can delete if you want to purge your setup of the\n original QuickStart Seed testing and git maintenance artifacts.\n See instructions in the optional\n [_Deleting non-essential files_](guide/setup#non-essential \"Setup: Deleting non-essential files\") section.\n *Do this only in the beginning to avoid accidentally deleting your own tests and git setup!*", "translation": "这个列表中的文件在清理时可以删除,它是原始的“快速上手”种子工程中的测试和 git 维护文件。\n 步骤参见可选的[删除非必要文件](guide/setup#non-essential \"Setup: Deleting non-essential files\")部分。\n *只在最初做这件事,以免不小心删除了你自己的测试文件和 git 配置!*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THEOPENSOURCEMITLICENSETOUSETHISSETUPCODEINYOURAPPLICATION", "original": "The open source MIT license to use this setup code in your application.", "translation": "应用的搭建代码中用到的开源 MIT 许可证。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "IDENTIFIESNPMPACKAGEDEPENDENCIESFORTHEPROJECT", "original": "Identifies `npm `package dependencies for the project.", "translation": "为项目指定 `npm` 依赖包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "CONTAINSCOMMANDSCRIPTSFORRUNNINGTHEAPPLICATIONRUNNINGTESTSANDMOREENTERNPMRUNFORALISTINGAHREFHTTPS:GITHUBCOMANGULARQUICKSTARTBLOBMASTERREADMEMD#NPMSCRIPTSTITLENPMSCRIPTSFORANGULARDOCUMENTATIONSAMPLESREADMOREAABOUTTHEM", "original": "Contains command scripts for running the application,\n running tests, and more. Enter `npm run` for a listing.\n <a href=\"https://github.com/angular/quickstart/blob/master/README.md#npm-scripts\"\n title=\"npm scripts for Angular documentation samples\">Read more</a> about them.", "translation": "包含了一些命令脚本,用来运行应用、运行测试与其他。输入 `npm run` 来查看命令列表。\n 到<a href=\"https://github.com/angular/quickstart/blob/master/README.md#npm-scripts\" \n target=\"_blank\" title=\"Angular 文档例子的 npm 脚本\">这里</a>阅读更多关于它们的说明。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "CONFIGURATIONFORTHEAHREFHTTP:WWWPROTRACTORTESTORGTITLEPROTRACTOR:ENDTOENDTESTINGFORANGULARPROTRACTORAENDTOENDE2ETESTRUNNER", "original": "Configuration for the\n <a href=\"http://www.protractortest.org/\" title=\"Protractor: end-to-end testing for Angular\">protractor</a>\n _end-to-end_ (e2e) test runner.", "translation": "<a href=\"http://www.protractortest.org/\" target=\"_blank\" title=\"Protractor: Angular 的端对端测试\">protractor</a> *端对端* (e2e) 测试器运行器的配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "INSTRUCTIONFORUSINGTHISGITREPOSITORYINYOURPROJECTWORTHREADINGBEFOREDELETING", "original": "Instruction for using this git repository in your project.\n Worth reading before deleting.", "translation": "项目中使用这个 git 库的说明。\n 在删除前值得阅读。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "GLOBALSTYLESFORTHEAPPLICATIONINITIALIZEDWITHANH1STYLEFORTHEQUICKSTARTDEMO", "original": "Global styles for the application. Initialized with an `<h1>` style for the QuickStart demo.", "translation": "应用的全局样式。初始化后,有个为《快速上手》演示准备的 `<h1>` 样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "TELLSTHESYSTEMJSMODULELOADERWHERETOFINDMODULESREFERENCEDINJAVASCRIPTIMPORTSTATEMENTSFOREXAMPLE:", "original": "Tells the **SystemJS** module loader where to find modules\n referenced in JavaScript `import` statements. For example:", "translation": "为 **SystemJS** 模块加载器指定去哪儿查找在 JavaScript 的 `import` 语句中引用的模块。例如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "DONTTOUCHTHISFILEUNLESSYOUAREFULLYVERSEDINSYSTEMJSCONFIGURATION", "original": "Don't touch this file unless you are fully versed in SystemJS configuration.", "translation": "除非你完全理解 SystemJS 的配置,不要修改它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "OPTIONALEXTRASYSTEMJSCONFIGURATIONAWAYTOADDSYSTEMJSMAPPINGSSUCHASFORAPPLICATIONBARRELSWITHOUTCHANGINGTHEORIGINALSYSTEMCONFIGJS", "original": "Optional extra SystemJS configuration.\n A way to add SystemJS mappings, such as for application _barrels_,\n without changing the original `system.config.js`.", "translation": "可选的额外 SystemJS 配置。\n 是添加 SystemJS 映射的途径,例如在无需修改原始 `systemjs.config.js` 的情况下为应用映射*封装桶*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "TELLSTHETYPESCRIPTCOMPILERHOWTOTRANSPILETYPESCRIPTSOURCEFILESINTOJAVASCRIPTFILESTHATRUNINALLMODERNBROWSERS", "original": "Tells the TypeScript compiler how to transpile TypeScript source files\n into JavaScript files that run in all modern browsers.", "translation": "为 TypeScript 编译器指定如何将 TypeScript 代码转换为 JavaScript 文件,用来在所有现代浏览器中运行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THENPMINSTALLEDTYPESCRIPTLINTERINSPECTSYOURTYPESCRIPTCODEANDCOMPLAINSWHENYOUVIOLATEONEOFITSRULES", "original": "The `npm` installed TypeScript linter inspects your TypeScript code\n and complains when you violate one of its rules.", "translation": "利用 `npm` 安装的 TypeScript 语法检查器 (linter) 检测 TypeScript 代码并在你违反它的规则时提示你。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "THISFILEDEFINESLINTINGRULESFAVOREDBYTHEANGULARSTYLEGUIDEGUIDESTYLEGUIDEANDBYTHEAUTHORSOFTHEDOCUMENTATION", "original": "This file defines linting rules favored by the\n [Angular style guide](guide/styleguide) and by the authors of the documentation.", "translation": "该文件定义了 [Angular 风格指南](guide/styleguide)与本文档站作者喜爱的语法检查规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup-systemjs-anatomy.md" }, { + "key": "#SETUPFORLOCALDEVELOPMENT", "original": "# Setup for local development", "translation": "# 搭建本地开发环境", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "THELIVEEXAMPLENAMEQUICKSTARTQUICKSTARTLIVECODINGLIVEEXAMPLEEXAMPLEISANANGULARPLAYGROUNDITSNOTWHEREYOUDDEVELOPAREALAPPLICATIONYOUSHOULDDEVELOPLOCALLYGUIDESETUP#WHYLOCALLYWHYDEVELOPLOCALLYONYOUROWNMACHINEANDTHATSALSOHOWWETHINKYOUSHOULDLEARNANGULAR", "original": "The <live-example name=quickstart>QuickStart live-coding</live-example> example is an Angular _playground_.\nIt's not where you'd develop a real application.\nYou [should develop locally](guide/setup#why-locally \"Why develop locally\") on your own machine ... and that's also how we think you should learn Angular.", "translation": "<live-example name=quickstart>《快速上手》在线编程</live-example>例子是 Angular 的*游乐场*。\n 它不是开发真实应用的地方。 \n 你应该在自己的电脑上[本地开发](guide/setup#why-locally \"为什么在本地开发?\")... 你也应该在本地环境学习 Angular。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "SETTINGUPANEWPROJECTONYOURMACHINEISQUICKANDEASYWITHTHEQUICKSTARTSEEDMAINTAINEDONGITHUBHTTPS:GITHUBCOMANGULARQUICKSTARTINSTALLTHEGITHUBQUICKSTARTREPO", "original": "Setting up a new project on your machine is quick and easy with the **QuickStart seed**,\nmaintained [on github](https://github.com/angular/quickstart \"Install the github QuickStart repo\").", "translation": "利用 [github 上](https://github.com/angular/quickstart \"安装 github 《快速上手》库\")的**《快速上手》种子**在你的电脑上搭建一个新项目是很快很容易的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "MAKESUREYOUHAVENODEANDNPMINSTALLEDGUIDESETUP#INSTALLPREREQUISITESWHATIFYOUDONTHAVENODEANDNPM", "original": "Make sure you have [node and npm installed](guide/setup#install-prerequisites \"What if you don't have node and npm?\").", "translation": "确定你已经安装了 [node 和 npm](guide/setup#install-prerequisites \"如果你没有 node 和 npm?\")。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "##CLONE", "original": "## Clone", "translation": "## 克隆", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "PERFORMTHECLONETOLAUNCHSTEPSWITHTHESETERMINALCOMMANDS", "original": "Perform the _clone-to-launch_ steps with these terminal commands.", "translation": "运行下列命令来执行*克隆并启动*步骤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "NPMSTARTFAILSINBASHFORWINDOWSINVERSIONSEARLIERTHANTHECREATORSUPDATEAPRIL2017", "original": "`npm start` fails in _Bash for Windows_ in versions earlier than the Creator's Update (April 2017).", "translation": "在*Bash for Windows*中 `npm start` 可能会失败,因为到 2017-01 为止它还不支持访问网络上的服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "##DOWNLOAD", "original": "## Download", "translation": "## 下载", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "AHREFHTTPS:GITHUBCOMANGULARQUICKSTARTARCHIVEMASTERZIPTITLEDOWNLOADTHEQUICKSTARTSEEDREPOSITORYDOWNLOADTHEQUICKSTARTSEEDAANDUNZIPITINTOYOURPROJECTFOLDERTHENPERFORMTHEREMAININGSTEPSWITHTHESETERMINALCOMMANDS", "original": "<a href=\"https://github.com/angular/quickstart/archive/master.zip\" title=\"Download the QuickStart seed repository\">Download the QuickStart seed</a>\nand unzip it into your project folder. Then perform the remaining steps with these terminal commands.", "translation": "<a href=\"https://github.com/angular/quickstart/archive/master.zip\" title=\"下载《快速上手》种子库\">下载《快速上手》种子</a>\n并解压到你的项目目录中。然后执行下面的命令完成剩余步骤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "NPMSTARTFAILSINBASHFORWINDOWSINVERSIONSEARLIERTHANTHECREATORSUPDATEAPRIL2017", "original": "`npm start` fails in _Bash for Windows_ in versions earlier than the Creator's Update (April 2017).", "translation": "在*Bash for Windows*中 `npm start` 可能会失败,因为到 2017-01 为止它还不支持访问网络上的服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "##DELETENONESSENTIALFILESOPTIONAL", "original": "## Delete _non-essential_ files (optional)", "translation": "## 删除*非必需*文件(可选)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "YOUCANQUICKLYDELETETHENONESSENTIALFILESTHATCONCERNTESTINGANDQUICKSTARTREPOSITORYMAINTENANCEINCLUDINGALLGITRELATEDARTIFACTSSUCHASTHEGITFOLDERANDGITIGNORE", "original": "You can quickly delete the _non-essential_ files that concern testing and QuickStart repository maintenance\n(***including all git-related artifacts*** such as the `.git` folder and `.gitignore`!).", "translation": "你可以快速删除一些涉及到测试和维护快速开始版本库的 *非必需* 文件\n(***包括所有 git 相关的文件***如 `.git` 文件夹和 `.gitignore`!)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "DOTHISONLYINTHEBEGINNINGTOAVOIDACCIDENTALLYDELETINGYOUROWNTESTSANDGITSETUP", "original": "Do this only in the beginning to avoid accidentally deleting your own tests and git setup!", "translation": "请只在开始时执行此删除操作,以防你自己的测试和 git 文件被意外删除!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "OPENATERMINALWINDOWINTHEPROJECTFOLDERANDENTERTHEFOLLOWINGCOMMANDSFORYOURENVIRONMENT:", "original": "Open a terminal window in the project folder and enter the following commands for your environment:", "translation": "在项目目录下打开一个终端窗口,并根据你的操作系统执行以下命令:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "##WHATSINTHEQUICKSTARTSEED", "original": "## What's in the QuickStart seed?", "translation": "## 《快速上手》种子库里都有什么?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "THEQUICKSTARTSEEDCONTAINSTHESAMEAPPLICATIONASTHEQUICKSTARTPLAYGROUNDBUTITSTRUEPURPOSEISTOPROVIDEASOLIDFOUNDATIONFORLOCALDEVELOPMENTCONSEQUENTLYTHEREAREMANYMOREFILESINTHEPROJECTFOLDERONYOURMACHINEMOSTOFWHICHYOUCANLEARNABOUTLATERGUIDESETUPSYSTEMJSANATOMYSETUPANATOMY", "original": "The **QuickStart seed** contains the same application as the QuickStart playground.\nBut its true purpose is to provide a solid foundation for _local_ development.\nConsequently, there are _many more files_ in the project folder on your machine,\nmost of which you can [learn about later](guide/setup-systemjs-anatomy \"Setup Anatomy\").", "translation": "**《快速上手》种子** 包含了与《快速上手》游乐场一样的应用,但是,它真正的目的是提供坚实的*本地*开发基础。\n所以你的电脑里的项目目录里面有*更多文件*,参见[搭建剖析](guide/setup-systemjs-anatomy \"Setup Anatomy\")。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "FOCUSONTHEFOLLOWINGTHREETYPESCRIPTTSFILESINTHESRCFOLDER", "original": "Focus on the following three TypeScript (`.ts`) files in the **`/src`** folder.", "translation": "注意**`/src`**目录中以下三个 TypeScript (`.ts`) 文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "ALLGUIDESANDCOOKBOOKSHAVEATLEASTTHESECOREFILESEACHFILEHASADISTINCTPURPOSEANDEVOLVESINDEPENDENTLYASTHEAPPLICATIONGROWS", "original": "All guides and cookbooks have _at least these core files_.\nEach file has a distinct purpose and evolves independently as the application grows.", "translation": "所有指南和烹饪书都至少有*这几个核心文件*。每个文件都有独特的用途,并且随着应用的成长各自独立演变。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "FILESOUTSIDESRCCONCERNBUILDINGDEPLOYINGANDTESTINGYOURAPPTHEYINCLUDECONFIGURATIONFILESANDEXTERNALDEPENDENCIES", "original": "Files outside `src/` concern building, deploying, and testing your app.\nThey include configuration files and external dependencies.", "translation": "`src/` 目录之外的文件为构建、部署和测试 app 相关的文件,他们只包括配置文件和外部依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "FILESINSIDESRCBELONGTOYOURAPPADDNEWTYPESCRIPTHTMLANDCSSFILESINSIDETHESRCDIRECTORYMOSTOFTHEMINSIDESRCAPPUNLESSTOLDTODOOTHERWISE", "original": "Files inside `src/` \"belong\" to your app.\nAdd new Typescript, HTML and CSS files inside the `src/` directory, most of them inside `src/app`,\nunless told to do otherwise.", "translation": "`src/` 目录下的文件才“属于”你的 app。\n除非明确指出,否则教程中添加的 TypeScript,HTML 和 CSS 文件都在 `src/` 目录下,\n大多数在 `src/app` 目录中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "THEFOLLOWINGAREALLINSRC", "original": "The following are all in `src/`", "translation": "`src/` 目录文件详情如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "FILE", "original": "File", "translation": "文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "PURPOSE", "original": "Purpose", "translation": "用途", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "DEFINESTHESAMEAPPCOMPONENTASTHEONEINTHEQUICKSTARTPLAYGROUNDITISTHEROOTCOMPONENTOFWHATWILLBECOMEATREEOFNESTEDCOMPONENTSASTHEAPPLICATIONEVOLVES", "original": "Defines the same `AppComponent` as the one in the QuickStart playground.\n It is the **root** component of what will become a tree of nested components\n as the application evolves.", "translation": "定义与《快速上手》游乐场同样的 `AppComponent`。\n 它是**根**组件,随着应用的演变,它将变成一颗嵌套组件树。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "DEFINESAPPMODULETHEROOTMODULEGUIDEBOOTSTRAPPINGAPPMODULE:THEROOTMODULETHATTELLSANGULARHOWTOASSEMBLETHEAPPLICATIONRIGHTNOWITDECLARESONLYTHEAPPCOMPONENTSOONTHEREWILLBEMORECOMPONENTSTODECLARE", "original": "Defines `AppModule`, the [root module](guide/bootstrapping \"AppModule: the root module\") that tells Angular how to assemble the application.\n Right now it declares only the `AppComponent`.\n Soon there will be more components to declare.", "translation": "定义 `AppModule`,[根模块](guide/bootstrapping \"AppModule: 根模块\")为 Angular 描述如何组装应用。\n 目前,它只声明了 `AppComponent`。\n 不久,它将声明更多组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "COMPILESTHEAPPLICATIONWITHTHEJITCOMPILERGUIDEGLOSSARY#JITANDBOOTSTRAPSGUIDEBOOTSTRAPPINGTHEAPPLICATIONSMAINMODULEAPPMODULETORUNINTHEBROWSERTHEJITCOMPILERISAREASONABLECHOICEDURINGTHEDEVELOPMENTOFMOSTPROJECTSANDITSTHEONLYVIABLECHOICEFORASAMPLERUNNINGINALIVECODINGENVIRONMENTLIKESTACKBLITZYOULLLEARNABOUTALTERNATIVECOMPILINGANDDEPLOYMENTGUIDEDEPLOYMENTOPTIONSLATERINTHEDOCUMENTATION", "original": "Compiles the application with the [JIT compiler](guide/glossary#jit) and\n [bootstraps](guide/bootstrapping)\n the application's main module (`AppModule`) to run in the browser.\n The JIT compiler is a reasonable choice during the development of most projects and\n it's the only viable choice for a sample running in a _live-coding_ environment like Stackblitz.\n You'll learn about alternative compiling and [deployment](guide/deployment) options later in the documentation.", "translation": "使[即时 (JIT) 编译器](guide/glossary#jit)用编译应用并且在浏览器中[启动](guide/bootstrapping \"启动应用\")并运行应用。\n 对于大多数项目的开发,这都是合理的选择。而且它是在像 Stackblitz 这样的*在线编程*环境中运行例子的唯一选择。\n 你将在本文档中学习其他编译和开发选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "###NEXTSTEP", "original": "### Next Step", "translation": "### 下一步", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "IFYOURENEWTOANGULARWERECOMMENDYOUFOLLOWTHETUTORIALTUTORIALTOUROFHEROESTUTORIAL", "original": "If you're new to Angular, we recommend you follow the [tutorial](tutorial \"Tour of Heroes tutorial\").", "translation": "如果你是 Angular 初学者,建议跟着[教程](tutorial \"《英雄指南》教程\")学习。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "##APPENDIX:NODEANDNPM", "original": "## Appendix: node and npm", "translation": "## 附录:node 与 npm", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "NODEJSANDNPMAREESSENTIALTOMODERNWEBDEVELOPMENTWITHANGULARANDOTHERPLATFORMSNODEPOWERSCLIENTDEVELOPMENTANDBUILDTOOLSTHENPMPACKAGEMANAGERITSELFANODEAPPLICATIONINSTALLSJAVASCRIPTLIBRARIES", "original": "Node.js and npm are essential to modern web development with Angular and other platforms.\nNode powers client development and build tools.\nThe _npm_ package manager, itself a _node_ application, installs JavaScript libraries.", "translation": "Node.js 和 npm 对使用 Angular 和其他平台进行现代网络开发是至关重要的。\nNode 驱动客户端开发和构建工具。\n*npm* 包管理器本身是 *node* 应用,用于安装 JavaScript 库。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "AHREFHTTPS:DOCSNPMJSCOMGETTINGSTARTEDINSTALLINGNODETARGETBLANKTITLEINSTALLINGNODEJSANDUPDATINGNPMGETTHEMNOWAIFTHEYRENOTALREADYINSTALLEDONYOURMACHINE", "original": "<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.", "translation": "如果你的电脑没有安装它们,请<a href=\"https://docs.npmjs.com/getting-started/installing-node\" target=\"_blank\" title=\"安装 Node.js 和更新 npm\">现在安装</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "VERIFYTHATYOUARERUNNINGNODEV4XXORHIGHERANDNPM3XXORHIGHERBYRUNNINGTHECOMMANDSNODEVANDNPMVINATERMINALCONSOLEWINDOWOLDERVERSIONSPRODUCEERRORS", "original": "**Verify that you are running node `v4.x.x` or higher and npm `3.x.x` or higher**\nby running the commands `node -v` and `npm -v` in a terminal/console window.\nOlder versions produce errors.", "translation": "在终端/控制器窗口运行命令 `node -v` 和 `npm -v`,来**确认你运行的 node 是 `v4.x.x` 或更高,npm 为 `3.x.x` 或更高。**\n老版本会产生错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "WERECOMMENDNVMHTTPS:GITHUBCOMCREATIONIXNVMFORMANAGINGMULTIPLEVERSIONSOFNODEANDNPMYOUMAYNEEDNVMHTTPS:GITHUBCOMCREATIONIXNVMIFYOUALREADYHAVEPROJECTSRUNNINGONYOURMACHINETHATUSEOTHERVERSIONSOFNODEANDNPM", "original": "We recommend [nvm](https://github.com/creationix/nvm) for managing multiple versions of node and npm.\nYou may need [nvm](https://github.com/creationix/nvm) if you already have projects running on your machine that\nuse other versions of node and npm.", "translation": "我们推荐使用 [nvm](https://github.com/creationix/nvm) 来管理多版本 node 和 npm。\n 如果你的电脑上已经有使用其他版本 node 和 npm 的项目,你可能需要 nvm。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "##APPENDIX:WHYDEVELOPLOCALLY", "original": "## Appendix: Why develop locally", "translation": "## 附录:为何在本地开发", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "LIVEEXAMPLETITLEQUICKSTARTSEEDINSTACKBLITZLIVECODINGLIVEEXAMPLEINTHEBROWSERISAGREATWAYTOEXPLOREANGULAR", "original": "<live-example title=\"QuickStart Seed in Stackblitz\">Live coding</live-example> in the browser is a great way to explore Angular.", "translation": "在浏览器中<live-example title=\"QuickStart Seed in Stackblitz\">在线编程</live-example>是很好的探索 Angular 的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "LINKSONALMOSTEVERYDOCUMENTATIONPAGEOPENCOMPLETEDSAMPLESINTHEBROWSERYOUCANPLAYWITHTHESAMPLECODESHAREYOURCHANGESWITHFRIENDSANDDOWNLOADANDRUNTHECODEONYOUROWNMACHINE", "original": "Links on almost every documentation page open completed samples in the browser.\nYou can play with the sample code, share your changes with friends, and download and run the code on your own machine.", "translation": "几乎每章文档里面的链接都在浏览器中打开完整的例子。\n你可以用这些代码做实验,或者与朋友共享你的修改,或者下载并在你自己的电脑上运行这些代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "THEQUICKSTARTGUIDEQUICKSTARTANGULARQUICKSTARTPLAYGROUNDSHOWSJUSTTHEAPPCOMPONENTFILEITCREATESTHEEQUIVALENTOFAPPMODULETSANDMAINTSINTERNALLYFORTHEPLAYGROUNDONLYSOTHEREADERCANDISCOVERANGULARWITHOUTDISTRACTIONTHEOTHERSAMPLESAREBASEDONTHEQUICKSTARTSEED", "original": "The [QuickStart](guide/quickstart \"Angular QuickStart Playground\") shows just the `AppComponent` file.\nIt creates the equivalent of `app.module.ts` and `main.ts` internally _for the playground only_.\nso the reader can discover Angular without distraction.\nThe other samples are based on the QuickStart seed.", "translation": "[快速上手](guide/quickstart \"Angular 快速起步游乐场\")仅仅展示了 `AppComponent` 文件。\n它在内部创建了只为*游乐场*而准备的等价 `app.module.ts` 和 `main.ts`。\n所以读者可以在零干扰的情况下探索 Angular。\n其他例子是基于 《快速上手》种子的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "ASMUCHFUNASTHISIS", "original": "As much fun as this is ...", "translation": "虽然有这么多的乐趣,但是...", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "YOUCANTSHIPYOURAPPINSTACKBLITZ", "original": "* you can't ship your app in Stackblitz", "translation": "你不能在 Stackblitz 里面发布你的应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "YOUARENTALWAYSONLINEWHENWRITINGCODE", "original": "* you aren't always online when writing code", "translation": "编程时你不可能总是在线", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "TRANSPILINGTYPESCRIPTINTHEBROWSERISSLOW", "original": "* transpiling TypeScript in the browser is slow", "translation": "在浏览器中编译 TypeScript 很慢", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "THETYPESUPPORTREFACTORINGANDCODECOMPLETIONONLYWORKINYOURLOCALIDE", "original": "* the type support, refactoring, and code completion only work in your local IDE", "translation": "只有本地 IDE 有类型支持、代码重构和代码自动完成", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "USETHELIVEEXAMPLETITLEQUICKSTARTSEEDINSTACKBLITZLIVECODINGLIVEEXAMPLEENVIRONMENTASAPLAYGROUNDAPLACETOTRYTHEDOCUMENTATIONSAMPLESANDEXPERIMENTONYOUROWNITSTHEPERFECTPLACETOREPRODUCEABUGWHENYOUWANTTOAHREFHTTPS:GITHUBCOMANGULARANGULARISSUESNEWTITLEFILEADOCUMENTATIONISSUEFILEADOCUMENTATIONISSUEAORAHREFHTTPS:GITHUBCOMANGULARANGULARISSUESNEWTITLEFILEANANGULARISSUEFILEANISSUEWITHANGULARITSELFA", "original": "Use the <live-example title=\"QuickStart Seed in Stackblitz\">live coding</live-example> environment as a _playground_,\na place to try the documentation samples and experiment on your own.\nIt's the perfect place to reproduce a bug when you want to\n<a href=\"https://github.com/angular/angular/issues/new\" title=\"File a documentation issue\">file a documentation issue</a> or\n<a href=\"https://github.com/angular/angular/issues/new\" title=\"File an Angular issue\">file an issue with Angular itself</a>.", "translation": "把<live-example title=\"QuickStart Seed in Stackblitz\">在线编程</live-example>环境当做*游乐场*,一个尝试文档例子和自己做实验的地方。\n当你想要<a href=\"https://github.com/angular/angular.io/issues/new\" target=\"_blank\" title=\"提交关于文档的问题\">提交关于文档的问题</a>或者\n<a href=\"https://github.com/angular/angular/issues/new\" target=\"_blank\" title=\"提交关于 Angular 的问题\">提交关于 Angular 自身的问题</a>时,\n它是重现错误的完美地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "FORREALDEVELOPMENTWESTRONGLYRECOMMENDDEVELOPINGLOCALLYGUIDESETUP#DEVELOPLOCALLY", "original": "For real development, we strongly recommend [developing locally](guide/setup#develop-locally).", "translation": "对于现实项目开发,我们强烈推荐在[本地开发](guide/setup#develop-locally)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "##APPENDIX:DEVELOPLOCALLYWITHIE", "original": "## Appendix: develop locally with IE", "translation": "## 附录:使用 IE 进行本地开发", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "IFYOUDEVELOPANGULARLOCALLYWITHNGSERVETHEREWILLBEWEBSOCKETCONNECTIONBEINGSETUPAUTOMATICALLYBETWEENBROWSERANDLOCALDEVSERVERSOWHENYOURCODECHANGEBROWSERCANAUTOMATICALLYREFRESH", "original": "If you develop angular locally with `ng serve`, there will be `websocket` connection being setup automatically between browser and local dev server, so when your code change, browser can automatically refresh.", "translation": "如果你使用 `ng serve` 进行本地开发,就会在浏览器和本地开发服务器之间自动建立一个 `WebSocket` 连接,因此,当你的代码变化时,浏览器也会自动刷新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "INWINDOWSBYDEFAULTONEAPPLICATIONCANONLYHAVE6WEBSOCKETCONNECTIONSAHREFHTTPS:MSDNMICROSOFTCOMLIBRARYEE33073628VVS8529ASPXF255MSPPERROR2147217396#WEBSOCKETMAXCONNTITLEMSDNWEBSOCKETSETTINGSMSDNWEBSOCKETSETTINGSASOIFIEWASREFRESHEDMANUNALLYORAUTOMATICALLYBYNGSERVESOMETIMESTHEWEBSOCKETWILLNOTCLOSEPROPERLYWHENWEBSOCKETCONNECTIONSEXCEEDLIMITATIONSSECURITYERRORWILLBETHROWNTHISERRORWILLNOTAFFECTTHEANGULARAPPLICATIONYOUCANJUSTRESTARTIETOCLEARTHISERRORORMODIFYTHEWINDOWSREGISTRYTOUPDATETHELIMITATIONS", "original": "In windows, by default one application can only have 6 websocket connections, <a href=\"https://msdn.microsoft.com/library/ee330736%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#websocket_maxconn\" title=\"MSDN WebSocket settings\">MSDN WebSocket Settings</a>.\nSo if IE was refreshed manunally or automatically by `ng serve`, sometimes, the websocket will not close properly, when websocket connections exceed limitations, `SecurityError` will be thrown, this error will not affect the angular application, you can just restart IE to clear this error, or modify the windows registry to update the limitations.", "translation": "在 Windows 中,默认情况下一个应用只能有六个 WebSocket 连接,参见 <a href=\"https://msdn.microsoft.com/library/ee330736%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#websocket_maxconn\" title=\"MSDN WebSocket settings\">MSDN 中的 WebSocket 设置部分</a>。\n所以,如果 IE 手动刷新或被 `ng serve` 触发了自动刷新,有时候 WebSocket 可能无法正常关闭,当 WebSocket 的连接数超限时,就会抛出 `SecurityError` 异常。请放心,这个异常对 Angular 应用没什么影响,你重启一下 IE 就能消除这个错误,或者修改 Windows 注册表来修改这个上限。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/setup.md" }, { + "key": "#SHARINGMODULES", "original": "# Sharing Modules", "translation": "# 共享特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "####PREREQUISITES", "original": "#### Prerequisites", "translation": "#### 前提条件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "ABASICUNDERSTANDINGOFTHEFOLLOWING:", "original": "A basic understanding of the following:", "translation": "对下列知识有基本的了解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "FEATUREMODULESGUIDEFEATUREMODULES", "original": "* [Feature Modules](guide/feature-modules).", - "translation": "[特性模块](guide/feature-modules).", + "translation": "[特性模块](guide/feature-modules)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "JAVASCRIPTMODULESVSNGMODULESGUIDENGMODULEVSJSMODULE", "original": "* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).", "translation": "[JavaScript 模块与 NgModules](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "FREQUENTLYUSEDMODULESGUIDEFREQUENTNGMODULES", "original": "* [Frequently Used Modules](guide/frequent-ngmodules).", - "translation": "[常用模块](guide/frequent-ngmodules).", + "translation": "[常用模块](guide/frequent-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "ROUTINGANDNAVIGATIONGUIDEROUTER", "original": "* [Routing and Navigation](guide/router).", - "translation": "[路由与导航](guide/router).", + "translation": "[路由与导航](guide/router)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "LAZYLOADINGMODULESGUIDELAZYLOADINGNGMODULES", "original": "* [Lazy loading modules](guide/lazy-loading-ngmodules).", - "translation": "[惰性加载模块](guide/lazy-loading-ngmodules).", + "translation": "[惰性加载模块](guide/lazy-loading-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "CREATINGSHAREDMODULESALLOWSYOUTOORGANIZEANDSTREAMLINEYOURCODEYOUCANPUTCOMMONLYUSEDDIRECTIVESPIPESANDCOMPONENTSINTOONEMODULEANDTHENIMPORTJUSTTHATMODULEWHEREVERYOUNEEDITINOTHERPARTSOFYOURAPP", "original": "Creating shared modules allows you to organize and streamline your code. You can put commonly\nused directives, pipes, and components into one module and then import just that module wherever\nyou need it in other parts of your app.", "translation": "创建共享模块能让你更好地组织和梳理代码。你可以把常用的指令、管道和组件放进一个模块中,然后在应用中其它需要这些的地方导入该模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "CONSIDERTHEFOLLOWINGMODULEFROMANIMAGINARYAPP:", "original": "Consider the following module from an imaginary app:", "translation": "想象某个应用有下列模块:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "NOTETHEFOLLOWING:", "original": "Note the following:", "translation": "请注意以下几点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "ITIMPORTSTHECOMMONMODULEBECAUSETHEMODULESCOMPONENTNEEDSCOMMONDIRECTIVES", "original": "* It imports the `CommonModule` because the module's component needs common directives.", "translation": "它导入了 `CommonModule`,因为该模块需要一些常用指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "ITDECLARESANDEXPORTSTHEUTILITYPIPEDIRECTIVEANDCOMPONENTCLASSES", "original": "* It declares and exports the utility pipe, directive, and component classes.", "translation": "它声明并导出了一些工具性的管道、指令和组件类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "ITREEXPORTSTHECOMMONMODULEANDFORMSMODULE", "original": "* It re-exports the `CommonModule` and `FormsModule`.", "translation": "它重新导出了 `CommonModule` 和 `FormsModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "BYREEXPORTINGCOMMONMODULEANDFORMSMODULEANYOTHERMODULETHATIMPORTSTHISSHAREDMODULEGETSACCESSTODIRECTIVESLIKENGIFANDNGFORFROMCOMMONMODULEANDCANBINDTOCOMPONENTPROPERTIESWITHNGMODELADIRECTIVEINTHEFORMSMODULE", "original": "By re-exporting `CommonModule` and `FormsModule`, any other module that imports this\n`SharedModule`, gets access to directives like `NgIf` and `NgFor` from `CommonModule`\nand can bind to component properties with `[(ngModel)]`, a directive in the `FormsModule`.", "translation": "通过重新导出 `CommonModule` 和 `FormsModule`,任何导入了这个 `SharedModule` 的其它模块,就都可以访问来自 `CommonModule` 的 `NgIf` 和 `NgFor` 等指令了,也可以绑定到来自 `FormsModule` 中的 `[(ngModel)]` 的属性了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "EVENTHOUGHTHECOMPONENTSDECLAREDBYSHAREDMODULEMIGHTNOTBINDWITHNGMODELANDTHEREMAYBENONEEDFORSHAREDMODULETOIMPORTFORMSMODULESHAREDMODULECANSTILLEXPORTFORMSMODULEWITHOUTLISTINGITAMONGITSIMPORTSTHISWAYYOUCANGIVEOTHERMODULESACCESSTOFORMSMODULEWITHOUTHAVINGTOIMPORTITDIRECTLYINTOTHENGMODULEDECORATOR", "original": "Even though the components declared by `SharedModule` might not bind\nwith `[(ngModel)]` and there may be no need for `SharedModule`\nto import `FormsModule`, `SharedModule` can still export\n`FormsModule` without listing it among its `imports`. This\nway, you can give other modules access to `FormsModule` without\nhaving to import it directly into the `@NgModule` decorator.", "translation": "即使 `SharedModule` 中声明的组件没有绑定过 `[(ngModel)]`,而且`SharedModule` 也不需要导入 `FormsModule`,`SharedModule` 仍然可以导出 `FormsModule`,而不必把它列在 `imports` 中。\n这种方式下,你可以让其它模块也能访问 `FormsModule`,而不用直接在自己的 `@NgModule` 装饰器中导入它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "###USINGCOMPONENTSVSSERVICESFROMOTHERMODULES", "original": "### Using components vs services from other modules.", "translation": "### 使用来自其它模块的组件和服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "THEREISANIMPORTANTDISTINCTIONBETWEENUSINGANOTHERMODULESCOMPONENTANDUSINGASERVICEFROMANOTHERMODULEIMPORTMODULESWHENYOUWANTTOUSEDIRECTIVESPIPESANDCOMPONENTSIMPORTINGAMODULEWITHSERVICESMEANSTHATYOUWILLHAVEANEWINSTANCEOFTHATSERVICEWHICHTYPICALLYISNOTWHATYOUNEEDTYPICALLYONEWANTSTOREUSEANEXISTINGSERVICEUSEMODULEIMPORTSTOCONTROLSERVICEINSTANTIATION", "original": "There is an important distinction between using another module's component and\nusing a service from another module. Import modules when you want to use\ndirectives, pipes, and components. Importing a module with services means that you will have a new instance of that service, which typically is not what you need (typically one wants to reuse an existing service). Use module imports to control service instantiation.", "translation": "在使用来自其它模块的组件和来自其它模块的服务时,有一个很重要的区别。\n当你要使用指令、管道和组件时,导入那些模块就可以了。而导入带有服务的模块意味着你会拥有那个服务的一个新实例,这通常不会是你想要的结果(你通常会想取到现存的服务)。使用模块导入来控制服务的实例化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "THEMOSTCOMMONWAYTOGETAHOLDOFSHAREDSERVICESISTHROUGHANGULARDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONRATHERTHANTHROUGHTHEMODULESYSTEMIMPORTINGAMODULEWILLRESULTINANEWSERVICEINSTANCEWHICHISNOTATYPICALUSAGE", "original": "The most common way to get a hold of shared services is through Angular\n[dependency injection](guide/dependency-injection), rather than through the module system (importing a module will result in a new service instance, which is not a typical usage).", "translation": "获取共享服务的最常见方式是通过 Angular 的[依赖注入系统](guide/dependency-injection),而不是模块系统(导入模块将导致创建新的服务实例,那不是典型的用法)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "TOREADABOUTSHARINGSERVICESSEEPROVIDERSGUIDEPROVIDERS", "original": "To read about sharing services, see [Providers](guide/providers).", "translation": "要进一步了解共享服务,参见[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "YOUMAYALSOBEINTERESTEDINTHEFOLLOWING:", "original": "You may also be interested in the following:", "translation": "你可能还对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "PROVIDERSGUIDEPROVIDERS", "original": "* [Providers](guide/providers).", - "translation": "[服务提供商](guide/providers).", + "translation": "[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "TYPESOFFEATUREMODULESGUIDEMODULETYPES", "original": "* [Types of Feature Modules](guide/module-types).", - "translation": "[特性模块的分类](guide/module-types).", + "translation": "[特性模块的分类](guide/module-types)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/sharing-ngmodules.md" }, { + "key": "#SINGLETONSERVICES", "original": "# Singleton services", "translation": "# 单例应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "####PREREQUISITES:", "original": "#### Prerequisites:", "translation": "#### 前提条件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "ABASICUNDERSTANDINGOFBOOTSTRAPPINGGUIDEBOOTSTRAPPING", "original": "* A basic understanding of [Bootstrapping](guide/bootstrapping).", "translation": "对[引导](guide/bootstrapping)有基本的了解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "FAMILIARITYWITHPROVIDERSGUIDEPROVIDERS", "original": "* Familiarity with [Providers](guide/providers).", "translation": "熟悉[服务提供商](guide/providers)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "FORASAMPLEAPPUSINGTHEAPPWIDESINGLETONSERVICETHATTHISPAGEDESCRIBESSEETHELIVEEXAMPLENAMENGMODULESLIVEEXAMPLESHOWCASINGALLTHEDOCUMENTEDFEATURESOFNGMODULES", "original": "For a sample app using the app-wide singleton service that this page describes, see the\n<live-example name=\"ngmodules\"></live-example> showcasing all the documented features of NgModules.", "translation": "本页中描述的这种全应用级单例服务的例子位于<live-example name=\"ngmodules\"></live-example>,它示范了 NgModule 的所有已文档化的特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "##PROVIDINGASINGLETONSERVICE", "original": "## Providing a singleton service", "translation": "## 提供单例服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "ANINJECTORCREATEDFROMAMODULEDEFINITIONWILLHAVESERVICESWHICHARESINGLETONSWITHRESPECTTOTHATINJECTORTOCONTROLTHELIFETIMEOFSERVICESONECONTROLSTHECREATIONANDDESTRUCTIONOFINJECTORSFOREXAMPLEAROUTEWILLHAVEANASSOCIATEDMODULEWHENTHEROUTEISACTIVATEDANINJECTORISCREATEDFROMTHATMODULEASACHILDOFTHECURRENTINJECTORWHENYOUNAVIGATEAWAYFROMTHEROUTETHEINJECTORISDESTROYEDTHISMEANSTHATSERVICESDECLAREDINAROUTEMODULEWILLHAVEALIFETIMEEQUALTOTHATOFTHEROUTESIMILARLYSERVICESPROVIDEDINANAPPLICATIONMODULEWILLHAVETHESAMELIFETIMEOFTHEAPPLICATIONHENCESINGLETON", "original": "An injector created from a module definition will have services which are singletons with respect to\nthat injector. To control the lifetime of services, one controls the creation and destruction of\ninjectors. For example, a route will have an associated module. When the route is activated, an\ninjector is created from that module as a child of the current injector. When you navigate away from\nthe route, the injector is destroyed. This means that services declared in a route module will have\na lifetime equal to that of the route. Similarly, services provided in an application module will\nhave the same lifetime of the application, hence singleton.", "translation": "那些在定义模块时创建的注入器将会拥有一些服务,这些服务对于该注入器来说都是单例的。要控制这些服务的生命周期,其实就是控制注入器的创建和销毁。\n比如,路由定义中就可以有一个关联模块。当激活该路由时,就会给那个模块创建一个新注入器,并将其作为当前注入器的子注入器。当离开该路由时,这个新注入器也就被销毁了。\n这也意味着在这个模块中声明的那些服务也随之销毁了,它们的生命周期与该路由完全相同。\n类似的,在应用模块中提供的那些服务的生命周期也等同于该应用,因此是单例的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "THEFOLLOWINGEXAMPLEMODULEISCALLEDASACONVENTIONCOREMODULETHISUSEOFNGMODULECREATESORGANIZATIONALINFRASTRUCTUREANDGIVESYOUAWAYOFPROVIDINGSERVICESFROMADESIGNATEDNGMODULE", "original": "The following example module is called, as a convention, `CoreModule`. This use of `@NgModule` creates organizational infrastructure and gives you\na way of providing services from a designated NgModule.", "translation": "下面的范例模块习惯上叫做 `CoreModule`。`@NgModule` 用来创建结构良好的基础设施,让你能够在一个指定的模块中提供服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "HERECOREMODULEPROVIDESTHEUSERSERVICEANDBECAUSEAPPMODULEIMPORTSCOREMODULEANYSERVICESTHATCOREMODULEPROVIDESAREAVAILABLETHROUGHOUTTHEAPPBECAUSEITISAROOTOFTHEINJECTORTREEITWILLALSOBEASINGLETONBECAUSETHEINJECTORLIFETIMEOFTHEAPPMODULEISFORTHEDURATIONOFTHEAPPLICATION", "original": "Here, `CoreModule` provides the `UserService`, and because `AppModule`\nimports `CoreModule`, any services that `CoreModule` provides are available\nthroughout 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.", "translation": "这里的 `CoreModule` 提供了 `UserService`,并且由于 `AppModule` 导入了 `CoreModule`,所以 `CoreModule` 中提供的任何服务也能在整个应用中使用,因为它是注入器树的根节点。\n它还是单例的,因为在该应用运行期间,该注入器的生命周期等同于 `AppModule` 的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "ANGULARREGISTERSTHEUSERSERVICEPROVIDERWITHTHEAPPROOTINJECTORMAKINGASINGLETONINSTANCEOFTHEUSERSERVICEAVAILABLETOANYCOMPONENTTHATNEEDSITWHETHERTHATCOMPONENTISEAGERLYORLAZILYLOADED", "original": "Angular registers the `UserService` provider with the app root\ninjector, making a singleton instance of the `UserService`\navailable to any component that needs it,\nwhether that component is eagerly or lazily loaded.", "translation": "Angular 使用应用的根注入器注册了 `UserService` 提供商,可以让任何需要它的组件(无论它是立即加载的还是惰性加载的)都能使用 `UserService` 的单例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "THEROOTAPPMODULECOULDREGISTERTHEUSERSERVICEDIRECTLYBUTASTHEAPPGROWSITCOULDHAVEOTHERSERVICESANDCOMPONENTSLIKESPINNERSMODALSANDSOONTOKEEPYOURAPPORGANIZEDCONSIDERUSINGAMODULESUCHASCOREMODULETHISTECHNIQUESIMPLIFIESTHEROOTAPPMODULEINITSCAPACITYASORCHESTRATOROFTHEAPPLICATIONASAWHOLE", "original": "The root `AppModule` could register the `UserService` directly,\nbut as the app grows, it could have other services and\ncomponents like spinners, modals, and so on. To\nkeep your app organized, consider using a module such as `CoreModule`.\nThis technique simplifies the root `AppModule` in its\ncapacity as orchestrator of the application as a whole.", "translation": "根模块 `AppModule` 当然也可以直接注册 `UserService`,不过随着应用的成长,可能还会出现其它的服务和组件,比如 列表框、模态框等等。\n要想保持你应用的良好结构,就要考虑使用诸如 `CoreModule` 这样的模块。\n这种方式简化了根模块 `AppModule`,让它只需要扮演整个应用的总指挥,而不必事必躬亲。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "NOWYOUCANINJECTSUCHSERVICESINTOCOMPONENTSASNEEDEDINTERMSOFANGULARNGMODULESYOUONLYNEEDTODEFINETHESERVICESINONENGMODULESEEJSMODULESVSNGMODULESGUIDENGMODULEVSJSMODULEFORMOREINFORMATIONONHOWTODIFFERENTIATEBETWEENTHETWO", "original": "Now you can inject such services into components as needed. In terms of\nAngular NgModules, you only need to define the services in one `@NgModule`.\nSee [JS Modules vs. NgModules](guide/ngmodule-vs-jsmodule) for\nmore information on how to differentiate between the two.", "translation": "现在,你可以把这些服务注入到需要它们的各个组件中了。\n从 Angular 模块的角度来说,你只需要把这些服务定义在一个 `@NgModule` 中。\n要想深入了解两者的区别,参见 [JS 模块 vs. NgModule](guide/ngmodule-vs-jsmodule)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "ASAGENERALRULEIMPORTMODULESWITHPROVIDERSEXACTLYONCEPREFERABLYINTHEAPPLICATIONSROOTMODULETHATSALSOUSUALLYTHEBESTPLACETOCONFIGUREWRAPANDOVERRIDETHEM", "original": "As a general rule, import modules with providers _exactly once_,\npreferably in the application's _root module_.\nThat's also usually the best place to configure, wrap, and override them.", "translation": "作为一个通用的规则,应该*只导入一次*带提供商的模块,最好在应用的*根模块*中。\n那里也是配置、包装和改写这些服务的最佳位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "FORMOREDETAILEDINFORMATIONONSERVICESSEETHESERVICESTUTORIALTOHPT4CHAPTEROFTHETOUROFHEROESTUTORIALTUTORIAL", "original": "For more detailed information on services, see the [Services](tutorial/toh-pt4) chapter of the\n[Tour of Heroes tutorial](tutorial).", "translation": "要想深入了解关于服务的信息,参见[《英雄指南》教程](tutorial)中的[服务](tutorial/toh-pt4)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "IFAMODULEPROVIDESBOTHPROVIDERSANDDECLARATIONSCOMPONENTSDIRECTIVESPIPESTHENLOADINGITINACHILDINJECTORSUCHASAROUTEWOULDDUPLICATETHEPROVIDERINSTANCESTHEDUPLICATIONOFPROVIDERSWOULDCAUSEISSUESASTHEYWOULDSHADOWTHEROOTINSTANCESWHICHAREPROBABLYMEANTTOBESINGLETONSFORTHISREASONANGULARPROVIDESAWAYTOSEPARATEPROVIDERSOUTOFTHEMODULESOTHATSAMEMODULECANBEIMPORTEDINTOTHEROOTMODULEWITHPROVIDERSANDCHILDMODULESWITHOUTPROVIDERS", "original": "If a module provides both providers and declarations (components, directives, pipes) then loading it in a child injector such as a route, would duplicate the provider instances. The duplication of providers would cause issues as they would shadow the root instances, which are probably meant to be singletons. For this reason Angular provides a way to separate providers out of the module so that same module can be imported into the root module with `providers` and child modules without `providers`.", "translation": "如果某个模块同时提供了服务提供商和可声明对象(组件、指令、管道),那么当在某个子注入器中加载它的时候(比如路由),就会生成多个该服务提供商的实例。\n而存在多个实例会导致一些问题,因为这些实例会屏蔽掉根注入器中该服务提供商的实例,而它的本意可能是作为单例对象使用的。\n因此,Angular 提供了一种方式来把服务提供商从该模块中分离出来,以便该模块既可以带着 `providers` 被根模块导入,也可以不带 `providers` 被子模块导入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "1CREATEASTATICMETHODFORROOTBYCONVENTIONONTHEMODULE", "original": "1. Create a static method `forRoot()` (by convention) on the module.", "translation": "在该模块上创建一个静态方法 `forRoot()`(习惯名称)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "2PLACETHEPROVIDERSINTOTHEFORROOTMETHODASFOLLOWS", "original": "2. Place the providers into the `forRoot` method as follows.", "translation": "把那些服务提供商放进 `forRoot` 方法中,参见下面的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "TOMAKETHISMORECONCRETECONSIDERTHEROUTERMODULEASANEXAMPLEROUTERMODULENEEDSTOPROVIDETHEROUTERSERVICEASWELLASTHEROUTEROUTLETDIRECTIVEROUTERMODULEHASTOBEIMPORTEDBYTHEROOTAPPLICATIONMODULESOTHATTHEAPPLICATIONHASAROUTERANDTHEAPPLICATIONHASATLEASTONEROUTEROUTLETITALSOMUSTBEIMPORTEDBYTHEINDIVIDUALROUTECOMPONENTSSOTHATTHEYCANPLACEROUTEROUTLETDIRECTIVESINTOTHEIRTEMPLATEFORSUBROUTES", "original": "To make this more concrete, consider the `RouterModule` as an example. `RouterModule` needs to provide the `Router` service, as well as the `RouterOutlet` directive. `RouterModule` has to be imported by the root application module so that the application has a `Router` and the application has at least one `RouterOutlet`. It also must be imported by the individual route components so that they can place `RouterOutlet` directives into their template for sub-routes.", "translation": "以 `RouterModule` 为例具体说说。`RouterModule` 要提供 `Router` 服务,还要提供 `RouterOutlet` 指令。\n`RouterModule` 要由根应用模块导入,以便该应用拥有一个路由器,而且它还需要至少一个 `RouterOutlet`。\n`RouterModule` 还必须由各个独立的路由组件导入,让它们能在自己的模板中使用 `RouterOutlet` 指令来支持其子路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "IFTHEROUTERMODULEDIDNTHAVEFORROOTTHENEACHROUTECOMPONENTWOULDINSTANTIATEANEWROUTERINSTANCEWHICHWOULDBREAKTHEAPPLICATIONASTHERECANONLYBEONEROUTERFORTHISREASONTHEROUTERMODULEHASTHEROUTEROUTLETDECLARATIONSOTHATITISAVAILABLEEVERYWHEREBUTTHEROUTERPROVIDERISONLYINTHEFORROOTTHERESULTISTHATTHEROOTAPPLICATIONMODULEIMPORTSROUTERMODULEFORROOTANDGETSAROUTERWHEREASALLROUTECOMPONENTSIMPORTROUTERMODULEWHICHDOESNOTINCLUDETHEROUTER", "original": "If the `RouterModule` didn’t have `forRoot()` then each route component would instantiate a new `Router` instance, which would break the application as there can only be one `Router`. For this reason, the `RouterModule` has the `RouterOutlet` declaration so that it is available everywhere, but the `Router` provider is only in the `forRoot()`. The result is that the root application module imports `RouterModule.forRoot(...)` and gets a `Router`, whereas all route components import `RouterModule` which does not include the `Router`.", "translation": "如果 `RouterModule` 没有 `forRoot()`,那么每个路由组件都会创建一个新的 `Router` 实例。这将会破坏整个应用,因为应用中只能有一个 `Router`。\n`RouterModule` 拥有 `RouterOutlet` 指令,它应该随处可用,但是 `Router` 只能有一个,它应该在 `forRoot()` 中提供。\n最终的结果就是,应用的根模块导入了 `RouterModule.forRoot(...)` 以获取 `Router`,而所有路由组件都导入了 `RouterModule`,它不包括这个 `Router` 服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "IFYOUHAVEAMODULEWHICHPROVIDESBOTHPROVIDERSANDDECLARATIONSUSETHISPATTERNTOSEPARATETHEMOUT", "original": "If you have a module which provides both providers and declarations, use this pattern to separate them out.", "translation": "如果你有一个同时提供服务提供商和可声明对象的模块,请使用下面的模式把它们分离开。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "AMODULETHATADDSPROVIDERSTOTHEAPPLICATIONCANOFFERAFACILITYFORCONFIGURINGTHOSEPROVIDERSASWELLTHROUGHTHEFORROOTMETHOD", "original": "A module that adds providers to the application can offer a\nfacility for configuring those providers as well through the\n`forRoot()` method.", "translation": "那些需要把服务提供商加到应用中的模块可以通过某种类似 `forRoot()` 方法的方式配置那些服务提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "FORROOTTAKESASERVICECONFIGURATIONOBJECTANDRETURNSAMODULEWITHPROVIDERSAPICOREMODULEWITHPROVIDERSWHICHISASIMPLEOBJECTWITHTHEFOLLOWINGPROPERTIES:", "original": "`forRoot()` takes a service configuration object and returns a\n[ModuleWithProviders](api/core/ModuleWithProviders), which is\na simple object with the following properties:", "translation": "`forRoot()` 接收一个服务配置对象,然后返回一个 [ModuleWithProviders](api/core/ModuleWithProviders) ,它是一个带有下列属性的简单对象:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "NGMODULE:INTHISEXAMPLETHECOREMODULECLASS", "original": "* `ngModule`: in this example, the `CoreModule` class.", "translation": "`ngModule`: 在这个例子中就是 `CoreModule` 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "PROVIDERS:THECONFIGUREDPROVIDERS", "original": "* `providers`: the configured providers.", "translation": "`providers` - 配置好的服务提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "INTHELIVEEXAMPLENAMENGMODULESLIVEEXAMPLELIVEEXAMPLETHEROOTAPPMODULEIMPORTSTHECOREMODULEANDADDSTHEPROVIDERSTOTHEAPPMODULEPROVIDERSSPECIFICALLYANGULARACCUMULATESALLIMPORTEDPROVIDERSBEFOREAPPENDINGTHEITEMSLISTEDINNGMODULEPROVIDERSTHISSEQUENCEENSURESTHATWHATEVERYOUADDEXPLICITLYTOTHEAPPMODULEPROVIDERSTAKESPRECEDENCEOVERTHEPROVIDERSOFIMPORTEDMODULES", "original": "In the <live-example name=\"ngmodules\">live example</live-example>\nthe root `AppModule` imports the `CoreModule` and adds the\n`providers` to the `AppModule` providers. Specifically,\nAngular accumulates all imported providers\nbefore appending the items listed in `@NgModule.providers`.\nThis sequence ensures that whatever you add explicitly to\nthe `AppModule` providers takes precedence over the providers\nof imported modules.", "translation": "在这个<live-example name=\"ngmodules\"></live-example>中,根 `AppModule` 导入了 `CoreModule`,并把它的 `providers` 添加到了 `AppModule` 的服务提供商中。\n特别是,Angular 会在 `@NgModule.providers` 前面添加这些导入的服务提供商。\n这种顺序保证了 `AppModule` 中的服务提供商总是会优先于那些从其它模块中导入的服务提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "IMPORTCOREMODULEANDUSEITSFORROOTMETHODONETIMEINAPPMODULEBECAUSEITREGISTERSSERVICESANDYOUONLYWANTTOREGISTERTHOSESERVICESONETIMEINYOURAPPIFYOUWERETOREGISTERTHEMMORETHANONCEYOUCOULDENDUPWITHMULTIPLEINSTANCESOFTHESERVICEANDARUNTIMEERROR", "original": "Import `CoreModule` and use its `forRoot()` method one time, in `AppModule`, because it registers services and you only want to register those services one time in your app. If you were to register them more than once, you could end up with multiple instances of the service and a runtime error.", "translation": "应该只在 `AppModule` 中导入 `CoreModule` 并只使用一次 `forRoot()` 方法,因为该方法中会注册服务,而你希望那些服务在该应用中只注册一次。\n如果你多次注册它们,就可能会得到该服务的多个实例,并导致运行时错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "YOUCANALSOADDAFORROOTMETHODINTHECOREMODULETHATCONFIGURESTHECOREUSERSERVICE", "original": "You can also add a `forRoot()` method in the `CoreModule` that configures\nthe core `UserService`.", "translation": "你还可以在 `CoreModule` 中添加一个用于配置 `UserService` 的 `forRoot()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "INTHEFOLLOWINGEXAMPLETHEOPTIONALINJECTEDUSERSERVICECONFIGEXTENDSTHECOREUSERSERVICEIFAUSERSERVICECONFIGEXISTSTHEUSERSERVICESETSTHEUSERNAMEFROMTHATCONFIG", "original": "In the following example, the optional, injected `UserServiceConfig`\nextends the core `UserService`. If a `UserServiceConfig` exists, the `UserService` sets the user name from that config.", "translation": "在下面的例子中,可选的注入 `UserServiceConfig` 扩展了 `Core` 模块中的 `UserService`。如果 `UserServiceConfig` 存在,就从这个配置中设置用户名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "HERESFORROOTTHATTAKESAUSERSERVICECONFIGOBJECT:", "original": "Here's `forRoot()` that takes a `UserServiceConfig` object:", "translation": "下面是一个接受 `UserServiceConfig` 参数的 `forRoot()` 方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "LASTLYCALLITWITHINTHEIMPORTSLISTOFTHEAPPMODULE", "original": "Lastly, call it within the `imports` list of the `AppModule`.", "translation": "最后,在 `AppModule` 的 `imports`*列表*中调用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "THEAPPDISPLAYSMISSMARPLEASTHEUSERINSTEADOFTHEDEFAULTSHERLOCKHOLMES", "original": "The app displays \"Miss Marple\" as the user instead of the default \"Sherlock Holmes\".", "translation": "该应用不再显示默认的 “Sherlock Holmes”,而是用 “Miss Marple” 作为用户名称。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "REMEMBERTOIMPORTCOREMODULEASAJAVASCRIPTIMPORTATTHETOPOFTHEFILEDONTADDITTOMORETHANONENGMODULEIMPORTSLIST", "original": "Remember to _import_ `CoreModule` as a Javascript import at the top of the file; don't add it to more than one `@NgModule` `imports` list.", "translation": "记住,在文件顶部使用 JavaScript 的 `import` 语句*导入* `CoreModule`,但不要在多于一个 `@NgModule` 的 `imports` 列表中添加它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "##PREVENTREIMPORTOFTHECOREMODULE", "original": "## Prevent reimport of the `CoreModule`", "translation": "## 防止重复导入 `CoreModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "ONLYTHEROOTAPPMODULESHOULDIMPORTTHECOREMODULEIFALAZYLOADEDMODULEIMPORTSITTOOTHEAPPCANGENERATEMULTIPLEINSTANCESGUIDENGMODULEFAQ#QWHYBADOFASERVICE", "original": "Only the root `AppModule` should import the `CoreModule`. If a\nlazy-loaded module imports it too, the app can generate\n[multiple instances](guide/ngmodule-faq#q-why-bad) of a service.", "translation": "只有根模块 `AppModule` 才能导入 `CoreModule`。如果一个惰性加载模块也导入了它,\n该应用就会为服务生成[多个实例](guide/ngmodule-faq#q-why-bad)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "TOGUARDAGAINSTALAZYLOADEDMODULEREIMPORTINGCOREMODULEADDTHEFOLLOWINGCOREMODULECONSTRUCTOR", "original": "To guard against a lazy-loaded module re-importing `CoreModule`, add the following `CoreModule` constructor.", "translation": "要想防止惰性加载模块重复导入 `CoreModule`,可以添加如下的 `CoreModule` 构造函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "THECONSTRUCTORTELLSANGULARTOINJECTTHECOREMODULEINTOITSELFTHEINJECTIONWOULDBECIRCULARIFANGULARLOOKEDFORCOREMODULEINTHECURRENTINJECTORTHESKIPSELFDECORATORMEANSLOOKFORCOREMODULEINANANCESTORINJECTORABOVEMEINTHEINJECTORHIERARCHY", "original": "The constructor tells Angular to inject the `CoreModule` into itself.\nThe injection would be circular if Angular looked for\n`CoreModule` in the _current_ injector. The `@SkipSelf`\ndecorator means \"look for `CoreModule` in an ancestor\ninjector, above me in the injector hierarchy.\"", "translation": "这个构造函数要求 Angular 把 `CoreModule` 注入到它自己。\n如果 Angular 在*当前*注入器中查找 `CoreModule`,这个注入过程就会陷入死循环。\n而 `@SkipSelf` 装饰器表示 “在注入器树中那些高于我的祖先注入器中查找 `CoreModule`”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "IFTHECONSTRUCTOREXECUTESASINTENDEDINTHEAPPMODULETHEREWOULDBENOANCESTORINJECTORTHATCOULDPROVIDEANINSTANCEOFCOREMODULEANDTHEINJECTORSHOULDGIVEUP", "original": "If the constructor executes as intended in the `AppModule`,\nthere would be no ancestor injector that could provide an instance of `CoreModule` and the injector should give up.", "translation": "如果构造函数在 `AppModule` 中执行,那就没有祖先注入器能提供 `CoreModule` 的实例,于是注入器就会放弃查找。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "BYDEFAULTTHEINJECTORTHROWSANERRORWHENITCANTFINDAREQUESTEDPROVIDERTHEOPTIONALDECORATORMEANSNOTFINDINGTHESERVICEISOKTHEINJECTORRETURNSNULLTHEPARENTMODULEPARAMETERISNULLANDTHECONSTRUCTORCONCLUDESUNEVENTFULLY", "original": "By default, the injector throws an error when it can't\nfind a requested provider.\nThe `@Optional` decorator means not finding the service is OK.\nThe injector returns `null`, the `parentModule` parameter is null,\nand the constructor concludes uneventfully.", "translation": "默认情况下,当注入器找不到想找的提供商时,会抛出一个错误。\n但 `@Optional` 装饰器表示找不到该服务也无所谓。\n于是注入器会返回 `null`,`parentModule` 参数也就被赋成了空值,而构造函数没有任何异常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "ITSADIFFERENTSTORYIFYOUIMPROPERLYIMPORTCOREMODULEINTOALAZYLOADEDMODULESUCHASCUSTOMERSMODULE", "original": "It's a different story if you improperly import `CoreModule` into a lazy-loaded module such as `CustomersModule`.", "translation": "但如果你把 `CoreModule` 导入到像 `CustomerModule` 这样的惰性加载模块中,事情就不一样了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "ANGULARCREATESALAZYLOADEDMODULEWITHITSOWNINJECTORACHILDOFTHEROOTINJECTORSKIPSELFCAUSESANGULARTOLOOKFORACOREMODULEINTHEPARENTINJECTORWHICHTHISTIMEISTHEROOTINJECTOROFCOURSEITFINDSTHEINSTANCEIMPORTEDBYTHEROOTAPPMODULENOWPARENTMODULEEXISTSANDTHECONSTRUCTORTHROWSTHEERROR", "original": "Angular creates a lazy-loaded module with its own injector,\na _child_ of the root injector.\n`@SkipSelf` causes Angular to look for a `CoreModule` in the parent injector, which this time is the root injector.\nOf course it finds the instance imported by the root `AppModule`.\nNow `parentModule` exists and the constructor throws the error.", "translation": "Angular 会创建一个惰性加载模块,它具有自己的注入器,它是根注入器的*子注入器*。\n`@SkipSelf` 让 Angular 在其父注入器中查找 `CoreModule`,这次,它的父注入器却是根注入器了(而上次的父注入器是空)。\n当然,这次它找到了由根模块 `AppModule` 导入的实例。\n该构造函数检测到存在 `parentModule`,于是抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "HEREARETHETWOFILESINTHEIRENTIRETYFORREFERENCE:", "original": "Here are the two files in their entirety for reference:", "translation": "以下这两个文件仅供参考:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "##MOREONNGMODULES", "original": "## More on NgModules", "translation": "## 关于 NgModule 的更多知识", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "YOUMAYALSOBEINTERESTEDIN:", "original": "You may also be interested in:", "translation": "你还可能对下列内容感兴趣:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "SHARINGMODULESGUIDESHARINGNGMODULESWHICHELABORATESONTHECONCEPTSCOVEREDONTHISPAGE", "original": "* [Sharing Modules](guide/sharing-ngmodules), which elaborates on the concepts covered on this page.", "translation": "[共享模块](guide/sharing-ngmodules)解释了本页中涉及的这些概念。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "LAZYLOADINGMODULESGUIDELAZYLOADINGNGMODULES", "original": "* [Lazy Loading Modules](guide/lazy-loading-ngmodules).", "translation": "[惰性加载模块](guide/lazy-loading-ngmodules)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "NGMODULEFAQGUIDENGMODULEFAQ", "original": "* [NgModule FAQ](guide/ngmodule-faq).", "translation": "[NgModule 常见问题](guide/ngmodule-faq)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/singleton-services.md" }, { + "key": "#STRUCTURALDIRECTIVES", "original": "# Structural Directives", "translation": "# 结构型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THISGUIDELOOKSATHOWANGULARMANIPULATESTHEDOMWITHSTRUCTURALDIRECTIVESANDHOWYOUCANWRITEYOUROWNSTRUCTURALDIRECTIVESTODOTHESAMETHING", "original": "This guide looks at how Angular manipulates the DOM with **structural directives** and\nhow you can write your own structural directives to do the same thing.", "translation": "本章将看看 Angular 如何用*结构型指令*操纵 DOM 树,以及你该如何写自己的结构型指令来完成同样的任务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "TRYTHELIVEEXAMPLELIVEEXAMPLE", "original": "Try the <live-example></live-example>.", "translation": "试试<live-example></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##WHATARESTRUCTURALDIRECTIVES", "original": "## What are structural directives?", "translation": "## 什么是结构型指令?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "STRUCTURALDIRECTIVESARERESPONSIBLEFORHTMLLAYOUTTHEYSHAPEORRESHAPETHEDOMSSTRUCTURETYPICALLYBYADDINGREMOVINGORMANIPULATINGELEMENTS", "original": "Structural directives are responsible for HTML layout.\nThey shape or reshape the DOM's _structure_, typically by adding, removing, or manipulating\nelements.", "translation": "结构型指令的职责是 HTML 布局。\n它们塑造或重塑 DOM 的结构,比如添加、移除或维护这些元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ASWITHOTHERDIRECTIVESYOUAPPLYASTRUCTURALDIRECTIVETOAHOSTELEMENTTHEDIRECTIVETHENDOESWHATEVERITSSUPPOSEDTODOWITHTHATHOSTELEMENTANDITSDESCENDANTS", "original": "As with other directives, you apply a structural directive to a _host element_.\nThe directive then does whatever it's supposed to do with that host element and its descendants.", "translation": "像其它指令一样,你可以把结构型指令应用到一个*宿主元素*上。\n然后它就可以对宿主元素及其子元素做点什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "STRUCTURALDIRECTIVESAREEASYTORECOGNIZEANASTERISKPRECEDESTHEDIRECTIVEATTRIBUTENAMEASINTHISEXAMPLE", "original": "Structural directives are easy to recognize.\nAn asterisk (*) precedes the directive attribute name as in this example.", "translation": "结构型指令非常容易识别。\n在这个例子中,星号(*)被放在指令的属性名之前。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "NOBRACKETSNOPARENTHESESJUSTNGIFSETTOASTRING", "original": "No brackets. No parentheses. Just `*ngIf` set to a string.", "translation": "没有方括号,没有圆括号,只是把 `*ngIf` 设置为一个字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOULLLEARNINTHISGUIDETHATTHEASTERISKISACONVENIENCENOTATIONGUIDESTRUCTURALDIRECTIVES#ASTERISKANDTHESTRINGISAMICROSYNTAXGUIDESTRUCTURALDIRECTIVES#MICROSYNTAXRATHERTHANTHEUSUALTEMPLATEEXPRESSIONGUIDETEMPLATESYNTAX#TEMPLATEEXPRESSIONSANGULARDESUGARSTHISNOTATIONINTOAMARKEDUPNGTEMPLATETHATSURROUNDSTHEHOSTELEMENTANDITSDESCENDENTSEACHSTRUCTURALDIRECTIVEDOESSOMETHINGDIFFERENTWITHTHATTEMPLATE", "original": "You'll learn in this guide that the [asterisk (*) is a convenience notation](guide/structural-directives#asterisk)\nand the string is a [_microsyntax_](guide/structural-directives#microsyntax) rather than the usual\n[template expression](guide/template-syntax#template-expressions).\nAngular desugars this notation into a marked-up `<ng-template>` that surrounds the\nhost element and its descendents.\nEach structural directive does something different with that template.", "translation": "在这个例子中,你将学到[星号(*)这个简写方法](guide/structural-directives#asterisk),而这个字符串是一个[*微语法*](guide/structural-directives#microsyntax),而不是通常的[模板表达式](guide/template-syntax#template-expressions)。\nAngular 会解开这个语法糖,变成一个 `<ng-template>` 标记,包裹着宿主元素及其子元素。\n每个结构型指令都可以用这个模板做点不同的事情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THREEOFTHECOMMONBUILTINSTRUCTURALDIRECTIVESMDASHNGIFGUIDETEMPLATESYNTAX#NGIFNGFORGUIDETEMPLATESYNTAX#NGFORANDNGSWITCHGUIDETEMPLATESYNTAX#NGSWITCHMDASHAREDESCRIBEDINTHETEMPLATESYNTAXGUIDETEMPLATESYNTAXGUIDEANDSEENINSAMPLESTHROUGHOUTTHEANGULARDOCUMENTATIONHERESANEXAMPLEOFTHEMINATEMPLATE:", "original": "Three of the common, built-in structural directives—[NgIf](guide/template-syntax#ngIf),\n[NgFor](guide/template-syntax#ngFor), and [NgSwitch...](guide/template-syntax#ngSwitch)—are\ndescribed in the [_Template Syntax_](guide/template-syntax) guide and seen in samples throughout the Angular documentation.\nHere's an example of them in a template:", "translation": "三个常用的内置结构型指令 —— [NgIf](guide/template-syntax#ngIf)、[NgFor](guide/template-syntax#ngFor)和[NgSwitch...](guide/template-syntax#ngSwitch)。\n你在[*模板语法*](guide/template-syntax)一章中学过它,并且在 Angular 文档的例子中到处都在用它。下面是模板中的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THISGUIDEWONTREPEATHOWTOUSETHEMBUTITDOESEXPLAINHOWTHEYWORKANDHOWTOWRITEYOUROWNGUIDESTRUCTURALDIRECTIVES#UNLESSSTRUCTURALDIRECTIVE", "original": "This guide won't repeat how to _use_ them. But it does explain _how they work_\nand how to [write your own](guide/structural-directives#unless) structural directive.", "translation": "本章不会重复讲如何*使用*它们,而是解释它们的*工作原理*以及如何[写自己的结构型指令](guide/structural-directives#unless)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "HEADERDIRECTIVESPELLINGHEADER", "original": "<header>Directive spelling</header>", "translation": "<header>指令的拼写形式</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THROUGHOUTTHISGUIDEYOULLSEEADIRECTIVESPELLEDINBOTHUPPERCAMELCASEANDLOWERCAMELCASEALREADYYOUVESEENNGIFANDNGIFTHERESAREASONNGIFREFERSTOTHEDIRECTIVECLASSNGIFREFERSTOTHEDIRECTIVESATTRIBUTENAME", "original": "Throughout this guide, you'll see a directive spelled in both _UpperCamelCase_ and _lowerCamelCase_.\nAlready you've seen `NgIf` and `ngIf`.\nThere's a reason. `NgIf` refers to the directive _class_;\n`ngIf` refers to the directive's _attribute name_.", "translation": "在本章中,你将看到指令同时具有两种拼写形式*大驼峰 `UpperCamelCase` 和小驼峰 `lowerCamelCase`,比如你已经看过的 `NgIf` 和 `ngIf`。\n这里的原因在于,`NgIf` 引用的是指令的*类名*,而 `ngIf` 引用的是指令的*属性名*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ADIRECTIVECLASSISSPELLEDINUPPERCAMELCASENGIFADIRECTIVESATTRIBUTENAMEISSPELLEDINLOWERCAMELCASENGIFTHEGUIDEREFERSTOTHEDIRECTIVECLASSWHENTALKINGABOUTITSPROPERTIESANDWHATTHEDIRECTIVEDOESTHEGUIDEREFERSTOTHEATTRIBUTENAMEWHENDESCRIBINGHOWYOUAPPLYTHEDIRECTIVETOANELEMENTINTHEHTMLTEMPLATE", "original": "A directive _class_ is spelled in _UpperCamelCase_ (`NgIf`).\nA directive's _attribute name_ is spelled in _lowerCamelCase_ (`ngIf`).\nThe guide refers to the directive _class_ when talking about its properties and what the directive does.\nThe guide refers to the _attribute name_ when describing how\nyou apply the directive to an element in the HTML template.", "translation": "指令的*类名*拼写成*大驼峰形式*(`NgIf`),而它的*属性名*则拼写成*小驼峰形式*(`ngIf`)。\n本章会在谈论指令的属性和工作原理时引用指令的*类名*,在描述如何在 HTML 模板中把该指令应用到元素时,引用指令的*属性名*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEREARETWOOTHERKINDSOFANGULARDIRECTIVESDESCRIBEDEXTENSIVELYELSEWHERE:1NBSPCOMPONENTSAND2NBSPATTRIBUTEDIRECTIVES", "original": "There are two other kinds of Angular directives, described extensively elsewhere:\n(1) components and (2) attribute directives.", "translation": "还有另外两种 Angular 指令,在本开发指南的其它地方有讲解:(1) 组件 (2) 属性型指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ACOMPONENTMANAGESAREGIONOFHTMLINTHEMANNEROFANATIVEHTMLELEMENTTECHNICALLYITSADIRECTIVEWITHATEMPLATE", "original": "A *component* manages a region of HTML in the manner of a native HTML element.\nTechnically it's a directive with a template.", "translation": "*组件*可以在原生 HTML 元素中管理一小片区域的 HTML。从技术角度说,它就是一个带模板的指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ANATTRIBUTEDIRECTIVEGUIDEATTRIBUTEDIRECTIVESCHANGESTHEAPPEARANCEORBEHAVIOROFANELEMENTCOMPONENTORANOTHERDIRECTIVEFOREXAMPLETHEBUILTINNGSTYLEGUIDETEMPLATESYNTAX#NGSTYLEDIRECTIVECHANGESSEVERALELEMENTSTYLESATTHESAMETIME", "original": "An [*attribute* directive](guide/attribute-directives) changes the appearance or behavior\nof an element, component, or another directive.\nFor example, the built-in [`NgStyle`](guide/template-syntax#ngStyle) directive\nchanges several element styles at the same time.", "translation": "[*属性型*指令](guide/attribute-directives)会改变某个元素、组件或其它指令的外观或行为。\n比如,内置的[`NgStyle`](guide/template-syntax#ngStyle)指令可以同时修改元素的多个样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOUCANAPPLYMANYATTRIBUTEDIRECTIVESTOONEHOSTELEMENTYOUCANONLYAPPLYONEGUIDESTRUCTURALDIRECTIVES#ONEPERELEMENTSTRUCTURALDIRECTIVETOAHOSTELEMENT", "original": "You can apply many _attribute_ directives to one host element.\nYou can [only apply one](guide/structural-directives#one-per-element) _structural_ directive to a host element.", "translation": "你可以在一个宿主元素上应用多个*属性型*指令,但[只能应用一个](guide/structural-directives#one-per-element)*结构型*指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##NGIFCASESTUDY", "original": "## NgIf case study", "translation": "## NgIf 案例分析", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "NGIFISTHESIMPLESTSTRUCTURALDIRECTIVEANDTHEEASIESTTOUNDERSTANDITTAKESABOOLEANEXPRESSIONANDMAKESANENTIRECHUNKOFTHEDOMAPPEARORDISAPPEAR", "original": "`NgIf` is the simplest structural directive and the easiest to understand.\nIt takes a boolean expression and makes an entire chunk of the DOM appear or disappear.", "translation": "`NgIf` 是一个很好的结构型指令案例:它接受一个布尔值,并据此让一整块 DOM 树出现或消失。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THENGIFDIRECTIVEDOESNTHIDEELEMENTSWITHCSSITADDSANDREMOVESTHEMPHYSICALLYFROMTHEDOMCONFIRMTHATFACTUSINGBROWSERDEVELOPERTOOLSTOINSPECTTHEDOM", "original": "The `ngIf` directive doesn't hide elements with CSS. It adds and removes them physically from the DOM.\nConfirm that fact using browser developer tools to inspect the DOM.", "translation": "`ngIf` 指令并不是使用 CSS 来隐藏元素的。它会把这些元素从 DOM 中物理删除。\n使用浏览器的开发者工具就可以确认这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THETOPPARAGRAPHISINTHEDOMTHEBOTTOMDISUSEDPARAGRAPHISNOTINITSPLACEISACOMMENTABOUTBINDINGSMOREABOUTTHATLATERGUIDESTRUCTURALDIRECTIVES#ASTERISK", "original": "The top paragraph is in the DOM. The bottom, disused paragraph is not;\nin its place is a comment about \"bindings\" (more about that [later](guide/structural-directives#asterisk)).", "translation": "可以看到第一段文字出现在了 DOM 中,而第二段则没有,在第二段的位置上是一个关于“绑定”的注释([稍后](guide/structural-directives#asterisk)有更多讲解)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "WHENTHECONDITIONISFALSENGIFREMOVESITSHOSTELEMENTFROMTHEDOMDETACHESITFROMDOMEVENTSTHEATTACHMENTSTHATITMADEDETACHESTHECOMPONENTFROMANGULARCHANGEDETECTIONANDDESTROYSITTHECOMPONENTANDDOMNODESCANBEGARBAGECOLLECTEDANDFREEUPMEMORY", "original": "When the condition is false, `NgIf` removes its host element from the DOM,\ndetaches it from DOM events (the attachments that it made),\ndetaches the component from Angular change detection, and destroys it.\nThe component and DOM nodes can be garbage-collected and free up memory.", "translation": "当条件为假时,`NgIf` 会从 DOM 中移除它的宿主元素,取消它监听过的那些 DOM 事件,从 Angular 变更检测中移除该组件,并销毁它。\n这些组件和 DOM 节点可以被当做垃圾收集起来,并且释放它们占用的内存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "###WHYREMOVERATHERTHANHIDE", "original": "### Why *remove* rather than *hide*?", "translation": "### 为什么*移除*而不是*隐藏*?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ADIRECTIVECOULDHIDETHEUNWANTEDPARAGRAPHINSTEADBYSETTINGITSDISPLAYSTYLETONONE", "original": "A directive could hide the unwanted paragraph instead by setting its `display` style to `none`.", "translation": "指令也可以通过把它的 `display` 风格设置为 `none` 而隐藏不需要的段落。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "WHILEINVISIBLETHEELEMENTREMAINSINTHEDOM", "original": "While invisible, the element remains in the DOM.", "translation": "当不可见时,这个元素仍然留在 DOM 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEDIFFERENCEBETWEENHIDINGANDREMOVINGDOESNTMATTERFORASIMPLEPARAGRAPHITDOESMATTERWHENTHEHOSTELEMENTISATTACHEDTOARESOURCEINTENSIVECOMPONENTSUCHACOMPONENTSBEHAVIORCONTINUESEVENWHENHIDDENTHECOMPONENTSTAYSATTACHEDTOITSDOMELEMENTITKEEPSLISTENINGTOEVENTSANGULARKEEPSCHECKINGFORCHANGESTHATCOULDAFFECTDATABINDINGSWHATEVERTHECOMPONENTWASDOINGITKEEPSDOING", "original": "The difference between hiding and removing doesn't matter for a simple paragraph.\nIt does matter when the host element is attached to a resource intensive component.\nSuch a component's behavior continues even when hidden.\nThe component stays attached to its DOM element. It keeps listening to events.\nAngular keeps checking for changes that could affect data bindings.\nWhatever the component was doing, it keeps doing.", "translation": "对于简单的段落,隐藏和移除之间的差异影响不大,但对于资源占用较多的组件是不一样的。\n当隐藏掉一个元素时,组件的行为还在继续 —— 它仍然附加在它所属的 DOM 元素上,\n它也仍在监听事件。Angular 会继续检查哪些能影响数据绑定的变更。\n组件原本要做的那些事情仍在继续。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ALTHOUGHINVISIBLETHECOMPONENTMDASHANDALLOFITSDESCENDANTCOMPONENTSMDASHTIEUPRESOURCESTHEPERFORMANCEANDMEMORYBURDENCANBESUBSTANTIALRESPONSIVENESSCANDEGRADEANDTHEUSERSEESNOTHING", "original": "Although invisible, the component—and all of its descendant components—tie up resources.\nThe performance and memory burden can be substantial, responsiveness can degrade, and the user sees nothing.", "translation": "虽然不可见,组件及其各级子组件仍然占用着资源,而这些资源如果分配给别人可能会更有用。\n在性能和内存方面的负担相当可观,响应度会降低,而用户却可能无法从中受益。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ONTHEPOSITIVESIDESHOWINGTHEELEMENTAGAINISQUICKTHECOMPONENTSPREVIOUSSTATEISPRESERVEDANDREADYTODISPLAYTHECOMPONENTDOESNTREINITIALIZEMDASHANOPERATIONTHATCOULDBEEXPENSIVESOHIDINGANDSHOWINGISSOMETIMESTHERIGHTTHINGTODO", "original": "On the positive side, showing the element again is quick.\nThe component's previous state is preserved and ready to display.\nThe component doesn't re-initialize—an operation that could be expensive.\nSo hiding and showing is sometimes the right thing to do.", "translation": "当然,从积极的一面看,重新显示这个元素会非常快。\n 组件以前的状态被保留着,并随时可以显示。\n 组件不用重新初始化 —— 该操作可能会比较昂贵。\n 这时候隐藏和显示就成了正确的选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "BUTINTHEABSENCEOFACOMPELLINGREASONTOKEEPTHEMAROUNDYOURPREFERENCESHOULDBETOREMOVEDOMELEMENTSTHATTHEUSERCANTSEEANDRECOVERTHEUNUSEDRESOURCESWITHASTRUCTURALDIRECTIVELIKENGIF", "original": "But in the absence of a compelling reason to keep them around,\nyour preference should be to remove DOM elements that the user can't see\nand recover the unused resources with a structural directive like `NgIf` .", "translation": "但是,除非有非常强烈的理由来保留它们,否则你会更倾向于移除用户看不见的那些 DOM 元素,并且使用 `NgIf` 这样的结构型指令来收回用不到的资源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THESESAMECONSIDERATIONSAPPLYTOEVERYSTRUCTURALDIRECTIVEWHETHERBUILTINORCUSTOMBEFOREAPPLYINGASTRUCTURALDIRECTIVEYOUMIGHTWANTTOPAUSEFORAMOMENTTOCONSIDERTHECONSEQUENCESOFADDINGANDREMOVINGELEMENTSANDOFCREATINGANDDESTROYINGCOMPONENTS", "original": "**These same considerations apply to every structural directive, whether built-in or custom.**\nBefore applying a structural directive, you might want to pause for a moment\nto consider the consequences of adding and removing elements and of creating and destroying components.", "translation": "**同样的考量也适用于每一个结构型指令,无论是内置的还是自定义的。**\n 你应该提醒自己慎重考虑添加元素、移除元素以及创建和销毁组件的后果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##THEASTERISKPREFIX", "original": "## The asterisk (*) prefix", "translation": "## 星号(*)前缀", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "SURELYYOUNOTICEDTHEASTERISKPREFIXTOTHEDIRECTIVENAMEANDWONDEREDWHYITISNECESSARYANDWHATITDOES", "original": "Surely you noticed the asterisk (*) prefix to the directive name\nand wondered why it is necessary and what it does.", "translation": "你可能注意到了指令名的星号(*)前缀,并且困惑于为什么需要它以及它是做什么的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "HEREISNGIFDISPLAYINGTHEHEROSNAMEIFHEROEXISTS", "original": "Here is `*ngIf` displaying the hero's name if `hero` exists.", "translation": "这里的 `*ngIf` 会在 `hero` 存在时显示英雄的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEASTERISKISSYNTACTICSUGARFORSOMETHINGABITMORECOMPLICATEDINTERNALLYANGULARTRANSLATESTHENGIFATTRIBUTEINTOANGTEMPLATEELEMENTWRAPPEDAROUNDTHEHOSTELEMENTLIKETHIS", "original": "The asterisk is \"syntactic sugar\" for something a bit more complicated.\nInternally, Angular translates the `*ngIf` _attribute_ into a `<ng-template>` _element_, wrapped around the host element, like this.", "translation": "星号是一个用来简化更复杂语法的“语法糖”。\n从内部实现来说,Angular 把 `*ngIf` *属性* 翻译成一个 `<ng-template>` *元素* 并用它来包裹宿主元素,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THENGIFDIRECTIVEMOVEDTOTHENGTEMPLATEELEMENTWHEREITBECAMEAPROPERTYBINDINGNGIF", "original": "* The `*ngIf` directive moved to the `<ng-template>` element where it became a property binding,`[ngIf]`.", "translation": "`*ngIf` 指令被移到了 `<ng-template>` 元素上。在那里它变成了一个属性绑定 `[ngIf]`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THERESTOFTHEDIVINCLUDINGITSCLASSATTRIBUTEMOVEDINSIDETHENGTEMPLATEELEMENT", "original": "* The rest of the `<div>`, including its class attribute, moved inside the `<ng-template>` element.", "translation": "`<div>` 上的其余部分,包括它的 `class` 属性在内,移到了内部的 `<ng-template>` 元素上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEFIRSTFORMISNOTACTUALLYRENDEREDONLYTHEFINISHEDPRODUCTENDSUPINTHEDOM", "original": "The first form is not actually rendered, only the finished product ends up in the DOM.", "translation": "第一种形态永远不会真的渲染出来。\n只有最终产出的结果才会出现在 DOM 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ANGULARCONSUMEDTHENGTEMPLATECONTENTDURINGITSACTUALRENDERINGANDREPLACEDTHENGTEMPLATEWITHADIAGNOSTICCOMMENT", "original": "Angular consumed the `<ng-template>` content during its actual rendering and\nreplaced the `<ng-template>` with a diagnostic comment.", "translation": "Angular 会在真正渲染的时候填充 `<ng-template>` 的内容,并且把 `<ng-template>` 替换为一个供诊断用的注释。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THENGFORGUIDESTRUCTURALDIRECTIVES#NGFORANDNGSWITCHGUIDESTRUCTURALDIRECTIVES#NGSWITCHDIRECTIVESFOLLOWTHESAMEPATTERN", "original": "The [`NgFor`](guide/structural-directives#ngFor) and [`NgSwitch...`](guide/structural-directives#ngSwitch) directives follow the same pattern.", "translation": "[`NgFor`](guide/structural-directives#ngFor)和[`NgSwitch...`](guide/structural-directives#ngSwitch)指令也都遵循同样的模式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##INSIDENGFOR", "original": "## Inside _*ngFor_", "translation": "## `*ngFor` 内幕", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ANGULARTRANSFORMSTHENGFORINSIMILARFASHIONFROMASTERISKSYNTAXTONGTEMPLATEELEMENT", "original": "Angular transforms the `*ngFor` in similar fashion from asterisk (*) syntax to `<ng-template>` _element_.", "translation": "Angular 会把 `*ngFor` 用同样的方式把星号(*)语法的 `template`*属性*转换成 `<ng-template>`*元素*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "HERESAFULLFEATUREDAPPLICATIONOFNGFORWRITTENBOTHWAYS:", "original": "Here's a full-featured application of `NgFor`, written both ways:", "translation": "这里有一个 `NgFor` 的全特性应用,同时用了这三种写法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THISISMANIFESTLYMORECOMPLICATEDTHANNGIFANDRIGHTLYSOTHENGFORDIRECTIVEHASMOREFEATURESBOTHREQUIREDANDOPTIONALTHANTHENGIFSHOWNINTHISGUIDEATMINIMUMNGFORNEEDSALOOPINGVARIABLELETHEROANDALISTHEROES", "original": "This is manifestly more complicated than `ngIf` and rightly so.\nThe `NgFor` directive has more features, both required and optional, than the `NgIf` shown in this guide.\nAt minimum `NgFor` needs a looping variable (`let hero`) and a list (`heroes`).", "translation": "它明显比 `ngIf` 复杂得多,确实如此。\n`NgFor` 指令比本章展示过的 `NgIf` 具有更多的必选特性和可选特性。\n至少 `NgFor` 会需要一个循环变量(`let hero`)和一个列表(`heroes`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOUENABLETHESEFEATURESINTHESTRINGASSIGNEDTONGFORWHICHYOUWRITEINANGULARSMICROSYNTAXGUIDESTRUCTURALDIRECTIVES#MICROSYNTAX", "original": "You enable these features in the string assigned to `ngFor`, which you write in Angular's [microsyntax](guide/structural-directives#microsyntax).", "translation": "你可以通过把一个字符串赋值给 `ngFor` 来启用这些特性,这个字符串使用 Angular 的[微语法](guide/structural-directives#microsyntax)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "EVERYTHINGOUTSIDETHENGFORSTRINGSTAYSWITHTHEHOSTELEMENTTHEDIVASITMOVESINSIDETHENGTEMPLATEINTHISEXAMPLETHENGCLASSODDSTAYSONTHEDIV", "original": "Everything _outside_ the `ngFor` string stays with the host element\n(the `<div>`) as it moves inside the `<ng-template>`.\nIn this example, the `[ngClass]=\"odd\"` stays on the `<div>`.", "translation": "`ngFor` 字符串*之外*的每一样东西都会留在宿主元素(`<div>`)上,也就是说它移到了 `<ng-template>` 内部。\n在这个例子中,`[ngClass]=\"odd\"` 留在了 `<div>` 上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "###MICROSYNTAX", "original": "### Microsyntax", "translation": "### 微语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEANGULARMICROSYNTAXLETSYOUCONFIGUREADIRECTIVEINACOMPACTFRIENDLYSTRINGTHEMICROSYNTAXPARSERTRANSLATESTHATSTRINGINTOATTRIBUTESONTHENGTEMPLATE:", "original": "The Angular microsyntax lets you configure a directive in a compact, friendly string.\nThe microsyntax parser translates that string into attributes on the `<ng-template>`:", "translation": "Angular 微语法能让你通过简短的、友好的字符串来配置一个指令。\n微语法解析器把这个字符串翻译成 `<ng-template>` 上的属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THELETKEYWORDDECLARESATEMPLATEINPUTVARIABLEGUIDESTRUCTURALDIRECTIVES#TEMPLATEINPUTVARIABLETHATYOUREFERENCEWITHINTHETEMPLATETHEINPUTVARIABLESINTHISEXAMPLEAREHEROIANDODDTHEPARSERTRANSLATESLETHEROLETIANDLETODDINTOVARIABLESNAMEDLETHEROLETIANDLETODD", "original": "* The `let` keyword declares a [_template input variable_](guide/structural-directives#template-input-variable)\nthat you reference within the template. The input variables in this example are `hero`, `i`, and `odd`.\nThe parser translates `let hero`, `let i`, and `let odd` into variables named,\n`let-hero`, `let-i`, and `let-odd`.", "translation": "`let` 关键字声明一个[模板输入变量](guide/structural-directives#template-input-variable),你会在模板中引用它。本例子中,这个输入变量就是 `hero`、`i` 和 `odd`。\n 解析器会把 `let hero`、`let i` 和 `let odd` 翻译成命名变量 `let-hero`、`let-i` 和 `let-odd`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEMICROSYNTAXPARSERTAKESOFANDTRACKBYTITLECASESTHEMOFOFTRACKBYTRACKBYANDPREFIXESTHEMWITHTHEDIRECTIVESATTRIBUTENAMENGFORYIELDINGTHENAMESNGFOROFANDNGFORTRACKBYTHOSEARETHENAMESOFTWONGFORINPUTPROPERTIESTHATSHOWTHEDIRECTIVELEARNSTHATTHELISTISHEROESANDTHETRACKBYFUNCTIONISTRACKBYID", "original": "* The microsyntax parser takes `of` and `trackBy`, title-cases them (`of` -> `Of`, `trackBy` -> `TrackBy`),\nand prefixes them with the directive's attribute name (`ngFor`), yielding the names `ngForOf` and `ngForTrackBy`.\nThose are the names of two `NgFor` _input properties_ .\nThat's how the directive learns that the list is `heroes` and the track-by function is `trackById`.", "translation": "微语法解析器接收 `of` 和 `trackby`,把它们首字母大写(`of` -> `Of`, `trackBy` -> `TrackBy`),\n 并且给它们加上指令的属性名(`ngFor`)前缀,最终生成的名字是 `ngForOf` 和 `ngForTrackBy`。\n 还有两个 `NgFor` 的*输入属性*,指令据此了解到列表是 `heroes`,而 track-by 函数是 `trackById`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ASTHENGFORDIRECTIVELOOPSTHROUGHTHELISTITSETSANDRESETSPROPERTIESOFITSOWNCONTEXTOBJECTTHESEPROPERTIESINCLUDEINDEXANDODDANDASPECIALPROPERTYNAMEDIMPLICIT", "original": "* As the `NgFor` directive loops through the list, it sets and resets properties of its own _context_ object.\nThese properties include `index` and `odd` and a special property named `$implicit`.", "translation": "`NgFor` 指令在列表上循环,每个循环中都会设置和重置它自己的*上下文*对象上的属性。\n 这些属性包括 `index` 和 `odd` 以及一个特殊的属性名 `$implicit`(隐式变量)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THELETIANDLETODDVARIABLESWEREDEFINEDASLETIINDEXANDLETODDODDANGULARSETSTHEMTOTHECURRENTVALUEOFTHECONTEXTSINDEXANDODDPROPERTIES", "original": "* The `let-i` and `let-odd` variables were defined as `let i=index` and `let odd=odd`.\nAngular sets them to the current value of the context's `index` and `odd` properties.", "translation": "`let-i` 和 `let-odd` 变量是通过 `let i=index` 和 `let odd=odd` 来定义的。\n Angular 把它们设置为*上下文*对象中的 `index` 和 `odd` 属性的当前值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THECONTEXTPROPERTYFORLETHEROWASNTSPECIFIEDITSINTENDEDSOURCEISIMPLICITANGULARSETSLETHEROTOTHEVALUEOFTHECONTEXTSIMPLICITPROPERTYWHICHNGFORHASINITIALIZEDWITHTHEHEROFORTHECURRENTITERATION", "original": "* The context property for `let-hero` wasn't specified.\nIts intended source is implicit.\nAngular sets `let-hero` to the value of the context's `$implicit` property\nwhich `NgFor` has initialized with the hero for the current iteration.", "translation": "这里并没有指定 `let-hero` 的上下文属性。它的来源是隐式的。\n Angular 将 `let-hero` 设置为此上下文中 `$implicit` 属性的值,\n 它是由 `NgFor` 用当前迭代中的英雄初始化的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEAPIGUIDEAPICOMMONNGFOROFAPI:NGFORDESCRIBESADDITIONALNGFORDIRECTIVEPROPERTIESANDCONTEXTPROPERTIES", "original": "* The [API guide](api/common/NgForOf \"API: NgFor\")\ndescribes additional `NgFor` directive properties and context properties.", "translation": "[API 参考手册](api/common/NgForOf \"API: NgFor\")中描述了 `NgFor` 指令的其它属性和上下文属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "NGFORISIMPLEMENTEDBYTHENGFOROFDIRECTIVEREADMOREABOUTADDITIONALNGFOROFDIRECTIVEPROPERTIESANDCONTEXTPROPERTIESNGFOROFAPIREFERENCEAPICOMMONNGFOROF", "original": "* `NgFor` is implemented by the `NgForOf` directive. Read more about additional `NgForOf` directive properties and context properties [NgForOf API reference](api/common/NgForOf).", "translation": "`NgFor` 是由 `NgForOf` 指令来实现的。请参阅[NgForOf API reference](api/common/NgForOf)来了解 `NgForOf` 指令的更多属性及其上下文属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THESEMICROSYNTAXMECHANISMSAREAVAILABLETOYOUWHENYOUWRITEYOUROWNSTRUCTURALDIRECTIVESSTUDYINGTHESOURCECODEFORNGIFHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERPACKAGESCOMMONSRCDIRECTIVESNGIFTSSOURCE:NGIFANDNGFOROFHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERPACKAGESCOMMONSRCDIRECTIVESNGFOROFTSSOURCE:NGFOROFISAGREATWAYTOLEARNMORE", "original": "These microsyntax mechanisms are available to you when you write your own structural directives.\nStudying the\n[source code for `NgIf`](https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_if.ts \"Source: NgIf\")\nand [`NgForOf`](https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_for_of.ts \"Source: NgForOf\")\nis a great way to learn more.", "translation": "这些微语法机制在你写自己的结构型指令时也同样有效,参考[`NgIf` 的源码](https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_if.ts \"Source: NgIf\")\n和[`NgFor` 的源码](https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_for_of.ts \"Source: NgFor\") 可以学到更多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "###TEMPLATEINPUTVARIABLE", "original": "### Template input variable", "translation": "### 模板输入变量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ATEMPLATEINPUTVARIABLEISAVARIABLEWHOSEVALUEYOUCANREFERENCEWITHINASINGLEINSTANCEOFTHETEMPLATETHEREARESEVERALSUCHVARIABLESINTHISEXAMPLE:HEROIANDODDALLAREPRECEDEDBYTHEKEYWORDLET", "original": "A _template input variable_ is a variable whose value you can reference _within_ a single instance of the template.\nThere are several such variables in this example: `hero`, `i`, and `odd`.\nAll are preceded by the keyword `let`.", "translation": "*模板输入变量*是这样一种变量,你可以*在单个实例的模板中*引用它的值。\n这个例子中有好几个模板输入变量:`hero`、`i` 和 `odd`。\n它们都是用 `let` 作为前导关键字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ATEMPLATEINPUTVARIABLEISNOTTHESAMEASATEMPLATEREFERENCEVARIABLEGUIDETEMPLATESYNTAX#REFVARSNEITHERSEMANTICALLYNORSYNTACTICALLY", "original": "A _template input variable_ is **_not_** the same as a\n[template _reference_ variable](guide/template-syntax#ref-vars),\nneither _semantically_ nor _syntactically_.", "translation": "*模板输入变量*和[模板引用变量](guide/template-syntax#ref-vars)是**不同的**,无论是在*语义*上还是*语法*上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOUDECLAREATEMPLATEINPUTVARIABLEUSINGTHELETKEYWORDLETHEROTHEVARIABLESSCOPEISLIMITEDTOASINGLEINSTANCEOFTHEREPEATEDTEMPLATEYOUCANUSETHESAMEVARIABLENAMEAGAININTHEDEFINITIONOFOTHERSTRUCTURALDIRECTIVES", "original": "You declare a template _input_ variable using the `let` keyword (`let hero`).\nThe variable's scope is limited to a _single instance_ of the repeated template.\nYou can use the same variable name again in the definition of other structural directives.", "translation": "你使用 `let` 关键字(如 `let hero`)在模板中声明一个模板*输入*变量。\n这个变量的范围被限制在所重复模板的*单一实例*上。\n事实上,你可以在其它结构型指令中使用同样的变量名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOUDECLAREATEMPLATEREFERENCEVARIABLEBYPREFIXINGTHEVARIABLENAMEWITH##VARAREFERENCEVARIABLEREFERSTOITSATTACHEDELEMENTCOMPONENTORDIRECTIVEITCANBEACCESSEDANYWHEREINTHEENTIRETEMPLATE", "original": "You declare a template _reference_ variable by prefixing the variable name with `#` (`#var`).\nA _reference_ variable refers to its attached element, component or directive.\nIt can be accessed _anywhere_ in the _entire template_.", "translation": "而声明模板*引用*变量使用的是给变量名加 `#` 前缀的方式(`#var`)。\n一个*引用*变量引用的是它所附着到的元素、组件或指令。它可以在*整个模板*的*任意位置*访问。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "TEMPLATEINPUTANDREFERENCEVARIABLENAMESHAVETHEIROWNNAMESPACESTHEHEROINLETHEROISNEVERTHESAMEVARIABLEASTHEHERODECLAREDAS#HERO", "original": "Template _input_ and _reference_ variable names have their own namespaces. The `hero` in `let hero` is never the same\nvariable as the `hero` declared as `#hero`.", "translation": "模板*输入*变量和*引用*变量具有各自独立的命名空间。`let hero` 中的 `hero` 和 `#hero` 中的 `hero` 并不是同一个变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "###ONESTRUCTURALDIRECTIVEPERHOSTELEMENT", "original": "### One structural directive per host element", "translation": "### 每个宿主元素上只能有一个结构型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "SOMEDAYYOULLWANTTOREPEATABLOCKOFHTMLBUTONLYWHENAPARTICULARCONDITIONISTRUEYOULLTRYTOPUTBOTHANNGFORANDANNGIFONTHESAMEHOSTELEMENTANGULARWONTLETYOUYOUMAYAPPLYONLYONESTRUCTURALDIRECTIVETOANELEMENT", "original": "Someday you'll want to repeat a block of HTML but only when a particular condition is true.\nYou'll _try_ to put both an `*ngFor` and an `*ngIf` on the same host element.\nAngular won't let you. You may apply only one _structural_ directive to an element.", "translation": "有时你会希望只有当特定的条件为真时才重复渲染一个 HTML 块。\n你可能试过把 `*ngFor` 和 `*ngIf` 放在同一个宿主元素上,但 Angular 不允许。这是因为你在一个元素上只能放一个*结构型*指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEREASONISSIMPLICITYSTRUCTURALDIRECTIVESCANDOCOMPLEXTHINGSWITHTHEHOSTELEMENTANDITSDESCENDENTSWHENTWODIRECTIVESLAYCLAIMTOTHESAMEHOSTELEMENTWHICHONETAKESPRECEDENCEWHICHSHOULDGOFIRSTTHENGIFORTHENGFORCANTHENGIFCANCELTHEEFFECTOFTHENGFORIFSOANDITSEEMSLIKEITSHOULDBESOHOWSHOULDANGULARGENERALIZETHEABILITYTOCANCELFOROTHERSTRUCTURALDIRECTIVES", "original": "The reason is simplicity. Structural directives can do complex things with the host element and its descendents.\nWhen two directives lay claim to the same host element, which one takes precedence?\nWhich should go first, the `NgIf` or the `NgFor`? Can the `NgIf` cancel the effect of the `NgFor`?\nIf so (and it seems like it should be so), how should Angular generalize the ability to cancel for other structural directives?", "translation": "原因很简单。结构型指令可能会对宿主元素及其子元素做很复杂的事。当两个指令放在同一个元素上时,谁先谁后?`NgIf` 优先还是 `NgFor` 优先?`NgIf` 可以取消 `NgFor` 的效果吗?\n如果要这样做,Angular 应该如何把这种能力泛化,以取消其它结构型指令的效果呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEREARENOEASYANSWERSTOTHESEQUESTIONSPROHIBITINGMULTIPLESTRUCTURALDIRECTIVESMAKESTHEMMOOTTHERESANEASYSOLUTIONFORTHISUSECASE:PUTTHENGIFONACONTAINERELEMENTTHATWRAPSTHENGFORELEMENTONEORBOTHELEMENTSCANBEANNGCONTAINERGUIDESTRUCTURALDIRECTIVES#NGCONTAINERSOYOUDONTHAVETOINTRODUCEEXTRALEVELSOFHTML", "original": "There are no easy answers to these questions. Prohibiting multiple structural directives makes them moot.\nThere's an easy solution for this use case: put the `*ngIf` on a container element that wraps the `*ngFor` element.\nOne or both elements can be an [`ng-container`](guide/structural-directives#ngcontainer) so you don't have to introduce extra levels of HTML.", "translation": "对这些问题,没有办法简单回答。而禁止多个结构型指令则可以简单地解决这个问题。\n这种情况下有一个简单的解决方案:把 `*ngIf` 放在一个\"容器\"元素上,再包装进 `*ngFor` 元素。\n这个元素可以使用[`ng-container`](guide/structural-directives#ngcontainer),以免引入一个新的 HTML 层级。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##INSIDENGSWITCHDIRECTIVES", "original": "## Inside _NgSwitch_ directives", "translation": "## `NgSwitch` 内幕", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEANGULARNGSWITCHISACTUALLYASETOFCOOPERATINGDIRECTIVES:NGSWITCHNGSWITCHCASEANDNGSWITCHDEFAULT", "original": "The Angular _NgSwitch_ is actually a set of cooperating directives: `NgSwitch`, `NgSwitchCase`, and `NgSwitchDefault`.", "translation": "Angular 的 `NgSwitch` 实际上是一组相互合作的指令:`NgSwitch`、`NgSwitchCase` 和 `NgSwitchDefault`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "HERESANEXAMPLE", "original": "Here's an example.", "translation": "例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THESWITCHVALUEASSIGNEDTONGSWITCHHEROEMOTIONDETERMINESWHICHIFANYOFTHESWITCHCASESAREDISPLAYED", "original": "The switch value assigned to `NgSwitch` (`hero.emotion`) determines which\n(if any) of the switch cases are displayed.", "translation": "一个值(`hero.emotion`)被被赋值给了 `NgSwitch`,以决定要显示哪一个分支。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "NGSWITCHITSELFISNOTASTRUCTURALDIRECTIVEITSANATTRIBUTEDIRECTIVETHATCONTROLSTHEBEHAVIOROFTHEOTHERTWOSWITCHDIRECTIVESTHATSWHYYOUWRITENGSWITCHNEVERNGSWITCH", "original": "`NgSwitch` itself is not a structural directive.\nIt's an _attribute_ directive that controls the behavior of the other two switch directives.\nThat's why you write `[ngSwitch]`, never `*ngSwitch`.", "translation": "`NgSwitch` 本身不是结构型指令,而是一个*属性型*指令,它控制其它两个 switch 指令的行为。\n这也就是为什么你要写成 `[ngSwitch]` 而不是 `*ngSwitch` 的原因。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "NGSWITCHCASEANDNGSWITCHDEFAULTARESTRUCTURALDIRECTIVESYOUATTACHTHEMTOELEMENTSUSINGTHEASTERISKPREFIXNOTATIONANNGSWITCHCASEDISPLAYSITSHOSTELEMENTWHENITSVALUEMATCHESTHESWITCHVALUETHENGSWITCHDEFAULTDISPLAYSITSHOSTELEMENTWHENNOSIBLINGNGSWITCHCASEMATCHESTHESWITCHVALUE", "original": "`NgSwitchCase` and `NgSwitchDefault` _are_ structural directives.\nYou attach them to elements using the asterisk (*) prefix notation.\nAn `NgSwitchCase` displays its host element when its value matches the switch value.\nThe `NgSwitchDefault` displays its host element when no sibling `NgSwitchCase` matches the switch value.", "translation": "`NgSwitchCase` 和 `NgSwitchDefault` *都是*结构型指令。\n因此你要使用星号(`*`)前缀来把它们附着到元素上。\n`NgSwitchCase` 会在它的值匹配上选项值的时候显示它的宿主元素。\n`NgSwitchDefault` 则会当没有兄弟 `NgSwitchCase` 匹配上时显示它的宿主元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEELEMENTTOWHICHYOUAPPLYADIRECTIVEISITSHOSTELEMENTTHEHAPPYHEROISTHEHOSTELEMENTFORTHEHAPPYNGSWITCHCASETHEUNKNOWNHEROISTHEHOSTELEMENTFORTHENGSWITCHDEFAULT", "original": "The element to which you apply a directive is its _host_ element.\nThe `<happy-hero>` is the host element for the happy `*ngSwitchCase`.\nThe `<unknown-hero>` is the host element for the `*ngSwitchDefault`.", "translation": "指令所在的元素就是它的**宿主**元素。\n`<happy-hero>` 是 `*ngSwitchCase` 的宿主元素。\n`<unknown-hero>` 是 `*ngSwitchDefault` 的宿主元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ASWITHOTHERSTRUCTURALDIRECTIVESTHENGSWITCHCASEANDNGSWITCHDEFAULTCANBEDESUGAREDINTOTHENGTEMPLATEELEMENTFORM", "original": "As with other structural directives, the `NgSwitchCase` and `NgSwitchDefault`\ncan be desugared into the `<ng-template>` element form.", "translation": "像其它的结构型指令一样,`NgSwitchCase` 和 `NgSwitchDefault` 也可以解开语法糖,变成 `<ng-template>` 的形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##PREFERTHEASTERISKSYNTAX", "original": "## Prefer the asterisk (*) syntax.", "translation": "## 优先使用星号(`*`)语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEASTERISKSYNTAXISMORECLEARTHANTHEDESUGAREDFORMUSELTNGCONTAINERGTGUIDESTRUCTURALDIRECTIVES#NGCONTAINERWHENTHERESNOSINGLEELEMENTTOHOSTTHEDIRECTIVE", "original": "The asterisk (*) syntax is more clear than the desugared form.\nUse [<ng-container>](guide/structural-directives#ng-container) when there's no single element\nto host the directive.", "translation": "星号(`*`)语法比不带语法糖的形式更加清晰。\n如果找不到单一的元素来应用该指令,可以使用[<ng-container>](guide/structural-directives#ng-container)作为该指令的容器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "WHILETHERESRARELYAGOODREASONTOAPPLYASTRUCTURALDIRECTIVEINTEMPLATEATTRIBUTEORELEMENTFORMITSSTILLIMPORTANTTOKNOWTHATANGULARCREATESANGTEMPLATEANDTOUNDERSTANDHOWITWORKSYOULLREFERTOTHENGTEMPLATEWHENYOUWRITEYOUROWNSTRUCTURALDIRECTIVEGUIDESTRUCTURALDIRECTIVES#UNLESS", "original": "While there's rarely a good reason to apply a structural directive in template _attribute_ or _element_ form,\nit's still important to know that Angular creates a `<ng-template>` and to understand how it works.\nYou'll refer to the `<ng-template>` when you [write your own structural directive](guide/structural-directives#unless).", "translation": "虽然很少有理由在模板中使用结构型指令的*属性*形式和*元素*形式,但这些幕后知识仍然是很重要的,即:Angular 会创建 `<ng-template>`,还要了解它的工作原理。\n当需要[写自己的结构型指令](guide/structural-directives#unless)时,你就要使用 `<ng-template>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##THELTNGTEMPLATEGT", "original": "## The *<ng-template>*", "translation": "## *<ng-template>*指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THELTNGTEMPLATEGTISANANGULARELEMENTFORRENDERINGHTMLITISNEVERDISPLAYEDDIRECTLYINFACTBEFORERENDERINGTHEVIEWANGULARREPLACESTHENGTEMPLATEANDITSCONTENTSWITHACOMMENT", "original": "The <ng-template> is an Angular element for rendering HTML.\nIt is never displayed directly.\nIn fact, before rendering the view, Angular _replaces_ the `<ng-template>` and its contents with a comment.", "translation": "<ng-template>是一个 Angular 元素,用来渲染 HTML。\n它永远不会直接显示出来。\n事实上,在渲染视图之前,Angular 会把 `<ng-template>` 及其内容*替换为*一个注释。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "IFTHEREISNOSTRUCTURALDIRECTIVEANDYOUMERELYWRAPSOMEELEMENTSINANGTEMPLATETHOSEELEMENTSDISAPPEARTHATSTHEFATEOFTHEMIDDLEHIPINTHEPHRASEHIPHIPHOORAY", "original": "If there is no structural directive and you merely wrap some elements in a `<ng-template>`,\nthose elements disappear.\nThat's the fate of the middle \"Hip!\" in the phrase \"Hip! Hip! Hooray!\".", "translation": "如果没有使用结构型指令,而仅仅把一些别的元素包装进 `<ng-template>` 中,那些元素就是不可见的。\n在下面的这个短语\"Hip! Hip! Hooray!\"中,中间的这个 \"Hip!\"(欢呼声) 就是如此。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ANGULARERASESTHEMIDDLEHIPLEAVINGTHECHEERABITLESSENTHUSIASTIC", "original": "Angular erases the middle \"Hip!\", leaving the cheer a bit less enthusiastic.", "translation": "Angular 抹掉了中间的那个 \"Hip!\" ,让欢呼声显得不再那么热烈了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ASTRUCTURALDIRECTIVEPUTSANGTEMPLATETOWORKASYOULLSEEWHENYOUWRITEYOUROWNSTRUCTURALDIRECTIVEGUIDESTRUCTURALDIRECTIVES#UNLESS", "original": "A structural directive puts a `<ng-template>` to work\nas you'll see when you [write your own structural directive](guide/structural-directives#unless).", "translation": "结构型指令会让 `<ng-template>` 正常工作,在你[写自己的结构型指令](guide/structural-directives#unless)时就会看到这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##GROUPSIBLINGELEMENTSWITHLTNGCONTAINERGT", "original": "## Group sibling elements with <ng-container>", "translation": "## 使用<ng-container>把一些兄弟元素归为一组", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THERESOFTENAROOTELEMENTTHATCANANDSHOULDHOSTTHESTRUCTURALDIRECTIVETHELISTELEMENTLIISATYPICALHOSTELEMENTOFANNGFORREPEATER", "original": "There's often a _root_ element that can and should host the structural directive.\nThe list element (`<li>`) is a typical host element of an `NgFor` repeater.", "translation": "通常都要有一个*根*元素作为结构型指令的数组。\n列表元素(`<li>`)就是一个典型的供 `NgFor` 使用的宿主元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "WHENTHEREISNTAHOSTELEMENTYOUCANUSUALLYWRAPTHECONTENTINANATIVEHTMLCONTAINERELEMENTSUCHASADIVANDATTACHTHEDIRECTIVETOTHATWRAPPER", "original": "When there isn't a host element, you can usually wrap the content in a native HTML container element,\nsuch as a `<div>`, and attach the directive to that wrapper.", "translation": "当没有这样一个单一的宿主元素时,你就可以把这些内容包裹在一个原生的 HTML 容器元素中,比如 `<div>`,并且把结构型指令附加到这个\"包裹\"上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "INTRODUCINGANOTHERCONTAINERELEMENTMDASHTYPICALLYASPANORDIVMDASHTOGROUPTHEELEMENTSUNDERASINGLEROOTISUSUALLYHARMLESSUSUALLYBUTNOTALWAYS", "original": "Introducing another container element—typically a `<span>` or `<div>`—to\ngroup the elements under a single _root_ is usually harmless.\n_Usually_ ... but not _always_.", "translation": "但引入另一个容器元素(通常是 `<span>` 或 `<div>`)来把一些元素归到一个单一的*根元素*下,通常也会带来问题。注意,是\"通常\"而不是\"总会\"。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEGROUPINGELEMENTMAYBREAKTHETEMPLATEAPPEARANCEBECAUSECSSSTYLESNEITHEREXPECTNORACCOMMODATETHENEWLAYOUTFOREXAMPLESUPPOSEYOUHAVETHEFOLLOWINGPARAGRAPHLAYOUT", "original": "The grouping element may break the template appearance because CSS styles\nneither expect nor accommodate the new layout.\nFor example, suppose you have the following paragraph layout.", "translation": "这种用于分组的元素可能会破坏模板的外观表现,因为 CSS 的样式既不曾期待也不会接受这种新的元素布局。\n比如,假设你有下列分段布局。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOUALSOHAVEACSSSTYLERULETHATHAPPENSTOAPPLYTOASPANWITHINAPARAGRAPH", "original": "You also have a CSS style rule that happens to apply to a `<span>` within a `<p>`aragraph.", "translation": "而你的 CSS 样式规则是应用于 `<p>` 元素下的 `<span>` 的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THECONSTRUCTEDPARAGRAPHRENDERSSTRANGELY", "original": "The constructed paragraph renders strangely.", "translation": "这样渲染出来的段落就会非常奇怪。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEPSPANSTYLEINTENDEDFORUSEELSEWHEREWASINADVERTENTLYAPPLIEDHERE", "original": "The `p span` style, intended for use elsewhere, was inadvertently applied here.", "translation": "本来为其它地方准备的 `p span` 样式,被意外的应用到了这里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ANOTHERPROBLEM:SOMEHTMLELEMENTSREQUIREALLIMMEDIATECHILDRENTOBEOFASPECIFICTYPEFOREXAMPLETHESELECTELEMENTREQUIRESOPTIONCHILDRENYOUCANTWRAPTHEOPTIONSINACONDITIONALDIVORASPAN", "original": "Another problem: some HTML elements require all immediate children to be of a specific type.\nFor example, the `<select>` element requires `<option>` children.\nYou can't wrap the _options_ in a conditional `<div>` or a `<span>`.", "translation": "另一个问题是:有些 HTML 元素需要所有的直属下级都具有特定的类型。\n比如,`<select>` 元素要求直属下级必须为 `<option>`,那就没办法把这些选项包装进 `<div>` 或 `<span>` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "WHENYOUTRYTHIS", "original": "When you try this,", "translation": "如果这样做:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEDROPDOWNISEMPTY", "original": "the drop down is empty.", "translation": "下拉列表就是空的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEBROWSERWONTDISPLAYANOPTIONWITHINASPAN", "original": "The browser won't display an `<option>` within a `<span>`.", "translation": "浏览器不会显示 `<span>` 中的 `<option>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "###LTNGCONTAINERGTTOTHERESCUE", "original": "### <ng-container> to the rescue", "translation": "### <ng-container> 的救赎", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEANGULARNGCONTAINERISAGROUPINGELEMENTTHATDOESNTINTERFEREWITHSTYLESORLAYOUTBECAUSEANGULARDOESNTPUTITINTHEDOM", "original": "The Angular `<ng-container>` is a grouping element that doesn't interfere with styles or layout\nbecause Angular _doesn't put it in the DOM_.", "translation": "Angular 的 `<ng-container>` 是一个分组元素,但它不会污染样式或元素布局,因为 Angular *压根不会把它放进 DOM* 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "HERESTHECONDITIONALPARAGRAPHAGAINTHISTIMEUSINGNGCONTAINER", "original": "Here's the conditional paragraph again, this time using `<ng-container>`.", "translation": "下面是重新实现的条件化段落,这次使用 `<ng-container>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ITRENDERSPROPERLY", "original": "It renders properly.", "translation": "这次就渲染对了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "NOWCONDITIONALLYEXCLUDEASELECTOPTIONWITHNGCONTAINER", "original": "Now conditionally exclude a _select_ `<option>` with `<ng-container>`.", "translation": "现在用 `<ng-container>` 来根据条件排除选择框中的某个 `<option>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEDROPDOWNWORKSPROPERLY", "original": "The drop down works properly.", "translation": "下拉框也工作正常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THENGCONTAINERISASYNTAXELEMENTRECOGNIZEDBYTHEANGULARPARSERITSNOTADIRECTIVECOMPONENTCLASSORINTERFACEITSMORELIKETHECURLYBRACESINAJAVASCRIPTIFBLOCK:", "original": "The `<ng-container>` is a syntax element recognized by the Angular parser.\nIt's not a directive, component, class, or interface.\nIt's more like the curly braces in a JavaScript `if`-block:", "translation": "`<ng-container>` 是一个由 Angular 解析器负责识别处理的语法元素。\n它不是一个指令、组件、类或接口,更像是 JavaScript 中 `if` 块中的花括号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "WITHOUTTHOSEBRACESJAVASCRIPTWOULDONLYEXECUTETHEFIRSTSTATEMENTWHENYOUINTENDTOCONDITIONALLYEXECUTEALLOFTHEMASASINGLEBLOCKTHENGCONTAINERSATISFIESASIMILARNEEDINANGULARTEMPLATES", "original": "Without those braces, JavaScript would only execute the first statement\nwhen you intend to conditionally execute all of them as a single block.\nThe `<ng-container>` satisfies a similar need in Angular templates.", "translation": "没有这些花括号,JavaScript 只会执行第一句,而你原本的意图是把其中的所有语句都视为一体来根据条件执行。\n而 `<ng-container>` 满足了 Angular 模板中类似的需求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##WRITEASTRUCTURALDIRECTIVE", "original": "## Write a structural directive", "translation": "## 写一个结构型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "INTHISSECTIONYOUWRITEANUNLESSDIRECTIVESTRUCTURALDIRECTIVETHATDOESTHEOPPOSITEOFNGIFNGIFDISPLAYSTHETEMPLATECONTENTWHENTHECONDITIONISTRUEUNLESSDIRECTIVEDISPLAYSTHECONTENTWHENTHECONDITIONISFALSE", "original": "In this section, you write an `UnlessDirective` structural directive\nthat does the opposite of `NgIf`.\n`NgIf` displays the template content when the condition is `true`.\n`UnlessDirective` displays the content when the condition is ***false***.", "translation": "在本节中,你会写一个名叫 `UnlessDirective` 的结构型指令,它是 `NgIf` 的反义词。\n`NgIf` 在条件为 `true` 的时候显示模板内容,而 `UnlessDirective` 则会在条件为 `false` 时显示模板内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "CREATINGADIRECTIVEISSIMILARTOCREATINGACOMPONENT", "original": "Creating a directive is similar to creating a component.", "translation": "创建指令很像创建组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "IMPORTTHEDIRECTIVEDECORATORINSTEADOFTHECOMPONENTDECORATOR", "original": "* Import the `Directive` decorator (instead of the `Component` decorator).", "translation": "导入 `Directive` 装饰器(而不再是 `Component`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "IMPORTTHEINPUTTEMPLATEREFANDVIEWCONTAINERREFSYMBOLSYOULLNEEDTHEMFORANYSTRUCTURALDIRECTIVE", "original": "* Import the `Input`, `TemplateRef`, and `ViewContainerRef` symbols; you'll need them for _any_ structural directive.", "translation": "导入符号 `Input`、`TemplateRef` 和 `ViewContainerRef`,你在*任何*结构型指令中都会需要它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "APPLYTHEDECORATORTOTHEDIRECTIVECLASS", "original": "* Apply the decorator to the directive class.", "translation": "给指令类添加装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "SETTHECSSATTRIBUTESELECTORTHATIDENTIFIESTHEDIRECTIVEWHENAPPLIEDTOANELEMENTINATEMPLATE", "original": "* Set the CSS *attribute selector* that identifies the directive when applied to an element in a template.", "translation": "设置 CSS *属性选择器* ,以便在模板中标识出这个指令该应用于哪个元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "HERESHOWYOUMIGHTBEGIN:", "original": "Here's how you might begin:", "translation": "这里是起点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEDIRECTIVESSELECTORISTYPICALLYTHEDIRECTIVESATTRIBUTENAMEINSQUAREBRACKETSAPPUNLESSTHEBRACKETSDEFINEACSSAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBCSSATTRIBUTESELECTORSTITLEMDN:ATTRIBUTESELECTORSATTRIBUTESELECTORA", "original": "The directive's _selector_ is typically the directive's **attribute name** in square brackets, `[appUnless]`.\nThe brackets define a CSS\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors\" title=\"MDN: Attribute selectors\">attribute selector</a>.", "translation": "指令的*选择器*通常是把指令的属性名括在方括号中,如 `[appUnless]`。\n这个方括号定义出了一个 CSS <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors\" title=\"MDN: Attribute selectors\">属性选择器</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEDIRECTIVEATTRIBUTENAMESHOULDBESPELLEDINLOWERCAMELCASEANDBEGINWITHAPREFIXDONTUSENGTHATPREFIXBELONGSTOANGULARPICKSOMETHINGSHORTTHATFITSYOUORYOURCOMPANYINTHISEXAMPLETHEPREFIXISAPP", "original": "The directive _attribute name_ should be spelled in _lowerCamelCase_ and begin with a prefix.\nDon't use `ng`. That prefix belongs to Angular.\nPick something short that fits you or your company.\nIn this example, the prefix is `app`.", "translation": "该指令的*属性名*应该拼写成*小驼峰*形式,并且带有一个前缀。\n但是,这个前缀不能用 `ng`,因为它只属于 Angular 本身。\n请选择一些简短的,适合你自己或公司的前缀。\n在这个例子中,前缀是 `my`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEDIRECTIVECLASSNAMEENDSINDIRECTIVEPERTHESTYLEGUIDEGUIDESTYLEGUIDE#0203ANGULARSTYLEGUIDEANGULARSOWNDIRECTIVESDONOT", "original": "The directive _class_ name ends in `Directive` per the [style guide](guide/styleguide#02-03 \"Angular Style Guide\").\nAngular's own directives do not.", "translation": "指令的*类名*用 `Directive` 结尾,参见[风格指南](guide/styleguide#02-03 \"Angular 风格指南\")。\n但 Angular 自己的指令例外。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "###TEMPLATEREFANDVIEWCONTAINERREF", "original": "### _TemplateRef_ and _ViewContainerRef_", "translation": "### _TemplateRef_ 和 _ViewContainerRef_", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ASIMPLESTRUCTURALDIRECTIVELIKETHISONECREATESANEMBEDDEDVIEWAPICOREEMBEDDEDVIEWREFAPI:EMBEDDEDVIEWREFFROMTHEANGULARGENERATEDNGTEMPLATEANDINSERTSTHATVIEWINAVIEWCONTAINERAPICOREVIEWCONTAINERREFAPI:VIEWCONTAINERREFADJACENTTOTHEDIRECTIVESORIGINALPHOSTELEMENT", "original": "A simple structural directive like this one creates an\n[_embedded view_](api/core/EmbeddedViewRef \"API: EmbeddedViewRef\")\nfrom the Angular-generated `<ng-template>` and inserts that view in a\n[_view container_](api/core/ViewContainerRef \"API: ViewContainerRef\")\nadjacent to the directive's original `<p>` host element.", "translation": "像这个例子一样的简单结构型指令会从 Angular 生成的 `<ng-template>` 元素中创建一个[*内嵌的视图*](api/core/EmbeddedViewRef \"API: EmbeddedViewRef\"),并把这个视图插入到一个[*视图容器*](api/core/ViewContainerRef \"API: ViewContainerRef\")中,紧挨着本指令原来的宿主元素 `<p>`(译注:注意不是子节点,而是兄弟节点)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOULLACQUIRETHENGTEMPLATECONTENTSWITHATEMPLATEREFAPICORETEMPLATEREFAPI:TEMPLATEREFANDACCESSTHEVIEWCONTAINERTHROUGHAVIEWCONTAINERREFAPICOREVIEWCONTAINERREFAPI:VIEWCONTAINERREF", "original": "You'll acquire the `<ng-template>` contents with a\n[`TemplateRef`](api/core/TemplateRef \"API: TemplateRef\")\nand access the _view container_ through a\n[`ViewContainerRef`](api/core/ViewContainerRef \"API: ViewContainerRef\").", "translation": "你可以使用[`TemplateRef`](api/core/TemplateRef \"API: TemplateRef\")取得 `<ng-template>` 的内容,并通过[`ViewContainerRef`](api/core/ViewContainerRef \"API: ViewContainerRef\")来访问这个*视图容器*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOUINJECTBOTHINTHEDIRECTIVECONSTRUCTORASPRIVATEVARIABLESOFTHECLASS", "original": "You inject both in the directive constructor as private variables of the class.", "translation": "你可以把它们都注入到指令的构造函数中,作为该类的私有属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "###THEAPPUNLESSPROPERTY", "original": "### The _appUnless_ property", "translation": "### *appUnless* 属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THEDIRECTIVECONSUMEREXPECTSTOBINDATRUEFALSECONDITIONTOAPPUNLESSTHATMEANSTHEDIRECTIVENEEDSANAPPUNLESSPROPERTYDECORATEDWITHINPUT", "original": "The directive consumer expects to bind a true/false condition to `[appUnless]`.\nThat means the directive needs an `appUnless` property, decorated with `@Input`", "translation": "该指令的使用者会把一个 true/false 条件绑定到 `[appUnless]` 属性上。\n也就是说,该指令需要一个带有 `@Input` 的 `appUnless` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "READABOUTINPUTINTHETEMPLATESYNTAXGUIDETEMPLATESYNTAX#INPUTSOUTPUTSGUIDE", "original": "Read about `@Input` in the [_Template Syntax_](guide/template-syntax#inputs-outputs) guide.", "translation": "要了解关于 `@Input` 的更多知识,参见[*模板语法*](guide/template-syntax#inputs-outputs)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ANGULARSETSTHEAPPUNLESSPROPERTYWHENEVERTHEVALUEOFTHECONDITIONCHANGESBECAUSETHEAPPUNLESSPROPERTYDOESWORKITNEEDSASETTER", "original": "Angular sets the `appUnless` property whenever the value of the condition changes.\nBecause the `appUnless` property does work, it needs a setter.", "translation": "一旦该值的条件发生了变化,Angular 就会去设置 `appUnless` 属性。因为不能用 `appUnless` 属性,所以你要为它定义一个设置器(setter)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "IFTHECONDITIONISFALSYANDTHEVIEWHASNTBEENCREATEDPREVIOUSLYTELLTHEVIEWCONTAINERTOCREATETHEEMBEDDEDVIEWFROMTHETEMPLATE", "original": "* If the condition is falsy and the view hasn't been created previously,\ntell the _view container_ to create the _embedded view_ from the template.", "translation": "如果条件为假,并且以前尚未创建过该视图,就告诉*视图容器(ViewContainer)*根据模板创建一个*内嵌视图*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "IFTHECONDITIONISTRUTHYANDTHEVIEWISCURRENTLYDISPLAYEDCLEARTHECONTAINERWHICHALSODESTROYSTHEVIEW", "original": "* If the condition is truthy and the view is currently displayed,\nclear the container which also destroys the view.", "translation": "如果条件为真,并且视图已经显示出来了,就会清除该容器,并销毁该视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "NOBODYREADSTHEAPPUNLESSPROPERTYSOITDOESNTNEEDAGETTER", "original": "Nobody reads the `appUnless` property so it doesn't need a getter.", "translation": "没有人会读取 `appUnless` 属性,因此它不需要定义 getter。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THECOMPLETEDDIRECTIVECODELOOKSLIKETHIS:", "original": "The completed directive code looks like this:", "translation": "完整的指令代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ADDTHISDIRECTIVETOTHEDECLARATIONSARRAYOFTHEAPPMODULE", "original": "Add this directive to the `declarations` array of the AppModule.", "translation": "把这个指令添加到 AppModule 的 `declarations` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THENCREATESOMEHTMLTOTRYIT", "original": "Then create some HTML to try it.", "translation": "然后创建一些 HTML 来试用一下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "WHENTHECONDITIONISFALSYTHETOPAPARAGRAPHAPPEARSANDTHEBOTTOMBPARAGRAPHDISAPPEARSWHENTHECONDITIONISTRUTHYTHETOPAPARAGRAPHISREMOVEDANDTHEBOTTOMBPARAGRAPHAPPEARS", "original": "When the `condition` is falsy, the top (A) paragraph appears and the bottom (B) paragraph disappears.\nWhen the `condition` is truthy, the top (A) paragraph is removed and the bottom (B) paragraph appears.", "translation": "当 `condition` 为 `false` 时,顶部的段落就会显示出来,而底部的段落消失了。\n当 `condition` 为 `true` 时,顶部的段落被移除了,而底部的段落显示了出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOUCANBOTHTRYANDDOWNLOADTHESOURCECODEFORTHISGUIDEINTHELIVEEXAMPLELIVEEXAMPLE", "original": "You can both try and download the source code for this guide in the <live-example></live-example>.", "translation": "你可以去<live-example></live-example>中下载本章的源码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "HEREISTHESOURCEFROMTHESRCAPPFOLDER", "original": "Here is the source from the `src/app/` folder.", "translation": "本章相关的代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "YOULEARNED", "original": "You learned", "translation": "你学到了", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THATSTRUCTURALDIRECTIVESMANIPULATEHTMLLAYOUT", "original": "* that structural directives manipulate HTML layout.", "translation": "结构型指令可以操纵 HTML 的元素布局。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "TOUSENGCONTAINERGUIDESTRUCTURALDIRECTIVES#NGCONTAINERASAGROUPINGELEMENTWHENTHEREISNOSUITABLEHOSTELEMENT", "original": "* to use [`<ng-container>`](guide/structural-directives#ngcontainer) as a grouping element when there is no suitable host element.", "translation": "当没有合适的容器元素时,可以使用[`<ng-container>`](guide/structural-directives#ngcontainer)对元素进行分组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "THATTHEANGULARDESUGARSASTERISKSYNTAXGUIDESTRUCTURALDIRECTIVES#ASTERISKINTOANGTEMPLATE", "original": "* that the Angular desugars [asterisk (*) syntax](guide/structural-directives#asterisk) into a `<ng-template>`.", "translation": "Angular 会把[星号(*)语法](guide/structural-directives#asterisk)解开成 `<ng-template>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "HOWTHATWORKSFORTHENGIFNGFORANDNGSWITCHBUILTINDIRECTIVES", "original": "* how that works for the `NgIf`, `NgFor` and `NgSwitch` built-in directives.", "translation": "内置指令 `NgIf`、`NgFor` 和 `NgSwitch` 的工作原理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "ABOUTTHEMICROSYNTAXGUIDESTRUCTURALDIRECTIVES#MICROSYNTAXTHATEXPANDSINTOANGTEMPLATEGUIDESTRUCTURALDIRECTIVES#TEMPLATE", "original": "* about the [_microsyntax_](guide/structural-directives#microsyntax) that expands into a [`<ng-template>`](guide/structural-directives#template).", "translation": "[*微语法*](guide/structural-directives#microsyntax)如何展开成[`<ng-template>`](guide/structural-directives#template)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "TOWRITEACUSTOMSTRUCTURALDIRECTIVEGUIDESTRUCTURALDIRECTIVES#UNLESSUNLESSDIRECTIVE", "original": "* to write a [custom structural directive](guide/structural-directives#unless), `UnlessDirective`.", "translation": "写了一个[自定义结构型指令](guide/structural-directives#unless) —— `UnlessDirective`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/structural-directives.md" }, { + "key": "#STYLEGUIDE", "original": "# Style Guide", "translation": "# 风格指南", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "LOOKINGFORANOPINIONATEDGUIDETOANGULARSYNTAXCONVENTIONSANDAPPLICATIONSTRUCTURESTEPRIGHTINTHISSTYLEGUIDEPRESENTSPREFERREDCONVENTIONSANDASIMPORTANTLYEXPLAINSWHY", "original": "Looking for an opinionated guide to Angular syntax, conventions, and application structure?\nStep right in!\nThis style guide presents preferred conventions and, as importantly, explains why.", "translation": "如果你正在寻找关于 Angular 语法、约定和应用组织结构的官方指南,那你就来对了。\n本风格指南介绍了提倡的约定,更重要的是,解释了为什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##STYLEVOCABULARY", "original": "## Style vocabulary", "translation": "## 风格词汇", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "EACHGUIDELINEDESCRIBESEITHERAGOODORBADPRACTICEANDALLHAVEACONSISTENTPRESENTATION", "original": "Each guideline describes either a good or bad practice, and all have a consistent presentation.", "translation": "每个指导原则都会描述好的或者坏的做法,所有指导原则风格一致。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "THEWORDINGOFEACHGUIDELINEINDICATESHOWSTRONGTHERECOMMENDATIONIS", "original": "The wording of each guideline indicates how strong the recommendation is.", "translation": "指导原则中使用的词汇表明推荐的程度。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOISONETHATSHOULDALWAYSBEFOLLOWEDALWAYSMIGHTBEABITTOOSTRONGOFAWORDGUIDELINESTHATLITERALLYSHOULDALWAYSBEFOLLOWEDAREEXTREMELYRAREONTHEOTHERHANDYOUNEEDAREALLYUNUSUALCASEFORBREAKINGADOGUIDELINE", "original": "**Do** is one that should always be followed.\n_Always_ might be a bit too strong of a word.\nGuidelines that literally should always be followed are extremely rare.\nOn the other hand, you need a really unusual case for breaking a *Do* guideline.", "translation": "**坚持**意味着总是应该遵循的约定。\n说*\"总是\"*可能显得有点绝对,应该*\"总是\"*遵循的指导原则非常少,但是,只有遇到非常不寻常的情况才能打破*坚持*的原则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERGUIDELINESSHOULDGENERALLYBEFOLLOWEDIFYOUFULLYUNDERSTANDTHEMEANINGBEHINDTHEGUIDELINEANDHAVEAGOODREASONTODEVIATETHENDOSOPLEASESTRIVETOBECONSISTENT", "original": "**Consider** guidelines should generally be followed.\nIf you fully understand the meaning behind the guideline and have a good reason to deviate, then do so. Please strive to be consistent.", "translation": "**考虑**标志着通常应该遵循的指导原则。\n如果你能完全理解指导原则背后的含义,并且很好的理由背离它,那就可以改变它。但是请保持一致。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDINDICATESSOMETHINGYOUSHOULDALMOSTNEVERDOCODEEXAMPLESTOAVOIDHAVEANUNMISTAKEABLEREDHEADER", "original": "**Avoid** indicates something you should almost never do. Code examples to *avoid* have an unmistakeable red header.", "translation": "**避免**标志着你决不应该做的事。需要*避免*的代码范例会有明显的红色标题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYGIVESREASONSFORFOLLOWINGTHEPREVIOUSRECOMMENDATIONS", "original": "**Why?** gives reasons for following the previous recommendations.", "translation": "**为何?**会给出随后的建议的理由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##FILESTRUCTURECONVENTIONS", "original": "## File structure conventions", "translation": "## 文件结构约定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "SOMECODEEXAMPLESDISPLAYAFILETHATHASONEORMORESIMILARLYNAMEDCOMPANIONFILESFOREXAMPLEHEROCOMPONENTTSANDHEROCOMPONENTHTML", "original": "Some code examples display a file that has one or more similarly named companion files.\nFor example, `hero.component.ts` and `hero.component.html`.", "translation": "在一些代码例子中,有的文件有一个或多个相似名字的伴随文件。(例如 hero.component.ts 和 hero.component.html)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "THEGUIDELINEUSESTHESHORTCUTHEROCOMPONENTTSHTMLCSSSPECTOREPRESENTTHOSEVARIOUSFILESUSINGTHISSHORTCUTMAKESTHISGUIDESFILESTRUCTURESEASIERTOREADANDMORETERSE", "original": "The guideline uses the shortcut `hero.component.ts|html|css|spec` to represent those various files. Using this shortcut makes this guide's file structures easier to read and more terse.", "translation": "本指南将会使用像 `hero.component.ts|html|css|spec` 的简写来表示上面描述的多个文件,目的是保持本指南的简洁性,增加描述文件结构时的可读性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##SINGLERESPONSIBILITY", "original": "## Single responsibility", "translation": "## 单一职责", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "APPLYTHEAHREFHTTPS:WIKIPEDIAORGWIKISINGLERESPONSIBILITYPRINCIPLEISINGLERESPONSIBILITYPRINCIPLEISRPATOALLCOMPONENTSSERVICESANDOTHERSYMBOLSTHISHELPSMAKETHEAPPCLEANEREASIERTOREADANDMAINTAINANDMORETESTABLE", "original": "Apply the\n<a href=\"https://wikipedia.org/wiki/Single_responsibility_principle\"><i>single responsibility principle</i> (SRP)</a>\nto all components, services, and other symbols.\nThis helps make the app cleaner, easier to read and maintain, and more testable.", "translation": "对所有的组件、服务等等应用<a href=\"https://wikipedia.org/wiki/Single_responsibility_principle\" target=\"_blank\"><i>单一职责原则</i> (SRP)</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###RULEOFONE", "original": "### Rule of One", "translation": "### 单一规则", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0101", "original": "#### Style 01-01", "translation": "#### 风格 01-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DODEFINEONETHINGSUCHASASERVICEORCOMPONENTPERFILE", "original": "**Do** define one thing, such as a service or component, per file.", "translation": "**坚持**每个文件只定义一样东西(例如服务或组件)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERLIMITINGFILESTO400LINESOFCODE", "original": "**Consider** limiting files to 400 lines of code.", "translation": "**考虑**把文件大小限制在 400 行代码以内。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYONECOMPONENTPERFILEMAKESITFAREASIERTOREADMAINTAINANDAVOIDCOLLISIONSWITHTEAMSINSOURCECONTROL", "original": "**Why?** One component per file makes it far easier to read, maintain, and avoid\ncollisions with teams in source control.", "translation": "**为何?**单组件文件非常容易阅读、维护,并能防止在版本控制系统里与团队冲突。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYONECOMPONENTPERFILEAVOIDSHIDDENBUGSTHATOFTENARISEWHENCOMBININGCOMPONENTSINAFILEWHERETHEYMAYSHAREVARIABLESCREATEUNWANTEDCLOSURESORUNWANTEDCOUPLINGWITHDEPENDENCIES", "original": "**Why?** One component per file avoids hidden bugs that often arise when combining components in a file where they may share variables, create unwanted closures, or unwanted coupling with dependencies.", "translation": "**为何?**单组件文件可以防止一些隐蔽的程序缺陷,当把多个组件合写在同一个文件中时,可能造成共享变量、创建意外的闭包,或者与依赖之间产生意外耦合等情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYASINGLECOMPONENTCANBETHEDEFAULTEXPORTFORITSFILEWHICHFACILITATESLAZYLOADINGWITHTHEROUTER", "original": "**Why?** A single component can be the default export for its file which facilitates lazy loading with the router.", "translation": "**为何?**单独的组件通常是该文件默认的导出,可以用路由器实现按需加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "THEKEYISTOMAKETHECODEMOREREUSABLEEASIERTOREADANDLESSMISTAKEPRONE", "original": "The key is to make the code more reusable, easier to read, and less mistake prone.", "translation": "最关键的是,可以增强代码可重用性和阅读性,减少出错的可能性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "THEFOLLOWINGNEGATIVEEXAMPLEDEFINESTHEAPPCOMPONENTBOOTSTRAPSTHEAPPDEFINESTHEHEROMODELOBJECTANDLOADSHEROESFROMTHESERVERALLINTHESAMEFILEDONTDOTHIS", "original": "The following *negative* example defines the `AppComponent`, bootstraps the app,\ndefines the `Hero` model object, and loads heroes from the server all in the same file.\n*Don't do this*.", "translation": "下面的*负面*例子定义了 `AppComponent`,它来引导应用程序,定义了 `Hero` 模型对象,并从服务器加载了英雄 ... 所有都在同一个文件。 *不要这么做*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ITISABETTERPRACTICETOREDISTRIBUTETHECOMPONENTANDITSSUPPORTINGCLASSESINTOTHEIROWNDEDICATEDFILES", "original": "It is a better practice to redistribute the component and its\nsupporting classes into their own, dedicated files.", "translation": "最好将组件及其支撑部件重新分配到独立的文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ASTHEAPPGROWSTHISRULEBECOMESEVENMOREIMPORTANT", "original": "As the app grows, this rule becomes even more important.", "translation": "随着应用程序的成长,本法则会变得越来越重要。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###SMALLFUNCTIONS", "original": "### Small functions", "translation": "### 小函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0102", "original": "#### Style 01-02", "translation": "#### 风格 01-02", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DODEFINESMALLFUNCTIONS", "original": "**Do** define small functions", "translation": "**坚持**定义简单函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERLIMITINGTONOMORETHAN75LINES", "original": "**Consider** limiting to no more than 75 lines.", "translation": "**考虑**限制在 75 行之内。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSMALLFUNCTIONSAREEASIERTOTESTESPECIALLYWHENTHEYDOONETHINGANDSERVEONEPURPOSE", "original": "**Why?** Small functions are easier to test, especially when they do one thing and serve one purpose.", "translation": "**为何?**简单函数更易于测试,特别是当它们只做一件事,只为一个目的服务时。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSMALLFUNCTIONSPROMOTEREUSE", "original": "**Why?** Small functions promote reuse.", "translation": "**为何?**简单函数促进代码重用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSMALLFUNCTIONSAREEASIERTOREAD", "original": "**Why?** Small functions are easier to read.", "translation": "**为何?**简单函数更易于阅读。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSMALLFUNCTIONSAREEASIERTOMAINTAIN", "original": "**Why?** Small functions are easier to maintain.", "translation": "**为何?**简单函数更易于维护。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSMALLFUNCTIONSHELPAVOIDHIDDENBUGSTHATCOMEWITHLARGEFUNCTIONSTHATSHAREVARIABLESWITHEXTERNALSCOPECREATEUNWANTEDCLOSURESORUNWANTEDCOUPLINGWITHDEPENDENCIES", "original": "**Why?** Small functions help avoid hidden bugs that come with large functions that share variables with external scope, create unwanted closures, or unwanted coupling with dependencies.", "translation": "**为何?**简单函数可避免易在大函数中产生的隐蔽性错误,例如与外界共享变量、创建意外的闭包或与依赖之间产生意外耦合等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##NAMING", "original": "## Naming", "translation": "## 命名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "NAMINGCONVENTIONSAREHUGELYIMPORTANTTOMAINTAINABILITYANDREADABILITYTHISGUIDERECOMMENDSNAMINGCONVENTIONSFORTHEFILENAMEANDTHESYMBOLNAME", "original": "Naming conventions are hugely important to maintainability and readability. This guide recommends naming conventions for the file name and the symbol name.", "translation": "命名约定对可维护性和可读性非常重要。本指南为文件名和符号名推荐了一套命名约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###GENERALNAMINGGUIDELINES", "original": "### General Naming Guidelines", "translation": "### 总体命名原则", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0201", "original": "#### Style 02-01", "translation": "#### 风格 02-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSECONSISTENTNAMESFORALLSYMBOLS", "original": "**Do** use consistent names for all symbols.", "translation": "**坚持**所有符号使用一致的命名规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOFOLLOWAPATTERNTHATDESCRIBESTHESYMBOLSFEATURETHENITSTYPETHERECOMMENDEDPATTERNISFEATURETYPETS", "original": "**Do** follow a pattern that describes the symbol's feature then its type. The recommended pattern is `feature.type.ts`.", "translation": "**坚持**遵循同一个模式来描述符号的特性和类型。推荐的模式为 `feature.type.ts`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYNAMINGCONVENTIONSHELPPROVIDEACONSISTENTWAYTOFINDCONTENTATAGLANCECONSISTENCYWITHINTHEPROJECTISVITALCONSISTENCYWITHATEAMISIMPORTANTCONSISTENCYACROSSACOMPANYPROVIDESTREMENDOUSEFFICIENCY", "original": "**Why?** Naming conventions help provide a consistent way to find content at a glance. Consistency within the project is vital. Consistency with a team is important. Consistency across a company provides tremendous efficiency.", "translation": "**为何?**命名约定提供了一致的方式来查找内容,让你一眼就能找到。\n项目的一致性是至关重要的。团队内的一致性也很重要。整个公司的一致性会提供惊人的效率。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHENAMINGCONVENTIONSSHOULDSIMPLYHELPFINDDESIREDCODEFASTERANDMAKEITEASIERTOUNDERSTAND", "original": "**Why?** The naming conventions should simply help find desired code faster and make it easier to understand.", "translation": "**为何?**命名约定帮助你更快得找到想找的代码,也更容易理解它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYNAMESOFFOLDERSANDFILESSHOULDCLEARLYCONVEYTHEIRINTENTFOREXAMPLEAPPHEROESHEROLISTCOMPONENTTSMAYCONTAINACOMPONENTTHATMANAGESALISTOFHEROES", "original": "**Why?** Names of folders and files should clearly convey their intent. For example, `app/heroes/hero-list.component.ts` may contain a component that manages a list of heroes.", "translation": "**为何?**目录名和文件名应该清楚的传递它们的意图。\n例如,`app/heroes/hero-list.component.ts` 包含了一个用来管理英雄列表的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###SEPARATEFILENAMESWITHDOTSANDDASHES", "original": "### Separate file names with dots and dashes", "translation": "### 使用点和横杠来分隔文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0202", "original": "#### Style 02-02", "translation": "#### 风格 02-02", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEDASHESTOSEPARATEWORDSINTHEDESCRIPTIVENAME", "original": "**Do** use dashes to separate words in the descriptive name.", "translation": "**坚持** 在描述性名字中,用横杠来分隔单词。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEDOTSTOSEPARATETHEDESCRIPTIVENAMEFROMTHETYPE", "original": "**Do** use dots to separate the descriptive name from the type.", "translation": "**坚持**使用点来分隔描述性名字和类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSECONSISTENTTYPENAMESFORALLCOMPONENTSFOLLOWINGAPATTERNTHATDESCRIBESTHECOMPONENTSFEATURETHENITSTYPEARECOMMENDEDPATTERNISFEATURETYPETS", "original": "**Do** use consistent type names for all components following a pattern that describes the component's feature then its type. A recommended pattern is `feature.type.ts`.", "translation": "**坚持**遵循先描述组件特性,再描述它的类型的模式,对所有组件使用一致的类型命名规则。推荐的模式为 `feature.type.ts`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSECONVENTIONALTYPENAMESINCLUDINGSERVICECOMPONENTPIPEMODULEANDDIRECTIVEINVENTADDITIONALTYPENAMESIFYOUMUSTBUTTAKECARENOTTOCREATETOOMANY", "original": "**Do** use conventional type names including `.service`, `.component`, `.pipe`, `.module`, and `.directive`.\nInvent additional type names if you must but take care not to create too many.", "translation": "**坚持**使用惯用的后缀来描述类型,包括 `*.service`、`*.component`、`*.pipe`、`.module`、`.directive`。\n必要时可以创建更多类型名,但必须注意,不要创建太多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTYPENAMESPROVIDEACONSISTENTWAYTOQUICKLYIDENTIFYWHATISINTHEFILE", "original": "**Why?** Type names provide a consistent way to quickly identify what is in the file.", "translation": "**为何?**类型名字提供一致的方式来快速的识别文件中有什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTYPENAMESMAKEITEASYTOFINDASPECIFICFILETYPEUSINGANEDITORORIDESFUZZYSEARCHTECHNIQUES", "original": "**Why?** Type names make it easy to find a specific file type using an editor or IDE's fuzzy search techniques.", "translation": "**为何?** 利用编辑器或者 IDE 的模糊搜索功能,可以很容易地找到特定文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYUNABBREVIATEDTYPENAMESSUCHASSERVICEAREDESCRIPTIVEANDUNAMBIGUOUSABBREVIATIONSSUCHASSRVSVCANDSERVCANBECONFUSING", "original": "**Why?** Unabbreviated type names such as `.service` are descriptive and unambiguous.\nAbbreviations such as `.srv`, `.svc`, and `.serv` can be confusing.", "translation": "**为何?** 像 `.service` 这样的没有简写过的类型名字,描述清楚,毫不含糊。\n像 `.srv`, `.svc`, 和 `.serv` 这样的简写可能令人困惑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTYPENAMESPROVIDEPATTERNMATCHINGFORANYAUTOMATEDTASKS", "original": "**Why?** Type names provide pattern matching for any automated tasks.", "translation": "**为何?**为自动化任务提供模式匹配。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###SYMBOLSANDFILENAMES", "original": "### Symbols and file names", "translation": "### 符号名与文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0203", "original": "#### Style 02-03", "translation": "#### 风格 02-03", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSECONSISTENTNAMESFORALLASSETSNAMEDAFTERWHATTHEYREPRESENT", "original": "**Do** use consistent names for all assets named after what they represent.", "translation": "**坚持**为所有东西使用一致的命名约定,以它们所代表的东西命名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEUPPERCAMELCASEFORCLASSNAMES", "original": "**Do** use upper camel case for class names.", "translation": "**坚持**使用大写驼峰命名法来命名类。符号名匹配它所在的文件名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOMATCHTHENAMEOFTHESYMBOLTOTHENAMEOFTHEFILE", "original": "**Do** match the name of the symbol to the name of the file.", "translation": "**坚持**在符号名后面追加约定的类型后缀(例如 `Component`、`Directive`、`Module`、`Pipe`、`Service`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOAPPENDTHESYMBOLNAMEWITHTHECONVENTIONALSUFFIXSUCHASCOMPONENTDIRECTIVEMODULEPIPEORSERVICEFORATHINGOFTHATTYPE", "original": "**Do** append the symbol name with the conventional suffix (such as `Component`,\n`Directive`, `Module`, `Pipe`, or `Service`) for a thing of that type.", "translation": "**坚持**在符号名后面追加约定的类型后缀(例如 `.component.ts`、`.directive.ts`、`.module.ts`、`.pipe.ts`、`.service.ts`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOGIVETHEFILENAMETHECONVENTIONALSUFFIXSUCHASCOMPONENTTSDIRECTIVETSMODULETSPIPETSORSERVICETSFORAFILEOFTHATTYPE", "original": "**Do** give the filename the conventional suffix (such as `.component.ts`, `.directive.ts`,\n`.module.ts`, `.pipe.ts`, or `.service.ts`) for a file of that type.", "translation": "**坚持**在文件名后面追加约定的类型后缀(例如 `.component.ts`、`.directive.ts`、`.module.ts`、`.pipe.ts`、`.service.ts`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCONSISTENTCONVENTIONSMAKEITEASYTOQUICKLYIDENTIFYANDREFERENCEASSETSOFDIFFERENTTYPES", "original": "**Why?** Consistent conventions make it easy to quickly identify\nand reference assets of different types.", "translation": "**为何?**遵循一致的约定可以快速识别和引用不同类型的资产。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "SYMBOLNAME", "original": "Symbol Name", "translation": "符号名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "FILENAME", "original": "File Name", "translation": "文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###SERVICENAMES", "original": "### Service names", "translation": "### 服务名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0204", "original": "#### Style 02-04", "translation": "#### 风格 02-04", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSECONSISTENTNAMESFORALLSERVICESNAMEDAFTERTHEIRFEATURE", "original": "**Do** use consistent names for all services named after their feature.", "translation": "**坚持**使用一致的规则命名服务,以它们的特性来命名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOSUFFIXASERVICECLASSNAMEWITHSERVICEFOREXAMPLESOMETHINGTHATGETSDATAORHEROESSHOULDBECALLEDADATASERVICEORAHEROSERVICE", "original": "**Do** suffix a service class name with `Service`.\nFor example, something that gets data or heroes\nshould be called a `DataService` or a `HeroService`.", "translation": "**坚持**为服务的类名加上 `Service` 后缀。\n例如,获取数据或英雄列表的服务应该命名为 `DataService` 或 `HeroService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AFEWTERMSAREUNAMBIGUOUSLYSERVICESTHEYTYPICALLYINDICATEAGENCYBYENDINGINERYOUMAYPREFERTONAMEASERVICETHATLOGSMESSAGESLOGGERRATHERTHANLOGGERSERVICEDECIDEIFTHISEXCEPTIONISAGREEABLEINYOURPROJECTASALWAYSSTRIVEFORCONSISTENCY", "original": "A few terms are unambiguously services. They typically\nindicate agency by ending in \"-er\". You may prefer to name\na service that logs messages `Logger` rather than `LoggerService`.\nDecide if this exception is agreeable in your project.\nAs always, strive for consistency.", "translation": "有些词汇显然就是服务,比如那些以“-er”后缀结尾的。比如把记日志的服务命名为 `Logger` 就比 `LoggerService` 更好些。需要在你的项目中决定这种特例是否可以接受。\n但无论如何,都要尽量保持一致。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPROVIDESACONSISTENTWAYTOQUICKLYIDENTIFYANDREFERENCESERVICES", "original": "**Why?** Provides a consistent way to quickly identify and reference services.", "translation": "**为何?**提供一致的方式来快速识别和引用服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCLEARSERVICENAMESSUCHASLOGGERDONOTREQUIREASUFFIX", "original": "**Why?** Clear service names such as `Logger` do not require a suffix.", "translation": "**为何?**像 `Logger` 这样的清楚的服务名不需要后缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSERVICENAMESSUCHASCREDITARENOUNSANDREQUIREASUFFIXANDSHOULDBENAMEDWITHASUFFIXWHENITISNOTOBVIOUSIFITISASERVICEORSOMETHINGELSE", "original": "**Why?** Service names such as `Credit` are nouns and require a suffix and should be named with a suffix when it is not obvious if it is a service or something else.", "translation": "**为何?**像 `Credit` 这样的,服务名是名词,需要一个后缀。当不能明显分辨它是服务还是其它东西时,应该添加后缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "SYMBOLNAME", "original": "Symbol Name", "translation": "符号名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "FILENAME", "original": "File Name", "translation": "文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###BOOTSTRAPPING", "original": "### Bootstrapping", "translation": "### 引导", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0205", "original": "#### Style 02-05", "translation": "#### 风格 02-05", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPUTBOOTSTRAPPINGANDPLATFORMLOGICFORTHEAPPINAFILENAMEDMAINTS", "original": "**Do** put bootstrapping and platform logic for the app in a file named `main.ts`.", "translation": "**坚持**把应用的引导程序和平台相关的逻辑放到名为 `main.ts` 的文件里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOINCLUDEERRORHANDLINGINTHEBOOTSTRAPPINGLOGIC", "original": "**Do** include error handling in the bootstrapping logic.", "translation": "**坚持**在引导逻辑中包含错误处理代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDPUTTINGAPPLOGICINMAINTSINSTEADCONSIDERPLACINGITINACOMPONENTORSERVICE", "original": "**Avoid** putting app logic in `main.ts`. Instead, consider placing it in a component or service.", "translation": "**避免**把应用逻辑放在 `main.ts` 中,而应放在组件或服务里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYFOLLOWSACONSISTENTCONVENTIONFORTHESTARTUPLOGICOFANAPP", "original": "**Why?** Follows a consistent convention for the startup logic of an app.", "translation": "**为何?**应用的启动逻辑遵循一致的约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYFOLLOWSAFAMILIARCONVENTIONFROMOTHERTECHNOLOGYPLATFORMS", "original": "**Why?** Follows a familiar convention from other technology platforms.", "translation": "**为何?**这是从其它技术平台借鉴的常用约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###DIRECTIVESELECTORS", "original": "### Directive selectors", "translation": "### 指令选择器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0206", "original": "#### Style 02-06", "translation": "#### 风格 02-06", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSELOWERCAMELCASEFORNAMINGTHESELECTORSOFDIRECTIVES", "original": "**Do** Use lower camel case for naming the selectors of directives.", "translation": "**坚持**使用小驼峰命名法来命名指令的选择器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYKEEPSTHENAMESOFTHEPROPERTIESDEFINEDINTHEDIRECTIVESTHATAREBOUNDTOTHEVIEWCONSISTENTWITHTHEATTRIBUTENAMES", "original": "**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.", "translation": "**为何?**保持指令中定义的属性名与绑定的视图 HTML 属性名字一致。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEANGULARHTMLPARSERISCASESENSITIVEANDRECOGNIZESLOWERCAMELCASE", "original": "**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.", "translation": "**为何?**Angular HTML 解析器是大小写敏感的,它识别小写驼峰写法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###CUSTOMPREFIXFORCOMPONENTS", "original": "### Custom prefix for components", "translation": "### 为组件添加自定义前缀", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0207", "original": "#### Style 02-07", "translation": "#### 风格 02-07", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEAHYPHENATEDLOWERCASEELEMENTSELECTORVALUEEGADMINUSERS", "original": "**Do** use a hyphenated, lowercase element selector value (e.g. `admin-users`).", "translation": "**坚持**使用带连字符的小写元素选择器值(例如 `admin-users`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEACUSTOMPREFIXFORACOMPONENTSELECTORFOREXAMPLETHEPREFIXTOHREPRESENTSFROMTOUROFHEROESANDTHEPREFIXADMINREPRESENTSANADMINFEATUREAREA", "original": "**Do** use a custom prefix for a component selector.\nFor example, the prefix `toh` represents from **T**our **o**f **H**eroes and the prefix `admin` represents an admin feature area.", "translation": "**坚持**为组件选择器添加自定义前缀。\n例如,`toh` 前缀表示 **T**our **o**f **H**eroes(英雄指南),而前缀 `admin 表示管理特性区。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEAPREFIXTHATIDENTIFIESTHEFEATUREAREAORTHEAPPITSELF", "original": "**Do** use a prefix that identifies the feature area or the app itself.", "translation": "**坚持**使用前缀来识别特性区或者应用程序本身。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPREVENTSELEMENTNAMECOLLISIONSWITHCOMPONENTSINOTHERAPPSANDWITHNATIVEHTMLELEMENTS", "original": "**Why?** Prevents element name collisions with components in other apps and with native HTML elements.", "translation": "**为何?**防止与其它应用中的组件和原生 HTML 元素发生命名冲突。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYMAKESITEASIERTOPROMOTEANDSHARETHECOMPONENTINOTHERAPPS", "original": "**Why?** Makes it easier to promote and share the component in other apps.", "translation": "**为何?**更容易在其它应用中推广和共享组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCOMPONENTSAREEASYTOIDENTIFYINTHEDOM", "original": "**Why?** Components are easy to identify in the DOM.", "translation": "**为何?**组件在 DOM 中更容易被区分出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###CUSTOMPREFIXFORDIRECTIVES", "original": "### Custom prefix for directives", "translation": "### 为指令添加自定义前缀", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0208", "original": "#### Style 02-08", "translation": "#### 风格 02-08", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEACUSTOMPREFIXFORTHESELECTOROFDIRECTIVESEGTHEPREFIXTOHFROMTOUROFHEROES", "original": "**Do** use a custom prefix for the selector of directives (e.g, the prefix `toh` from **T**our **o**f **H**eroes).", "translation": "**坚持**为指令的选择器添加自定义前缀(例如前缀 `toh` 来自 **T**our **o**f **H**eroes)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOSPELLNONELEMENTSELECTORSINLOWERCAMELCASEUNLESSTHESELECTORISMEANTTOMATCHANATIVEHTMLATTRIBUTE", "original": "**Do** spell non-element selectors in lower camel case unless the selector is meant to match a native HTML attribute.", "translation": "**坚持**用小驼峰形式拼写非元素选择器,除非该选择器用于匹配原生 HTML 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPREVENTSNAMECOLLISIONS", "original": "**Why?** Prevents name collisions.", "translation": "**为何?**防止名字冲突。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYDIRECTIVESAREEASILYIDENTIFIED", "original": "**Why?** Directives are easily identified.", "translation": "**为何?**指令更加容易被识别。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###PIPENAMES", "original": "### Pipe names", "translation": "### 管道名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0209", "original": "#### Style 02-09", "translation": "#### 风格 02-09", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSECONSISTENTNAMESFORALLPIPESNAMEDAFTERTHEIRFEATURE", "original": "**Do** use consistent names for all pipes, named after their feature.", "translation": "**坚持**为所有管道使用一致的命名约定,用它们的特性来命名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPROVIDESACONSISTENTWAYTOQUICKLYIDENTIFYANDREFERENCEPIPES", "original": "**Why?** Provides a consistent way to quickly identify and reference pipes.", "translation": "**为何?**提供一致方式快速识别和引用管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "SYMBOLNAME", "original": "Symbol Name", "translation": "符号名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "FILENAME", "original": "File Name", "translation": "文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###UNITTESTFILENAMES", "original": "### Unit test file names", "translation": "### 单元测试文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0210", "original": "#### Style 02-10", "translation": "#### 风格 02-10", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMETESTSPECIFICATIONFILESTHESAMEASTHECOMPONENTTHEYTEST", "original": "**Do** name test specification files the same as the component they test.", "translation": "**坚持**测试规格文件名与被测试组件文件名相同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMETESTSPECIFICATIONFILESWITHASUFFIXOFSPEC", "original": "**Do** name test specification files with a suffix of `.spec`.", "translation": "**坚持**测试规格文件名添加 `.spec` 后缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPROVIDESACONSISTENTWAYTOQUICKLYIDENTIFYTESTS", "original": "**Why?** Provides a consistent way to quickly identify tests.", "translation": "**为何?**提供一致的方式来快速识别测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPROVIDESPATTERNMATCHINGFORKARMAHTTP:KARMARUNNERGITHUBIOOROTHERTESTRUNNERS", "original": "**Why?** Provides pattern matching for [karma](http://karma-runner.github.io/) or other test runners.", "translation": "**为何?**提供一个与 [karma](http://karma-runner.github.io/) 或者其它测试运行器相配的命名模式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "TESTTYPE", "original": "Test Type", "translation": "测试类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "FILENAMES", "original": "File Names", "translation": "文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "COMPONENTS", "original": "Components", "translation": "组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "SERVICES", "original": "Services", "translation": "服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "PIPES", "original": "Pipes", "translation": "管道", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###ENDTOENDE2ETESTFILENAMES", "original": "### _End-to-End_ (E2E) test file names", "translation": "### *端到端*(E2E)测试的文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0211", "original": "#### Style 02-11", "translation": "#### 风格 02-11", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMEENDTOENDTESTSPECIFICATIONFILESAFTERTHEFEATURETHEYTESTWITHASUFFIXOFE2ESPEC", "original": "**Do** name end-to-end test specification files after the feature they test with a suffix of `.e2e-spec`.", "translation": "**坚持**端到端测试规格文件和它们所测试的特性同名,添加 `.e2e-spec` 后缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPROVIDESACONSISTENTWAYTOQUICKLYIDENTIFYENDTOENDTESTS", "original": "**Why?** Provides a consistent way to quickly identify end-to-end tests.", "translation": "**为何?**提供一致的方式快速识别端到端测试文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPROVIDESPATTERNMATCHINGFORTESTRUNNERSANDBUILDAUTOMATION", "original": "**Why?** Provides pattern matching for test runners and build automation.", "translation": "**为何?**提供一个与测试运行器和构建自动化匹配的模式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "TESTTYPE", "original": "Test Type", "translation": "测试类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "FILENAMES", "original": "File Names", "translation": "文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ENDTOENDTESTS", "original": "End-to-End Tests", "translation": "端到端测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###ANGULARNGMODULENAMES", "original": "### Angular _NgModule_ names", "translation": "### Angular *NgModule* 命名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0212", "original": "#### Style 02-12", "translation": "#### 风格 02-12", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOAPPENDTHESYMBOLNAMEWITHTHESUFFIXMODULE", "original": "**Do** append the symbol name with the suffix `Module`.", "translation": "**坚持**为符号名添加 `Module` 后缀", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOGIVETHEFILENAMETHEMODULETSEXTENSION", "original": "**Do** give the file name the `.module.ts` extension.", "translation": "**坚持**为文件名添加 `.module.ts` 扩展名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMETHEMODULEAFTERTHEFEATUREANDFOLDERITRESIDESIN", "original": "**Do** name the module after the feature and folder it resides in.", "translation": "**坚持**用特性名和所在目录命名模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPROVIDESACONSISTENTWAYTOQUICKLYIDENTIFYANDREFERENCEMODULES", "original": "**Why?** Provides a consistent way to quickly identify and reference modules.", "translation": "**为何?**提供一致的方式来快速标识和引用模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYUPPERCAMELCASEISCONVENTIONALFORIDENTIFYINGOBJECTSTHATCANBEINSTANTIATEDUSINGACONSTRUCTOR", "original": "**Why?** Upper camel case is conventional for identifying objects that can be instantiated using a constructor.", "translation": "**为何?**大驼峰命名法是一种命名约定,用来标识可用构造函数实例化的对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYEASILYIDENTIFIESTHEMODULEASTHEROOTOFTHESAMENAMEDFEATURE", "original": "**Why?** Easily identifies the module as the root of the same named feature.", "translation": "**为何?**很容易就能看出这个模块是同名特性的根模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOSUFFIXAROUTINGMODULECLASSNAMEWITHROUTINGMODULE", "original": "**Do** suffix a _RoutingModule_ class name with `RoutingModule`.", "translation": "**坚持**为 *RoutingModule* 类名添加 `RoutingModule` 后缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOENDTHEFILENAMEOFAROUTINGMODULEWITHROUTINGMODULETS", "original": "**Do** end the filename of a _RoutingModule_ with `-routing.module.ts`.", "translation": "**坚持**为 *RoutingModule* 的文件名添加 `-routing.module.ts` 后缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYAROUTINGMODULEISAMODULEDEDICATEDEXCLUSIVELYTOCONFIGURINGTHEANGULARROUTERACONSISTENTCLASSANDFILENAMECONVENTIONMAKETHESEMODULESEASYTOSPOTANDVERIFY", "original": "**Why?** A `RoutingModule` is a module dedicated exclusively to configuring the Angular router.\nA consistent class and file name convention make these modules easy to spot and verify.", "translation": "**为何?**`RoutingModule` 是一种专门用来配置 Angular 路由器的模块。\n“类名和文件名保持一致”的约定使这些模块易于发现和验证。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "SYMBOLNAME", "original": "Symbol Name", "translation": "符号名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "FILENAME", "original": "File Name", "translation": "文件名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##CODINGCONVENTIONS", "original": "## Coding conventions", "translation": "## 编程约定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "HAVEACONSISTENTSETOFCODINGNAMINGANDWHITESPACECONVENTIONS", "original": "Have a consistent set of coding, naming, and whitespace conventions.", "translation": "坚持一致的编程、命名和空格的约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###CLASSES", "original": "### Classes", "translation": "### 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0301", "original": "#### Style 03-01", "translation": "#### 风格 03-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEUPPERCAMELCASEWHENNAMINGCLASSES", "original": "**Do** use upper camel case when naming classes.", "translation": "**坚持**使用大写驼峰命名法来命名类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYFOLLOWSCONVENTIONALTHINKINGFORCLASSNAMES", "original": "**Why?** Follows conventional thinking for class names.", "translation": "**为何?**遵循类命名传统约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCLASSESCANBEINSTANTIATEDANDCONSTRUCTANINSTANCEBYCONVENTIONUPPERCAMELCASEINDICATESACONSTRUCTABLEASSET", "original": "**Why?** Classes can be instantiated and construct an instance.\nBy convention, upper camel case indicates a constructable asset.", "translation": "**为何?**类可以被实例化和构造实例。根据约定,用大写驼峰命名法来标识可构造的东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###CONSTANTS", "original": "### Constants", "translation": "### 常量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0302", "original": "#### Style 03-02", "translation": "#### 风格 03-02", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DODECLAREVARIABLESWITHCONSTIFTHEIRVALUESSHOULDNOTCHANGEDURINGTHEAPPLICATIONLIFETIME", "original": "**Do** declare variables with `const` if their values should not change during the application lifetime.", "translation": "**坚持**用 `const` 声明变量,除非它们的值在应用的生命周期内会发生变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCONVEYSTOREADERSTHATTHEVALUEISINVARIANT", "original": "**Why?** Conveys to readers that the value is invariant.", "translation": "**为何?**告诉读者这个值是不可变的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTYPESCRIPTHELPSENFORCETHATINTENTBYREQUIRINGIMMEDIATEINITIALIZATIONANDBYPREVENTINGSUBSEQUENTREASSIGNMENT", "original": "**Why?** TypeScript helps enforce that intent by requiring immediate initialization and by\npreventing subsequent re-assignment.", "translation": "**为何?** TypeScript 会要求在声明时立即初始化,并阻止再次赋值,以帮助确保你的设计意图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERSPELLINGCONSTVARIABLESINLOWERCAMELCASE", "original": "**Consider** spelling `const` variables in lower camel case.", "translation": "**考虑** 把常量名拼写为小驼峰格式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYLOWERCAMELCASEVARIABLENAMESHEROROUTESAREEASIERTOREADANDUNDERSTANDTHANTHETRADITIONALUPPERSNAKECASENAMESHEROROUTES", "original": "**Why?** Lower camel case variable names (`heroRoutes`) are easier to read and understand\nthan the traditional UPPER_SNAKE_CASE names (`HERO_ROUTES`).", "translation": "**为何?**小驼峰变量名 (`heroRoutes`) 比传统的大写蛇形命名法 (`HERO_ROUTES`) 更容易阅读和理解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHETRADITIONOFNAMINGCONSTANTSINUPPERSNAKECASEREFLECTSANERABEFORETHEMODERNIDESTHATQUICKLYREVEALTHECONSTDECLARATIONTYPESCRIPTPREVENTSACCIDENTALREASSIGNMENT", "original": "**Why?** The tradition of naming constants in UPPER_SNAKE_CASE reflects\nan era before the modern IDEs that quickly reveal the `const` declaration.\nTypeScript prevents accidental reassignment.", "translation": "**为何?** 把常量命名为大写蛇形命名法的传统源于现代 IDE 出现之前,\n以便阅读时可以快速发现那些 `const` 定义。\nTypeScript 本身就能够防止意外赋值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOTOLERATEEXISTINGCONSTVARIABLESTHATARESPELLEDINUPPERSNAKECASE", "original": "**Do** tolerate _existing_ `const` variables that are spelled in UPPER_SNAKE_CASE.", "translation": "**坚持**容许*现存的*`const` 常量沿用大写蛇形命名法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHETRADITIONOFUPPERSNAKECASEREMAINSPOPULARANDPERVASIVEESPECIALLYINTHIRDPARTYMODULESITISRARELYWORTHTHEEFFORTTOCHANGETHEMATTHERISKOFBREAKINGEXISTINGCODEANDDOCUMENTATION", "original": "**Why?** The tradition of UPPER_SNAKE_CASE remains popular and pervasive,\nespecially in third party modules.\nIt is rarely worth the effort to change them at the risk of breaking existing code and documentation.", "translation": "**为何?**传统的大写蛇形命名法仍然很流行、很普遍,特别是在第三方模块中。\n修改它们没多大价值,还会有破坏现有代码和文档的风险。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###INTERFACES", "original": "### Interfaces", "translation": "### 接口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0303", "original": "#### Style 03-03", "translation": "#### 风格 03-03", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMEANINTERFACEUSINGUPPERCAMELCASE", "original": "**Do** name an interface using upper camel case.", "translation": "**坚持**使用大写驼峰命名法来命名接口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERNAMINGANINTERFACEWITHOUTANIPREFIX", "original": "**Consider** naming an interface without an `I` prefix.", "translation": "**考虑**不要在接口名字前面加 `I` 前缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERUSINGACLASSINSTEADOFANINTERFACEFORSERVICESANDDECLARABLESCOMPONENTSDIRECTIVESANDPIPES", "original": "**Consider** using a class instead of an interface for services and declarables (components, directives, and pipes).", "translation": "**考虑**在服务和可声明对象(组件、指令和管道)中用类代替接口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERUSINGANINTERFACEFORDATAMODELS", "original": "**Consider** using an interface for data models.", "translation": "**考虑**用接口作为数据模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYAHREFHTTPS:GITHUBCOMMICROSOFTTYPESCRIPTWIKICODINGGUIDELINESTYPESCRIPTGUIDELINESADISCOURAGETHEIPREFIX", "original": "**Why?** <a href=\"https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines\">TypeScript guidelines</a>\ndiscourage the `I` prefix.", "translation": "**为何?**<a href=\"https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines\" target=\"_blank\">TypeScript 指导原则</a>不建议使用 “I” 前缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYACLASSALONEISLESSCODETHANACLASSPLUSINTERFACE", "original": "**Why?** A class alone is less code than a _class-plus-interface_.", "translation": "**为何?**单独一个类的代码量小于*类+接口*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYACLASSCANACTASANINTERFACEUSEIMPLEMENTSINSTEADOFEXTENDS", "original": "**Why?** A class can act as an interface (use `implements` instead of `extends`).", "translation": "**为何?**类可以作为接口使用(只是用 `implements` 代替 `extends` 而已)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYANINTERFACECLASSCANBEAPROVIDERLOOKUPTOKENINANGULARDEPENDENCYINJECTION", "original": "**Why?** An interface-class can be a provider lookup token in Angular dependency injection.", "translation": "**为何?**在 Angular 依赖注入系统中,接口类(译注:指写成类的形式,但是只当做接口使用)可以作为服务提供商的查找令牌。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###PROPERTIESANDMETHODS", "original": "### Properties and methods", "translation": "### 属性和方法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0304", "original": "#### Style 03-04", "translation": "#### 样式 03-04", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSELOWERCAMELCASETONAMEPROPERTIESANDMETHODS", "original": "**Do** use lower camel case to name properties and methods.", "translation": "**坚持**使用小写驼峰命名法来命名属性和方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDPREFIXINGPRIVATEPROPERTIESANDMETHODSWITHANUNDERSCORE", "original": "**Avoid** prefixing private properties and methods with an underscore.", "translation": "**避免**为私有属性和方法添加下划线前缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYFOLLOWSCONVENTIONALTHINKINGFORPROPERTIESANDMETHODS", "original": "**Why?** Follows conventional thinking for properties and methods.", "translation": "**为何?**遵循传统属性和方法的命名约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYJAVASCRIPTLACKSATRUEPRIVATEPROPERTYORMETHOD", "original": "**Why?** JavaScript lacks a true private property or method.", "translation": "**为何?** JavaScript 不支持真正的私有属性和方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTYPESCRIPTTOOLINGMAKESITEASYTOIDENTIFYPRIVATEVSPUBLICPROPERTIESANDMETHODS", "original": "**Why?** TypeScript tooling makes it easy to identify private vs. public properties and methods.", "translation": "**为何?** TypeScript 工具让识别私有或公有属性和方法变得很简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###IMPORTLINESPACING", "original": "### Import line spacing", "translation": "### 导入语句中的空行", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0306", "original": "#### Style 03-06", "translation": "#### 风格 03-06", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERLEAVINGONEEMPTYLINEBETWEENTHIRDPARTYIMPORTSANDAPPLICATIONIMPORTS", "original": "**Consider** leaving one empty line between third party imports and application imports.", "translation": "**坚持**在第三方导入和应用导入之间留一个空行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERLISTINGIMPORTLINESALPHABETIZEDBYTHEMODULE", "original": "**Consider** listing import lines alphabetized by the module.", "translation": "**考虑**按模块名字的字母顺排列导入行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERLISTINGDESTRUCTUREDIMPORTEDSYMBOLSALPHABETICALLY", "original": "**Consider** listing destructured imported symbols alphabetically.", "translation": "**考虑**在解构表达式中按字母顺序排列导入的东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEEMPTYLINESEPARATESYOURSTUFFFROMTHEIRSTUFF", "original": "**Why?** The empty line separates _your_ stuff from _their_ stuff.", "translation": "**为何?**空行可以让阅读和定位本地导入更加容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYALPHABETIZINGMAKESITEASIERTOREADANDLOCATESYMBOLS", "original": "**Why?** Alphabetizing makes it easier to read and locate symbols.", "translation": "**为何?**按字母顺序排列可以让阅读和定位本地导入更加容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##APPLICATIONSTRUCTUREANDNGMODULES", "original": "## Application structure and NgModules", "translation": "## 应用程序结构与 Angular 模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "HAVEANEARTERMVIEWOFIMPLEMENTATIONANDALONGTERMVISIONSTARTSMALLBUTKEEPINMINDWHERETHEAPPISHEADINGDOWNTHEROAD", "original": "Have a near-term view of implementation and a long-term vision. Start small but keep in mind where the app is heading down the road.", "translation": "准备一个近期实施方案和一个长期的愿景。从零开始,但要考虑应用程序接下来的路往哪儿走。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ALLOFTHEAPPSCODEGOESINAFOLDERNAMEDSRCALLFEATUREAREASAREINTHEIROWNFOLDERWITHTHEIROWNNGMODULE", "original": "All of the app's code goes in a folder named `src`.\nAll feature areas are in their own folder, with their own NgModule.", "translation": "所有应用程序的源代码都放到名叫 `src` 的目录里。\n所有特性区都在自己的文件夹中,带有它们自己的 Angular 模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ALLCONTENTISONEASSETPERFILEEACHCOMPONENTSERVICEANDPIPEISINITSOWNFILEALLTHIRDPARTYVENDORSCRIPTSARESTOREDINANOTHERFOLDERANDNOTINTHESRCFOLDERYOUDIDNTWRITETHEMANDYOUDONTWANTTHEMCLUTTERINGSRCUSETHENAMINGCONVENTIONSFORFILESINTHISGUIDE", "original": "All content is one asset per file. Each component, service, and pipe is in its own file.\nAll third party vendor scripts are stored in another folder and not in the `src` folder.\nYou didn't write them and you don't want them cluttering `src`.\nUse the naming conventions for files in this guide.", "translation": "所有内容都遵循每个文件一个特性的原则。每个组件、服务和管道都在自己的文件里。\n所有第三方程序包保存到其它目录里,而不是 `src` 目录。\n你不会修改它们,所以不希望它们弄乱你的应用程序。\n使用本指南介绍的文件命名约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0401", "original": "#### Style 04-01", "translation": "#### 风格 04-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOSTRUCTURETHEAPPSUCHTHATYOUCANLOCATECODEQUICKLYIDENTIFYTHECODEATAGLANCEKEEPTHEFLATTESTSTRUCTUREYOUCANANDTRYTOBEDRY", "original": "**Do** structure the app such that you can **L**ocate code quickly,\n**I**dentify the code at a glance,\nkeep the **F**lattest structure you can, and\n**T**ry to be DRY.", "translation": "**坚持**组织应用的结构,达到这些目的:快速定位 (`L`ocate) 代码、一眼识别 (`I`dentify) 代码、 尽量保持扁平结构 (`F`lattest) 和尝试 (`T`ry) 遵循 DRY (Do Not Repeat Yourself, 不重复自己) 原则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DODEFINETHESTRUCTURETOFOLLOWTHESEFOURBASICGUIDELINESLISTEDINORDEROFIMPORTANCE", "original": "**Do** define the structure to follow these four basic guidelines, listed in order of importance.", "translation": "**坚持**四项基本原则定义文件结构,上面的原则是按重要顺序排列的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYLIFTPROVIDESACONSISTENTSTRUCTURETHATSCALESWELLISMODULARANDMAKESITEASIERTOINCREASEDEVELOPEREFFICIENCYBYFINDINGCODEQUICKLYTOCONFIRMYOURINTUITIONABOUTAPARTICULARSTRUCTUREASK:CANIQUICKLYOPENANDSTARTWORKINALLOFTHERELATEDFILESFORTHISFEATURE", "original": "**Why?** LIFT Provides a consistent structure that scales well, is modular, and makes it easier to increase developer efficiency by finding code quickly.\nTo confirm your intuition about a particular structure, ask:\n_can I quickly open and start work in all of the related files for this feature_?", "translation": "**为何?**LIFT 提供了一致的结构,它具有扩展性强、模块化的特性。因为容易快速锁定代码,提高了开发者的效率。\n另外,检查应用结构是否合理的方法是问问自己:我能快速打开与此特性有关的所有文件并开始工作吗?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###LOCATE", "original": "### Locate", "translation": "### 定位", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0402", "original": "#### Style 04-02", "translation": "#### 风格 04-02", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOMAKELOCATINGCODEINTUITIVESIMPLEANDFAST", "original": "**Do** make locating code intuitive, simple and fast.", "translation": "**坚持**直观、简单和快速地定位代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTOWORKEFFICIENTLYYOUMUSTBEABLETOFINDFILESQUICKLYESPECIALLYWHENYOUDONOTKNOWORDONOTREMEMBERTHEFILENAMESKEEPINGRELATEDFILESNEAREACHOTHERINANINTUITIVELOCATIONSAVESTIMEADESCRIPTIVEFOLDERSTRUCTUREMAKESAWORLDOFDIFFERENCETOYOUANDTHEPEOPLEWHOCOMEAFTERYOU", "original": "**Why?** To work efficiently you must be able to find files quickly,\nespecially when you do not know (or do not remember) the file _names_.\nKeeping related files near each other in an intuitive location saves time.\nA descriptive folder structure makes a world of difference to you and the people who come after you.", "translation": "**为何?**\n要想高效的工作,就必须能迅速找到文件,特别是当不知道(或不记得)文件*名*时。\n把相关的文件一起放在一个直观的位置可以节省时间。\n富有描述性的目录结构会让你和后面的维护者眼前一亮。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###IDENTIFY", "original": "### Identify", "translation": "### 识别", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0403", "original": "#### Style 04-03", "translation": "#### 风格 04-03", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMETHEFILESUCHTHATYOUINSTANTLYKNOWWHATITCONTAINSANDREPRESENTS", "original": "**Do** name the file such that you instantly know what it contains and represents.", "translation": "**坚持**命名文件到这个程度:看到名字立刻知道它包含了什么,代表了什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOBEDESCRIPTIVEWITHFILENAMESANDKEEPTHECONTENTSOFTHEFILETOEXACTLYONECOMPONENT", "original": "**Do** be descriptive with file names and keep the contents of the file to exactly one component.", "translation": "**坚持**文件名要具有说明性,确保文件中只包含一个组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDFILESWITHMULTIPLECOMPONENTSMULTIPLESERVICESORAMIXTURE", "original": "**Avoid** files with multiple components, multiple services, or a mixture.", "translation": "**避免**创建包含多个组件、服务或者混合体的文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSPENDLESSTIMEHUNTINGANDPECKINGFORCODEANDBECOMEMOREEFFICIENTLONGERFILENAMESAREFARBETTERTHANSHORTBUTOBSCUREABBREVIATEDNAMES", "original": "**Why?** Spend less time hunting and pecking for code, and become more efficient.\nLonger file names are far better than _short-but-obscure_ abbreviated names.", "translation": "**为何?**花费更少的时间来查找和琢磨代码,就会变得更有效率。\n较长的文件名远胜于*较短却容易混淆的*缩写名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ITMAYBEADVANTAGEOUSTODEVIATEFROMTHEONETHINGPERFILERULEWHENYOUHAVEASETOFSMALLCLOSELYRELATEDFEATURESTHATAREBETTERDISCOVEREDANDUNDERSTOODINASINGLEFILETHANASMULTIPLEFILESBEWARYOFTHISLOOPHOLE", "original": "It may be advantageous to deviate from the _one-thing-per-file_ rule when\nyou have a set of small, closely-related features that are better discovered and understood\nin a single file than as multiple files. Be wary of this loophole.", "translation": "当你有一组小型、紧密相关的特性时,违反*一物一文件*的规则可能会更好,\n这种情况下单一文件可能会比多个文件更容易发现和理解。注意这个例外。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###FLAT", "original": "### Flat", "translation": "### 扁平", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0404", "original": "#### Style 04-04", "translation": "#### 风格 04-04", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOKEEPAFLATFOLDERSTRUCTUREASLONGASPOSSIBLE", "original": "**Do** keep a flat folder structure as long as possible.", "translation": "**坚持**尽可能保持扁平的目录结构。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERCREATINGSUBFOLDERSWHENAFOLDERREACHESSEVENORMOREFILES", "original": "**Consider** creating sub-folders when a folder reaches seven or more files.", "translation": "**考虑**当同一目录下达到 7 个或更多个文件时创建子目录。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERCONFIGURINGTHEIDETOHIDEDISTRACTINGIRRELEVANTFILESSUCHASGENERATEDJSANDJSMAPFILES", "original": "**Consider** configuring the IDE to hide distracting, irrelevant files such as generated `.js` and `.js.map` files.", "translation": "**考虑**配置 IDE,以隐藏无关的文件,例如生成出来的 `.js` 文件和 `.js.map` 文件等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYNOONEWANTSTOSEARCHFORAFILETHROUGHSEVENLEVELSOFFOLDERSAFLATSTRUCTUREISEASYTOSCAN", "original": "**Why?** No one wants to search for a file through seven levels of folders.\nA flat structure is easy to scan.", "translation": "**为何?**没人想要在超过七层的目录中查找文件。扁平的结构有利于搜索。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ONTHEOTHERHANDAHREFHTTPS:ENWIKIPEDIAORGWIKITHEMAGICALNUMBERSEVENPLUSORMINUSTWOPSYCHOLOGISTSBELIEVEATHATHUMANSSTARTTOSTRUGGLEWHENTHENUMBEROFADJACENTINTERESTINGTHINGSEXCEEDSNINESOWHENAFOLDERHASTENORMOREFILESITMAYBETIMETOCREATESUBFOLDERS", "original": "On the other hand,\n<a href=\"https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two\">psychologists believe</a>\nthat humans start to struggle when the number of adjacent interesting things exceeds nine.\nSo when a folder has ten or more files, it may be time to create subfolders.", "translation": "另一方面,<a href=\"https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two\" target=\"_blank\">心理学家们相信</a>,\n当关注的事物超过 9 个时,人类就会开始感到吃力。\n所以,当一个文件夹中的文件有 10 个或更多个文件时,可能就是创建子目录的时候了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "BASEYOURDECISIONONYOURCOMFORTLEVELUSEAFLATTERSTRUCTUREUNTILTHEREISANOBVIOUSVALUETOCREATINGANEWFOLDER", "original": "Base your decision on your comfort level.\nUse a flatter structure until there is an obvious value to creating a new folder.", "translation": "还是根据你自己的舒适度而定吧。\n除非创建新文件夹能有显著的价值,否则尽量使用扁平结构。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###TDRYTRYTOBEDRY", "original": "### _T-DRY_ (Try to be _DRY_)", "translation": "### *T-DRY*(尽量不重复自己)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0405", "original": "#### Style 04-05", "translation": "#### 风格 04-05", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOBEDRYDONTREPEATYOURSELF", "original": "**Do** be DRY (Don't Repeat Yourself).", "translation": "**坚持** DRY(Don't Repeat Yourself,不重复自己)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDBEINGSODRYTHATYOUSACRIFICEREADABILITY", "original": "**Avoid** being so DRY that you sacrifice readability.", "translation": "**避免**过度 DRY,以致牺牲了阅读性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYBEINGDRYISIMPORTANTBUTNOTCRUCIALIFITSACRIFICESTHEOTHERELEMENTSOFLIFTTHATSWHYITSCALLEDTDRYFOREXAMPLEITSREDUNDANTTONAMEATEMPLATEHEROVIEWCOMPONENTHTMLBECAUSEWITHTHEHTMLEXTENSIONITISOBVIOUSLYAVIEWBUTIFSOMETHINGISNOTOBVIOUSORDEPARTSFROMACONVENTIONTHENSPELLITOUT", "original": "**Why?** Being DRY is important, but not crucial if it sacrifices the other elements of LIFT.\nThat's why it's called _T-DRY_.\nFor example, it's redundant to name a template `hero-view.component.html` because\nwith the `.html` extension, it is obviously a view.\nBut if something is not obvious or departs from a convention, then spell it out.", "translation": "**为何?**虽然 DRY 很重要,但如果要以牺牲 LIFT 的其它原则为代价,那就不值得了。\n这也就是为什么它被称为 *T-DRY*。\n例如,把组件命名为 `hero-view.component.html` 是多余的,因为带有 `.html` 扩展名的文件显然就是一个视图 (view)。\n但如果它不那么显著,或不符合常规,就把它写出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###OVERALLSTRUCTURALGUIDELINES", "original": "### Overall structural guidelines", "translation": "### 总体结构的指导原则", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0406", "original": "#### Style 04-06", "translation": "#### 风格 04-06", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOSTARTSMALLBUTKEEPINMINDWHERETHEAPPISHEADINGDOWNTHEROAD", "original": "**Do** start small but keep in mind where the app is heading down the road.", "translation": "**坚持**从零开始,但要考虑应用程序接下来的路往哪儿走。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOHAVEANEARTERMVIEWOFIMPLEMENTATIONANDALONGTERMVISION", "original": "**Do** have a near term view of implementation and a long term vision.", "translation": "**坚持**有一个近期实施方案和一个长期的愿景。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPUTALLOFTHEAPPSCODEINAFOLDERNAMEDSRC", "original": "**Do** put all of the app's code in a folder named `src`.", "translation": "**坚持**把所有源代码都放到名为 `src` 的目录里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERCREATINGAFOLDERFORACOMPONENTWHENITHASMULTIPLEACCOMPANYINGFILESTSHTMLCSSANDSPEC", "original": "**Consider** creating a folder for a component when it has multiple accompanying files (`.ts`, `.html`, `.css` and `.spec`).", "translation": "**坚持**如果组件具有多个伴隨文件 (`.ts`、`.html`、`.css` 和 `.spec`),就为它创建一个文件夹。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYHELPSKEEPTHEAPPSTRUCTURESMALLANDEASYTOMAINTAININTHEEARLYSTAGESWHILEBEINGEASYTOEVOLVEASTHEAPPGROWS", "original": "**Why?** Helps keep the app structure small and easy to maintain in the early stages, while being easy to evolve as the app grows.", "translation": "**为何?** 在早期阶段能够帮助保持应用的结构小巧且易于维护,这样当应用增长时就容易进化了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCOMPONENTSOFTENHAVEFOURFILESEGHTMLCSSTSANDSPECTSANDCANCLUTTERAFOLDERQUICKLY", "original": "**Why?** Components often have four files (e.g. `*.html`, `*.css`, `*.ts`, and `*.spec.ts`) and can clutter a folder quickly.", "translation": "**为何?** 组件通常有四个文件 (`*.html`、 `*.css`、 `*.ts` 和 `*.spec.ts`),它们很容易把一个目录弄乱。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "HEREISACOMPLIANTFOLDERANDFILESTRUCTURE:", "original": "Here is a compliant folder and file structure:", "translation": "下面是符合规范的目录和文件结构", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHILECOMPONENTSINDEDICATEDFOLDERSAREWIDELYPREFERREDANOTHEROPTIONFORSMALLAPPSISTOKEEPCOMPONENTSFLATNOTINADEDICATEDFOLDERTHISADDSUPTOFOURFILESTOTHEEXISTINGFOLDERBUTALSOREDUCESTHEFOLDERNESTINGWHATEVERYOUCHOOSEBECONSISTENT", "original": "While components in dedicated folders are widely preferred,\nanother option for small apps is to keep components flat (not in a dedicated folder).\nThis adds up to four files to the existing folder, but also reduces the folder nesting.\nWhatever you choose, be consistent.", "translation": "把组件放在专用目录中的方式广受欢迎,对于小型应用,还可以保持组件扁平化(而不是放在专用目录中)。\n这样会把四个文件放在现有目录中,也会减少目录的嵌套。无论你如何选择,请保持一致。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###FOLDERSBYFEATURESTRUCTURE", "original": "### _Folders-by-feature_ structure", "translation": "### 按特性组织的目录结构", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0407", "original": "#### Style 04-07", "translation": "#### 风格 04-07", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOCREATEFOLDERSNAMEDFORTHEFEATUREAREATHEYREPRESENT", "original": "**Do** create folders named for the feature area they represent.", "translation": "**坚持**根据特性区命名目录。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYADEVELOPERCANLOCATETHECODEANDIDENTIFYWHATEACHFILEREPRESENTSATAGLANCETHESTRUCTUREISASFLATASITCANBEANDTHEREARENOREPETITIVEORREDUNDANTNAMES", "original": "**Why?** A developer can locate the code and identify what each file represents\nat a glance. The structure is as flat as it can be and there are no repetitive or redundant names.", "translation": "**为何?**开发人员可以快速定位代码,扫一眼就能知道每个文件代表什么,目录尽可能保持扁平,既没有重复也没有多余的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHELIFTGUIDELINESAREALLCOVERED", "original": "**Why?** The LIFT guidelines are all covered.", "translation": "**为何?** LIFT 原则中包含了所有这些。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYHELPSREDUCETHEAPPFROMBECOMINGCLUTTEREDTHROUGHORGANIZINGTHECONTENTANDKEEPINGTHEMALIGNEDWITHTHELIFTGUIDELINES", "original": "**Why?** Helps reduce the app from becoming cluttered through organizing the\ncontent and keeping them aligned with the LIFT guidelines.", "translation": "**为何?**遵循 LIFT 原则精心组织内容,避免应用变得杂乱无章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYWHENTHEREAREALOTOFFILESFOREXAMPLE10LOCATINGTHEMISEASIERWITHACONSISTENTFOLDERSTRUCTUREANDMOREDIFFICULTINAFLATSTRUCTURE", "original": "**Why?** When there are a lot of files, for example 10+,\nlocating them is easier with a consistent folder structure\nand more difficult in a flat structure.", "translation": "**为何?**当有很多文件时(例如 10 个以上),在专用目录型结构中定位它们会比在扁平结构中更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOCREATEANNGMODULEFOREACHFEATUREAREA", "original": "**Do** create an NgModule for each feature area.", "translation": "**坚持**为每个特性区创建一个 Angular 模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYNGMODULESMAKEITEASYTOLAZYLOADROUTABLEFEATURES", "original": "**Why?** NgModules make it easy to lazy load routable features.", "translation": "**为何?** Angular 模块使惰性加载可路由的特性变得更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYNGMODULESMAKEITEASIERTOISOLATETESTANDREUSEFEATURES", "original": "**Why?** NgModules make it easier to isolate, test, and re-use features.", "translation": "**为何?**Angular 模块隔离、测试和复用特性更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#FILETREEREFERTOTHISFOLDERANDFILESTRUCTUREEXAMPLEA", "original": "<a href=\"#file-tree\">Refer to this _folder and file structure_ example.</a>", "translation": "<a href=\"#file-tree\">点这里查看目录和文件结构的范例</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###APPROOTMODULE", "original": "### App _root module_", "translation": "### 应用的*根模块*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0408", "original": "#### Style 04-08", "translation": "#### 风格 04-08", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOCREATEANNGMODULEINTHEAPPSROOTFOLDERFOREXAMPLEINSRCAPP", "original": "**Do** create an NgModule in the app's root folder,\nfor example, in `/src/app`.", "translation": "**坚持**在应用的根目录创建一个 Angular 模块(例如 `/src/app`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYEVERYAPPREQUIRESATLEASTONEROOTNGMODULE", "original": "**Why?** Every app requires at least one root NgModule.", "translation": "**为何?**每个应用都至少需要一个根 Angular 模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERNAMINGTHEROOTMODULEAPPMODULETS", "original": "**Consider** naming the root module `app.module.ts`.", "translation": "**考虑**把根模块命名为 `app.module.ts`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYMAKESITEASIERTOLOCATEANDIDENTIFYTHEROOTMODULE", "original": "**Why?** Makes it easier to locate and identify the root module.", "translation": "**为何?**能让定位和识别根模块变得更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###FEATUREMODULES", "original": "### Feature modules", "translation": "### 特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0409", "original": "#### Style 04-09", "translation": "#### 风格 04-09", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOCREATEANNGMODULEFORALLDISTINCTFEATURESINANAPPLICATIONFOREXAMPLEAHEROESFEATURE", "original": "**Do** create an NgModule for all distinct features in an application;\nfor example, a `Heroes` feature.", "translation": "**坚持**为应用中每个明显的特性创建一个 Angular 模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPLACETHEFEATUREMODULEINTHESAMENAMEDFOLDERASTHEFEATUREAREAFOREXAMPLEINAPPHEROES", "original": "**Do** place the feature module in the same named folder as the feature area;\nfor example, in `app/heroes`.", "translation": "**坚持**把特性模块放在与特性区同名的目录中(例如 `app/heroes`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMETHEFEATUREMODULEFILEREFLECTINGTHENAMEOFTHEFEATUREAREAANDFOLDERFOREXAMPLEAPPHEROESHEROESMODULETS", "original": "**Do** name the feature module file reflecting the name of the feature area\nand folder; for example, `app/heroes/heroes.module.ts`.", "translation": "**坚持**特性模块的文件名应该能反映出特性区的名字和目录(例如 `app/heroes/heroes.module.ts`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMETHEFEATUREMODULESYMBOLREFLECTINGTHENAMEOFTHEFEATUREAREAFOLDERANDFILEFOREXAMPLEAPPHEROESHEROESMODULETSDEFINESHEROESMODULE", "original": "**Do** name the feature module symbol reflecting the name of the feature\narea, folder, and file; for example, `app/heroes/heroes.module.ts` defines `HeroesModule`.", "translation": "**坚持**特性模块的符号名应该能反映出特性区、目录和文件名(例如在 `app/heroes/heroes.module.ts` 中定义 `HeroesModule`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYAFEATUREMODULECANEXPOSEORHIDEITSIMPLEMENTATIONFROMOTHERMODULES", "original": "**Why?** A feature module can expose or hide its implementation from other modules.", "translation": "**为何?**特性模块可以对其它模块暴露或隐藏自己的实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYAFEATUREMODULEIDENTIFIESDISTINCTSETSOFRELATEDCOMPONENTSTHATCOMPRISETHEFEATUREAREA", "original": "**Why?** A feature module identifies distinct sets of related components that comprise the feature area.", "translation": "**为何?**特性模块标记出组成该特性分区的相关组件集合。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYAFEATUREMODULECANEASILYBEROUTEDTOBOTHEAGERLYANDLAZILY", "original": "**Why?** A feature module can easily be routed to both eagerly and lazily.", "translation": "**为何?**方便路由到特性模块 —— 无论是用主动加载还是惰性加载的方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYAFEATUREMODULEDEFINESCLEARBOUNDARIESBETWEENSPECIFICFUNCTIONALITYANDOTHERAPPLICATIONFEATURES", "original": "**Why?** A feature module defines clear boundaries between specific functionality and other application features.", "translation": "**为何?**特性模块在特定的功能和其它应用特性之间定义了清晰的边界。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYAFEATUREMODULEHELPSCLARIFYANDMAKEITEASIERTOASSIGNDEVELOPMENTRESPONSIBILITIESTODIFFERENTTEAMS", "original": "**Why?** A feature module helps clarify and make it easier to assign development responsibilities to different teams.", "translation": "**为何?**特性模块帮助澄清开发职责,以便于把这些职责指派给不同的项目组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYAFEATUREMODULECANEASILYBEISOLATEDFORTESTING", "original": "**Why?** A feature module can easily be isolated for testing.", "translation": "**为何?**特性模块易于隔离,以便测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###SHAREDFEATUREMODULE", "original": "### Shared feature module", "translation": "### 共享特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0410", "original": "#### Style 04-10", "translation": "#### 风格 04-10", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOCREATEAFEATUREMODULENAMEDSHAREDMODULEINASHAREDFOLDERFOREXAMPLEAPPSHAREDSHAREDMODULETSDEFINESSHAREDMODULE", "original": "**Do** create a feature module named `SharedModule` in a `shared` folder;\nfor example, `app/shared/shared.module.ts` defines `SharedModule`.", "translation": "**坚持**在 `shared` 目录中创建名叫 `SharedModule` 的特性模块(例如在 `app/shared/shared.module.ts` 中定义 `SharedModule`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DODECLARECOMPONENTSDIRECTIVESANDPIPESINASHAREDMODULEWHENTHOSEITEMSWILLBEREUSEDANDREFERENCEDBYTHECOMPONENTSDECLAREDINOTHERFEATUREMODULES", "original": "**Do** declare components, directives, and pipes in a shared module when those\nitems will be re-used and referenced by the components declared in other feature modules.", "translation": "**坚持**在共享模块中声明那些可能被特性模块引用的可复用组件、指令和管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERUSINGTHENAMESHAREDMODULEWHENTHECONTENTSOFASHAREDMODULEAREREFERENCEDACROSSTHEENTIREAPPLICATION", "original": "**Consider** using the name SharedModule when the contents of a shared\nmodule are referenced across the entire application.", "translation": "**考虑**把可能在整个应用中到处引用的模块命名为 SharedModule", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDPROVIDINGSERVICESINSHAREDMODULESSERVICESAREUSUALLYSINGLETONSTHATAREPROVIDEDONCEFORTHEENTIREAPPLICATIONORINAPARTICULARFEATUREMODULE", "original": "**Avoid** providing services in shared modules. Services are usually\nsingletons that are provided once for the entire application or\nin a particular feature module.", "translation": "**避免** 在共享模块中提供服务。服务通常是单例的,应该在整个应用或一个特定的特性模块中只有一份。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOIMPORTALLMODULESREQUIREDBYTHEASSETSINTHESHAREDMODULEFOREXAMPLECOMMONMODULEANDFORMSMODULE", "original": "**Do** import all modules required by the assets in the `SharedModule`;\nfor example, `CommonModule` and `FormsModule`.", "translation": "**坚持**在 `SharedModule` 中导入所有模块都需要的资产(例如 `CommonModule` 和 `FormsModule`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSHAREDMODULEWILLCONTAINCOMPONENTSDIRECTIVESANDPIPESTHATMAYNEEDFEATURESFROMANOTHERCOMMONMODULEFOREXAMPLENGFORINCOMMONMODULE", "original": "**Why?** `SharedModule` will contain components, directives and pipes\nthat may need features from another common module; for example,\n`ngFor` in `CommonModule`.", "translation": "**为何?** `SharedModule` 中包含的组件、指令和管道可能需要来自其它公共模块的特性(例如来自 `CommonModule` 中的 `ngFor` 指令)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DODECLAREALLCOMPONENTSDIRECTIVESANDPIPESINTHESHAREDMODULE", "original": "**Do** declare all components, directives, and pipes in the `SharedModule`.", "translation": "**坚持**在 `SharedModule` 中声明所有组件、指令和管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOEXPORTALLSYMBOLSFROMTHESHAREDMODULETHATOTHERFEATUREMODULESNEEDTOUSE", "original": "**Do** export all symbols from the `SharedModule` that other feature modules need to use.", "translation": "**坚持**从 `SharedModule` 中导出其它特性模块所需的全部符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSHAREDMODULEEXISTSTOMAKECOMMONLYUSEDCOMPONENTSDIRECTIVESANDPIPESAVAILABLEFORUSEINTHETEMPLATESOFCOMPONENTSINMANYOTHERMODULES", "original": "**Why?** `SharedModule` exists to make commonly used components, directives and pipes available for use in the templates of components in many other modules.", "translation": "**为何?** `SharedModule` 的存在,能让常用的组件、指令和管道在很多其它模块的组件模板中都自动可用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDSPECIFYINGAPPWIDESINGLETONPROVIDERSINASHAREDMODULEINTENTIONALSINGLETONSAREOKTAKECARE", "original": "**Avoid** specifying app-wide singleton providers in a `SharedModule`. Intentional singletons are OK. Take care.", "translation": "**避免**在 `SharedModule` 中指定应用级的单例服务提供商。如果是刻意要得到多个服务单例也行,不过还是要小心。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYALAZYLOADEDFEATUREMODULETHATIMPORTSTHATSHAREDMODULEWILLMAKEITSOWNCOPYOFTHESERVICEANDLIKELYHAVEUNDESIRABLERESULTS", "original": "**Why?** A lazy loaded feature module that imports that shared module will make its own copy of the service and likely have undesirable results.", "translation": "**为何?**惰性加载的特性模块如果导入了这个共享模块,会创建一份自己的服务副本,这可能会导致意料之外的后果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYYOUDONTWANTEACHMODULETOHAVEITSOWNSEPARATEINSTANCEOFSINGLETONSERVICESYETTHEREISAREALDANGEROFTHATHAPPENINGIFTHESHAREDMODULEPROVIDESASERVICE", "original": "**Why?** You don't want each module to have its own separate instance of singleton services.\nYet there is a real danger of that happening if the `SharedModule` provides a service.", "translation": "**为何?**对于单例服务,你不希望每个模块都有自己的实例。\n而如果 `SharedModule` 提供了一个服务,那就有可能发生这种情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###COREFEATUREMODULE", "original": "### Core feature module", "translation": "### 核心特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0411", "original": "#### Style 04-11", "translation": "#### 风格 04-11", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERCOLLECTINGNUMEROUSAUXILIARYSINGLEUSECLASSESINSIDEACOREMODULETOSIMPLIFYTHEAPPARENTSTRUCTUREOFAFEATUREMODULE", "original": "**Consider** collecting numerous, auxiliary, single-use classes inside a core module\nto simplify the apparent structure of a feature module.", "translation": "**考虑**把那些数量庞大、辅助性的、只用一次的类收集到核心模块中,让特性模块的结构更清晰简明。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERCALLINGTHEAPPLICATIONWIDECOREMODULECOREMODULEIMPORTINGCOREMODULEINTOTHEROOTAPPMODULEREDUCESITSCOMPLEXITYANDEMPHASIZESITSROLEASORCHESTRATOROFTHEAPPLICATIONASAWHOLE", "original": "**Consider** calling the application-wide core module, `CoreModule`.\nImporting `CoreModule` into the root `AppModule` reduces its complexity\nand emphasizes its role as orchestrator of the application as a whole.", "translation": "**坚持**把那些“只用一次”的类收集到 `CoreModule` 中,并对外隐藏它们的实现细节。简化的 `AppModule` 会导入 `CoreModule`,并且把它作为整个应用的总指挥。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOCREATEAFEATUREMODULENAMEDCOREMODULEINACOREFOLDEREGAPPCORECOREMODULETSDEFINESCOREMODULE", "original": "**Do** create a feature module named `CoreModule` in a `core` folder (e.g. `app/core/core.module.ts` defines `CoreModule`).", "translation": "**坚持**在 `core` 目录下创建一个名叫 `CoreModule` 的特性模块(例如在 `app/core/core.module.ts` 中定义 `CoreModule`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPUTASINGLETONSERVICEWHOSEINSTANCEWILLBESHAREDTHROUGHOUTTHEAPPLICATIONINTHECOREMODULEEGEXCEPTIONSERVICEANDLOGGERSERVICE", "original": "**Do** put a singleton service whose instance will be shared throughout the application in the `CoreModule` (e.g. `ExceptionService` and `LoggerService`).", "translation": "**坚持**把要共享给整个应用的单例服务放进 `CoreModule` 中(例如 `ExceptionService` 和 `LoggerService`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOIMPORTALLMODULESREQUIREDBYTHEASSETSINTHECOREMODULEEGCOMMONMODULEANDFORMSMODULE", "original": "**Do** import all modules required by the assets in the `CoreModule` (e.g. `CommonModule` and `FormsModule`).", "translation": "**坚持**导入 `CoreModule` 中的资产所需要的全部模块(例如 `CommonModule` 和 `FormsModule`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCOREMODULEPROVIDESONEORMORESINGLETONSERVICESANGULARREGISTERSTHEPROVIDERSWITHTHEAPPROOTINJECTORMAKINGASINGLETONINSTANCEOFEACHSERVICEAVAILABLETOANYCOMPONENTTHATNEEDSTHEMWHETHERTHATCOMPONENTISEAGERLYORLAZILYLOADED", "original": "**Why?** `CoreModule` provides one or more singleton services. Angular registers the providers with the app root injector, making a singleton instance of each service available to any component that needs them, whether that component is eagerly or lazily loaded.", "translation": "**为何?** `CoreModule` 提供了一个或多个单例服务。Angular 使用应用的根注入器注册这些服务提供商,让每个服务的这个单例对象对所有需要它们的组件都是可用的,而不用管该组件是通过主动加载还是惰性加载的方式加载的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCOREMODULEWILLCONTAINSINGLETONSERVICESWHENALAZYLOADEDMODULEIMPORTSTHESEITWILLGETANEWINSTANCEANDNOTTHEINTENDEDAPPWIDESINGLETON", "original": "**Why?** `CoreModule` will contain singleton services. When a lazy loaded module imports these, it will get a new instance and not the intended app-wide singleton.", "translation": "**为何?**`CoreModule` 将包含一些单例服务。而如果是由惰性加载模块来导入这些服务,它就会得到一个新实例,而不是所期望的全应用级单例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOGATHERAPPLICATIONWIDESINGLEUSECOMPONENTSINTHECOREMODULEIMPORTITONCEINTHEAPPMODULEWHENTHEAPPSTARTSANDNEVERIMPORTITANYWHEREELSEEGNAVCOMPONENTANDSPINNERCOMPONENT", "original": "**Do** gather application-wide, single use components in the `CoreModule`.\nImport it once (in the `AppModule`) when the app starts and never import it anywhere else. (e.g. `NavComponent` and `SpinnerComponent`).", "translation": "**坚持**把应用级、只用一次的组件收集到 `CoreModule` 中。\n只在应用启动时从 `AppModule` 中导入它一次,以后再也不要导入它(例如 `NavComponent` 和 `SpinnerComponent`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYREALWORLDAPPSCANHAVESEVERALSINGLEUSECOMPONENTSEGSPINNERSMESSAGETOASTSANDMODALDIALOGSTHATAPPEARONLYINTHEAPPCOMPONENTTEMPLATETHEYARENOTIMPORTEDELSEWHERESOTHEYRENOTSHAREDINTHATSENSEYETTHEYRETOOBIGANDMESSYTOLEAVELOOSEINTHEROOTFOLDER", "original": "**Why?** Real world apps can have several single-use components (e.g., spinners, message toasts, and modal dialogs) that appear only in the `AppComponent` template.\nThey are not imported elsewhere so they're not shared in that sense.\nYet they're too big and messy to leave loose in the root folder.", "translation": "**为何?**真实世界中的应用会有很多只用一次的组件(例如加载动画、消息浮层、模态框等),它们只会在 `AppComponent` 的模板中出现。\n不会在其它地方导入它们,所以没有共享的价值。\n然而它们又太大了,放在根目录中就会显得乱七八糟的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDIMPORTINGTHECOREMODULEANYWHEREEXCEPTINTHEAPPMODULE", "original": "**Avoid** importing the `CoreModule` anywhere except in the `AppModule`.", "translation": "**避免**在 `AppModule` 之外的任何地方导入 `CoreModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYALAZILYLOADEDFEATUREMODULETHATDIRECTLYIMPORTSTHECOREMODULEWILLMAKEITSOWNCOPYOFSERVICESANDLIKELYHAVEUNDESIRABLERESULTS", "original": "**Why?** A lazily loaded feature module that directly imports the `CoreModule` will make its own copy of services and likely have undesirable results.", "translation": "**为何?**如果惰性加载的特性模块直接导入 `CoreModule`,就会创建它自己的服务副本,并导致意料之外的后果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYANEAGERLYLOADEDFEATUREMODULEALREADYHASACCESSTOTHEAPPMODULESINJECTORANDTHUSTHECOREMODULESSERVICES", "original": "**Why?** An eagerly loaded feature module already has access to the `AppModule`'s injector, and thus the `CoreModule`'s services.", "translation": "**为何?**主动加载的特性模块已经准备好了访问 `AppModule` 的注入器,因此也能取得 `CoreModule` 中的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOEXPORTALLSYMBOLSFROMTHECOREMODULETHATTHEAPPMODULEWILLIMPORTANDMAKEAVAILABLEFOROTHERFEATUREMODULESTOUSE", "original": "**Do** export all symbols from the `CoreModule` that the `AppModule` will import and make available for other feature modules to use.", "translation": "**坚持**从 `CoreModule` 中导出 `AppModule` 需导入的所有符号,使它们在所有特性模块中可用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCOREMODULEEXISTSTOMAKECOMMONLYUSEDSINGLETONSERVICESAVAILABLEFORUSEINTHEMANYOTHERMODULES", "original": "**Why?** `CoreModule` exists to make commonly used singleton services available for use in the many other modules.", "translation": "**为何?**`CoreModule` 的存在就让常用的单例服务在所有其它模块中可用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYYOUWANTTHEENTIREAPPTOUSETHEONESINGLETONINSTANCEYOUDONTWANTEACHMODULETOHAVEITSOWNSEPARATEINSTANCEOFSINGLETONSERVICESYETTHEREISAREALDANGEROFTHATHAPPENINGACCIDENTALLYIFTHECOREMODULEPROVIDESASERVICE", "original": "**Why?** You want the entire app to use the one, singleton instance.\nYou don't want each module to have its own separate instance of singleton services.\nYet there is a real danger of that happening accidentally if the `CoreModule` provides a service.", "translation": "**为何?**你希望整个应用都使用这个单例服务。\n你不希望每个模块都有这个单例服务的单独的实例。\n然而,如果 `CoreModule` 中提供了一个服务,就可能偶尔导致这种后果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "APPMODULEISALITTLESMALLERBECAUSEMANYAPPROOTCLASSESHAVEMOVEDTOOTHERMODULESAPPMODULEISSTABLEBECAUSEYOUWILLADDFUTURECOMPONENTSANDPROVIDERSTOOTHERMODULESNOTTHISONEAPPMODULEDELEGATESTOIMPORTEDMODULESRATHERTHANDOINGWORKAPPMODULEISFOCUSEDONITSMAINTASKORCHESTRATINGTHEAPPASAWHOLE", "original": "`AppModule` is a little smaller because many app/root classes have moved to other modules.\n`AppModule` is stable because you will add future components and providers to other modules, not this one.\n`AppModule` delegates to imported modules rather than doing work.\n`AppModule` is focused on its main task, orchestrating the app as a whole.", "translation": "`AppModule` 变得更小了,因为很多应用根部的类都被移到了其它模块中。\n`AppModule` 变得稳定了,因为你将会往其它模块中添加特性组件和服务提供商,而不是这个 `AppModule`。\n`AppModule` 把工作委托给了导入的模块,而不是亲力亲为。\n`AppModule` 聚焦在它自己的主要任务上:作为整个应用的总指挥。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###PREVENTREIMPORTOFTHECOREMODULE", "original": "### Prevent re-import of the core module", "translation": "### 防止多次导入 `CoreModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0412", "original": "#### Style 04-12", "translation": "#### 风格 04-12", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ONLYTHEROOTAPPMODULESHOULDIMPORTTHECOREMODULE", "original": "Only the root `AppModule` should import the `CoreModule`.", "translation": "应该只有 `AppModule` 才允许导入 `CoreModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOGUARDAGAINSTREIMPORTINGOFCOREMODULEANDFAILFASTBYADDINGGUARDLOGIC", "original": "**Do** guard against reimporting of `CoreModule` and fail fast by adding guard logic.", "translation": "**坚持**防范多次导入 `CoreModule`,并通过添加守卫逻辑来尽快失败。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYGUARDSAGAINSTREIMPORTINGOFTHECOREMODULE", "original": "**Why?** Guards against reimporting of the `CoreModule`.", "translation": "**为何?**守卫可以阻止对 `CoreModule` 的多次导入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYGUARDSAGAINSTCREATINGMULTIPLEINSTANCESOFASSETSINTENDEDTOBESINGLETONS", "original": "**Why?** Guards against creating multiple instances of assets intended to be singletons.", "translation": "**为何?**守卫会禁止创建单例服务的多个实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###LAZYLOADEDFOLDERS", "original": "### Lazy Loaded folders", "translation": "### 惰性加载的目录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0413", "original": "#### Style 04-13", "translation": "#### 样式 04-13", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ADISTINCTAPPLICATIONFEATUREORWORKFLOWMAYBELAZYLOADEDORLOADEDONDEMANDRATHERTHANWHENTHEAPPLICATIONSTARTS", "original": "A distinct application feature or workflow may be *lazy loaded* or *loaded on demand* rather than when the application starts.", "translation": "某些边界清晰的应用特性或工作流可以做成*惰性加载*或*按需加载*的,而不用总是随着应用启动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPUTTHECONTENTSOFLAZYLOADEDFEATURESINALAZYLOADEDFOLDERATYPICALLAZYLOADEDFOLDERCONTAINSAROUTINGCOMPONENTITSCHILDCOMPONENTSANDTHEIRRELATEDASSETSANDMODULES", "original": "**Do** put the contents of lazy loaded features in a *lazy loaded folder*.\nA typical *lazy loaded folder* contains a *routing component*, its child components, and their related assets and modules.", "translation": "**坚持**把惰性加载特性下的内容放进*惰性加载目录*中。\n典型的*惰性加载目录*包含*路由组件*及其子组件以及与它们有关的那些资产和模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEFOLDERMAKESITEASYTOIDENTIFYANDISOLATETHEFEATURECONTENT", "original": "**Why?** The folder makes it easy to identify and isolate the feature content.", "translation": "**为何?**这种目录让标识和隔离这些特性内容变得更轻松。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###NEVERDIRECTLYIMPORTLAZYLOADEDFOLDERS", "original": "### Never directly import lazy loaded folders", "translation": "### 永远不要直接导入惰性加载的目录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0414", "original": "#### Style 04-14", "translation": "#### 样式 04-14", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDALLOWINGMODULESINSIBLINGANDPARENTFOLDERSTODIRECTLYIMPORTAMODULEINALAZYLOADEDFEATURE", "original": "**Avoid** allowing modules in sibling and parent folders to directly import a module in a *lazy loaded feature*.", "translation": "**避免**让兄弟模块和父模块直接导入*惰性加载特性*中的模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYDIRECTLYIMPORTINGANDUSINGAMODULEWILLLOADITIMMEDIATELYWHENTHEINTENTIONISTOLOADITONDEMAND", "original": "**Why?** Directly importing and using a module will load it immediately when the intention is to load it on demand.", "translation": "**为何?**直接导入并使用此模块会立即加载它,而原本的设计意图是按需加载它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##COMPONENTS", "original": "## Components", "translation": "## 组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###COMPONENTSELECTORNAMES", "original": "### Component selector names", "translation": "### 组件选择器命名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0502", "original": "#### Style 05-02", "translation": "#### 风格 05-02", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEDASHEDCASEORKEBABCASEFORNAMINGTHEELEMENTSELECTORSOFCOMPONENTS", "original": "**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.", "translation": "**坚持**使用*中线 (dashed) 命名法*或*烤串 (kebab) 命名法*来命名组件中的元素选择器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYKEEPSTHEELEMENTNAMESCONSISTENTWITHTHESPECIFICATIONFORCUSTOMELEMENTSHTTPS:WWWW3ORGTRCUSTOMELEMENTS", "original": "**Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).", "translation": "**为何?**保持元素命名与[自定义元素](https://www.w3.org/TR/custom-elements/)命名规范一致。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###COMPONENTSASELEMENTS", "original": "### Components as elements", "translation": "### 把组件当做元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0503", "original": "#### Style 05-03", "translation": "#### 风格 05-03", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERGIVINGCOMPONENTSANELEMENTSELECTORASOPPOSEDTOATTRIBUTEORCLASSSELECTORS", "original": "**Consider** giving components an _element_ selector, as opposed to _attribute_ or _class_ selectors.", "translation": "**考虑**给组件一个*元素*选择器,而不是*属性*或*类*选择器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYCOMPONENTSHAVETEMPLATESCONTAININGHTMLANDOPTIONALANGULARTEMPLATESYNTAXTHEYDISPLAYCONTENTDEVELOPERSPLACECOMPONENTSONTHEPAGEASTHEYWOULDNATIVEHTMLELEMENTSANDWEBCOMPONENTS", "original": "**Why?** components have templates containing HTML and optional Angular template syntax.\nThey display content.\nDevelopers place components on the page as they would native HTML elements and web components.", "translation": "**为何?**组件有很多包含 HTML 以及可选 Angular 模板语法的模板。\n它们显示内容。开发人员会把组件像原生 HTML 元素和 WebComponents 一样放进页面中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYITISEASIERTORECOGNIZETHATASYMBOLISACOMPONENTBYLOOKINGATTHETEMPLATESHTML", "original": "**Why?** It is easier to recognize that a symbol is a component by looking at the template's html.", "translation": "**为何?**查看组件模板的 HTML 时,更容易识别一个符号是组件还是指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "THEREAREAFEWCASESWHEREYOUGIVEACOMPONENTANATTRIBUTESUCHASWHENYOUWANTTOAUGMENTABUILTINELEMENTFOREXAMPLEMATERIALDESIGNHTTPS:MATERIALANGULARIOCOMPONENTSBUTTONOVERVIEWUSESTHISTECHNIQUEWITHBUTTONMATBUTTONHOWEVERYOUWOULDNTUSETHISTECHNIQUEONACUSTOMELEMENT", "original": "There are a few cases where you give a component an attribute, such as when you want to augment a built-in element. For example, [Material Design](https://material.angular.io/components/button/overview) uses this technique with `<button mat-button>`. However, you wouldn't use this technique on a custom element.", "translation": "少数情况下,你要为组件使用属性选择器,比如你要加强某个内置元素时。\n比如,[Material Design 组件库](https://material.angular.io/components/button/overview)就会对 `<button mat-button>` 使用这项技术。不过,你不应该在自定义组件上使用这项技术。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###EXTRACTTEMPLATESANDSTYLESTOTHEIROWNFILES", "original": "### Extract templates and styles to their own files", "translation": "### 把模板和样式提取到它们自己的文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0504", "original": "#### Style 05-04", "translation": "#### 风格 05-04", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOEXTRACTTEMPLATESANDSTYLESINTOASEPARATEFILEWHENMORETHAN3LINES", "original": "**Do** extract templates and styles into a separate file, when more than 3 lines.", "translation": "**坚持**当超过 3 行时,把模板和样式提取到一个单独的文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMETHETEMPLATEFILECOMPONENTNAMECOMPONENTHTMLWHERECOMPONENTNAMEISTHECOMPONENTNAME", "original": "**Do** name the template file `[component-name].component.html`, where [component-name] is the component name.", "translation": "**坚持**把模板文件命名为 `[component-name].component.html`,其中,[component-name] 是组件名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMETHESTYLEFILECOMPONENTNAMECOMPONENTCSSWHERECOMPONENTNAMEISTHECOMPONENTNAME", "original": "**Do** name the style file `[component-name].component.css`, where [component-name] is the component name.", "translation": "**坚持**把样式文件命名为 `[component-name].component.css`,其中,[component-name] 是组件名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOSPECIFYCOMPONENTRELATIVEURLSPREFIXEDWITH", "original": "**Do** specify _component-relative_ URLs, prefixed with `./`.", "translation": "**坚持**指定*相对于模块的* URL ,给它加上 `./` 前缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYLARGEINLINETEMPLATESANDSTYLESOBSCURETHECOMPONENTSPURPOSEANDIMPLEMENTATIONREDUCINGREADABILITYANDMAINTAINABILITY", "original": "**Why?** Large, inline templates and styles obscure the component's purpose and implementation, reducing readability and maintainability.", "translation": "**为何?**巨大的、内联的模板和样式表会遮盖组件的意图和实现方式,削弱可读性和可维护性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYINMOSTEDITORSSYNTAXHINTSANDCODESNIPPETSARENTAVAILABLEWHENDEVELOPINGINLINETEMPLATESANDSTYLESTHEANGULARTYPESCRIPTLANGUAGESERVICEFORTHCOMINGPROMISESTOOVERCOMETHISDEFICIENCYFORHTMLTEMPLATESINTHOSEEDITORSTHATSUPPORTITITWONTHELPWITHCSSSTYLES", "original": "**Why?** In most editors, syntax hints and code snippets aren't available when developing inline templates and styles.\nThe Angular TypeScript Language Service (forthcoming) promises to overcome this deficiency for HTML templates\nin those editors that support it; it won't help with CSS styles.", "translation": "**为何?**在多数编辑器中,编写内联的模板和样式表时都无法使用语法提示和代码片段功能。\nAngular 的 TypeScript 语言服务(即将到来)可以帮助那些编辑器在编写 HTML 模板时克服这一缺陷,但对 CSS 样式没有帮助。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYACOMPONENTRELATIVEURLREQUIRESNOCHANGEWHENYOUMOVETHECOMPONENTFILESASLONGASTHEFILESSTAYTOGETHER", "original": "**Why?** A _component relative_ URL requires no change when you move the component files, as long as the files stay together.", "translation": "**为何?**当你移动组件文件时,相对于组件的 URL 不需要修改,因为这些文件始终会在一起。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEPREFIXISSTANDARDSYNTAXFORRELATIVEURLSDONTDEPENDONANGULARSCURRENTABILITYTODOWITHOUTTHATPREFIX", "original": "**Why?** The `./` prefix is standard syntax for relative URLs; don't depend on Angular's current ability to do without that prefix.", "translation": "**为何?**`./` 前缀是相对 URL 的标准语法,不必依赖 Angular 的特殊处理,如果没有前缀则不行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###DECORATEINPUTANDOUTPUTPROPERTIES", "original": "### Decorate _input_ and _output_ properties", "translation": "### 内联输入和输出属性装饰器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0512", "original": "#### Style 05-12", "translation": "#### 风格 05-12", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSETHEINPUTANDOUTPUTCLASSDECORATORSINSTEADOFTHEINPUTSANDOUTPUTSPROPERTIESOFTHEDIRECTIVEANDCOMPONENTMETADATA:", "original": "**Do** use the `@Input()` and `@Output()` class decorators instead of the `inputs` and `outputs` properties of the\n`@Directive` and `@Component` metadata:", "translation": "**坚持** 使用 `@Input()` 和 `@Output()`,而非 `@Directive` 和 `@Component` 装饰器的 `inputs` 和 `outputs` 属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERPLACINGINPUTOROUTPUTONTHESAMELINEASTHEPROPERTYITDECORATES", "original": "**Consider** placing `@Input()` or `@Output()` on the same line as the property it decorates.", "translation": "**坚持**把 `@Input()` 或者 `@Output()` 放到所装饰的属性的同一行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYITISEASIERANDMOREREADABLETOIDENTIFYWHICHPROPERTIESINACLASSAREINPUTSOROUTPUTS", "original": "**Why?** It is easier and more readable to identify which properties in a class are inputs or outputs.", "translation": "**为何?**易于在类里面识别哪些属性是输入属性或输出属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYIFYOUEVERNEEDTORENAMETHEPROPERTYOREVENTNAMEASSOCIATEDWITHINPUTOROUTPUTYOUCANMODIFYITINASINGLEPLACE", "original": "**Why?** If you ever need to rename the property or event name associated with\n`@Input` or `@Output`, you can modify it in a single place.", "translation": "**为何?** 如果需要重命名与 `@Input` 或者 `@Output` 关联的属性或事件名,你可以在一个位置修改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEMETADATADECLARATIONATTACHEDTOTHEDIRECTIVEISSHORTERANDTHUSMOREREADABLE", "original": "**Why?** The metadata declaration attached to the directive is shorter and thus more readable.", "translation": "**为何?**依附到指令的元数据声明会比较简短,更易于阅读。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPLACINGTHEDECORATORONTHESAMELINEUSUALLYMAKESFORSHORTERCODEANDSTILLEASILYIDENTIFIESTHEPROPERTYASANINPUTOROUTPUTPUTITONTHELINEABOVEWHENDOINGSOISCLEARLYMOREREADABLE", "original": "**Why?** Placing the decorator on the same line _usually_ makes for shorter code and still easily identifies the property as an input or output.\nPut it on the line above when doing so is clearly more readable.", "translation": "**为何?**把装饰器放到同一行可以精简代码,同时更易于识别输入或输出属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###AVOIDALIASINGINPUTSANDOUTPUTS", "original": "### Avoid aliasing _inputs_ and _outputs_", "translation": "### 避免为输入和输出属性指定别名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0513", "original": "#### Style 05-13", "translation": "#### 风格 05-13", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AVOIDINPUTANDOUTPUTALIASESEXCEPTWHENITSERVESANIMPORTANTPURPOSE", "original": "**Avoid** _input_ and _output_ aliases except when it serves an important purpose.", "translation": "**避免**除非有重要目的,否则不要为输入和输出指定别名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTWONAMESFORTHESAMEPROPERTYONEPRIVATEONEPUBLICISINHERENTLYCONFUSING", "original": "**Why?** Two names for the same property (one private, one public) is inherently confusing.", "translation": "**为何?**同一个属性有两个名字(一个对内一个对外)很容易导致混淆。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYYOUSHOULDUSEANALIASWHENTHEDIRECTIVENAMEISALSOANINPUTPROPERTYANDTHEDIRECTIVENAMEDOESNTDESCRIBETHEPROPERTY", "original": "**Why?** You should use an alias when the directive name is also an _input_ property,\nand the directive name doesn't describe the property.", "translation": "**为何?**如果指令名也同时用作*输入*属性,而且指令名无法准确描述这个属性的用途时,应该使用别名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###MEMBERSEQUENCE", "original": "### Member sequence", "translation": "### 成员顺序", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0514", "original": "#### Style 05-14", "translation": "#### 风格 05-14", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPLACEPROPERTIESUPTOPFOLLOWEDBYMETHODS", "original": "**Do** place properties up top followed by methods.", "translation": "**坚持**把属性成员放在前面,方法成员放在后面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPLACEPRIVATEMEMBERSAFTERPUBLICMEMBERSALPHABETIZED", "original": "**Do** place private members after public members, alphabetized.", "translation": "**坚持**先放公共成员,再放私有成员,并按照字母顺序排列。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYPLACINGMEMBERSINACONSISTENTSEQUENCEMAKESITEASYTOREADANDHELPSINSTANTLYIDENTIFYWHICHMEMBERSOFTHECOMPONENTSERVEWHICHPURPOSE", "original": "**Why?** Placing members in a consistent sequence makes it easy to read and\nhelps instantly identify which members of the component serve which purpose.", "translation": "**为何?**把类的成员按照统一的顺序排列,易于阅读,能立即识别出组件的哪个成员服务于何种目的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###DELEGATECOMPLEXCOMPONENTLOGICTOSERVICES", "original": "### Delegate complex component logic to services", "translation": "### 把逻辑放到服务里", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0515", "original": "#### Style 05-15", "translation": "#### 风格 05-15", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOLIMITLOGICINACOMPONENTTOONLYTHATREQUIREDFORTHEVIEWALLOTHERLOGICSHOULDBEDELEGATEDTOSERVICES", "original": "**Do** limit logic in a component to only that required for the view. All other logic should be delegated to services.", "translation": "**坚持**在组件中只包含与视图相关的逻辑。所有其它逻辑都应该放到服务中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOMOVEREUSABLELOGICTOSERVICESANDKEEPCOMPONENTSSIMPLEANDFOCUSEDONTHEIRINTENDEDPURPOSE", "original": "**Do** move reusable logic to services and keep components simple and focused on their intended purpose.", "translation": "**坚持**把可重用的逻辑放到服务中,保持组件简单,聚焦于它们预期目的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYLOGICMAYBEREUSEDBYMULTIPLECOMPONENTSWHENPLACEDWITHINASERVICEANDEXPOSEDVIAAFUNCTION", "original": "**Why?** Logic may be reused by multiple components when placed within a service and exposed via a function.", "translation": "**为何?**当逻辑被放置到服务里,并以函数的形式暴露时,可以被多个组件重复使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYLOGICINASERVICECANMOREEASILYBEISOLATEDINAUNITTESTWHILETHECALLINGLOGICINTHECOMPONENTCANBEEASILYMOCKED", "original": "**Why?** Logic in a service can more easily be isolated in a unit test, while the calling logic in the component can be easily mocked.", "translation": "**为何?**在单元测试时,服务里的逻辑更容易被隔离。当组件中调用逻辑时,也很容易被模拟。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYREMOVESDEPENDENCIESANDHIDESIMPLEMENTATIONDETAILSFROMTHECOMPONENT", "original": "**Why?** Removes dependencies and hides implementation details from the component.", "translation": "**为何?**从组件移除依赖并隐藏实施细节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYKEEPSTHECOMPONENTSLIMTRIMANDFOCUSED", "original": "**Why?** Keeps the component slim, trim, and focused.", "translation": "**为何?**保持组件苗条、精简和聚焦。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###DONTPREFIXOUTPUTPROPERTIES", "original": "### Don't prefix _output_ properties", "translation": "### 不要给输出属性加前缀", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0516", "original": "#### Style 05-16", "translation": "#### 风格 05-16", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMEEVENTSWITHOUTTHEPREFIXON", "original": "**Do** name events without the prefix `on`.", "translation": "**坚持**命名事件时,不要带前缀 `on`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DONAMEEVENTHANDLERMETHODSWITHTHEPREFIXONFOLLOWEDBYTHEEVENTNAME", "original": "**Do** name event handler methods with the prefix `on` followed by the event name.", "translation": "**坚持**把事件处理器方法命名为 `on` 前缀之后紧跟着事件名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHISISCONSISTENTWITHBUILTINEVENTSSUCHASBUTTONCLICKS", "original": "**Why?** This is consistent with built-in events such as button clicks.", "translation": "**为何?**与内置事件命名一致,例如按钮点击。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYANGULARALLOWSFORANALTERNATIVESYNTAXGUIDETEMPLATESYNTAX#BINDINGSYNTAXONIFTHEEVENTITSELFWASPREFIXEDWITHONTHISWOULDRESULTINANONONEVENTBINDINGEXPRESSION", "original": "**Why?** Angular allows for an [alternative syntax](guide/template-syntax#binding-syntax) `on-*`. If the event itself was prefixed with `on` this would result in an `on-onEvent` binding expression.", "translation": "**为何?**Angular 允许[另一种备选语法](guide/template-syntax#binding-syntax) `on-*`。如果事件的名字本身带有前缀 `on`,那么绑定的表达式可能是 `on-onEvent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###PUTPRESENTATIONLOGICINTHECOMPONENTCLASS", "original": "### Put presentation logic in the component class", "translation": "### 把表现层逻辑放到组件类里", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0517", "original": "#### Style 05-17", "translation": "#### 风格 05-17", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPUTPRESENTATIONLOGICINTHECOMPONENTCLASSANDNOTINTHETEMPLATE", "original": "**Do** put presentation logic in the component class, and not in the template.", "translation": "**坚持**把表现层逻辑放进组件类中,而不要放在模板里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYLOGICWILLBECONTAINEDINONEPLACETHECOMPONENTCLASSINSTEADOFBEINGSPREADINTWOPLACES", "original": "**Why?** Logic will be contained in one place (the component class) instead of being spread in two places.", "translation": "**为何?**逻辑应该只出现在一个地方(组件类里)而不应分散在两个地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYKEEPINGTHECOMPONENTSPRESENTATIONLOGICINTHECLASSINSTEADOFTHETEMPLATEIMPROVESTESTABILITYMAINTAINABILITYANDREUSABILITY", "original": "**Why?** Keeping the component's presentation logic in the class instead of the template improves testability, maintainability, and reusability.", "translation": "**为何?**将组件的表现层逻辑放到组件类而非模板里,可以增强测试性、维护性和重复使用性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##DIRECTIVES", "original": "## Directives", "translation": "## 指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###USEDIRECTIVESTOENHANCEANELEMENT", "original": "### Use directives to enhance an element", "translation": "### 使用指令来增强已有元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0601", "original": "#### Style 06-01", "translation": "#### 风格 06-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEATTRIBUTEDIRECTIVESWHENYOUHAVEPRESENTATIONLOGICWITHOUTATEMPLATE", "original": "**Do** use attribute directives when you have presentation logic without a template.", "translation": "**坚持**当你需要有表现层逻辑,但没有模板时,使用属性型指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYATTRIBUTEDIRECTIVESDONTHAVEANASSOCIATEDTEMPLATE", "original": "**Why?** Attribute directives don't have an associated template.", "translation": "**为何?**属性型指令没有模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYANELEMENTMAYHAVEMORETHANONEATTRIBUTEDIRECTIVEAPPLIED", "original": "**Why?** An element may have more than one attribute directive applied.", "translation": "**为何?**一个元素可以使用多个属性型指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###HOSTLISTENERHOSTBINDINGDECORATORSVERSUSHOSTMETADATA", "original": "### _HostListener_/_HostBinding_ decorators versus _host_ metadata", "translation": "### *HostListener* 和 *HostBinding* 装饰器 vs. 组件元数据 *host*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0603", "original": "#### Style 06-03", "translation": "#### 风格 06-03", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERPREFERRINGTHEHOSTLISTENERANDHOSTBINDINGTOTHEHOSTPROPERTYOFTHEDIRECTIVEANDCOMPONENTDECORATORS", "original": "**Consider** preferring the `@HostListener` and `@HostBinding` to the\n`host` property of the `@Directive` and `@Component` decorators.", "translation": "**考虑**优先使用 `@HostListener` 和 `@HostBinding`,而不是 `@Directive` 和 `@Component` 装饰器的 `host` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOBECONSISTENTINYOURCHOICE", "original": "**Do** be consistent in your choice.", "translation": "**坚持**让你的选择保持一致。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEPROPERTYASSOCIATEDWITHHOSTBINDINGORTHEMETHODASSOCIATEDWITHHOSTLISTENERCANBEMODIFIEDONLYINASINGLEPLACEMDASHINTHEDIRECTIVESCLASSIFYOUUSETHEHOSTMETADATAPROPERTYYOUMUSTMODIFYBOTHTHEPROPERTYMETHODDECLARATIONINTHEDIRECTIVESCLASSANDTHEMETADATAINTHEDECORATORASSOCIATEDWITHTHEDIRECTIVE", "original": "**Why?** The property associated with `@HostBinding` or the method associated with `@HostListener`\ncan be modified only in a single place—in the directive's class.\nIf you use the `host` metadata property, you must modify both the property/method declaration in the \ndirective's class and the metadata in the decorator associated with the directive.", "translation": "**为何?**对于关联到 `@HostBinding` 的属性或关联到 `@HostListener` 的方法,要修改时,只需在指令类中的一个地方修改。\n如果使用元数据属性 `host`,你就得在组件类中修改属性声明的同时修改相关的元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "COMPAREWITHTHELESSPREFERREDHOSTMETADATAALTERNATIVE", "original": "Compare with the less preferred `host` metadata alternative.", "translation": "与不推荐的方式(`host` 元数据)比较一下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEHOSTMETADATAISONLYONETERMTOREMEMBERANDDOESNTREQUIREEXTRAESIMPORTS", "original": "**Why?** The `host` metadata is only one term to remember and doesn't require extra ES imports.", "translation": "**为何?**`host` 元数据只是一个便于记忆的名字而已,并不需要额外的 ES 导入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##SERVICES", "original": "## Services", "translation": "## 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###SERVICESARESINGLETONS", "original": "### Services are singletons", "translation": "### 服务总是单例的", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0701", "original": "#### Style 07-01", "translation": "#### 风格 07-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSESERVICESASSINGLETONSWITHINTHESAMEINJECTORUSETHEMFORSHARINGDATAANDFUNCTIONALITY", "original": "**Do** use services as singletons within the same injector. Use them for sharing data and functionality.", "translation": "**坚持**在同一个注入器内,把服务当做单例使用。用它们来共享数据和功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSERVICESAREIDEALFORSHARINGMETHODSACROSSAFEATUREAREAORANAPP", "original": "**Why?** Services are ideal for sharing methods across a feature area or an app.", "translation": "**为何?**服务是在特性范围或应用内共享方法的理想载体。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYSERVICESAREIDEALFORSHARINGSTATEFULINMEMORYDATA", "original": "**Why?** Services are ideal for sharing stateful in-memory data.", "translation": "**为何?**服务是共享状态性内存数据的理想载体。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###SINGLERESPONSIBILITY", "original": "### Single responsibility", "translation": "### 单一职责", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0702", "original": "#### Style 07-02", "translation": "#### 风格 07-02", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOCREATESERVICESWITHASINGLERESPONSIBILITYTHATISENCAPSULATEDBYITSCONTEXT", "original": "**Do** create services with a single responsibility that is encapsulated by its context.", "translation": "**坚持**创建单一职责的服务,用职责封装在它的上下文中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOCREATEANEWSERVICEONCETHESERVICEBEGINSTOEXCEEDTHATSINGULARPURPOSE", "original": "**Do** create a new service once the service begins to exceed that singular purpose.", "translation": "**坚持**当服务成长到超出单一用途时,创建一个新服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYWHENASERVICEHASMULTIPLERESPONSIBILITIESITBECOMESDIFFICULTTOTEST", "original": "**Why?** When a service has multiple responsibilities, it becomes difficult to test.", "translation": "**为何?**当服务有多个职责时,它很难被测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYWHENASERVICEHASMULTIPLERESPONSIBILITIESEVERYCOMPONENTORSERVICETHATINJECTSITNOWCARRIESTHEWEIGHTOFTHEMALL", "original": "**Why?** When a service has multiple responsibilities, every component or service that injects it now carries the weight of them all.", "translation": "**为何?**当某个服务有多个职责时,每个注入它的组件或服务都会承担这些职责的全部开销。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###PROVIDINGASERVICE", "original": "### Providing a service", "translation": "### 提供一个服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0703", "original": "#### Style 07-03", "translation": "#### 风格 07-03", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOPROVIDESERVICESTOTHEANGULARINJECTORATTHETOPMOSTCOMPONENTWHERETHEYWILLBESHARED", "original": "**Do** provide services to the Angular injector at the top-most component where they will be shared.", "translation": "**坚持**将服务提供到共享范围内的顶级组件的 Angular 注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEANGULARINJECTORISHIERARCHICAL", "original": "**Why?** The Angular injector is hierarchical.", "translation": "**为何?** Angular 注入器是层次化的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYWHENPROVIDINGTHESERVICETOATOPLEVELCOMPONENTTHATINSTANCEISSHAREDANDAVAILABLETOALLCHILDCOMPONENTSOFTHATTOPLEVELCOMPONENT", "original": "**Why?** When providing the service to a top level component,\nthat instance is shared and available to all child components of that top level component.", "translation": "**为何?**在顶层组件提供服务时,该服务实例在所有子组件中可见并共享。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHISISIDEALWHENASERVICEISSHARINGMETHODSORSTATE", "original": "**Why?** This is ideal when a service is sharing methods or state.", "translation": "**为何?**服务是共享方法或状态的理想载体。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHISISNOTIDEALWHENTWODIFFERENTCOMPONENTSNEEDDIFFERENTINSTANCESOFASERVICEINTHISSCENARIOITWOULDBEBETTERTOPROVIDETHESERVICEATTHECOMPONENTLEVELTHATNEEDSTHENEWANDSEPARATEINSTANCE", "original": "**Why?** This is not ideal when two different components need different instances of a service. In this scenario it would be better to provide the service at the component level that needs the new and separate instance.", "translation": "**为何?**当不同的两个组件需要一个服务的不同的实例时,上面的方法这就不理想了。在这种情况下,对于需要崭新和单独服务实例的组件,最好在组件级提供服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###USETHEINJECTABLECLASSDECORATOR", "original": "### Use the @Injectable() class decorator", "translation": "### 使用 @Injectable() 类装饰器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0704", "original": "#### Style 07-04", "translation": "#### 风格 07-04", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSETHEINJECTABLECLASSDECORATORINSTEADOFTHEINJECTPARAMETERDECORATORWHENUSINGTYPESASTOKENSFORTHEDEPENDENCIESOFASERVICE", "original": "**Do** use the `@Injectable()` class decorator instead of the `@Inject` parameter decorator when using types as tokens for the dependencies of a service.", "translation": "**坚持**当使用类型作为令牌来注入服务的依赖时,使用 `@Injectable()` 类装饰器,而非 `@Inject()` 参数装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEANGULARDEPENDENCYINJECTIONDIMECHANISMRESOLVESASERVICESOWNDEPENDENCIESBASEDONTHEDECLAREDTYPESOFTHATSERVICESCONSTRUCTORPARAMETERS", "original": "**Why?** The Angular Dependency Injection (DI) mechanism resolves a service's own\ndependencies based on the declared types of that service's constructor parameters.", "translation": "**为何?** Angular 的 DI 机制会根据服务的构造函数参数的声明类型来解析服务的所有依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYWHENASERVICEACCEPTSONLYDEPENDENCIESASSOCIATEDWITHTYPETOKENSTHEINJECTABLESYNTAXISMUCHLESSVERBOSECOMPAREDTOUSINGINJECTONEACHINDIVIDUALCONSTRUCTORPARAMETER", "original": "**Why?** When a service accepts only dependencies associated with type tokens, the `@Injectable()` syntax is much less verbose compared to using `@Inject()` on each individual constructor parameter.", "translation": "**为何?**当服务只接受类型令牌相关的依赖时,比起在每个构造函数参数上使用 `@Inject()`,`@Injectable()` 的语法简洁多了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##DATASERVICES", "original": "## Data Services", "translation": "## 数据服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###TALKTOTHESERVERTHROUGHASERVICE", "original": "### Talk to the server through a service", "translation": "### 通过服务与 Web 服务器通讯", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0801", "original": "#### Style 08-01", "translation": "#### 风格 08-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOREFACTORLOGICFORMAKINGDATAOPERATIONSANDINTERACTINGWITHDATATOASERVICE", "original": "**Do** refactor logic for making data operations and interacting with data to a service.", "translation": "**坚持**把数据操作和与数据交互的逻辑重构到服务里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOMAKEDATASERVICESRESPONSIBLEFORXHRCALLSLOCALSTORAGESTASHINGINMEMORYORANYOTHERDATAOPERATIONS", "original": "**Do** make data services responsible for XHR calls, local storage, stashing in memory, or any other data operations.", "translation": "**坚持**让数据服务来负责 XHR 调用、本地储存、内存储存或者其它数据操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHECOMPONENTSRESPONSIBILITYISFORTHEPRESENTATIONANDGATHERINGOFINFORMATIONFORTHEVIEWITSHOULDNOTCAREHOWITGETSTHEDATAJUSTTHATITKNOWSWHOTOASKFORITSEPARATINGTHEDATASERVICESMOVESTHELOGICONHOWTOGETITTOTHEDATASERVICEANDLETSTHECOMPONENTBESIMPLERANDMOREFOCUSEDONTHEVIEW", "original": "**Why?** The component's responsibility is for the presentation and gathering of information for the view. It should not care how it gets the data, just that it knows who to ask for it. Separating the data services moves the logic on how to get it to the data service, and lets the component be simpler and more focused on the view.", "translation": "**为何?**组件的职责是为视图展示或收集信息。它不应该关心如何获取数据,它只需要知道向谁请求数据。把如何获取数据的逻辑移动到数据服务里,简化了组件,让其聚焦于视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHISMAKESITEASIERTOTESTMOCKORREALTHEDATACALLSWHENTESTINGACOMPONENTTHATUSESADATASERVICE", "original": "**Why?** This makes it easier to test (mock or real) the data calls when testing a component that uses a data service.", "translation": "**为何?**在测试使用数据服务的组件时,可以让数据调用更容易被测试(模拟或者真实)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYTHEDETAILSOFDATAMANAGEMENTSUCHASHEADERSHTTPMETHODSCACHINGERRORHANDLINGANDRETRYLOGICAREIRRELEVANTTOCOMPONENTSANDOTHERDATACONSUMERS", "original": "**Why?** The details of data management, such as headers, HTTP methods,\ncaching, error handling, and retry logic, are irrelevant to components\nand other data consumers.", "translation": "**为何?**数据管理的详情,比如头信息、方法、缓存、错误处理和重试逻辑,不是组件和其它的数据消费者应该关心的事情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "ADATASERVICEENCAPSULATESTHESEDETAILSITSEASIERTOEVOLVETHESEDETAILSINSIDETHESERVICEWITHOUTAFFECTINGITSCONSUMERSANDITSEASIERTOTESTTHECONSUMERSWITHMOCKSERVICEIMPLEMENTATIONS", "original": "A data service encapsulates these details. It's easier to evolve these\ndetails inside the service without affecting its consumers. And it's\neasier to test the consumers with mock service implementations.", "translation": "数据服务应该封装这些细节。这样,在服务内部修改细节,就不会影响到它的消费者。并且更容易通过实现一个模拟服务来对消费者进行测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##LIFECYCLEHOOKS", "original": "## Lifecycle hooks", "translation": "## 生命周期钩子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "USELIFECYCLEHOOKSTOTAPINTOIMPORTANTEVENTSEXPOSEDBYANGULAR", "original": "Use Lifecycle hooks to tap into important events exposed by Angular.", "translation": "使用生命周期钩子来介入到 Angular 暴露的重要事件里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###IMPLEMENTLIFECYCLEHOOKINTERFACES", "original": "### Implement lifecycle hook interfaces", "translation": "### 实现生命周期钩子接口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLE0901", "original": "#### Style 09-01", "translation": "#### 风格 09-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOIMPLEMENTTHELIFECYCLEHOOKINTERFACES", "original": "**Do** implement the lifecycle hook interfaces.", "translation": "**坚持**实现生命周期钩子接口。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "WHYLIFECYCLEINTERFACESPRESCRIBETYPEDMETHODSIGNATURESUSETHOSESIGNATURESTOFLAGSPELLINGANDSYNTAXMISTAKES", "original": "**Why?** Lifecycle interfaces prescribe typed method\nsignatures. use those signatures to flag spelling and syntax mistakes.", "translation": "**为何?**如果使用强类型的方法签名,编译器和编辑器可以帮你揪出拼写错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "##APPENDIX", "original": "## Appendix", "translation": "## 附录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "USEFULTOOLSANDTIPSFORANGULAR", "original": "Useful tools and tips for Angular.", "translation": "有用的 Angular 工具和小提示", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLEA01", "original": "#### Style A-01", "translation": "#### 风格 A-01", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSECODELYZERHTTPS:WWWNPMJSCOMPACKAGECODELYZERTOFOLLOWTHISGUIDE", "original": "**Do** use [codelyzer](https://www.npmjs.com/package/codelyzer) to follow this guide.", "translation": "**坚持**使用 [codelyzer](https://www.npmjs.com/package/codelyzer) 来实施本指南。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERADJUSTINGTHERULESINCODELYZERTOSUITYOURNEEDS", "original": "**Consider** adjusting the rules in codelyzer to suit your needs.", "translation": "**考虑**调整 codelyzer 的规则来满足你的需求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "###FILETEMPLATESANDSNIPPETS", "original": "### File templates and snippets", "translation": "### 文档模板和代码片段", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "####STYLEA02", "original": "#### Style A-02", "translation": "#### 风格 A-02", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "DOUSEFILETEMPLATESORSNIPPETSTOHELPFOLLOWCONSISTENTSTYLESANDPATTERNSHEREARETEMPLATESANDORSNIPPETSFORSOMEOFTHEWEBDEVELOPMENTEDITORSANDIDES", "original": "**Do** use file templates or snippets to help follow consistent styles and patterns. Here are templates and/or snippets for some of the web development editors and IDEs.", "translation": "**坚持**使用文件模板或代码片段来帮助实现一致的风格和模式。下面是为一些网络开发编辑器和 IDE 准备的模板和/或代码片段:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERUSINGSNIPPETSHTTPS:MARKETPLACEVISUALSTUDIOCOMITEMSITEMNAMEJOHNPAPAANGULAR2FORVISUALSTUDIOCODEHTTPS:CODEVISUALSTUDIOCOMTHATFOLLOWTHESESTYLESANDGUIDELINES", "original": "**Consider** using [snippets](https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2) for [Visual Studio Code](https://code.visualstudio.com/) that follow these styles and guidelines.", "translation": "**考虑**使用 [Visual Studio Code](https://code.visualstudio.com/)的[代码片段](https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2) 来实施本风格指南。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERUSINGSNIPPETSHTTPS:ATOMIOPACKAGESANGULAR2TYPESCRIPTSNIPPETSFORATOMHTTPS:ATOMIOTHATFOLLOWTHESESTYLESANDGUIDELINES", "original": "**Consider** using [snippets](https://atom.io/packages/angular-2-typescript-snippets) for [Atom](https://atom.io/) that follow these styles and guidelines.", "translation": "**考虑**使用 [Atom](https://atom.io/) 的[代码片断](https://atom.io/packages/angular-2-typescript-snippets)来实施本风格指南。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERUSINGSNIPPETSHTTPS:GITHUBCOMORIZENSSUBLIMEANGULAR2SNIPPETSFORSUBLIMETEXTHTTP:WWWSUBLIMETEXTCOMTHATFOLLOWTHESESTYLESANDGUIDELINES", "original": "**Consider** using [snippets](https://github.com/orizens/sublime-angular2-snippets) for [Sublime Text](http://www.sublimetext.com/) that follow these styles and guidelines.", "translation": "**考虑**使用 [Sublime Text](http://www.sublimetext.com/)的[代码片断](https://github.com/orizens/sublime-angular2-snippets) 来实施本风格指南。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "CONSIDERUSINGSNIPPETSHTTPS:GITHUBCOMMHARTINGTONVIMANGULAR2SNIPPETSFORVIMHTTP:WWWVIMORGTHATFOLLOWTHESESTYLESANDGUIDELINES", "original": "**Consider** using [snippets](https://github.com/mhartington/vim-angular2-snippets) for [Vim](http://www.vim.org/) that follow these styles and guidelines.", "translation": "**考虑**使用 [Vim](http://www.vim.org/) 的[代码片断](https://github.com/mhartington/vim-angular2-snippets)来实施本风格指南。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "AHREF#TOCBACKTOTOPA", "original": "<a href=\"#toc\">Back to top</a>", "translation": "<a href=\"#toc\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/styleguide.md" }, { + "key": "#TEMPLATESYNTAX", "original": "# Template Syntax", "translation": "# 模板语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEANGULARAPPLICATIONMANAGESWHATTHEUSERSEESANDCANDOACHIEVINGTHISTHROUGHTHEINTERACTIONOFACOMPONENTCLASSINSTANCETHECOMPONENTANDITSUSERFACINGTEMPLATE", "original": "The Angular application manages what the user sees and can do, achieving this through the interaction of a\ncomponent class instance (the *component*) and its user-facing template.", "translation": "Angular 应用管理着用户之所见和所为,并通过 Component 类的实例(*组件*)和面向用户的模板来与用户交互。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUMAYBEFAMILIARWITHTHECOMPONENTTEMPLATEDUALITYFROMYOUREXPERIENCEWITHMODELVIEWCONTROLLERMVCORMODELVIEWVIEWMODELMVVMINANGULARTHECOMPONENTPLAYSTHEPARTOFTHECONTROLLERVIEWMODELANDTHETEMPLATEREPRESENTSTHEVIEW", "original": "You may be familiar with the component/template duality from your experience with model-view-controller (MVC) or model-view-viewmodel (MVVM).\nIn Angular, the component plays the part of the controller/viewmodel, and the template represents the view.", "translation": "从使用模型-视图-控制器 (MVC) 或模型-视图-视图模型 (MVVM) 的经验中,很多开发人员都熟悉了组件和模板这两个概念。\n 在 Angular 中,组件扮演着控制器或视图模型的角色,模板则扮演视图的角色。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISPAGEISACOMPREHENSIVETECHNICALREFERENCETOTHEANGULARTEMPLATELANGUAGEITEXPLAINSBASICPRINCIPLESOFTHETEMPLATELANGUAGEANDDESCRIBESMOSTOFTHESYNTAXTHATYOULLENCOUNTERELSEWHEREINTHEDOCUMENTATION", "original": "This page is a comprehensive technical reference to the Angular template language.\nIt explains basic principles of the template language and describes most of the syntax that you'll encounter elsewhere in the documentation.", "translation": "这是一篇关于 Angular 模板语言的技术大全。\n它解释了模板语言的基本原理,并描述了你将在文档中其它地方遇到的大部分语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "MANYCODESNIPPETSILLUSTRATETHEPOINTSANDCONCEPTSALLOFTHEMAVAILABLEINTHELIVEEXAMPLETITLETEMPLATESYNTAXLIVECODELIVEEXAMPLE", "original": "Many code snippets illustrate the points and concepts, all of them available\nin the <live-example title=\"Template Syntax Live Code\"></live-example>.", "translation": "这里还有很多代码片段用来解释技术点和概念,它们全都在<live-example title=\"模板语法的在线例子\"></live-example>中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##HTMLINTEMPLATES", "original": "## HTML in templates", "translation": "## 模板中的 HTML", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HTMLISTHELANGUAGEOFTHEANGULARTEMPLATEALMOSTALLHTMLSYNTAXISVALIDTEMPLATESYNTAXTHESCRIPTELEMENTISANOTABLEEXCEPTIONITISFORBIDDENELIMINATINGTHERISKOFSCRIPTINJECTIONATTACKSINPRACTICESCRIPTISIGNOREDANDAWARNINGAPPEARSINTHEBROWSERCONSOLESEETHESECURITYGUIDESECURITYPAGEFORDETAILS", "original": "HTML is the language of the Angular template.\nAlmost all HTML syntax is valid template syntax.\nThe `<script>` element is a notable exception;\nit is forbidden, eliminating the risk of script injection attacks.\nIn practice, `<script>` is ignored and a warning appears in the browser console.\nSee the [Security](guide/security) page for details.", "translation": "HTML 是 Angular 模板的语言。几乎所有的 HTML 语法都是有效的模板语法。\n但值得注意的例外是 `<script>` 元素,它被禁用了,以阻止脚本注入攻击的风险。(实际上,`<script>` 只是被忽略了。)\n参见[安全](guide/security)页了解详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SOMELEGALHTMLDOESNTMAKEMUCHSENSEINATEMPLATETHEHTMLBODYANDBASEELEMENTSHAVENOUSEFULROLEPRETTYMUCHEVERYTHINGELSEISFAIRGAME", "original": "Some legal HTML doesn't make much sense in a template.\nThe `<html>`, `<body>`, and `<base>` elements have no useful role.\nPretty much everything else is fair game.", "translation": "有些合法的 HTML 被用在模板中是没有意义的。`<html>`、`<body>` 和 `<base>` 元素这个舞台上中并没有扮演有用的角色。剩下的所有元素基本上就都一样用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANEXTENDTHEHTMLVOCABULARYOFYOURTEMPLATESWITHCOMPONENTSANDDIRECTIVESTHATAPPEARASNEWELEMENTSANDATTRIBUTESINTHEFOLLOWINGSECTIONSYOULLLEARNHOWTOGETANDSETDOMDOCUMENTOBJECTMODELVALUESDYNAMICALLYTHROUGHDATABINDING", "original": "You can extend the HTML vocabulary of your templates with components and directives that appear as new elements and attributes.\nIn the following sections, you'll learn how to get and set DOM (Document Object Model) values dynamically through data binding.", "translation": "可以通过组件和指令来扩展模板中的 HTML 词汇。它们看上去就是新元素和属性。接下来将学习如何通过数据绑定来动态获取/设置 DOM(文档对象模型)的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BEGINWITHTHEFIRSTFORMOFDATABINDINGMDASHINTERPOLATIONMDASHTOSEEHOWMUCHRICHERTEMPLATEHTMLCANBE", "original": "Begin with the first form of data binding—interpolation—to see how much richer template HTML can be.", "translation": "首先看看数据绑定的第一种形式 —— 插值表达式,它展示了模板的 HTML 可以有多丰富。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##INTERPOLATIONSPANCLASSSYNTAX#XFEFFSPAN", "original": "## Interpolation ( <span class=\"syntax\">{{...}}</span> )", "translation": "## 插值表达式 ( <span class=\"syntax\">{{...}}</span> )", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUMETTHEDOUBLECURLYBRACESOFINTERPOLATIONANDEARLYINYOURANGULAREDUCATION", "original": "You met the double-curly braces of interpolation, `{{` and `}}`, early in your Angular education.", "translation": "在以前的 Angular 教程中,你遇到过由双花括号括起来的插值表达式,`{{` 和 `}}`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUUSEINTERPOLATIONTOWEAVECALCULATEDSTRINGSINTOTHETEXTBETWEENHTMLELEMENTTAGSANDWITHINATTRIBUTEASSIGNMENTS", "original": "You use interpolation to weave calculated strings into the text between HTML element tags and within attribute assignments.", "translation": "插值表达式可以把计算后的字符串插入到 HTML 元素标签内的文本或对标签的属性进行赋值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETEXTBETWEENTHEBRACESISOFTENTHENAMEOFACOMPONENTPROPERTYANGULARREPLACESTHATNAMEWITHTHESTRINGVALUEOFTHECORRESPONDINGCOMPONENTPROPERTYINTHEEXAMPLEABOVEANGULAREVALUATESTHETITLEANDHEROIMAGEURLPROPERTIESANDFILLSINTHEBLANKSFIRSTDISPLAYINGABOLDAPPLICATIONTITLEANDTHENAHEROICIMAGE", "original": "The text between the braces is often the name of a component property. Angular replaces that name with the\nstring value of the corresponding component property. In the example above, Angular evaluates the `title` and `heroImageUrl` properties\nand \"fills in the blanks\", first displaying a bold application title and then a heroic image.", "translation": "在括号之间的“素材”,通常是组件属性的名字。Angular 会用组件中相应属性的字符串值,替换这个名字。\n 上例中,Angular 计算 `title` 和 `heroImageUrl` 属性的值,并把它们填在空白处。\n 首先显示粗体的应用标题,然后显示英雄的图片。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "MOREGENERALLYTHETEXTBETWEENTHEBRACESISATEMPLATEEXPRESSIONTHATANGULARFIRSTEVALUATESANDTHENCONVERTSTOASTRINGTHEFOLLOWINGINTERPOLATIONILLUSTRATESTHEPOINTBYADDINGTHETWONUMBERS:", "original": "More generally, the text between the braces is a **template expression** that Angular first **evaluates**\nand then **converts to a string**. The following interpolation illustrates the point by adding the two numbers:", "translation": "一般来说,括号间的素材是一个**模板表达式**,Angular 先**对它求值**,再把它**转换成字符串**。\n 下列插值表达式通过把括号中的两个数字相加说明了这一点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEEXPRESSIONCANINVOKEMETHODSOFTHEHOSTCOMPONENTSUCHASGETVALSEENHERE:", "original": "The expression can invoke methods of the host component such as `getVal()`, seen here:", "translation": "这个表达式可以调用宿主组件的方法,就像下面用的 `getVal()`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULAREVALUATESALLEXPRESSIONSINDOUBLECURLYBRACESCONVERTSTHEEXPRESSIONRESULTSTOSTRINGSANDLINKSTHEMWITHNEIGHBORINGLITERALSTRINGSFINALLYITASSIGNSTHISCOMPOSITEINTERPOLATEDRESULTTOANELEMENTORDIRECTIVEPROPERTY", "original": "Angular evaluates all expressions in double curly braces,\nconverts the expression results to strings, and links them with neighboring literal strings. Finally,\nit assigns this composite interpolated result to an **element or directive property**.", "translation": "Angular 对所有双花括号中的表达式求值,把求值的结果转换成字符串,并把它们跟相邻的字符串字面量连接起来。最后,把这个组合出来的插值结果赋给**元素或指令的属性**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUAPPEARTOBEINSERTINGTHERESULTBETWEENELEMENTTAGSANDASSIGNINGITTOATTRIBUTESITSCONVENIENTTOTHINKSOANDYOURARELYSUFFERFORTHISMISTAKETHOUGHTHISISNOTEXACTLYTRUEINTERPOLATIONISASPECIALSYNTAXTHATANGULARCONVERTSINTOAPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDINGASISEXPLAINEDBELOWGUIDETEMPLATESYNTAX#PROPERTYBINDINGORINTERPOLATION", "original": "You appear to be inserting the result between element tags and assigning it to attributes.\nIt's convenient to think so, and you rarely suffer for this mistake.\nThough this is not exactly true. Interpolation is a special syntax that Angular converts into a\n[property binding](guide/template-syntax#property-binding), as is explained [below](guide/template-syntax#property-binding-or-interpolation).", "translation": "表面上看,你在元素标签之间插入了结果和对标签的属性进行了赋值。\n这样思考起来很方便,并且这个误解很少给你带来麻烦。\n但严格来讲,这是不对的。插值表达式是一个特殊的语法,Angular 把它转换成了[属性绑定](guide/template-syntax#property-binding),[后面](guide/template-syntax#property-binding-or-interpolation)将会解释这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BUTFIRSTLETSTAKEACLOSERLOOKATTEMPLATEEXPRESSIONSANDSTATEMENTS", "original": "But first, let's take a closer look at template expressions and statements.", "translation": "讲解属性绑定之前,先深入了解一下模板表达式和模板语句。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##TEMPLATEEXPRESSIONS", "original": "## Template expressions", "translation": "## 模板表达式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATEMPLATEEXPRESSIONPRODUCESAVALUEANGULAREXECUTESTHEEXPRESSIONANDASSIGNSITTOAPROPERTYOFABINDINGTARGETTHETARGETMIGHTBEANHTMLELEMENTACOMPONENTORADIRECTIVE", "original": "A template **expression** produces a value.\nAngular executes the expression and assigns it to a property of a binding target;\nthe target might be an HTML element, a component, or a directive.", "translation": "模板**表达式**产生一个值。\n Angular 执行这个表达式,并把它赋值给绑定目标的属性,这个绑定目标可能是 HTML 元素、组件或指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEINTERPOLATIONBRACESIN11SURROUNDTHETEMPLATEEXPRESSION11INTHEPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDINGSECTIONBELOWATEMPLATEEXPRESSIONAPPEARSINQUOTESTOTHERIGHTOFTHENBSPSYMBOLASINPROPERTYEXPRESSION", "original": "The interpolation braces in `{{1 + 1}}` surround the template expression `1 + 1`.\nIn the [property binding](guide/template-syntax#property-binding) section below,\na template expression appears in quotes to the right of the `=` symbol as in `[property]=\"expression\"`.", "translation": "`{{1 + 1}}` 中所包含的模板表达式是 `1 + 1`。\n 在[属性绑定](guide/template-syntax#property-binding)中会再次看到模板表达式,它出现在 `=` 右侧的引号中,就像这样:`[property]=\"expression\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUWRITETHESETEMPLATEEXPRESSIONSINALANGUAGETHATLOOKSLIKEJAVASCRIPTMANYJAVASCRIPTEXPRESSIONSARELEGALTEMPLATEEXPRESSIONSBUTNOTALL", "original": "You write these template expressions in a language that looks like JavaScript.\nMany JavaScript expressions are legal template expressions, but not all.", "translation": "编写模板表达式所用的语言看起来很像 JavaScript。\n 很多 JavaScript 表达式也是合法的模板表达式,但不是全部。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "JAVASCRIPTEXPRESSIONSTHATHAVEORPROMOTESIDEEFFECTSAREPROHIBITEDINCLUDING:", "original": "JavaScript expressions that have or promote side effects are prohibited,\nincluding:", "translation": "JavaScript 中那些具有或可能引发副作用的表达式是被禁止的,包括:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ASSIGNMENTS", "original": "* assignments (`=`, `+=`, `-=`, ...)", "translation": "赋值 (`=`, `+=`, `-=`, ...)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CODENEWCODE", "original": "* <code>new</code>", "translation": "`new` 运算符", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CHAININGEXPRESSIONSWITHCODECODEORCODECODE", "original": "* chaining expressions with <code>;</code> or <code>,</code>", "translation": "使用 `;` 或 `,` 的链式表达式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INCREMENTANDDECREMENTOPERATORSAND", "original": "* increment and decrement operators (`++` and `--`)", - "translation": "自增或自减操作符 (`++` 和 `--`)", + "translation": "自增和自减运算符:`++` 和 `--`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "OTHERNOTABLEDIFFERENCESFROMJAVASCRIPTSYNTAXINCLUDE:", "original": "Other notable differences from JavaScript syntax include:", "translation": "和 JavaScript 语 法的其它显著不同包括:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NOSUPPORTFORTHEBITWISEOPERATORSAND", "original": "* no support for the bitwise operators `|` and `&`", "translation": "不支持位运算 `|` 和 `&`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NEWTEMPLATEEXPRESSIONOPERATORSGUIDETEMPLATESYNTAX#EXPRESSIONOPERATORSSUCHASAND", "original": "* new [template expression operators](guide/template-syntax#expression-operators), such as `|`, `?.` and `!`.", "translation": "具有新的[模板表达式运算符](guide/template-syntax#expression-operators),比如 `|`、`?.` 和 `!`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###EXPRESSIONCONTEXT", "original": "### Expression context", "translation": "### 表达式上下文", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEEXPRESSIONCONTEXTISTYPICALLYTHECOMPONENTINSTANCEINTHEFOLLOWINGSNIPPETSTHETITLEWITHINDOUBLECURLYBRACESANDTHEISUNCHANGEDINQUOTESREFERTOPROPERTIESOFTHEAPPCOMPONENT", "original": "The *expression context* is typically the _component_ instance.\nIn the following snippets, the `title` within double-curly braces and the\n`isUnchanged` in quotes refer to properties of the `AppComponent`.", "translation": "典型的*表达式上下文*就是这个**组件实例**,它是各种绑定值的来源。\n在下面的代码片段中,双花括号中的 `title` 和引号中的 `isUnchanged` 所引用的都是 `AppComponent` 中的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANEXPRESSIONMAYALSOREFERTOPROPERTIESOFTHETEMPLATESCONTEXTSUCHASATEMPLATEINPUTVARIABLEGUIDETEMPLATESYNTAX#TEMPLATEINPUTVARIABLELETHEROORATEMPLATEREFERENCEVARIABLEGUIDETEMPLATESYNTAX#REFVARS#HEROINPUT", "original": "An expression may also refer to properties of the _template's_ context\nsuch as a [template input variable](guide/template-syntax#template-input-variable) (`let hero`)\nor a [template reference variable](guide/template-syntax#ref-vars) (`#heroInput`).", "translation": "表达式的上下文可以包括组件之外的对象。\n 比如[模板输入变量](guide/template-syntax#template-input-variable) (`let hero`)和[模板引用变量](guide/template-syntax#ref-vars)(`#heroInput`)就是备选的上下文对象之一。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THECONTEXTFORTERMSINANEXPRESSIONISABLENDOFTHETEMPLATEVARIABLESTHEDIRECTIVESCONTEXTOBJECTIFITHASONEANDTHECOMPONENTSMEMBERSIFYOUREFERENCEANAMETHATBELONGSTOMORETHANONEOFTHESENAMESPACESTHETEMPLATEVARIABLENAMETAKESPRECEDENCEFOLLOWEDBYANAMEINTHEDIRECTIVESCONTEXTANDLASTLYTHECOMPONENTSMEMBERNAMES", "original": "The context for terms in an expression is a blend of the _template variables_,\nthe directive's _context_ object (if it has one), and the component's _members_.\nIf you reference a name that belongs to more than one of these namespaces,\nthe template variable name takes precedence, followed by a name in the directive's _context_,\nand, lastly, the component's member names.", "translation": "表达式中的上下文变量是由*模板变量*、指令的*上下文变量*(如果有)和组件的*成员*叠加而成的。\n如果你要引用的变量名存在于一个以上的命名空间中,那么,模板变量是最优先的,其次是指令的上下文变量,最后是组件的成员。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEPREVIOUSEXAMPLEPRESENTSSUCHANAMECOLLISIONTHECOMPONENTHASAHEROPROPERTYANDTHENGFORDEFINESAHEROTEMPLATEVARIABLETHEHEROINHERONAMEREFERSTOTHETEMPLATEINPUTVARIABLENOTTHECOMPONENTSPROPERTY", "original": "The previous example presents such a name collision. The component has a `hero`\nproperty and the `*ngFor` defines a `hero` template variable.\nThe `hero` in `{{hero.name}}`\nrefers to the template input variable, not the component's property.", "translation": "上一个例子中就体现了这种命名冲突。组件具有一个名叫 `hero` 的属性,而 `*ngFor` 声明了一个也叫 `hero` 的模板变量。\n在 `{{hero.name}}` 表达式中的 `hero` 实际引用的是模板变量,而不是组件的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TEMPLATEEXPRESSIONSCANNOTREFERTOANYTHINGINTHEGLOBALNAMESPACEEXCEPTUNDEFINEDTHEYCANTREFERTOWINDOWORDOCUMENTTHEYCANTCALLCONSOLELOGORMATHMAXTHEYARERESTRICTEDTOREFERENCINGMEMBERSOFTHEEXPRESSIONCONTEXT", "original": "Template expressions cannot refer to anything in\nthe global namespace (except `undefined`). They can't refer to `window` or `document`. They\ncan't call `console.log` or `Math.max`. They are restricted to referencing\nmembers of the expression context.", "translation": "模板表达式不能引用全局命名空间中的任何东西,比如 `window` 或 `document`。它们也不能调用 `console.log` 或 `Math.max`。\n它们只能引用表达式上下文中的成员。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###EXPRESSIONGUIDELINES", "original": "### Expression guidelines", "translation": "### 表达式指南", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TEMPLATEEXPRESSIONSCANMAKEORBREAKANAPPLICATIONPLEASEFOLLOWTHESEGUIDELINES:", "original": "Template expressions can make or break an application.\nPlease follow these guidelines:", "translation": "模板表达式能成就或毁掉一个应用。请遵循下列指南:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NOVISIBLESIDEEFFECTSGUIDETEMPLATESYNTAX#NOVISIBLESIDEEFFECTS", "original": "* [No visible side effects](guide/template-syntax#no-visible-side-effects)", "translation": "[没有可见的副作用](guide/template-syntax#no-visible-side-effects)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "QUICKEXECUTIONGUIDETEMPLATESYNTAX#QUICKEXECUTION", "original": "* [Quick execution](guide/template-syntax#quick-execution)", "translation": "[执行迅速](guide/template-syntax#quick-execution)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SIMPLICITYGUIDETEMPLATESYNTAX#SIMPLICITY", "original": "* [Simplicity](guide/template-syntax#simplicity)", "translation": "[非常简单](guide/template-syntax#simplicity)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "IDEMPOTENCEGUIDETEMPLATESYNTAX#IDEMPOTENCE", "original": "* [Idempotence](guide/template-syntax#idempotence)", "translation": "[幂等性](guide/template-syntax#idempotence)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEONLYEXCEPTIONSTOTHESEGUIDELINESSHOULDBEINSPECIFICCIRCUMSTANCESTHATYOUTHOROUGHLYUNDERSTAND", "original": "The only exceptions to these guidelines should be in specific circumstances that you thoroughly understand.", "translation": "超出上面指南外的情况应该只出现在那些你确信自己已经彻底理解的特定场景中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####NOVISIBLESIDEEFFECTS", "original": "#### No visible side effects", "translation": "#### 没有可见的副作用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATEMPLATEEXPRESSIONSHOULDNOTCHANGEANYAPPLICATIONSTATEOTHERTHANTHEVALUEOFTHETARGETPROPERTY", "original": "A template expression should not change any application state other than the value of the\ntarget property.", "translation": "模板表达式除了目标属性的值以外,不应该改变应用的任何状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISRULEISESSENTIALTOANGULARSUNIDIRECTIONALDATAFLOWPOLICYYOUSHOULDNEVERWORRYTHATREADINGACOMPONENTVALUEMIGHTCHANGESOMEOTHERDISPLAYEDVALUETHEVIEWSHOULDBESTABLETHROUGHOUTASINGLERENDERINGPASS", "original": "This rule is essential to Angular's \"unidirectional data flow\" policy.\nYou should never worry that reading a component value might change some other displayed value.\nThe view should be stable throughout a single rendering pass.", "translation": "这条规则是 Angular “单向数据流”策略的基础。\n永远不用担心读取组件值可能改变另外的显示值。\n在一次单独的渲染过程中,视图应该总是稳定的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####QUICKEXECUTION", "original": "#### Quick execution", "translation": "#### 执行迅速", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULAREXECUTESTEMPLATEEXPRESSIONSAFTEREVERYCHANGEDETECTIONCYCLECHANGEDETECTIONCYCLESARETRIGGEREDBYMANYASYNCHRONOUSACTIVITIESSUCHASPROMISERESOLUTIONSHTTPRESULTSTIMEREVENTSKEYPRESSESANDMOUSEMOVES", "original": "Angular executes template expressions after every change detection cycle.\nChange detection cycles are triggered by many asynchronous activities such as\npromise resolutions, http results, timer events, keypresses and mouse moves.", "translation": "Angular 会在每个变更检测周期后执行模板表达式。\n它们可能在每一次按键或鼠标移动后被调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "EXPRESSIONSSHOULDFINISHQUICKLYORTHEUSEREXPERIENCEMAYDRAGESPECIALLYONSLOWERDEVICESCONSIDERCACHINGVALUESWHENTHEIRCOMPUTATIONISEXPENSIVE", "original": "Expressions should finish quickly or the user experience may drag, especially on slower devices.\nConsider caching values when their computation is expensive.", "translation": "表达式应该快速结束,否则用户就会感到拖沓,特别是在较慢的设备上。\n当计算代价较高时,应该考虑缓存那些从其它值计算得出的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####SIMPLICITY", "original": "#### Simplicity", "translation": "#### 非常简单", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ALTHOUGHITSPOSSIBLETOWRITEQUITECOMPLEXTEMPLATEEXPRESSIONSYOUSHOULDAVOIDTHEM", "original": "Although it's possible to write quite complex template expressions, you should avoid them.", "translation": "虽然也可以写出相当复杂的模板表达式,但不要那么写。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "APROPERTYNAMEORMETHODCALLSHOULDBETHENORMANOCCASIONALBOOLEANNEGATIONISOKOTHERWISECONFINEAPPLICATIONANDBUSINESSLOGICTOTHECOMPONENTITSELFWHEREITWILLBEEASIERTODEVELOPANDTEST", "original": "A property name or method call should be the norm.\nAn occasional Boolean negation (`!`) is OK.\nOtherwise, confine application and business logic to the component itself,\nwhere it will be easier to develop and test.", "translation": "常规是属性名或方法调用。偶尔的逻辑取反 (`!`) 也还凑合。\n其它情况下,应在组件中实现应用和业务逻辑,使开发和测试变得更容易。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####IDEMPOTENCE", "original": "#### Idempotence", "translation": "#### 幂等性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANIDEMPOTENTHTTPS:ENWIKIPEDIAORGWIKIIDEMPOTENCEEXPRESSIONISIDEALBECAUSEITISFREEOFSIDEEFFECTSANDIMPROVESANGULARSCHANGEDETECTIONPERFORMANCE", "original": "An [idempotent](https://en.wikipedia.org/wiki/Idempotence) expression is ideal because\nit is free of side effects and improves Angular's change detection performance.", "translation": "最好使用[幂等的](https://en.wikipedia.org/wiki/Idempotence)表达式,因为它没有副作用,并且能提升 Angular 变更检测的性能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INANGULARTERMSANIDEMPOTENTEXPRESSIONALWAYSRETURNSEXACTLYTHESAMETHINGUNTILONEOFITSDEPENDENTVALUESCHANGES", "original": "In Angular terms, an idempotent expression always returns *exactly the same thing* until\none of its dependent values changes.", "translation": "在 Angular 的术语中,幂等的表达式应该总是返回*完全相同的东西*,直到某个依赖值发生改变。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "DEPENDENTVALUESSHOULDNOTCHANGEDURINGASINGLETURNOFTHEEVENTLOOPIFANIDEMPOTENTEXPRESSIONRETURNSASTRINGORANUMBERITRETURNSTHESAMESTRINGORNUMBERWHENCALLEDTWICEINAROWIFTHEEXPRESSIONRETURNSANOBJECTINCLUDINGANARRAYITRETURNSTHESAMEOBJECTREFERENCEWHENCALLEDTWICEINAROW", "original": "Dependent values should not change during a single turn of the event loop.\nIf an idempotent expression returns a string or a number, it returns the same string or number\nwhen called twice in a row. If the expression returns an object (including an `array`),\nit returns the same object *reference* when called twice in a row.", "translation": "在单独的一次事件循环中,被依赖的值不应该改变。\n 如果幂等的表达式返回一个字符串或数字,连续调用它两次,也应该返回相同的字符串或数字。\n 如果幂等的表达式返回一个对象(包括 `Date` 或 `Array`),连续调用它两次,也应该返回同一个对象的*引用*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##TEMPLATESTATEMENTS", "original": "## Template statements", "translation": "## 模板语句", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATEMPLATESTATEMENTRESPONDSTOANEVENTRAISEDBYABINDINGTARGETSUCHASANELEMENTCOMPONENTORDIRECTIVEYOULLSEETEMPLATESTATEMENTSINTHEEVENTBINDINGGUIDETEMPLATESYNTAX#EVENTBINDINGSECTIONAPPEARINGINQUOTESTOTHERIGHTOFTHENBSPSYMBOLASINEVENTSTATEMENT", "original": "A template **statement** responds to an **event** raised by a binding target\nsuch as an element, component, or directive.\nYou'll see template statements in the [event binding](guide/template-syntax#event-binding) section,\nappearing in quotes to the right of the `=` symbol as in `(event)=\"statement\"`.", "translation": "模板**语句**用来响应由绑定目标(如 HTML 元素、组件或指令)触发的**事件**。\n模板语句将在[事件绑定](guide/template-syntax#event-binding)一节看到,它出现在 `=` 号右侧的引号中,就像这样:`(event)=\"statement\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATEMPLATESTATEMENTHASASIDEEFFECTTHATSTHEWHOLEPOINTOFANEVENTITSHOWYOUUPDATEAPPLICATIONSTATEFROMUSERACTION", "original": "A template statement *has a side effect*.\nThat's the whole point of an event.\nIt's how you update application state from user action.", "translation": "模板语句*有副作用*。\n这是事件处理的关键。因为你要根据用户的输入更新应用状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "RESPONDINGTOEVENTSISTHEOTHERSIDEOFANGULARSUNIDIRECTIONALDATAFLOWYOUREFREETOCHANGEANYTHINGANYWHEREDURINGTHISTURNOFTHEEVENTLOOP", "original": "Responding to events is the other side of Angular's \"unidirectional data flow\".\nYou're free to change anything, anywhere, during this turn of the event loop.", "translation": "响应事件是 Angular 中“单向数据流”的另一面。\n 在一次事件循环中,可以随意改变任何地方的任何东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "LIKETEMPLATEEXPRESSIONSTEMPLATESTATEMENTSUSEALANGUAGETHATLOOKSLIKEJAVASCRIPTTHETEMPLATESTATEMENTPARSERDIFFERSFROMTHETEMPLATEEXPRESSIONPARSERANDSPECIFICALLYSUPPORTSBOTHBASICASSIGNMENTANDCHAININGEXPRESSIONSWITHCODECODEORCODECODE", "original": "Like template expressions, template *statements* use a language that looks like JavaScript.\nThe template statement parser differs from the template expression parser and\nspecifically supports both basic assignment (`=`) and chaining expressions\n(with <code>;</code> or <code>,</code>).", "translation": "和模板表达式一样,模板*语句*使用的语言也像 JavaScript。\n 模板语句解析器和模板表达式解析器有所不同,特别之处在于它支持基本赋值 (`=`) 和表达式链 (`;` 和 `,`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HOWEVERCERTAINJAVASCRIPTSYNTAXISNOTALLOWED:", "original": "However, certain JavaScript syntax is not allowed:", "translation": "然而,某些 JavaScript 语法仍然是不允许的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CODENEWCODE", "original": "* <code>new</code>", "translation": "`new` 运算符", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INCREMENTANDDECREMENTOPERATORSAND", "original": "* increment and decrement operators, `++` and `--`", "translation": "自增和自减运算符:`++` 和 `--`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "OPERATORASSIGNMENTSUCHASAND", "original": "* operator assignment, such as `+=` and `-=`", "translation": "操作并赋值,例如 `+=` 和 `-=`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEBITWISEOPERATORSAND", "original": "* the bitwise operators `|` and `&`", "translation": "位操作符 `|` 和 `&`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETEMPLATEEXPRESSIONOPERATORSGUIDETEMPLATESYNTAX#EXPRESSIONOPERATORS", "original": "* the [template expression operators](guide/template-syntax#expression-operators)", "translation": "[模板表达式运算符](guide/template-syntax#expression-operators)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###STATEMENTCONTEXT", "original": "### Statement context", "translation": "### 语句上下文", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ASWITHEXPRESSIONSSTATEMENTSCANREFERONLYTOWHATSINTHESTATEMENTCONTEXTSUCHASANEVENTHANDLINGMETHODOFTHECOMPONENTINSTANCE", "original": "As with expressions, statements can refer only to what's in the statement context\nsuch as an event handling method of the component instance.", "translation": "和表达式中一样,语句只能引用语句上下文中 —— 通常是正在绑定事件的那个**组件实例**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESTATEMENTCONTEXTISTYPICALLYTHECOMPONENTINSTANCETHEDELETEHEROINCLICKDELETEHEROISAMETHODOFTHEDATABOUNDCOMPONENT", "original": "The *statement context* is typically the component instance.\nThe *deleteHero* in `(click)=\"deleteHero()\"` is a method of the data-bound component.", "translation": "典型的*语句上下文*就是当前组件的实例。\n`(click)=\"deleteHero()\"` 中的 *deleteHero* 就是这个数据绑定组件上的一个方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESTATEMENTCONTEXTMAYALSOREFERTOPROPERTIESOFTHETEMPLATESOWNCONTEXTINTHEFOLLOWINGEXAMPLESTHETEMPLATEEVENTOBJECTATEMPLATEINPUTVARIABLEGUIDETEMPLATESYNTAX#TEMPLATEINPUTVARIABLELETHEROANDATEMPLATEREFERENCEVARIABLEGUIDETEMPLATESYNTAX#REFVARS#HEROFORMAREPASSEDTOANEVENTHANDLINGMETHODOFTHECOMPONENT", "original": "The statement context may also refer to properties of the template's own context.\nIn the following examples, the template `$event` object,\na [template input variable](guide/template-syntax#template-input-variable) (`let hero`),\nand a [template reference variable](guide/template-syntax#ref-vars) (`#heroForm`)\nare passed to an event handling method of the component.", "translation": "语句上下文可以引用模板自身上下文中的属性。\n在下面的例子中,就把模板的 `$event` 对象、[模板输入变量](guide/template-syntax#template-input-variable) (`let hero`)和[模板引用变量](guide/template-syntax#ref-vars) (`#heroForm`)传给了组件中的一个事件处理器方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TEMPLATECONTEXTNAMESTAKEPRECEDENCEOVERCOMPONENTCONTEXTNAMESINDELETEHEROHEROABOVETHEHEROISTHETEMPLATEINPUTVARIABLENOTTHECOMPONENTSHEROPROPERTY", "original": "Template context names take precedence over component context names.\nIn `deleteHero(hero)` above, the `hero` is the template input variable,\nnot the component's `hero` property.", "translation": "模板上下文中的变量名的优先级高于组件上下文中的变量名。在上面的 `deleteHero(hero)` 中,`hero` 是一个模板输入变量,而不是组件中的 `hero` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TEMPLATESTATEMENTSCANNOTREFERTOANYTHINGINTHEGLOBALNAMESPACETHEYCANTREFERTOWINDOWORDOCUMENTTHEYCANTCALLCONSOLELOGORMATHMAX", "original": "Template statements cannot refer to anything in the global namespace. They\ncan't refer to `window` or `document`.\nThey can't call `console.log` or `Math.max`.", "translation": "模板语句不能引用全局命名空间的任何东西。比如不能引用 `window` 或 `document`,也不能调用 `console.log` 或 `Math.max`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###STATEMENTGUIDELINES", "original": "### Statement guidelines", "translation": "### 语句指南", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ASWITHEXPRESSIONSAVOIDWRITINGCOMPLEXTEMPLATESTATEMENTSAMETHODCALLORSIMPLEPROPERTYASSIGNMENTSHOULDBETHENORM", "original": "As with expressions, avoid writing complex template statements.\nA method call or simple property assignment should be the norm.", "translation": "和表达式一样,避免写复杂的模板语句。\n常规是函数调用或者属性赋值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NOWTHATYOUHAVEAFEELFORTEMPLATEEXPRESSIONSANDSTATEMENTSYOUREREADYTOLEARNABOUTTHEVARIETIESOFDATABINDINGSYNTAXBEYONDINTERPOLATION", "original": "Now that you have a feel for template expressions and statements,\nyou're ready to learn about the varieties of data binding syntax beyond interpolation.", "translation": "现在,对模板表达式和语句有了一点感觉了吧。\n 除插值表达式外,还有各种各样的数据绑定语法,是学习它们是时候了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##BINDINGSYNTAX:ANOVERVIEW", "original": "## Binding syntax: An overview", "translation": "## 绑定语法:概览", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "DATABINDINGISAMECHANISMFORCOORDINATINGWHATUSERSSEEWITHAPPLICATIONDATAVALUESWHILEYOUCOULDPUSHVALUESTOANDPULLVALUESFROMHTMLTHEAPPLICATIONISEASIERTOWRITEREADANDMAINTAINIFYOUTURNTHESECHORESOVERTOABINDINGFRAMEWORKYOUSIMPLYDECLAREBINDINGSBETWEENBINDINGSOURCESANDTARGETHTMLELEMENTSANDLETTHEFRAMEWORKDOTHEWORK", "original": "Data binding is a mechanism for coordinating what users see, with application data values.\nWhile you could push values to and pull values from HTML,\nthe application is easier to write, read, and maintain if you turn these chores over to a binding framework.\nYou simply declare bindings between binding sources and target HTML elements and let the framework do the work.", "translation": "数据绑定是一种机制,用来协调用户所见和应用数据。\n虽然你能往 HTML 推送值或者从 HTML 拉取值,\n但如果把这些琐事交给数据绑定框架处理,\n应用会更容易编写、阅读和维护。\n只要简单地在绑定源和目标 HTML 元素之间声明绑定,框架就会完成这项工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULARPROVIDESMANYKINDSOFDATABINDINGTHISGUIDECOVERSMOSTOFTHEMAFTERAHIGHLEVELVIEWOFANGULARDATABINDINGANDITSSYNTAX", "original": "Angular provides many kinds of data binding.\nThis guide covers most of them, after a high-level view of Angular data binding and its syntax.", "translation": "Angular 提供了各种各样的数据绑定,本章将逐一讨论。\n先从高层视角来看看 Angular 数据绑定及其语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BINDINGTYPESCANBEGROUPEDINTOTHREECATEGORIESDISTINGUISHEDBYTHEDIRECTIONOFDATAFLOW:FROMTHESOURCETOVIEWFROMVIEWTOSOURCEANDINTHETWOWAYSEQUENCE:VIEWTOSOURCETOVIEW:", "original": "Binding types can be grouped into three categories distinguished by the direction of data flow:\nfrom the _source-to-view_, from _view-to-source_, and in the two-way sequence: _view-to-source-to-view_:", "translation": "绑定的类型可以根据数据流的方向分成三类:\n*从数据源到视图*、*从视图到数据源*以及双向的*从视图到数据源再到视图*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "DATADIRECTION", "original": "Data direction", "translation": "数据方向", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SYNTAX", "original": "Syntax", "translation": "语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TYPE", "original": "Type", "translation": "绑定类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ONEWAYBRFROMDATASOURCEBRTOVIEWTARGET", "original": "One-way<br>from data source<br>to view target", "translation": "单向<br>从数据源<br>到视图", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTERPOLATIONBRPROPERTYBRATTRIBUTEBRCLASSBRSTYLE", "original": "Interpolation<br>\n Property<br>\n Attribute<br>\n Class<br>\n Style", "translation": "插值表达式<br>\n 属性<br>\n Attribute<br>\n CSS 类<br>\n 样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ONEWAYBRFROMVIEWTARGETBRTODATASOURCE", "original": "One-way<br>from view target<br>to data source", "translation": "从视图到数据源的单向绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "EVENT", "original": "Event", "translation": "事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TWOWAY", "original": "Two-way", "translation": "双向", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TWOWAY", "original": "Two-way", "translation": "双向", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BINDINGTYPESOTHERTHANINTERPOLATIONHAVEATARGETNAMETOTHELEFTOFTHEEQUALSIGNEITHERSURROUNDEDBYPUNCTUATIONORPRECEDEDBYAPREFIXBINDONBINDON", "original": "Binding types other than interpolation have a **target name** to the left of the equal sign,\neither surrounded by punctuation (`[]`, `()`) or preceded by a prefix (`bind-`, `on-`, `bindon-`).", "translation": "除了插值表达式之外的绑定类型,在等号左边是**目标名**,\n 无论是包在括号中 (`[]`、`()`) 还是用前缀形式 (`bind-`、`on-`、`bindon-`) 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETARGETNAMEISTHENAMEOFAPROPERTYITMAYLOOKLIKETHENAMEOFANATTRIBUTEBUTITNEVERISTOAPPRECIATETHEDIFFERENCEYOUMUSTDEVELOPANEWWAYTOTHINKABOUTTEMPLATEHTML", "original": "The target name is the name of a _property_. It may look like the name of an _attribute_ but it never is.\nTo appreciate the difference, you must develop a new way to think about template HTML.", "translation": "这个目标名就是*属性(Property)*的名字。它可能看起来像是*元素属性(Attribute)*的名字,但它不是。\n要理解它们的不同点,你必须尝试用另一种方式来审视模板中的 HTML。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###ANEWMENTALMODEL", "original": "### A new mental model", "translation": "### 新的思维模型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WITHALLTHEPOWEROFDATABINDINGANDTHEABILITYTOEXTENDTHEHTMLVOCABULARYWITHCUSTOMMARKUPITISTEMPTINGTOTHINKOFTEMPLATEHTMLASHTMLPLUS", "original": "With all the power of data binding and the ability to extend the HTML vocabulary\nwith custom markup, it is tempting to think of template HTML as *HTML Plus*.", "translation": "数据绑定的威力和允许用自定义标记扩展 HTML 词汇的能力,会让你把模板 HTML 当成 *HTML+*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ITREALLYISHTMLPLUSBUTITSALSOSIGNIFICANTLYDIFFERENTTHANTHEHTMLYOUREUSEDTOITREQUIRESANEWMENTALMODEL", "original": "It really *is* HTML Plus.\nBut it's also significantly different than the HTML you're used to.\nIt requires a new mental model.", "translation": "它其实*就是* HTML+。\n但它也跟你曾使用的 HTML 有着显著的不同。\n这里需要一种新的思维模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTHENORMALCOURSEOFHTMLDEVELOPMENTYOUCREATEAVISUALSTRUCTUREWITHHTMLELEMENTSANDYOUMODIFYTHOSEELEMENTSBYSETTINGELEMENTATTRIBUTESWITHSTRINGCONSTANTS", "original": "In the normal course of HTML development, you create a visual structure with HTML elements, and\nyou modify those elements by setting element attributes with string constants.", "translation": "在正常的 HTML 开发过程中,你使用 HTML 元素来创建视觉结构,\n通过把字符串常量设置到元素的 attribute 来修改那些元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUSTILLCREATEASTRUCTUREANDINITIALIZEATTRIBUTEVALUESTHISWAYINANGULARTEMPLATES", "original": "You still create a structure and initialize attribute values this way in Angular templates.", "translation": "在 Angular 模板中,你仍使用同样的方式创建结构和初始化 attribute 值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THENYOULEARNTOCREATENEWELEMENTSWITHCOMPONENTSTHATENCAPSULATEHTMLANDDROPTHEMINTOTEMPLATESASIFTHEYWERENATIVEHTMLELEMENTS", "original": "Then you learn to create new elements with components that encapsulate HTML\nand drop them into templates as if they were native HTML elements.", "translation": "然后,用封装了 HTML 的组件创建新元素,并把它们当作原生 HTML 元素在模板中使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THATSHTMLPLUS", "original": "That's HTML Plus.", "translation": "这就是 HTML+。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THENYOULEARNABOUTDATABINDINGTHEFIRSTBINDINGYOUMEETMIGHTLOOKLIKETHIS:", "original": "Then you learn about data binding. The first binding you meet might look like this:", "translation": "现在开始学习数据绑定。你碰到的第一种数据绑定是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOULLGETTOTHATPECULIARBRACKETNOTATIONINAMOMENTLOOKINGBEYONDITYOURINTUITIONSUGGESTSTHATYOUREBINDINGTOTHEBUTTONSDISABLEDATTRIBUTEANDSETTINGITTOTHECURRENTVALUEOFTHECOMPONENTSISUNCHANGEDPROPERTY", "original": "You'll get to that peculiar bracket notation in a moment. Looking beyond it,\nyour intuition suggests that you're binding to the button's `disabled` attribute and setting\nit to the current value of the component's `isUnchanged` property.", "translation": "过会儿再认识那个怪异的方括号记法。直觉告诉你,你正在绑定按钮的 `disabled` attribute。\n 并把它设置为组件的 `isUnchanged` 属性的当前值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOURINTUITIONISINCORRECTYOUREVERYDAYHTMLMENTALMODELISMISLEADINGINFACTONCEYOUSTARTDATABINDINGYOUARENOLONGERWORKINGWITHHTMLATTRIBUTESYOUARENTSETTINGATTRIBUTESYOUARESETTINGTHEPROPERTIESOFDOMELEMENTSCOMPONENTSANDDIRECTIVES", "original": "Your intuition is incorrect! Your everyday HTML mental model is misleading.\nIn fact, once you start data binding, you are no longer working with HTML *attributes*. You aren't setting attributes.\nYou are setting the *properties* of DOM elements, components, and directives.", "translation": "但你的直觉是错的!日常的 HTML 思维模式在误导着你。\n实际上,一旦开始数据绑定,就不再跟 HTML attribute 打交道了。\n这里不是设置 attribute,而是设置 DOM 元素、组件和指令的 property。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###HTMLATTRIBUTEVSDOMPROPERTY", "original": "### HTML attribute vs. DOM property", "translation": "### HTML attribute 与 DOM property 的对比", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEDISTINCTIONBETWEENANHTMLATTRIBUTEANDADOMPROPERTYISCRUCIALTOUNDERSTANDINGHOWANGULARBINDINGWORKS", "original": "The distinction between an HTML attribute and a DOM property is crucial to understanding how Angular binding works.", "translation": "要想理解 Angular 绑定如何工作,重点是搞清 HTML attribute 和 DOM property 之间的区别。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATTRIBUTESAREDEFINEDBYHTMLPROPERTIESAREDEFINEDBYTHEDOMDOCUMENTOBJECTMODEL", "original": "**Attributes are defined by HTML. Properties are defined by the DOM (Document Object Model).**", "translation": "**attribute 是由 HTML 定义的。property 是由 DOM (Document Object Model) 定义的。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "AFEWHTMLATTRIBUTESHAVE1:1MAPPINGTOPROPERTIESIDISONEEXAMPLE", "original": "* A few HTML attributes have 1:1 mapping to properties. `id` is one example.", "translation": "少量 HTML attribute 和 property 之间有着 1:1 的映射,如 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SOMEHTMLATTRIBUTESDONTHAVECORRESPONDINGPROPERTIESCOLSPANISONEEXAMPLE", "original": "* Some HTML attributes don't have corresponding properties. `colspan` is one example.", "translation": "有些 HTML attribute 没有对应的 property,如 `colspan`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SOMEDOMPROPERTIESDONTHAVECORRESPONDINGATTRIBUTESTEXTCONTENTISONEEXAMPLE", "original": "* Some DOM properties don't have corresponding attributes. `textContent` is one example.", "translation": "有些 DOM property 没有对应的 attribute,如 `textContent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "MANYHTMLATTRIBUTESAPPEARTOMAPTOPROPERTIESBUTNOTINTHEWAYYOUMIGHTTHINK", "original": "* Many HTML attributes appear to map to properties ... but not in the way you might think!", "translation": "大量 HTML attribute 看起来映射到了 property…… 但却不像你想的那样!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THATLASTCATEGORYISCONFUSINGUNTILYOUGRASPTHISGENERALRULE:", "original": "That last category is confusing until you grasp this general rule:", "translation": "最后一类尤其让人困惑…… 除非你能理解这个普遍原则:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATTRIBUTESINITIALIZEDOMPROPERTIESANDTHENTHEYAREDONEPROPERTYVALUESCANCHANGEATTRIBUTEVALUESCANT", "original": "**Attributes *initialize* DOM properties and then they are done.\nProperty values can change; attribute values can't.**", "translation": "**attribute *初始化* DOM property,然后它们的任务就完成了。property 的值可以改变;attribute 的值不能改变。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "FOREXAMPLEWHENTHEBROWSERRENDERSINPUTTYPETEXTVALUEBOBITCREATESACORRESPONDINGDOMNODEWITHAVALUEPROPERTYINITIALIZEDTOBOB", "original": "For example, when the browser renders `<input type=\"text\" value=\"Bob\">`, it creates a\ncorresponding DOM node with a `value` property *initialized* to \"Bob\".", "translation": "例如,当浏览器渲染 `<input type=\"text\" value=\"Bob\">` 时,它将创建相应 DOM 节点,\n它的 `value` 这个 property 被*初始化为* “Bob”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENTHEUSERENTERSSALLYINTOTHEINPUTBOXTHEDOMELEMENTVALUEPROPERTYBECOMESSALLYBUTTHEHTMLVALUEATTRIBUTEREMAINSUNCHANGEDASYOUDISCOVERIFYOUASKTHEINPUTELEMENTABOUTTHATATTRIBUTE:INPUTGETATTRIBUTEVALUERETURNSBOB", "original": "When the user enters \"Sally\" into the input box, the DOM element `value` *property* becomes \"Sally\".\nBut the HTML `value` *attribute* remains unchanged as you discover if you ask the input element\nabout that attribute: `input.getAttribute('value')` returns \"Bob\".", "translation": "当用户在输入框中输入 “Sally” 时,DOM 元素的 `value` 这个 *property* 变成了 “Sally”。\n但是该 HTML 的 `value` 这个 *attribute* 保持不变。如果你读取 input 元素的 attribute,就会发现确实没变:\n`input.getAttribute('value') // 返回 \"Bob\"`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEHTMLATTRIBUTEVALUESPECIFIESTHEINITIALVALUETHEDOMVALUEPROPERTYISTHECURRENTVALUE", "original": "The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.", "translation": "HTML 的 `value` 这个 attribute 指定了*初始*值;DOM 的 `value` 这个 property 是*当前*值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEDISABLEDATTRIBUTEISANOTHERPECULIAREXAMPLEABUTTONSDISABLEDPROPERTYISFALSEBYDEFAULTSOTHEBUTTONISENABLEDWHENYOUADDTHEDISABLEDATTRIBUTEITSPRESENCEALONEINITIALIZESTHEBUTTONSDISABLEDPROPERTYTOTRUESOTHEBUTTONISDISABLED", "original": "The `disabled` attribute is another peculiar example. A button's `disabled` *property* is\n`false` by default so the button is enabled.\nWhen you add the `disabled` *attribute*, its presence alone initializes the button's `disabled` *property* to `true`\nso the button is disabled.", "translation": "`disabled` 这个 attribute 是另一种特例。按钮的 `disabled` 这个 *property* 是 `false`,因为默认情况下按钮是可用的。\n当你添加 `disabled` 这个 *attribute* 时,只要它出现了按钮的 `disabled` 这个 *property* 就初始化为 `true`,于是按钮就被禁用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ADDINGANDREMOVINGTHEDISABLEDATTRIBUTEDISABLESANDENABLESTHEBUTTONTHEVALUEOFTHEATTRIBUTEISIRRELEVANTWHICHISWHYYOUCANNOTENABLEABUTTONBYWRITINGBUTTONDISABLEDFALSESTILLDISABLEDBUTTON", "original": "Adding and removing the `disabled` *attribute* disables and enables the button. The value of the *attribute* is irrelevant,\nwhich is why you cannot enable a button by writing `<button disabled=\"false\">Still Disabled</button>`.", "translation": "添加或删除 `disabled` 这个 *attribute* 会禁用或启用这个按钮。但 *attribute* 的值无关紧要,这就是你为什么没法通过\n`<button disabled=\"false\">仍被禁用</button>` 这种写法来启用按钮。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SETTINGTHEBUTTONSDISABLEDPROPERTYSAYWITHANANGULARBINDINGDISABLESORENABLESTHEBUTTONTHEVALUEOFTHEPROPERTYMATTERS", "original": "Setting the button's `disabled` *property* (say, with an Angular binding) disables or enables the button.\nThe value of the *property* matters.", "translation": "设置按钮的 `disabled` 这个 *property*(如,通过 Angular 绑定)可以禁用或启用这个按钮。\n这就是 *property* 的价值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEHTMLATTRIBUTEANDTHEDOMPROPERTYARENOTTHESAMETHINGEVENWHENTHEYHAVETHESAMENAME", "original": "**The HTML attribute and the DOM property are not the same thing, even when they have the same name.**", "translation": "**就算名字相同,HTML attribute 和 DOM property 也不是同一样东西。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISFACTBEARSREPEATING:TEMPLATEBINDINGWORKSWITHPROPERTIESANDEVENTSNOTATTRIBUTES", "original": "This fact bears repeating:\n**Template binding works with *properties* and *events*, not *attributes*.**", "translation": "这句话值得再强调一次:\n**模板绑定是通过 *property* 和*事件*来工作的,而不是 *attribute*。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HEADERAWORLDWITHOUTATTRIBUTESHEADER", "original": "<header>A world without attributes</header>", "translation": "<header>没有 attribute 的世界</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTHEWORLDOFANGULARTHEONLYROLEOFATTRIBUTESISTOINITIALIZEELEMENTANDDIRECTIVESTATEWHENYOUWRITEADATABINDINGYOUREDEALINGEXCLUSIVELYWITHPROPERTIESANDEVENTSOFTHETARGETOBJECTHTMLATTRIBUTESEFFECTIVELYDISAPPEAR", "original": "In the world of Angular, the only role of attributes is to initialize element and directive state.\nWhen you write a data binding, you're dealing exclusively with properties and events of the target object.\nHTML attributes effectively disappear.", "translation": "在 Angular 的世界中,attribute 唯一的作用是用来初始化元素和指令的状态。\n当进行数据绑定时,只是在与元素和指令的 property 和事件打交道,而 attribute 就完全靠边站了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WITHTHISMODELFIRMLYINMINDREADONTOLEARNABOUTBINDINGTARGETS", "original": "With this model firmly in mind, read on to learn about binding targets.", "translation": "把这个思维模型牢牢的印在脑子里,接下来,学习什么是绑定目标。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###BINDINGTARGETS", "original": "### Binding targets", "translation": "### 绑定目标", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETARGETOFADATABINDINGISSOMETHINGINTHEDOMDEPENDINGONTHEBINDINGTYPETHETARGETCANBEANELEMENTCOMPONENTDIRECTIVEPROPERTYANELEMENTCOMPONENTDIRECTIVEEVENTORRARELYANATTRIBUTENAMETHEFOLLOWINGTABLESUMMARIZES:", "original": "The **target of a data binding** is something in the DOM.\nDepending on the binding type, the target can be an\n(element | component | directive) property, an\n(element | component | directive) event, or (rarely) an attribute name.\nThe following table summarizes:", "translation": "**数据绑定的目标**是 DOM 中的某些东西。\n这个目标可能是(元素 | 组件 | 指令的)property、(元素 | 组件 | 指令的)事件,或(极少数情况下) attribute 名。\n下面是的汇总表:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TYPE", "original": "Type", "translation": "绑定类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TARGET", "original": "Target", "translation": "目标", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "EXAMPLES", "original": "Examples", "translation": "范例", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "PROPERTY", "original": "Property", "translation": "属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ELEMENTNBSPPROPERTYBRCOMPONENTNBSPPROPERTYBRDIRECTIVENBSPPROPERTY", "original": "Element property<br>\n Component property<br>\n Directive property", "translation": "元素的 property<br>\n 组件的 property<br>\n 指令的 property", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "EVENT", "original": "Event", "translation": "事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ELEMENTNBSPEVENTBRCOMPONENTNBSPEVENTBRDIRECTIVENBSPEVENT", "original": "Element event<br>\n Component event<br>\n Directive event", "translation": "元素的事件<br>\n 组件的事件<br>\n 指令的事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TWOWAY", "original": "Two-way", "translation": "双向", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "EVENTANDPROPERTY", "original": "Event and property", "translation": "事件与 property", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATTRIBUTETHENBSPEXCEPTION", "original": "Attribute\n (the exception)", "translation": "attribute(例外情况)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CLASS", "original": "Class", "translation": "CSS 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "STYLE", "original": "Style", "translation": "样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WITHTHISBROADVIEWINMINDYOUREREADYTOLOOKATBINDINGTYPESINDETAIL", "original": "With this broad view in mind, you're ready to look at binding types in detail.", "translation": "放开眼界,来看看每种绑定类型的具体情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##PROPERTYBINDINGSPANCLASSSYNTAXPROPERTYSPAN", "original": "## Property binding ( <span class=\"syntax\">[property]</span> )", "translation": "## 属性绑定 ( <span class=\"syntax\">[属性名]</span> )", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WRITEATEMPLATEPROPERTYBINDINGTOSETAPROPERTYOFAVIEWELEMENTTHEBINDINGSETSTHEPROPERTYTOTHEVALUEOFATEMPLATEEXPRESSIONGUIDETEMPLATESYNTAX#TEMPLATEEXPRESSIONS", "original": "Write a template **property binding** to set a property of a view element.\nThe binding sets the property to the value of a [template expression](guide/template-syntax#template-expressions).", "translation": "当要把视图元素的属性 (property) 设置为[模板表达式](guide/template-syntax#template-expressions)时,就要写模板的**属性 (property) 绑定**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEMOSTCOMMONPROPERTYBINDINGSETSANELEMENTPROPERTYTOACOMPONENTPROPERTYVALUEANEXAMPLEISBINDINGTHESRCPROPERTYOFANIMAGEELEMENTTOACOMPONENTSHEROIMAGEURLPROPERTY:", "original": "The most common property binding sets an element property to a component property value. An example is\nbinding the `src` property of an image element to a component's `heroImageUrl` property:", "translation": "最常用的属性绑定是把元素属性设置为组件属性的值。\n下面这个例子中,image 元素的 `src` 属性会被绑定到组件的 `heroImageUrl` 属性上:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANOTHEREXAMPLEISDISABLINGABUTTONWHENTHECOMPONENTSAYSTHATITISUNCHANGED:", "original": "Another example is disabling a button when the component says that it `isUnchanged`:", "translation": "另一个例子是当组件说它 `isUnchanged`(未改变)时禁用按钮:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANOTHERISSETTINGAPROPERTYOFADIRECTIVE:", "original": "Another is setting a property of a directive:", "translation": "另一个例子是设置指令的属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YETANOTHERISSETTINGTHEMODELPROPERTYOFACUSTOMCOMPONENTAGREATWAYFORPARENTANDCHILDCOMPONENTSTOCOMMUNICATE:", "original": "Yet another is setting the model property of a custom component (a great way\nfor parent and child components to communicate):", "translation": "还有另一个例子是设置自定义组件的模型属性(这是父子组件之间通讯的重要途径):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###ONEWAYIN", "original": "### One-way *in*", "translation": "### 单向*输入*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "PEOPLEOFTENDESCRIBEPROPERTYBINDINGASONEWAYDATABINDINGBECAUSEITFLOWSAVALUEINONEDIRECTIONFROMACOMPONENTSDATAPROPERTYINTOATARGETELEMENTPROPERTY", "original": "People often describe property binding as *one-way data binding* because it flows a value in one direction,\nfrom a component's data property into a target element property.", "translation": "人们经常把属性绑定描述成*单向数据绑定*,因为值的流动是单向的,从组件的数据属性流动到目标元素的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANNOTUSEPROPERTYBINDINGTOPULLVALUESOUTOFTHETARGETELEMENTYOUCANTBINDTOAPROPERTYOFTHETARGETELEMENTTOREADITYOUCANONLYSETIT", "original": "You cannot use property binding to pull values *out* of the target element.\nYou can't bind to a property of the target element to _read_ it. You can only _set_ it.", "translation": "不能使用属性绑定来从目标元素拉取值,也不能绑定到目标元素的属性来读取它。只能设置它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SIMILARLYYOUCANNOTUSEPROPERTYBINDINGTOCALLAMETHODONTHETARGETELEMENT", "original": "Similarly, you cannot use property binding to *call* a method on the target element.", "translation": "也不能使用属性 绑定 来*调用*目标元素上的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "IFTHEELEMENTRAISESEVENTSYOUCANLISTENTOTHEMWITHANEVENTBINDINGGUIDETEMPLATESYNTAX#EVENTBINDING", "original": "If the element raises events, you can listen to them with an [event binding](guide/template-syntax#event-binding).", "translation": "如果这个元素触发了事件,可以通过[事件绑定](guide/template-syntax#event-binding)来监听它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "IFYOUMUSTREADATARGETELEMENTPROPERTYORCALLONEOFITSMETHODSYOULLNEEDADIFFERENTTECHNIQUESEETHEAPIREFERENCEFORVIEWCHILDAPICOREVIEWCHILDANDCONTENTCHILDAPICORECONTENTCHILD", "original": "If you must read a target element property or call one of its methods,\nyou'll need a different technique.\nSee the API reference for\n[ViewChild](api/core/ViewChild) and\n[ContentChild](api/core/ContentChild).", "translation": "如果必须读取目标元素上的属性或调用它的某个方法,得用另一种技术。\n参见 API 参考手册中的\n[ViewChild](api/core/ViewChild) 和\n[ContentChild](api/core/ContentChild)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###BINDINGTARGET", "original": "### Binding target", "translation": "### 绑定目标", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANELEMENTPROPERTYBETWEENENCLOSINGSQUAREBRACKETSIDENTIFIESTHETARGETPROPERTYTHETARGETPROPERTYINTHEFOLLOWINGCODEISTHEIMAGEELEMENTSSRCPROPERTY", "original": "An element property between enclosing square brackets identifies the target property.\nThe target property in the following code is the image element's `src` property.", "translation": "包裹在方括号中的元素属性名标记着目标属性。下列代码中的目标属性是 image 元素的 `src` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SOMEPEOPLEPREFERTHEBINDPREFIXALTERNATIVEKNOWNASTHECANONICALFORM:", "original": "Some people prefer the `bind-` prefix alternative, known as the *canonical form*:", "translation": "有些人喜欢用 `bind-` 前缀的可选形式,并称之为*规范形式*:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETARGETNAMEISALWAYSTHENAMEOFAPROPERTYEVENWHENITAPPEARSTOBETHENAMEOFSOMETHINGELSEYOUSEESRCANDMAYTHINKITSTHENAMEOFANATTRIBUTENOITSTHENAMEOFANIMAGEELEMENTPROPERTY", "original": "The target name is always the name of a property, even when it appears to be the name of something else.\nYou see `src` and may think it's the name of an attribute. No. It's the name of an image element property.", "translation": "目标的名字总是 property 的名字。即使它看起来和别的名字一样。\n看到 `src` 时,可能会把它当做 attribute。不!它不是!它是 image 元素的 property 名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ELEMENTPROPERTIESMAYBETHEMORECOMMONTARGETSBUTANGULARLOOKSFIRSTTOSEEIFTHENAMEISAPROPERTYOFAKNOWNDIRECTIVEASITISINTHEFOLLOWINGEXAMPLE:", "original": "Element properties may be the more common targets,\nbut Angular looks first to see if the name is a property of a known directive,\nas it is in the following example:", "translation": "元素属性可能是最常见的绑定目标,但 Angular 会先去看这个名字是否是某个已知指令的属性名,就像下面的例子中一样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TECHNICALLYANGULARISMATCHINGTHENAMETOADIRECTIVEINPUTGUIDETEMPLATESYNTAX#INPUTSOUTPUTSONEOFTHEPROPERTYNAMESLISTEDINTHEDIRECTIVESINPUTSARRAYORAPROPERTYDECORATEDWITHINPUTSUCHINPUTSMAPTOTHEDIRECTIVESOWNPROPERTIES", "original": "Technically, Angular is matching the name to a directive [input](guide/template-syntax#inputs-outputs),\none of the property names listed in the directive's `inputs` array or a property decorated with `@Input()`.\nSuch inputs map to the directive's own properties.", "translation": "严格来说,Angular 正在匹配指令的[输入属性](guide/template-syntax#inputs-outputs)的名字。\n这个名字是指令的 `inputs` 数组中所列的名字,或者是带有 `@Input()` 装饰器的属性。\n这些输入属性被映射为指令自己的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "IFTHENAMEFAILSTOMATCHAPROPERTYOFAKNOWNDIRECTIVEORELEMENTANGULARREPORTSANUNKNOWNDIRECTIVEERROR", "original": "If the name fails to match a property of a known directive or element, Angular reports an “unknown directive” error.", "translation": "如果名字没有匹配上已知指令或元素的属性,Angular 就会报告“未知指令”的错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###AVOIDSIDEEFFECTS", "original": "### Avoid side effects", "translation": "### 消除副作用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ASMENTIONEDPREVIOUSLYEVALUATIONOFATEMPLATEEXPRESSIONSHOULDHAVENOVISIBLESIDEEFFECTSTHEEXPRESSIONLANGUAGEITSELFDOESITSPARTTOKEEPYOUSAFEYOUCANTASSIGNAVALUETOANYTHINGINAPROPERTYBINDINGEXPRESSIONNORUSETHEINCREMENTANDDECREMENTOPERATORS", "original": "As mentioned previously, evaluation of a template expression should have no visible side effects.\nThe expression language itself does its part to keep you safe.\nYou can't assign a value to anything in a property binding expression nor use the increment and decrement operators.", "translation": "正如以前讨论过的,模板表达式的计算不能有可见的副作用。表达式语言本身可以提供一部分安全保障。\n 不能在属性绑定表达式中对任何东西赋值,也不能使用自增、自减运算符。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "OFCOURSETHEEXPRESSIONMIGHTINVOKEAPROPERTYORMETHODTHATHASSIDEEFFECTSANGULARHASNOWAYOFKNOWINGTHATORSTOPPINGYOU", "original": "Of course, the expression might invoke a property or method that has side effects.\nAngular has no way of knowing that or stopping you.", "translation": "当然,表达式可能会调用具有副作用的属性或方法。但 Angular 没法知道这一点,也没法阻止你。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEEXPRESSIONCOULDCALLSOMETHINGLIKEGETFOOONLYYOUKNOWWHATGETFOODOESIFGETFOOCHANGESSOMETHINGANDYOUHAPPENTOBEBINDINGTOTHATSOMETHINGYOURISKANUNPLEASANTEXPERIENCEANGULARMAYORMAYNOTDISPLAYTHECHANGEDVALUEANGULARMAYDETECTTHECHANGEANDTHROWAWARNINGERRORINGENERALSTICKTODATAPROPERTIESANDTOMETHODSTHATRETURNVALUESANDDONOMORE", "original": "The expression could call something like `getFoo()`. Only you know what `getFoo()` does.\nIf `getFoo()` changes something and you happen to be binding to that something, you risk an unpleasant experience.\nAngular may or may not display the changed value. Angular may detect the change and throw a warning error.\nIn general, stick to data properties and to methods that return values and do no more.", "translation": "表达式中可以调用像 `getFoo()` 这样的方法。只有你知道 `getFoo()` 干了什么。\n如果 `getFoo()` 改变了某个东西,恰好又绑定到个这个东西,你就可能把自己坑了。\nAngular 可能显示也可能不显示变化后的值。Angular 还可能检测到变化,并抛出警告型错误。\n一般建议是,只绑定数据属性和那些只返回值而不做其它事情的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###RETURNTHEPROPERTYPE", "original": "### Return the proper type", "translation": "### 返回恰当的类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETEMPLATEEXPRESSIONSHOULDEVALUATETOTHETYPEOFVALUEEXPECTEDBYTHETARGETPROPERTYRETURNASTRINGIFTHETARGETPROPERTYEXPECTSASTRINGRETURNANUMBERIFTHETARGETPROPERTYEXPECTSANUMBERRETURNANOBJECTIFTHETARGETPROPERTYEXPECTSANOBJECT", "original": "The template expression should evaluate to the type of value expected by the target property.\nReturn a string if the target property expects a string.\nReturn a number if the target property expects a number.\nReturn an object if the target property expects an object.", "translation": "模板表达式应该返回目标属性所需类型的值。\n如果目标属性想要个字符串,就返回字符串。\n如果目标属性想要个数字,就返回数字。\n如果目标属性想要个对象,就返回对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEHEROPROPERTYOFTHEHERODETAILCOMPONENTEXPECTSAHEROOBJECTWHICHISEXACTLYWHATYOURESENDINGINTHEPROPERTYBINDING:", "original": "The `hero` property of the `HeroDetail` component expects a `Hero` object, which is exactly what you're sending in the property binding:", "translation": "`HeroDetail` 组件的 `hero` 属性想要一个 `Hero` 对象,那就在属性绑定中精确地给它一个 `Hero` 对象:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###REMEMBERTHEBRACKETS", "original": "### Remember the brackets", "translation": "### 别忘了方括号", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEBRACKETSTELLANGULARTOEVALUATETHETEMPLATEEXPRESSIONIFYOUOMITTHEBRACKETSANGULARTREATSTHESTRINGASACONSTANTANDINITIALIZESTHETARGETPROPERTYWITHTHATSTRINGITDOESNOTEVALUATETHESTRING", "original": "The brackets tell Angular to evaluate the template expression.\nIf you omit the brackets, Angular treats the string as a constant\nand *initializes the target property* with that string.\nIt does *not* evaluate the string!", "translation": "方括号告诉 Angular 要计算模板表达式。\n如果忘了加方括号,Angular 会把这个表达式当做字符串常量看待,并用该字符串来*初始化目标属性*。\n它*不会*计算这个字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "DONTMAKETHEFOLLOWINGMISTAKE:", "original": "Don't make the following mistake:", "translation": "不要出现这样的失误:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###ONETIMESTRINGINITIALIZATION", "original": "### One-time string initialization", "translation": "### 一次性字符串初始化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUSHOULDOMITTHEBRACKETSWHENALLOFTHEFOLLOWINGARETRUE:", "original": "You *should* omit the brackets when all of the following are true:", "translation": "当满足下列条件时,*应该*省略括号:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETARGETPROPERTYACCEPTSASTRINGVALUE", "original": "* The target property accepts a string value.", "translation": "目标属性接受字符串值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESTRINGISAFIXEDVALUETHATYOUCANBAKEINTOTHETEMPLATE", "original": "* The string is a fixed value that you can bake into the template.", "translation": "字符串是个固定值,可以直接合并到模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISINITIALVALUENEVERCHANGES", "original": "* This initial value never changes.", "translation": "这个初始值永不改变。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUROUTINELYINITIALIZEATTRIBUTESTHISWAYINSTANDARDHTMLANDITWORKSJUSTASWELLFORDIRECTIVEANDCOMPONENTPROPERTYINITIALIZATIONTHEFOLLOWINGEXAMPLEINITIALIZESTHEPREFIXPROPERTYOFTHEHERODETAILCOMPONENTTOAFIXEDSTRINGNOTATEMPLATEEXPRESSIONANGULARSETSITANDFORGETSABOUTIT", "original": "You routinely initialize attributes this way in standard HTML, and it works\njust as well for directive and component property initialization.\nThe following example initializes the `prefix` property of the `HeroDetailComponent` to a fixed string,\nnot a template expression. Angular sets it and forgets about it.", "translation": "你经常这样在标准 HTML 中用这种方式初始化 attribute,这种方式也可以用在初始化指令和组件的属性。\n下面这个例子把 `HeroDetailComponent` 的 `prefix` 属性初始化为固定的字符串,而不是模板表达式。Angular 设置它,然后忘记它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEHEROBINDINGONTHEOTHERHANDREMAINSALIVEBINDINGTOTHECOMPONENTSCURRENTHEROPROPERTY", "original": "The `[hero]` binding, on the other hand, remains a live binding to the component's `currentHero` property.", "translation": "作为对比,`[hero]` 绑定是组件的 `currentHero` 属性的活绑定,它会一直随着更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###PROPERTYBINDINGORINTERPOLATION", "original": "### Property binding or interpolation?", "translation": "### 属性绑定还是插值表达式?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUOFTENHAVEACHOICEBETWEENINTERPOLATIONANDPROPERTYBINDINGTHEFOLLOWINGBINDINGPAIRSDOTHESAMETHING:", "original": "You often have a choice between interpolation and property binding.\nThe following binding pairs do the same thing:", "translation": "你通常得在插值表达式和属性绑定之间做出选择。\n下列这几对绑定做的事情完全相同:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTERPOLATIONISACONVENIENTALTERNATIVETOPROPERTYBINDINGINMANYCASES", "original": "_Interpolation_ is a convenient alternative to _property binding_ in many cases.", "translation": "在多数情况下,插值表达式是更方便的备选项。\n实际上,在渲染视图之前,Angular 把这些插值表达式翻译成相应的属性绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENRENDERINGDATAVALUESASSTRINGSTHEREISNOTECHNICALREASONTOPREFERONEFORMTOTHEOTHERYOULEANTOWARDREADABILITYWHICHTENDSTOFAVORINTERPOLATIONYOUSUGGESTESTABLISHINGCODINGSTYLERULESANDCHOOSINGTHEFORMTHATBOTHCONFORMSTOTHERULESANDFEELSMOSTNATURALFORTHETASKATHAND", "original": "When rendering data values as strings, there is no technical reason to prefer one form to the other.\nYou lean toward readability, which tends to favor interpolation.\nYou suggest establishing coding style rules and choosing the form that\nboth conforms to the rules and feels most natural for the task at hand.", "translation": "当要渲染的数据类型是字符串时,没有技术上的理由证明哪种形式更好。\n你倾向于可读性,所以倾向于插值表达式。\n建议建立代码风格规则,选择一种形式,\n这样,既遵循了规则,又能让手头的任务做起来更自然。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENSETTINGANELEMENTPROPERTYTOANONSTRINGDATAVALUEYOUMUSTUSEPROPERTYBINDING", "original": "When setting an element property to a non-string data value, you must use _property binding_.", "translation": "但数据类型不是字符串时,就必须使用*属性绑定*了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####CONTENTSECURITY", "original": "#### Content security", "translation": "#### 内容安全", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "IMAGINETHEFOLLOWINGMALICIOUSCONTENT", "original": "Imagine the following *malicious content*.", "translation": "假设下面的*恶意内容*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "FORTUNATELYANGULARDATABINDINGISONALERTFORDANGEROUSHTMLITSANITIZESGUIDESECURITY#SANITIZATIONANDSECURITYCONTEXTSTHEVALUESBEFOREDISPLAYINGTHEMITWILLNOTALLOWHTMLWITHSCRIPTTAGSTOLEAKINTOTHEBROWSERNEITHERWITHINTERPOLATIONNORPROPERTYBINDING", "original": "Fortunately, Angular data binding is on alert for dangerous HTML.\nIt [*sanitizes*](guide/security#sanitization-and-security-contexts) the values before displaying them.\nIt **will not** allow HTML with script tags to leak into the browser, neither with interpolation\nnor property binding.", "translation": "幸运的是,Angular 数据绑定对危险 HTML 有防备。\n在显示它们之前,它对内容先进行*消毒*。\n不管是插值表达式还是属性绑定,都**不会**允许带有 script 标签的 HTML 泄漏到浏览器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTERPOLATIONHANDLESTHESCRIPTTAGSDIFFERENTLYTHANPROPERTYBINDINGBUTBOTHAPPROACHESRENDERTHECONTENTHARMLESSLY", "original": "Interpolation handles the script tags differently than property binding but both approaches render the\ncontent harmlessly.", "translation": "插值表达式处理 script 标签与属性绑定有所不同,但是二者都只渲染没有危害的内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##ATTRIBUTECLASSANDSTYLEBINDINGS", "original": "## Attribute, class, and style bindings", "translation": "## attribute、class 和 style 绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETEMPLATESYNTAXPROVIDESSPECIALIZEDONEWAYBINDINGSFORSCENARIOSLESSWELLSUITEDTOPROPERTYBINDING", "original": "The template syntax provides specialized one-way bindings for scenarios less well suited to property binding.", "translation": "模板语法为那些不太适合使用属性绑定的场景提供了专门的单向数据绑定形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###ATTRIBUTEBINDING", "original": "### Attribute binding", "translation": "### attribute 绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANSETTHEVALUEOFANATTRIBUTEDIRECTLYWITHANATTRIBUTEBINDING", "original": "You can set the value of an attribute directly with an **attribute binding**.", "translation": "可以通过**attribute 绑定**来直接设置 attribute 的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISISTHEONLYEXCEPTIONTOTHERULETHATABINDINGSETSATARGETPROPERTYTHISISTHEONLYBINDINGTHATCREATESANDSETSANATTRIBUTE", "original": "This is the only exception to the rule that a binding sets a target property.\nThis is the only binding that creates and sets an attribute.", "translation": "这是“绑定到目标属性 (property)”这条规则中唯一的例外。这是唯一的能创建和设置 attribute 的绑定形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISGUIDESTRESSESREPEATEDLYTHATSETTINGANELEMENTPROPERTYWITHAPROPERTYBINDINGISALWAYSPREFERREDTOSETTINGTHEATTRIBUTEWITHASTRINGWHYDOESANGULAROFFERATTRIBUTEBINDING", "original": "This guide stresses repeatedly that setting an element property with a property binding\nis always preferred to setting the attribute with a string. Why does Angular offer attribute binding?", "translation": "本章中,通篇都在说通过属性绑定来设置元素的属性总是好于用字符串设置 attribute。为什么 Angular 还提供了 attribute 绑定呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUMUSTUSEATTRIBUTEBINDINGWHENTHEREISNOELEMENTPROPERTYTOBIND", "original": "**You must use attribute binding when there is no element property to bind.**", "translation": "**因为当元素没有属性可绑的时候,就必须使用 attribute 绑定。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CONSIDERTHEARIAHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBACCESSIBILITYARIASVGHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBSVGANDTABLESPANATTRIBUTESTHEYAREPUREATTRIBUTESTHEYDONOTCORRESPONDTOELEMENTPROPERTIESANDTHEYDONOTSETELEMENTPROPERTIESTHEREARENOPROPERTYTARGETSTOBINDTO", "original": "Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA),\n[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG), and\ntable span attributes. They are pure attributes.\nThey do not correspond to element properties, and they do not set element properties.\nThere are no property targets to bind to.", "translation": "考虑 [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA),\n [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG) 和 table 中的 colspan/rowspan 等 attribute。\n 它们是纯粹的 attribute,没有对应的属性可供绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISFACTBECOMESPAINFULLYOBVIOUSWHENYOUWRITESOMETHINGLIKETHIS", "original": "This fact becomes painfully obvious when you write something like this.", "translation": "如果想写出类似下面这样的东西,就会暴露出痛点了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANDYOUGETTHISERROR:", "original": "And you get this error:", "translation": "会得到这个错误:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ASTHEMESSAGESAYSTHETDELEMENTDOESNOTHAVEACOLSPANPROPERTYITHASTHECOLSPANATTRIBUTEBUTINTERPOLATIONANDPROPERTYBINDINGCANSETONLYPROPERTIESNOTATTRIBUTES", "original": "As the message says, the `<td>` element does not have a `colspan` property.\nIt has the \"colspan\" *attribute*, but\ninterpolation and property binding can set only *properties*, not attributes.", "translation": "正如提示中所说,`<td>` 元素没有 `colspan` 属性。\n 但是插值表达式和属性绑定只能设置*属性*,不能设置 attribute。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUNEEDATTRIBUTEBINDINGSTOCREATEANDBINDTOSUCHATTRIBUTES", "original": "You need attribute bindings to create and bind to such attributes.", "translation": "你需要 attribute 绑定来创建和绑定到这样的 attribute。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATTRIBUTEBINDINGSYNTAXRESEMBLESPROPERTYBINDINGINSTEADOFANELEMENTPROPERTYBETWEENBRACKETSSTARTWITHTHEPREFIXATTRFOLLOWEDBYADOTANDTHENAMEOFTHEATTRIBUTEYOUTHENSETTHEATTRIBUTEVALUEUSINGANEXPRESSIONTHATRESOLVESTOASTRING", "original": "Attribute binding syntax resembles property binding.\nInstead of an element property between brackets, start with the prefix **`attr`**,\nfollowed by a dot (`.`) and the name of the attribute.\nYou then set the attribute value, using an expression that resolves to a string.", "translation": "attribute 绑定的语法与属性绑定类似。\n 但方括号中的部分不是元素的属性名,而是由**`attr`**前缀,一个点 (`.`) 和 attribute 的名字组成。\n 可以通过值为字符串的表达式来设置 attribute 的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BINDATTRCOLSPANTOACALCULATEDVALUE:", "original": "Bind `[attr.colspan]` to a calculated value:", "translation": "这里把 `[attr.colspan]` 绑定到一个计算值:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HERESHOWTHETABLERENDERS:", "original": "Here's how the table renders:", "translation": "这里是表格渲染出来的样子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ONEOFTHEPRIMARYUSECASESFORATTRIBUTEBINDINGISTOSETARIAATTRIBUTESASINTHISEXAMPLE:", "original": "One of the primary use cases for attribute binding\nis to set ARIA attributes, as in this example:", "translation": "attribute 绑定的主要用例之一是设置 ARIA attribute(译注:ARIA 指可访问性,用于给残障人士访问互联网提供便利),\n就像这个例子中一样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###CLASSBINDING", "original": "### Class binding", "translation": "### CSS 类绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANADDANDREMOVECSSCLASSNAMESFROMANELEMENTSCLASSATTRIBUTEWITHACLASSBINDING", "original": "You can add and remove CSS class names from an element's `class` attribute with\na **class binding**.", "translation": "借助 **CSS 类绑定**,可以从元素的 `class` attribute 上添加和移除 CSS 类名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CLASSBINDINGSYNTAXRESEMBLESPROPERTYBINDINGINSTEADOFANELEMENTPROPERTYBETWEENBRACKETSSTARTWITHTHEPREFIXCLASSOPTIONALLYFOLLOWEDBYADOTANDTHENAMEOFACSSCLASS:CLASSCLASSNAME", "original": "Class binding syntax resembles property binding.\nInstead of an element property between brackets, start with the prefix `class`,\noptionally followed by a dot (`.`) and the name of a CSS class: `[class.class-name]`.", "translation": "CSS 类绑定绑定的语法与属性绑定类似。\n但方括号中的部分不是元素的属性名,而是由**`class`**前缀,一个点 (`.`)和 CSS 类的名字组成,\n其中后两部分是可选的。形如:`[class.class-name]`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEFOLLOWINGEXAMPLESSHOWHOWTOADDANDREMOVETHEAPPLICATIONSSPECIALCLASSWITHCLASSBINDINGSHERESHOWTOSETTHEATTRIBUTEWITHOUTBINDING:", "original": "The following examples show how to add and remove the application's \"special\" class\nwith class bindings. Here's how to set the attribute without binding:", "translation": "下列例子示范了如何通过 CSS 类绑定来添加和移除应用的 \"special\" 类。不用绑定直接设置 attribute 时是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANREPLACETHATWITHABINDINGTOASTRINGOFTHEDESIREDCLASSNAMESTHISISANALLORNOTHINGREPLACEMENTBINDING", "original": "You can replace that with a binding to a string of the desired class names; this is an all-or-nothing, replacement binding.", "translation": "可以把它改写为绑定到所需 CSS 类名的绑定;这是一个或者全有或者全无的替换型绑定。\n(译注:即当 badCurly 有值时 class 这个 attribute 设置的内容会被完全覆盖)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "FINALLYYOUCANBINDTOASPECIFICCLASSNAMEANGULARADDSTHECLASSWHENTHETEMPLATEEXPRESSIONEVALUATESTOTRUTHYITREMOVESTHECLASSWHENTHEEXPRESSIONISFALSY", "original": "Finally, you can bind to a specific class name.\nAngular adds the class when the template expression evaluates to truthy.\nIt removes the class when the expression is falsy.", "translation": "最后,可以绑定到特定的类名。\n 当模板表达式的求值结果是真值时,Angular 会添加这个类,反之则移除它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHILETHISISAFINEWAYTOTOGGLEASINGLECLASSNAMETHENGCLASSDIRECTIVEGUIDETEMPLATESYNTAX#NGCLASSISUSUALLYPREFERREDWHENMANAGINGMULTIPLECLASSNAMESATTHESAMETIME", "original": "While this is a fine way to toggle a single class name,\nthe [NgClass directive](guide/template-syntax#ngClass) is usually preferred when managing multiple class names at the same time.", "translation": "虽然这是切换单一类名的好办法,但人们通常更喜欢使用 [NgClass 指令](guide/template-syntax#ngClass) 来同时管理多个类名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###STYLEBINDING", "original": "### Style binding", "translation": "### 样式绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANSETINLINESTYLESWITHASTYLEBINDING", "original": "You can set inline styles with a **style binding**.", "translation": "通过**样式绑定**,可以设置内联样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "STYLEBINDINGSYNTAXRESEMBLESPROPERTYBINDINGINSTEADOFANELEMENTPROPERTYBETWEENBRACKETSSTARTWITHTHEPREFIXSTYLEFOLLOWEDBYADOTANDTHENAMEOFACSSSTYLEPROPERTY:STYLESTYLEPROPERTY", "original": "Style binding syntax resembles property binding.\nInstead of an element property between brackets, start with the prefix `style`,\nfollowed by a dot (`.`) and the name of a CSS style property: `[style.style-property]`.", "translation": "样式绑定的语法与属性绑定类似。\n但方括号中的部分不是元素的属性名,而由**`style`**前缀,一个点 (`.`)和 CSS 样式的属性名组成。\n形如:`[style.style-property]`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SOMESTYLEBINDINGSTYLESHAVEAUNITEXTENSIONTHEFOLLOWINGEXAMPLECONDITIONALLYSETSTHEFONTSIZEINEMANDUNITS", "original": "Some style binding styles have a unit extension.\nThe following example conditionally sets the font size in “em” and “%” units .", "translation": "有些样式绑定中的样式带有单位。在这里,以根据条件用 “em” 和 “%” 来设置字体大小的单位。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHILETHISISAFINEWAYTOSETASINGLESTYLETHENGSTYLEDIRECTIVEGUIDETEMPLATESYNTAX#NGSTYLEISGENERALLYPREFERREDWHENSETTINGSEVERALINLINESTYLESATTHESAMETIME", "original": "While this is a fine way to set a single style,\nthe [NgStyle directive](guide/template-syntax#ngStyle) is generally preferred when setting several inline styles at the same time.", "translation": "虽然这是设置单一样式的好办法,但人们通常更喜欢使用 [NgStyle 指令](guide/template-syntax#ngStyle) 来同时设置多个内联样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NOTETHATASTYLEPROPERTYNAMECANBEWRITTENINEITHERDASHCASEGUIDEGLOSSARY#DASHCASEASSHOWNABOVEORCAMELCASEGUIDEGLOSSARY#CAMELCASESUCHASFONTSIZE", "original": "Note that a _style property_ name can be written in either\n[dash-case](guide/glossary#dash-case), as shown above, or\n[camelCase](guide/glossary#camelcase), such as `fontSize`.", "translation": "注意,*样式属性*命名方法可以用[中线命名法](guide/glossary#dash-case),像上面的一样\n 也可以用[驼峰式命名法](guide/glossary#camelcase),如 `fontSize`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##EVENTBINDINGSPANCLASSSYNTAXEVENTSPAN", "original": "## Event binding ( <span class=\"syntax\">(event)</span> )", "translation": "## 事件绑定 ( <span class=\"syntax\">(事件名)</span> )", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEBINDINGSDIRECTIVESYOUVEMETSOFARFLOWDATAINONEDIRECTION:FROMACOMPONENTTOANELEMENT", "original": "The bindings directives you've met so far flow data in one direction: **from a component to an element**.", "translation": "前面遇到的绑定的数据流都是单向的:**从组件到元素**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "USERSDONTJUSTSTAREATTHESCREENTHEYENTERTEXTINTOINPUTBOXESTHEYPICKITEMSFROMLISTSTHEYCLICKBUTTONSSUCHUSERACTIONSMAYRESULTINAFLOWOFDATAINTHEOPPOSITEDIRECTION:FROMANELEMENTTOACOMPONENT", "original": "Users don't just stare at the screen. They enter text into input boxes. They pick items from lists.\nThey click buttons. Such user actions may result in a flow of data in the opposite direction:\n**from an element to a component**.", "translation": "但用户不会只盯着屏幕看。他们会在输入框中输入文本。他们会从列表中选取条目。\n他们会点击按钮。这类用户动作可能导致反向的数据流:*从元素到组件*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEONLYWAYTOKNOWABOUTAUSERACTIONISTOLISTENFORCERTAINEVENTSSUCHASKEYSTROKESMOUSEMOVEMENTSCLICKSANDTOUCHESYOUDECLAREYOURINTERESTINUSERACTIONSTHROUGHANGULAREVENTBINDING", "original": "The only way to know about a user action is to listen for certain events such as\nkeystrokes, mouse movements, clicks, and touches.\nYou declare your interest in user actions through Angular event binding.", "translation": "知道用户动作的唯一方式是监听某些事件,如按键、鼠标移动、点击和触摸屏幕。\n可以通过 Angular 事件绑定来声明对哪些用户动作感兴趣。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "EVENTBINDINGSYNTAXCONSISTSOFATARGETEVENTNAMEWITHINPARENTHESESONTHELEFTOFANEQUALSIGNANDAQUOTEDTEMPLATESTATEMENTGUIDETEMPLATESYNTAX#TEMPLATESTATEMENTSONTHERIGHTTHEFOLLOWINGEVENTBINDINGLISTENSFORTHEBUTTONSCLICKEVENTSCALLINGTHECOMPONENTSONSAVEMETHODWHENEVERACLICKOCCURS:", "original": "Event binding syntax consists of a **target event** name\nwithin parentheses on the left of an equal sign, and a quoted\n[template statement](guide/template-syntax#template-statements) on the right.\nThe following event binding listens for the button's click events, calling\nthe component's `onSave()` method whenever a click occurs:", "translation": "事件绑定语法由等号左侧带圆括号的**目标事件**和右侧引号中的[模板语句](guide/template-syntax#template-statements)组成。\n下面事件绑定监听按钮的点击事件。每当点击发生时,都会调用组件的 `onSave()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###TARGETEVENT", "original": "### Target event", "translation": "### 目标事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANAMEBETWEENPARENTHESESMDASHFOREXAMPLECLICKMDASHIDENTIFIESTHETARGETEVENTINTHEFOLLOWINGEXAMPLETHETARGETISTHEBUTTONSCLICKEVENT", "original": "A **name between parentheses** — for example, `(click)` —\nidentifies the target event. In the following example, the target is the button's click event.", "translation": "**圆括号中的名称** —— 比如 `(click)` —— 标记出目标事件。在下面例子中,目标是按钮的 click 事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SOMEPEOPLEPREFERTHEONPREFIXALTERNATIVEKNOWNASTHECANONICALFORM:", "original": "Some people prefer the `on-` prefix alternative, known as the **canonical form**:", "translation": "有些人更喜欢带 `on-` 前缀的备选形式,称之为**规范形式**:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ELEMENTEVENTSMAYBETHEMORECOMMONTARGETSBUTANGULARLOOKSFIRSTTOSEEIFTHENAMEMATCHESANEVENTPROPERTYOFAKNOWNDIRECTIVEASITDOESINTHEFOLLOWINGEXAMPLE:", "original": "Element events may be the more common targets, but Angular looks first to see if the name matches an event property\nof a known directive, as it does in the following example:", "translation": "元素事件可能是更常见的目标,但 Angular 会先看这个名字是否能匹配上已知指令的事件属性,就像下面这个例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEMYCLICKDIRECTIVEISFURTHERDESCRIBEDINTHESECTIONONALIASINGINPUTOUTPUTPROPERTIESGUIDETEMPLATESYNTAX#ALIASINGIO", "original": "The `myClick` directive is further described in the section\non [aliasing input/output properties](guide/template-syntax#aliasing-io).", "translation": "更多关于该 `myClick` 指令的解释,见[给输入/输出属性起别名](guide/template-syntax#aliasing-io)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "IFTHENAMEFAILSTOMATCHANELEMENTEVENTORANOUTPUTPROPERTYOFAKNOWNDIRECTIVEANGULARREPORTSANUNKNOWNDIRECTIVEERROR", "original": "If the name fails to match an element event or an output property of a known directive,\nAngular reports an “unknown directive” error.", "translation": "如果这个名字没能匹配到元素事件或已知指令的输出属性,Angular 就会报“未知指令”错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###EVENTANDEVENTHANDLINGSTATEMENTS", "original": "### *$event* and event handling statements", "translation": "### *$event* 和事件处理语句", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INANEVENTBINDINGANGULARSETSUPANEVENTHANDLERFORTHETARGETEVENT", "original": "In an event binding, Angular sets up an event handler for the target event.", "translation": "在事件绑定中,Angular 会为目标事件设置事件处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENTHEEVENTISRAISEDTHEHANDLEREXECUTESTHETEMPLATESTATEMENTTHETEMPLATESTATEMENTTYPICALLYINVOLVESARECEIVERWHICHPERFORMSANACTIONINRESPONSETOTHEEVENTSUCHASSTORINGAVALUEFROMTHEHTMLCONTROLINTOAMODEL", "original": "When the event is raised, the handler executes the template statement.\nThe template statement typically involves a receiver, which performs an action\nin response to the event, such as storing a value from the HTML control\ninto a model.", "translation": "当事件发生时,这个处理器会执行模板语句。\n典型的模板语句通常涉及到响应事件执行动作的接收器,例如从 HTML 控件中取得值,并存入模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEBINDINGCONVEYSINFORMATIONABOUTTHEEVENTINCLUDINGDATAVALUESTHROUGHANEVENTOBJECTNAMEDEVENT", "original": "The binding conveys information about the event, including data values, through\nan **event object named `$event`**.", "translation": "绑定会通过**名叫 `$event` 的事件对象**传递关于此事件的信息(包括数据值)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESHAPEOFTHEEVENTOBJECTISDETERMINEDBYTHETARGETEVENTIFTHETARGETEVENTISANATIVEDOMELEMENTEVENTTHENEVENTISADOMEVENTOBJECTHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBEVENTSWITHPROPERTIESSUCHASTARGETANDTARGETVALUE", "original": "The shape of the event object is determined by the target event.\nIf the target event is a native DOM element event, then `$event` is a\n[DOM event object](https://developer.mozilla.org/en-US/docs/Web/Events),\nwith properties such as `target` and `target.value`.", "translation": "事件对象的形态取决于目标事件。如果目标事件是原生 DOM 元素事件,\n`$event` 就是 [DOM 事件对象](https://developer.mozilla.org/en-US/docs/Web/Events),它有像 `target` 和 `target.value` 这样的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CONSIDERTHISEXAMPLE:", "original": "Consider this example:", "translation": "考虑这个范例:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISCODESETSTHEINPUTBOXVALUEPROPERTYBYBINDINGTOTHENAMEPROPERTYTOLISTENFORCHANGESTOTHEVALUETHECODEBINDSTOTHEINPUTBOXSINPUTEVENTWHENTHEUSERMAKESCHANGESTHEINPUTEVENTISRAISEDANDTHEBINDINGEXECUTESTHESTATEMENTWITHINACONTEXTTHATINCLUDESTHEDOMEVENTOBJECTEVENT", "original": "This code sets the input box `value` property by binding to the `name` property.\nTo listen for changes to the value, the code binds to the input box's `input` event.\nWhen the user makes changes, the `input` event is raised, and the binding executes\nthe statement within a context that includes the DOM event object, `$event`.", "translation": "上面的代码在把输入框的 `value` 属性绑定到 `firstName` 属性。\n要监听对值的修改,代码绑定到输入框的 `input` 事件。\n当用户造成更改时,`input` 事件被触发,并在包含了 DOM 事件对象 (`$event`) 的上下文中执行这条语句。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TOUPDATETHENAMEPROPERTYTHECHANGEDTEXTISRETRIEVEDBYFOLLOWINGTHEPATHEVENTTARGETVALUE", "original": "To update the `name` property, the changed text is retrieved by following the path `$event.target.value`.", "translation": "要更新 `firstName` 属性,就要通过路径 `$event.target.value` 来获取更改后的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "IFTHEEVENTBELONGSTOADIRECTIVERECALLTHATCOMPONENTSAREDIRECTIVESEVENTHASWHATEVERSHAPETHEDIRECTIVEDECIDESTOPRODUCE", "original": "If the event belongs to a directive (recall that components are directives),\n`$event` has whatever shape the directive decides to produce.", "translation": "如果事件属于指令(回想一下,组件是指令的一种),那么 `$event` 具体是什么由指令决定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###CUSTOMEVENTSWITHSPANCLASSSYNTAXEVENTEMITTERSPAN", "original": "### Custom events with <span class=\"syntax\">EventEmitter</span>", "translation": "### 使用 <span class=\"syntax\">EventEmitter</span> 实现自定义事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "DIRECTIVESTYPICALLYRAISECUSTOMEVENTSWITHANANGULAREVENTEMITTERAPICOREEVENTEMITTERTHEDIRECTIVECREATESANEVENTEMITTERANDEXPOSESITASAPROPERTYTHEDIRECTIVECALLSEVENTEMITTEREMITPAYLOADTOFIREANEVENTPASSINGINAMESSAGEPAYLOADWHICHCANBEANYTHINGPARENTDIRECTIVESLISTENFORTHEEVENTBYBINDINGTOTHISPROPERTYANDACCESSINGTHEPAYLOADTHROUGHTHEEVENTOBJECT", "original": "Directives typically raise custom events with an Angular [EventEmitter](api/core/EventEmitter).\nThe directive creates an `EventEmitter` and exposes it as a property.\nThe directive calls `EventEmitter.emit(payload)` to fire an event, passing in a message payload, which can be anything.\nParent directives listen for the event by binding to this property and accessing the payload through the `$event` object.", "translation": "通常,指令使用 Angular [EventEmitter](api/core/EventEmitter) 来触发自定义事件。\n指令创建一个 `EventEmitter` 实例,并且把它作为属性暴露出来。\n指令调用 `EventEmitter.emit(payload)` 来触发事件,可以传入任何东西作为消息载荷。\n父指令通过绑定到这个属性来监听事件,并通过 `$event` 对象来访问载荷。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CONSIDERAHERODETAILCOMPONENTTHATPRESENTSHEROINFORMATIONANDRESPONDSTOUSERACTIONSALTHOUGHTHEHERODETAILCOMPONENTHASADELETEBUTTONITDOESNTKNOWHOWTODELETETHEHEROITSELFTHEBESTITCANDOISRAISEANEVENTREPORTINGTHEUSERSDELETEREQUEST", "original": "Consider a `HeroDetailComponent` that presents hero information and responds to user actions.\nAlthough the `HeroDetailComponent` has a delete button it doesn't know how to delete the hero itself.\nThe best it can do is raise an event reporting the user's delete request.", "translation": "假设 `HeroDetailComponent` 用于显示英雄的信息,并响应用户的动作。\n虽然 `HeroDetailComponent` 包含删除按钮,但它自己并不知道该如何删除这个英雄。\n最好的做法是触发事件来报告“删除用户”的请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HEREARETHEPERTINENTEXCERPTSFROMTHATHERODETAILCOMPONENT:", "original": "Here are the pertinent excerpts from that `HeroDetailComponent`:", "translation": "下面的代码节选自 `HeroDetailComponent`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THECOMPONENTDEFINESADELETEREQUESTPROPERTYTHATRETURNSANEVENTEMITTERWHENTHEUSERCLICKSDELETETHECOMPONENTINVOKESTHEDELETEMETHODTELLINGTHEEVENTEMITTERTOEMITAHEROOBJECT", "original": "The component defines a `deleteRequest` property that returns an `EventEmitter`.\nWhen the user clicks *delete*, the component invokes the `delete()` method,\ntelling the `EventEmitter` to emit a `Hero` object.", "translation": "组件定义了 `deleteRequest` 属性,它是 `EventEmitter` 实例。\n当用户点击*删除*时,组件会调用 `delete()` 方法,让 `EventEmitter` 发出一个 `Hero` 对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NOWIMAGINEAHOSTINGPARENTCOMPONENTTHATBINDSTOTHEHERODETAILCOMPONENTSDELETEREQUESTEVENT", "original": "Now imagine a hosting parent component that binds to the `HeroDetailComponent`'s `deleteRequest` event.", "translation": "现在,假设有个宿主的父组件,它绑定了 `HeroDetailComponent` 的 `deleteRequest` 事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENTHEDELETEREQUESTEVENTFIRESANGULARCALLSTHEPARENTCOMPONENTSDELETEHEROMETHODPASSINGTHEHEROTODELETEEMITTEDBYHERODETAILINTHEEVENTVARIABLE", "original": "When the `deleteRequest` event fires, Angular calls the parent component's `deleteHero` method,\npassing the *hero-to-delete* (emitted by `HeroDetail`) in the `$event` variable.", "translation": "当 `deleteRequest` 事件触发时,Angular 调用父组件的 `deleteHero` 方法,\n在 `$event` 变量中传入*要删除的英雄*(来自 `HeroDetail`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###TEMPLATESTATEMENTSHAVESIDEEFFECTS", "original": "### Template statements have side effects", "translation": "### 模板语句有副作用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEDELETEHEROMETHODHASASIDEEFFECT:ITDELETESAHEROTEMPLATESTATEMENTSIDEEFFECTSARENOTJUSTOKBUTEXPECTED", "original": "The `deleteHero` method has a side effect: it deletes a hero.\nTemplate statement side effects are not just OK, but expected.", "translation": "`deleteHero` 方法有副作用:它删除了一个英雄。\n模板语句的副作用不仅没问题,反而正是所期望的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "DELETINGTHEHEROUPDATESTHEMODELPERHAPSTRIGGERINGOTHERCHANGESINCLUDINGQUERIESANDSAVESTOAREMOTESERVERTHESECHANGESPERCOLATETHROUGHTHESYSTEMANDAREULTIMATELYDISPLAYEDINTHISANDOTHERVIEWS", "original": "Deleting the hero updates the model, perhaps triggering other changes\nincluding queries and saves to a remote server.\nThese changes percolate through the system and are ultimately displayed in this and other views.", "translation": "删除这个英雄会更新模型,还可能触发其它修改,包括向远端服务器的查询和保存。\n这些变更通过系统进行扩散,并最终显示到当前以及其它视图中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##TWOWAYBINDINGSPANCLASSSYNTAXSPAN", "original": "## Two-way binding ( <span class=\"syntax\">[(...)]</span> )", "translation": "## 双向数据绑定 ( <span class=\"syntax\">[(...)]</span> )", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUOFTENWANTTOBOTHDISPLAYADATAPROPERTYANDUPDATETHATPROPERTYWHENTHEUSERMAKESCHANGES", "original": "You often want to both display a data property and update that property when the user makes changes.", "translation": "你经常需要显示数据属性,并在用户作出更改时更新该属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ONTHEELEMENTSIDETHATTAKESACOMBINATIONOFSETTINGASPECIFICELEMENTPROPERTYANDLISTENINGFORANELEMENTCHANGEEVENT", "original": "On the element side that takes a combination of setting a specific element property\nand listening for an element change event.", "translation": "在元素层面上,既要设置元素属性,又要监听元素事件变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULAROFFERSASPECIALTWOWAYDATABINDINGSYNTAXFORTHISPURPOSEXTHEXSYNTAXCOMBINESTHEBRACKETSOFPROPERTYBINDINGXWITHTHEPARENTHESESOFEVENTBINDINGX", "original": "Angular offers a special _two-way data binding_ syntax for this purpose, **`[(x)]`**.\nThe `[(x)]` syntax combines the brackets\nof _property binding_, `[x]`, with the parentheses of _event binding_, `(x)`.", "translation": "Angular 为此提供一种特殊的*双向数据绑定*语法:**`[(x)]`**。\n`[(x)]` 语法结合了*属性绑定*的方括号 `[x]` 和*事件绑定*的圆括号 `(x)`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HEADERBANANAINABOXHEADER", "original": "<header>[( )] = banana in a box</header>", "translation": "<header>[( )] = 盒子里的香蕉</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "VISUALIZEABANANAINABOXTOREMEMBERTHATTHEPARENTHESESGOINSIDETHEBRACKETS", "original": "Visualize a *banana in a box* to remember that the parentheses go _inside_ the brackets.", "translation": "想象*盒子里的香蕉*来记住方括号套圆括号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEXSYNTAXISEASYTODEMONSTRATEWHENTHEELEMENTHASASETTABLEPROPERTYCALLEDXANDACORRESPONDINGEVENTNAMEDXCHANGEHERESASIZERCOMPONENTTHATFITSTHEPATTERNITHASASIZEVALUEPROPERTYANDACOMPANIONSIZECHANGEEVENT:", "original": "The `[(x)]` syntax is easy to demonstrate when the element has a settable property called `x`\nand a corresponding event named `xChange`.\nHere's a `SizerComponent` that fits the pattern.\nIt has a `size` value property and a companion `sizeChange` event:", "translation": "当一个元素拥有可以设置的属性 `x` 和对应的事件 `xChange` 时,解释 `[(x)]` 语法就容易多了。\n下面的 `SizerComponent` 符合这个模式。它有 `size` 属性和伴随的 `sizeChange` 事件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEINITIALSIZEISANINPUTVALUEFROMAPROPERTYBINDINGCLICKINGTHEBUTTONSINCREASESORDECREASESTHESIZEWITHINMINMAXVALUESCONSTRAINTSANDTHENRAISESEMITSTHESIZECHANGEEVENTWITHTHEADJUSTEDSIZE", "original": "The initial `size` is an input value from a property binding.\nClicking the buttons increases or decreases the `size`, within min/max values constraints,\nand then raises (_emits_) the `sizeChange` event with the adjusted size.", "translation": "`size` 的初始值是一个输入值,来自属性绑定。(译注:注意 `size` 前面的 `@Input`)\n点击按钮,在最小/最大值范围限制内增加或者减少 `size`。\n然后用调整后的 `size` 触发 `sizeChange` 事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HERESANEXAMPLEINWHICHTHEAPPCOMPONENTFONTSIZEPXISTWOWAYBOUNDTOTHESIZERCOMPONENT:", "original": "Here's an example in which the `AppComponent.fontSizePx` is two-way bound to the `SizerComponent`:", "translation": "下面的例子中,`AppComponent.fontSize` 被双向绑定到 `SizerComponent`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEAPPCOMPONENTFONTSIZEPXESTABLISHESTHEINITIALSIZERCOMPONENTSIZEVALUECLICKINGTHEBUTTONSUPDATESTHEAPPCOMPONENTFONTSIZEPXVIATHETWOWAYBINDINGTHEREVISEDAPPCOMPONENTFONTSIZEPXVALUEFLOWSTHROUGHTOTHESTYLEBINDINGMAKINGTHEDISPLAYEDTEXTBIGGERORSMALLER", "original": "The `AppComponent.fontSizePx` establishes the initial `SizerComponent.size` value.\nClicking the buttons updates the `AppComponent.fontSizePx` via the two-way binding.\nThe revised `AppComponent.fontSizePx` value flows through to the _style_ binding,\nmaking the displayed text bigger or smaller.", "translation": "`SizerComponent.size` 初始值是 `AppComponent.fontSizePx`。\n点击按钮时,通过双向绑定更新 `AppComponent.fontSizePx`。\n被修改的 `AppComponent.fontSizePx` 通过*样式*绑定,改变文本的显示大小。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETWOWAYBINDINGSYNTAXISREALLYJUSTSYNTACTICSUGARFORAPROPERTYBINDINGANDANEVENTBINDINGANGULARDESUGARSTHESIZERCOMPONENTBINDINGINTOTHIS:", "original": "The two-way binding syntax is really just syntactic sugar for a _property_ binding and an _event_ binding.\nAngular _desugars_ the `SizerComponent` binding into this:", "translation": "双向绑定语法实际上是*属性*绑定和*事件绑定*的语法糖。\nAngular 将 `SizerComponent` 的绑定分解成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEEVENTVARIABLECONTAINSTHEPAYLOADOFTHESIZERCOMPONENTSIZECHANGEEVENTANGULARASSIGNSTHEEVENTVALUETOTHEAPPCOMPONENTFONTSIZEPXWHENTHEUSERCLICKSTHEBUTTONS", "original": "The `$event` variable contains the payload of the `SizerComponent.sizeChange` event.\nAngular assigns the `$event` value to the `AppComponent.fontSizePx` when the user clicks the buttons.", "translation": "`$event` 变量包含了 `SizerComponent.sizeChange` 事件的荷载。\n当用户点击按钮时,Angular 将 `$event` 赋值给 `AppComponent.fontSizePx`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CLEARLYTHETWOWAYBINDINGSYNTAXISAGREATCONVENIENCECOMPAREDTOSEPARATEPROPERTYANDEVENTBINDINGS", "original": "Clearly the two-way binding syntax is a great convenience compared to separate property and event bindings.", "translation": "显然,比起单独绑定属性和事件,双向数据绑定语法显得非常方便。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ITWOULDBECONVENIENTTOUSETWOWAYBINDINGWITHHTMLFORMELEMENTSLIKEINPUTANDSELECTHOWEVERNONATIVEHTMLELEMENTFOLLOWSTHEXVALUEANDXCHANGEEVENTPATTERN", "original": "It would be convenient to use two-way binding with HTML form elements like `<input>` and `<select>`.\nHowever, no native HTML element follows the `x` value and `xChange` event pattern.", "translation": "如果能在像 `<input>` 和 `<select>` 这样的 HTML 元素上使用双向数据绑定就更好了。\n可惜,原生 HTML 元素不遵循 `x` 值和 `xChange` 事件的模式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "FORTUNATELYTHEANGULARNGMODELGUIDETEMPLATESYNTAX#NGMODELDIRECTIVEISABRIDGETHATENABLESTWOWAYBINDINGTOFORMELEMENTS", "original": "Fortunately, the Angular [_NgModel_](guide/template-syntax#ngModel) directive is a bridge that enables two-way binding to form elements.", "translation": "幸运的是,Angular 以 [_NgModel_](guide/template-syntax#ngModel) 指令为桥梁,允许在表单元素上使用双向数据绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##BUILTINDIRECTIVES", "original": "## Built-in directives", "translation": "## 内置指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "EARLIERVERSIONSOFANGULARINCLUDEDOVERSEVENTYBUILTINDIRECTIVESTHECOMMUNITYCONTRIBUTEDMANYMOREANDCOUNTLESSPRIVATEDIRECTIVESHAVEBEENCREATEDFORINTERNALAPPLICATIONS", "original": "Earlier versions of Angular included over seventy built-in directives.\nThe community contributed many more, and countless private directives\nhave been created for internal applications.", "translation": "上一版本的 Angular 中包含了超过 70 个内置指令。\n 社区贡献了更多,这还没算为内部应用而创建的无数私有指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUDONTNEEDMANYOFTHOSEDIRECTIVESINANGULARYOUCANOFTENACHIEVETHESAMERESULTSWITHTHEMORECAPABLEANDEXPRESSIVEANGULARBINDINGSYSTEMWHYCREATEADIRECTIVETOHANDLEACLICKWHENYOUCANWRITEASIMPLEBINDINGSUCHASTHIS", "original": "You don't need many of those directives in Angular.\nYou can often achieve the same results with the more capable and expressive Angular binding system.\nWhy create a directive to handle a click when you can write a simple binding such as this?", "translation": "在新版的 Angular 中不需要那么多指令。\n 使用更强大、更富有表现力的 Angular 绑定系统,其实可以达到同样的效果。\n 如果能用简单的绑定达到目的,为什么还要创建指令来处理点击事件呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUSTILLBENEFITFROMDIRECTIVESTHATSIMPLIFYCOMPLEXTASKSANGULARSTILLSHIPSWITHBUILTINDIRECTIVESJUSTNOTASMANYYOULLWRITEYOUROWNDIRECTIVESJUSTNOTASMANY", "original": "You still benefit from directives that simplify complex tasks.\nAngular still ships with built-in directives; just not as many.\nYou'll write your own directives, just not as many.", "translation": "你仍然可以从简化复杂任务的指令中获益。\nAngular 发布时仍然带有内置指令,只是没那么多了。\n你仍会写自己的指令,只是没那么多了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISSEGMENTREVIEWSSOMEOFTHEMOSTFREQUENTLYUSEDBUILTINDIRECTIVESCLASSIFIEDASEITHERATTRIBUTEDIRECTIVESGUIDETEMPLATESYNTAX#ATTRIBUTEDIRECTIVESORSTRUCTURALDIRECTIVESGUIDETEMPLATESYNTAX#STRUCTURALDIRECTIVES", "original": "This segment reviews some of the most frequently used built-in directives,\nclassified as either [_attribute_ directives](guide/template-syntax#attribute-directives) or [_structural_ directives](guide/template-syntax#structural-directives).", "translation": "下面来看一下那些最常用的内置指令。它们可分为[*属性型*指令](guide/template-syntax#attribute-directives) 或 [*结构型*指令](guide/template-syntax#structural-directives)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##BUILTINATTRIBUTEDIRECTIVES", "original": "## Built-in _attribute_ directives", "translation": "## 内置*属性型*指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATTRIBUTEDIRECTIVESLISTENTOANDMODIFYTHEBEHAVIOROFOTHERHTMLELEMENTSATTRIBUTESPROPERTIESANDCOMPONENTSTHEYAREUSUALLYAPPLIEDTOELEMENTSASIFTHEYWEREHTMLATTRIBUTESHENCETHENAME", "original": "Attribute directives listen to and modify the behavior of\nother HTML elements, attributes, properties, and components.\nThey are usually applied to elements as if they were HTML attributes, hence the name.", "translation": "属性型指令会监听和修改其它 HTML 元素或组件的行为、元素属性(Attribute)、DOM 属性(Property)。\n它们通常会作为 HTML 属性的名称而应用在元素上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "MANYDETAILSARECOVEREDINTHEATTRIBUTEDIRECTIVESGUIDEATTRIBUTEDIRECTIVESGUIDEMANYNGMODULESSUCHASTHEROUTERMODULEGUIDEROUTERROUTINGANDNAVIGATIONANDTHEFORMSMODULEGUIDEFORMSFORMSDEFINETHEIROWNATTRIBUTEDIRECTIVESTHISSECTIONISANINTRODUCTIONTOTHEMOSTCOMMONLYUSEDATTRIBUTEDIRECTIVES:", "original": "Many details are covered in the [_Attribute Directives_](guide/attribute-directives) guide.\nMany NgModules such as the [`RouterModule`](guide/router \"Routing and Navigation\")\nand the [`FormsModule`](guide/forms \"Forms\") define their own attribute directives.\nThis section is an introduction to the most commonly used attribute directives:", "translation": "更多的细节参见[*属性型指令*](guide/attribute-directives)一章。\n很多 Angular 模块,比如[`RouterModule`](guide/router \"Routing and Navigation\")和[`FormsModule`](guide/forms \"Forms\")都定义了自己的属性型指令。\n本节将会介绍几个最常用的属性型指令:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGCLASSGUIDETEMPLATESYNTAX#NGCLASSADDANDREMOVEASETOFCSSCLASSES", "original": "* [`NgClass`](guide/template-syntax#ngClass) - add and remove a set of CSS classes", "translation": "[`NgClass`](guide/template-syntax#ngClass) - 添加或移除一组 CSS 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGSTYLEGUIDETEMPLATESYNTAX#NGSTYLEADDANDREMOVEASETOFHTMLSTYLES", "original": "* [`NgStyle`](guide/template-syntax#ngStyle) - add and remove a set of HTML styles", "translation": "[`NgStyle`](guide/template-syntax#ngStyle) - 添加或移除一组 CSS 样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGMODELGUIDETEMPLATESYNTAX#NGMODELTWOWAYDATABINDINGTOANHTMLFORMELEMENT", "original": "* [`NgModel`](guide/template-syntax#ngModel) - two-way data binding to an HTML form element", "translation": "[`NgModel`](guide/template-syntax#ngModel) - 双向绑定到 HTML 表单元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUTYPICALLYCONTROLHOWELEMENTSAPPEARBYADDINGANDREMOVINGCSSCLASSESDYNAMICALLYYOUCANBINDTOTHENGCLASSTOADDORREMOVESEVERALCLASSESSIMULTANEOUSLY", "original": "You typically control how elements appear\nby adding and removing CSS classes dynamically.\nYou can bind to the `ngClass` to add or remove several classes simultaneously.", "translation": "你经常用动态添加或删除 CSS 类的方式来控制元素如何显示。\n通过绑定到 `NgClass`,可以同时添加或移除多个类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ACLASSBINDINGGUIDETEMPLATESYNTAX#CLASSBINDINGISAGOODWAYTOADDORREMOVEASINGLECLASS", "original": "A [class binding](guide/template-syntax#class-binding) is a good way to add or remove a *single* class.", "translation": "[CSS 类绑定](guide/template-syntax#class-binding) 是添加或删除*单个*类的最佳途径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TOADDORREMOVEMANYCSSCLASSESATTHESAMETIMETHENGCLASSDIRECTIVEMAYBETHEBETTERCHOICE", "original": "To add or remove *many* CSS classes at the same time, the `NgClass` directive may be the better choice.", "translation": "当想要同时添加或移除*多个* CSS 类时,`NgClass` 指令可能是更好的选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TRYBINDINGNGCLASSTOAKEY:VALUECONTROLOBJECTEACHKEYOFTHEOBJECTISACSSCLASSNAMEITSVALUEISTRUEIFTHECLASSSHOULDBEADDEDFALSEIFITSHOULDBEREMOVED", "original": "Try binding `ngClass` to a key:value control object.\nEach key of the object is a CSS class name; its value is `true` if the class should be added,\n`false` if it should be removed.", "translation": "试试把 `ngClass` 绑定到一个 key:value 形式的控制对象。这个对象中的每个 key 都是一个 CSS 类名,如果它的 value 是 `true`,这个类就会被加上,否则就会被移除。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CONSIDERASETCURRENTCLASSESCOMPONENTMETHODTHATSETSACOMPONENTPROPERTYCURRENTCLASSESWITHANOBJECTTHATADDSORREMOVESTHREECLASSESBASEDONTHETRUEFALSESTATEOFTHREEOTHERCOMPONENTPROPERTIES:", "original": "Consider a `setCurrentClasses` component method that sets a component property,\n`currentClasses` with an object that adds or removes three classes based on the\n`true`/`false` state of three other component properties:", "translation": "组件方法 `setCurrentClasses` 可以把组件的属性 `currentClasses` 设置为一个对象,它将会根据三个其它组件的状态为 `true` 或 `false` 而添加或移除三个类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ADDINGANNGCLASSPROPERTYBINDINGTOCURRENTCLASSESSETSTHEELEMENTSCLASSESACCORDINGLY:", "original": "Adding an `ngClass` property binding to `currentClasses` sets the element's classes accordingly:", "translation": "把 `NgClass` 属性绑定到 `currentClasses`,根据它来设置此元素的 CSS 类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ITSUPTOYOUTOCALLSETCURRENTCLASSESBOTHINITIALLYANDWHENTHEDEPENDENTPROPERTIESCHANGE", "original": "It's up to you to call `setCurrentClasses()`, both initially and when the dependent properties change.", "translation": "你既可以在初始化时调用 `setCurrentClassess()`,也可以在所依赖的属性变化时调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANSETINLINESTYLESDYNAMICALLYBASEDONTHESTATEOFTHECOMPONENTWITHNGSTYLEYOUCANSETMANYINLINESTYLESSIMULTANEOUSLY", "original": "You can set inline styles dynamically, based on the state of the component.\nWith `NgStyle` you can set many inline styles simultaneously.", "translation": "你可以根据组件的状态动态设置内联样式。\n`NgStyle` 绑定可以同时设置多个内联样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ASTYLEBINDINGGUIDETEMPLATESYNTAX#STYLEBINDINGISANEASYWAYTOSETASINGLESTYLEVALUE", "original": "A [style binding](guide/template-syntax#style-binding) is an easy way to set a *single* style value.", "translation": "[样式绑定](guide/template-syntax#style-binding)是设置*单一*样式值的简单方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TOSETMANYINLINESTYLESATTHESAMETIMETHENGSTYLEDIRECTIVEMAYBETHEBETTERCHOICE", "original": "To set *many* inline styles at the same time, the `NgStyle` directive may be the better choice.", "translation": "如果要同时设置*多个*内联样式,`NgStyle` 指令可能是更好的选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TRYBINDINGNGSTYLETOAKEY:VALUECONTROLOBJECTEACHKEYOFTHEOBJECTISASTYLENAMEITSVALUEISWHATEVERISAPPROPRIATEFORTHATSTYLE", "original": "Try binding `ngStyle` to a key:value control object.\nEach key of the object is a style name; its value is whatever is appropriate for that style.", "translation": "`NgStyle` 需要绑定到一个 key:value 控制对象。\n 对象的每个 key 是样式名,它的 value 是能用于这个样式的任何值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "CONSIDERASETCURRENTSTYLESCOMPONENTMETHODTHATSETSACOMPONENTPROPERTYCURRENTSTYLESWITHANOBJECTTHATDEFINESTHREESTYLESBASEDONTHESTATEOFTHREEOTHERCOMPONENTPROPERTIES:", "original": "Consider a `setCurrentStyles` component method that sets a component property, `currentStyles`\nwith an object that defines three styles, based on the state of three other component properties:", "translation": "来看看组件的 `setCurrentStyles` 方法,它会根据另外三个属性的状态把组件的 `currentStyles` 属性设置为一个定义了三个样式的对象:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ADDINGANNGSTYLEPROPERTYBINDINGTOCURRENTSTYLESSETSTHEELEMENTSSTYLESACCORDINGLY:", "original": "Adding an `ngStyle` property binding to `currentStyles` sets the element's styles accordingly:", "translation": "把 `NgStyle` 属性绑定到 `currentStyles`,以据此设置此元素的样式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ITSUPTOYOUTOCALLSETCURRENTSTYLESBOTHINITIALLYANDWHENTHEDEPENDENTPROPERTIESCHANGE", "original": "It's up to you to call `setCurrentStyles()`, both initially and when the dependent properties change.", "translation": "你既可以在初始化时调用 `setCurrentStyles()`,也可以在所依赖的属性变化时调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###NGMODELTWOWAYBINDINGTOFORMELEMENTSWITHSPANCLASSSYNTAXNGMODELSPAN", "original": "### NgModel - Two-way binding to form elements with <span class=\"syntax\">[(ngModel)]</span>", "translation": "### NgModel - 使用<span class=\"syntax\">[(ngModel)]</span>双向绑定到表单元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENDEVELOPINGDATAENTRYFORMSYOUOFTENBOTHDISPLAYADATAPROPERTYANDUPDATETHATPROPERTYWHENTHEUSERMAKESCHANGES", "original": "When developing data entry forms, you often both display a data property and\nupdate that property when the user makes changes.", "translation": "当开发数据输入表单时,你通常都要既显示数据属性又根据用户的更改去修改那个属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TWOWAYDATABINDINGWITHTHENGMODELDIRECTIVEMAKESTHATEASYHERESANEXAMPLE:", "original": "Two-way data binding with the `NgModel` directive makes that easy. Here's an example:", "translation": "使用 `NgModel` 指令进行双向数据绑定可以简化这种工作。例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####FORMSMODULEISREQUIREDTOUSENGMODEL", "original": "#### _FormsModule_ is required to use _ngModel_", "translation": "#### 使用 `ngModel` 时需要 `FormsModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BEFOREUSINGTHENGMODELDIRECTIVEINATWOWAYDATABINDINGYOUMUSTIMPORTTHEFORMSMODULEANDADDITTOTHENGMODULESIMPORTSLISTLEARNMOREABOUTTHEFORMSMODULEANDNGMODELINTHEFORMSGUIDEFORMS#NGMODELGUIDE", "original": "Before using the `ngModel` directive in a two-way data binding,\nyou must import the `FormsModule` and add it to the NgModule's `imports` list.\nLearn more about the `FormsModule` and `ngModel` in the\n[Forms](guide/forms#ngModel) guide.", "translation": "在使用 `ngModel` 指令进行双向数据绑定之前,你必须导入 `FormsModule` 并把它添加到 Angular 模块的 `imports` 列表中。\n要了解 `FormsModule` 和 `ngModel` 的更多知识,参见[表单](guide/forms#ngModel)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HERESHOWTOIMPORTTHEFORMSMODULETOMAKENGMODELAVAILABLE", "original": "Here's how to import the `FormsModule` to make `[(ngModel)]` available.", "translation": "导入 `FormsModule` 并让 `[(ngModel)]` 可用的代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####INSIDESPANCLASSSYNTAXNGMODELSPAN", "original": "#### Inside <span class=\"syntax\">[(ngModel)]</span>", "translation": "#### <span class=\"syntax\">[(ngModel)]</span>内幕", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "LOOKINGBACKATTHENAMEBINDINGNOTETHATYOUCOULDHAVEACHIEVEDTHESAMERESULTWITHSEPARATEBINDINGSTOTHEINPUTELEMENTSVALUEPROPERTYANDINPUTEVENT", "original": "Looking back at the `name` binding, note that\nyou could have achieved the same result with separate bindings to\nthe `<input>` element's `value` property and `input` event.", "translation": "回头看看 `name` 绑定,注意,你可以通过分别绑定到 `<input>` 元素的 `value` 属性和 `input` 事件来达到同样的效果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THATSCUMBERSOMEWHOCANREMEMBERWHICHELEMENTPROPERTYTOSETANDWHICHELEMENTEVENTEMITSUSERCHANGESHOWDOYOUEXTRACTTHECURRENTLYDISPLAYEDTEXTFROMTHEINPUTBOXSOYOUCANUPDATETHEDATAPROPERTYWHOWANTSTOLOOKTHATUPEACHTIME", "original": "That's cumbersome. Who can remember which element property to set and which element event emits user changes?\nHow do you extract the currently displayed text from the input box so you can update the data property?\nWho wants to look that up each time?", "translation": "那样显得很笨重,谁会记得该设置哪个元素属性以及当用户修改时触发哪个事件?\n你该如何提取输入框中的文本并且更新数据属性?谁会希望每次都去查资料来确定这些?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THATNGMODELDIRECTIVEHIDESTHESEONEROUSDETAILSBEHINDITSOWNNGMODELINPUTANDNGMODELCHANGEOUTPUTPROPERTIES", "original": "That `ngModel` directive hides these onerous details behind its own `ngModel` input and `ngModelChange` output properties.", "translation": "`ngModel` 指令通过自己的输入属性 `ngModel` 和输出属性 `ngModelChange` 隐藏了那些细节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THENGMODELDATAPROPERTYSETSTHEELEMENTSVALUEPROPERTYANDTHENGMODELCHANGEEVENTPROPERTYLISTENSFORCHANGESTOTHEELEMENTSVALUE", "original": "The `ngModel` data property sets the element's value property and the `ngModelChange` event property\nlistens for changes to the element's value.", "translation": "`ngModel` 输入属性会设置该元素的值,并通过 `ngModelChange` 的输出属性来监听元素值的变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEDETAILSARESPECIFICTOEACHKINDOFELEMENTANDTHEREFORETHENGMODELDIRECTIVEONLYWORKSFORANELEMENTSUPPORTEDBYACONTROLVALUEACCESSORAPIFORMSCONTROLVALUEACCESSORTHATADAPTSANELEMENTTOTHISPROTOCOLTHEINPUTBOXISONEOFTHOSEELEMENTSANGULARPROVIDESVALUEACCESSORSFORALLOFTHEBASICHTMLFORMELEMENTSANDTHEFORMSGUIDEFORMSGUIDESHOWSHOWTOBINDTOTHEM", "original": "The details are specific to each kind of element and therefore the `NgModel` directive only works for an element\nsupported by a [ControlValueAccessor](api/forms/ControlValueAccessor)\nthat adapts an element to this protocol.\nThe `<input>` box is one of those elements.\nAngular provides *value accessors* for all of the basic HTML form elements and the\n[_Forms_](guide/forms) guide shows how to bind to them.", "translation": "各种元素都有很多特有的处理细节,因此 `NgModel` 指令只支持实现了[ControlValueAccessor](api/forms/ControlValueAccessor)的元素,\n它们能让元素适配本协议。\n`<input>` 输入框正是其中之一。\nAngular 为所有的基础 HTML 表单都提供了*值访问器(Value accessor)*,[*表单*](guide/forms)一章展示了如何绑定它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANTAPPLYNGMODELTOANONFORMNATIVEELEMENTORATHIRDPARTYCUSTOMCOMPONENTUNTILYOUWRITEASUITABLEVALUEACCESSORATECHNIQUETHATISBEYONDTHESCOPEOFTHISGUIDE", "original": "You can't apply `[(ngModel)]` to a non-form native element or a third-party custom component\nuntil you write a suitable *value accessor*,\na technique that is beyond the scope of this guide.", "translation": "你不能把 `[(ngModel)]` 用到非表单类的原生元素或第三方自定义组件上,除非写一个合适的*值访问器*,这种技巧超出了本章的范围。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUDONTNEEDAVALUEACCESSORFORANANGULARCOMPONENTTHATYOUWRITEBECAUSEYOUCANNAMETHEVALUEANDEVENTPROPERTIESTOSUITANGULARSBASICTWOWAYBINDINGSYNTAXGUIDETEMPLATESYNTAX#TWOWAYANDSKIPNGMODELALTOGETHERTHESIZERSHOWNABOVEGUIDETEMPLATESYNTAX#TWOWAYISANEXAMPLEOFTHISTECHNIQUE", "original": "You don't need a _value accessor_ for an Angular component that you write because you\ncan name the value and event properties\nto suit Angular's basic [two-way binding syntax](guide/template-syntax#two-way) and skip `NgModel` altogether.\nThe [`sizer` shown above](guide/template-syntax#two-way) is an example of this technique.", "translation": "你自己写的 Angular 组件不需要*值访问器*,因为你可以让值和事件的属性名适应 Angular 基本的[双向绑定语法](guide/template-syntax#two-way),而不使用 `NgModel`。\n[前面看过的 `sizer`](guide/template-syntax#two-way)就是使用这种技巧的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SEPARATENGMODELBINDINGSISANIMPROVEMENTOVERBINDINGTOTHEELEMENTSNATIVEPROPERTIESYOUCANDOBETTER", "original": "Separate `ngModel` bindings is an improvement over binding to the element's native properties. You can do better.", "translation": "使用独立的 `ngModel` 绑定优于绑定到该元素的原生属性,你可以做得更好。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUSHOULDNTHAVETOMENTIONTHEDATAPROPERTYTWICEANGULARSHOULDBEABLETOCAPTURETHECOMPONENTSDATAPROPERTYANDSETITWITHASINGLEDECLARATIONWHICHITCANWITHTHENGMODELSYNTAX:", "original": "You shouldn't have to mention the data property twice. Angular should be able to capture\nthe component's data property and set it\nwith a single declaration, which it can with the `[(ngModel)]` syntax:", "translation": "你不用被迫两次引用这个数据属性,Angular 可以捕获该元素的数据属性,并且通过一个简单的声明来设置它,这样它就可以使用 `[(ngModel)]` 语法了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ISNGMODELALLYOUNEEDISTHEREEVERAREASONTOFALLBACKTOITSEXPANDEDFORM", "original": "Is `[(ngModel)]` all you need? Is there ever a reason to fall back to its expanded form?", "translation": "`[(ngModel)]` 就是你需要的一切吗?有没有什么理由回退到它的展开形式?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THENGMODELSYNTAXCANONLYSETADATABOUNDPROPERTYIFYOUNEEDTODOSOMETHINGMOREORSOMETHINGDIFFERENTYOUCANWRITETHEEXPANDEDFORM", "original": "The `[(ngModel)]` syntax can only _set_ a data-bound property.\nIf you need to do something more or something different, you can write the expanded form.", "translation": "`[(ngModel)]` 语法只能*设置*数据绑定属性。\n如果要做更多或者做点不一样的事,也可以写它的展开形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEFOLLOWINGCONTRIVEDEXAMPLEFORCESTHEINPUTVALUETOUPPERCASE:", "original": "The following contrived example forces the input value to uppercase:", "translation": "下面这个生造的例子强制输入框的内容变成大写:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HEREAREALLVARIATIONSINACTIONINCLUDINGTHEUPPERCASEVERSION:", "original": "Here are all variations in action, including the uppercase version:", "translation": "这里是所有这些变体的动画,包括这个大写转换的版本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##BUILTINSTRUCTURALDIRECTIVES", "original": "## Built-in _structural_ directives", "translation": "## 内置*结构型*指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "STRUCTURALDIRECTIVESARERESPONSIBLEFORHTMLLAYOUTTHEYSHAPEORRESHAPETHEDOMSSTRUCTURETYPICALLYBYADDINGREMOVINGANDMANIPULATINGTHEHOSTELEMENTSTOWHICHTHEYAREATTACHED", "original": "Structural directives are responsible for HTML layout.\nThey shape or reshape the DOM's _structure_, typically by adding, removing, and manipulating\nthe host elements to which they are attached.", "translation": "结构型指令的职责是 HTML 布局。\n它们塑造或重塑 DOM 的*结构*,这通常是通过添加、移除和操纵它们所附加到的宿主元素来实现的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEDEEPDETAILSOFSTRUCTURALDIRECTIVESARECOVEREDINTHESTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVESGUIDEWHEREYOULLLEARN:", "original": "The deep details of structural directives are covered in the\n[_Structural Directives_](guide/structural-directives) guide\nwhere you'll learn:", "translation": "关于结构型指令的详情参见[*结构型指令*](guide/structural-directives)一章,在那里你将学到:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHYYOUPREFIXTHEDIRECTIVENAMEWITHANASTERISKGUIDESTRUCTURALDIRECTIVES#ASTERISKTHEINNGIF", "original": "* why you\n[_prefix the directive name with an asterisk_ (\\*)](guide/structural-directives#asterisk \"The * in *ngIf\").", "translation": "为什么要[给结构型指令的名字加上(\\*)前缀?](guide/structural-directives#asterisk \"The * in *ngIf\")", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TOUSENGCONTAINERGUIDESTRUCTURALDIRECTIVES#NGCONTAINERNGCONTAINERTOGROUPELEMENTSWHENTHEREISNOSUITABLEHOSTELEMENTFORTHEDIRECTIVE", "original": "* to use [`<ng-container>`](guide/structural-directives#ngcontainer \"<ng-container>\")\nto group elements when there is no suitable host element for the directive.", "translation": "当没有合适的宿主元素放置指令时,可用 [`<ng-container>`](guide/structural-directives#ngcontainer \"<ng-container>\") 对元素进行分组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HOWTOWRITEYOUROWNSTRUCTURALDIRECTIVE", "original": "* how to write your own structural directive.", "translation": "如何写自己的结构型指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THATYOUCANONLYAPPLYONESTRUCTURALDIRECTIVEGUIDESTRUCTURALDIRECTIVES#ONEPERELEMENTONEPERHOSTELEMENTTOANELEMENT", "original": "* that you can only apply [one structural directive](guide/structural-directives#one-per-element \"one per host element\") to an element.", "translation": "你只能往一个元素上应用[一个结构型指令](guide/structural-directives#one-per-element \"one per host element\")。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISSECTIONISANINTRODUCTIONTOTHECOMMONSTRUCTURALDIRECTIVES:", "original": "_This_ section is an introduction to the common structural directives:", "translation": "*本节*是对常见结构型指令的简介:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGIFGUIDETEMPLATESYNTAX#NGIFCONDITIONALLYADDORREMOVEANELEMENTFROMTHEDOM", "original": "* [`NgIf`](guide/template-syntax#ngIf) - conditionally add or remove an element from the DOM", "translation": "[`NgIf`](guide/template-syntax#ngIf) - 根据条件把一个元素添加到 DOM 中或从 DOM 移除", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGSWITCHGUIDETEMPLATESYNTAX#NGSWITCHASETOFDIRECTIVESTHATSWITCHAMONGALTERNATIVEVIEWS", "original": "* [`NgSwitch`](guide/template-syntax#ngSwitch) - a set of directives that switch among alternative views", "translation": "[`NgSwitch`](guide/template-syntax#ngSwitch) 一组指令,用来在多个可选视图之间切换。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGFOROFGUIDETEMPLATESYNTAX#NGFORREPEATATEMPLATEFOREACHITEMINALIST", "original": "* [NgForOf](guide/template-syntax#ngFor) - repeat a template for each item in a list", "translation": "[NgForOf](guide/template-syntax#ngFor) - 对列表中的每个条目重复套用同一个模板", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANADDORREMOVEANELEMENTFROMTHEDOMBYAPPLYINGANNGIFDIRECTIVETOTHATELEMENTCALLEDTHEHOSTELEMENTBINDTHEDIRECTIVETOACONDITIONEXPRESSIONLIKEISACTIVEINTHISEXAMPLE", "original": "You can add or remove an element from the DOM by applying an `NgIf` directive to\nthat element (called the _host element_).\nBind the directive to a condition expression like `isActive` in this example.", "translation": "通过把 `NgIf` 指令应用到元素上(称为*宿主元素*),你可以往 DOM 中添加或从 DOM 中移除这个元素。\n在下面的例子中,该指令绑定到了类似于 `isActive` 这样的条件表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "DONTFORGETTHEASTERISKINFRONTOFNGIF", "original": "Don't forget the asterisk (`*`) in front of `ngIf`.", "translation": "别忘了 `ngIf` 前面的星号(`*`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENTHEISACTIVEEXPRESSIONRETURNSATRUTHYVALUENGIFADDSTHEHERODETAILCOMPONENTTOTHEDOMWHENTHEEXPRESSIONISFALSYNGIFREMOVESTHEHERODETAILCOMPONENTFROMTHEDOMDESTROYINGTHATCOMPONENTANDALLOFITSSUBCOMPONENTS", "original": "When the `isActive` expression returns a truthy value, `NgIf` adds the `HeroDetailComponent` to the DOM.\nWhen the expression is falsy, `NgIf` removes the `HeroDetailComponent`\nfrom the DOM, destroying that component and all of its sub-components.", "translation": "当 `isActive` 表达式返回真值时,`NgIf` 把 `HeroDetailComponent` 添加到 DOM 中;为假时,`NgIf` 会从 DOM 中移除 `HeroDetailComponent`,并销毁该组件及其所有子组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####SHOWHIDEISNOTTHESAMETHING", "original": "#### Show/hide is not the same thing", "translation": "#### 这和显示/隐藏不是一回事", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANCONTROLTHEVISIBILITYOFANELEMENTWITHACLASSGUIDETEMPLATESYNTAX#CLASSBINDINGORSTYLEGUIDETEMPLATESYNTAX#STYLEBINDINGBINDING:", "original": "You can control the visibility of an element with a\n[class](guide/template-syntax#class-binding) or [style](guide/template-syntax#style-binding) binding:", "translation": "你也可以通过[类绑定](guide/template-syntax#class-binding)或[样式绑定](guide/template-syntax#style-binding)来显示或隐藏一个元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HIDINGANELEMENTISQUITEDIFFERENTFROMREMOVINGANELEMENTWITHNGIF", "original": "Hiding an element is quite different from removing an element with `NgIf`.", "translation": "但隐藏子树和用 `NgIf` 排除子树是截然不同的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENYOUHIDEANELEMENTTHATELEMENTANDALLOFITSDESCENDENTSREMAININTHEDOMALLCOMPONENTSFORTHOSEELEMENTSSTAYINMEMORYANDANGULARMAYCONTINUETOCHECKFORCHANGESYOUCOULDBEHOLDINGONTOCONSIDERABLECOMPUTINGRESOURCESANDDEGRADINGPERFORMANCEFORSOMETHINGTHEUSERCANTSEE", "original": "When you hide an element, that element and all of its descendents remain in the DOM.\nAll components for those elements stay in memory and\nAngular may continue to check for changes.\nYou could be holding onto considerable computing resources and degrading performance,\nfor something the user can't see.", "translation": "当隐藏子树时,它仍然留在 DOM 中。\n子树中的组件及其状态仍然保留着。\n即使对于不可见属性,Angular 也会继续检查变更。\n子树可能占用相当可观的内存和运算资源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENNGIFISFALSEANGULARREMOVESTHEELEMENTANDITSDESCENDENTSFROMTHEDOMITDESTROYSTHEIRCOMPONENTSPOTENTIALLYFREEINGUPSUBSTANTIALRESOURCESRESULTINGINAMORERESPONSIVEUSEREXPERIENCE", "original": "When `NgIf` is `false`, Angular removes the element and its descendents from the DOM.\nIt destroys their components, potentially freeing up substantial resources,\nresulting in a more responsive user experience.", "translation": "当 `NgIf` 为 `false` 时,Angular 从 DOM 中物理地移除了这个元素子树。\n它销毁了子树中的组件及其状态,也潜在释放了可观的资源,最终让用户体验到更好的性能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESHOWHIDETECHNIQUEISFINEFORAFEWELEMENTSWITHFEWCHILDRENYOUSHOULDBEWARYWHENHIDINGLARGECOMPONENTTREESNGIFMAYBETHESAFERCHOICE", "original": "The show/hide technique is fine for a few elements with few children.\nYou should be wary when hiding large component trees; `NgIf` may be the safer choice.", "translation": "显示/隐藏的技术对于只有少量子元素的元素是很好用的,但要当心别试图隐藏大型组件树。相比之下,`NgIf` 则是个更安全的选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####GUARDAGAINSTNULL", "original": "#### Guard against null", "translation": "#### 防范空指针错误", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THENGIFDIRECTIVEISOFTENUSEDTOGUARDAGAINSTNULLSHOWHIDEISUSELESSASAGUARDANGULARWILLTHROWANERRORIFANESTEDEXPRESSIONTRIESTOACCESSAPROPERTYOFNULL", "original": "The `ngIf` directive is often used to guard against null.\nShow/hide is useless as a guard.\nAngular will throw an error if a nested expression tries to access a property of `null`.", "translation": "`ngIf` 指令通常会用来防范空指针错误。\n而显示/隐藏的方式是无法防范的,当一个表达式尝试访问空值的属性时,Angular 就会抛出一个异常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HEREWESEENGIFGUARDINGTWODIVSTHECURRENTHERONAMEWILLAPPEARONLYWHENTHEREISACURRENTHEROTHENULLHEROWILLNEVERBEDISPLAYED", "original": "Here we see `NgIf` guarding two `<div>`s.\nThe `currentHero` name will appear only when there is a `currentHero`.\nThe `nullHero` will never be displayed.", "translation": "这里我们用 `NgIf` 来保护了两个 `<div>` 防范空指针错误。\n`currentHero` 的名字只有当存在 `currentHero` 时才会显示出来。\n而 `nullHero` 永远不会显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SEEALSOTHESAFENAVIGATIONOPERATORGUIDETEMPLATESYNTAX#SAFENAVIGATIONOPERATORSAFENAVIGATIONOPERATORDESCRIBEDBELOW", "original": "See also the\n[_safe navigation operator_](guide/template-syntax#safe-navigation-operator \"Safe navigation operator (?.)\")\ndescribed below.", "translation": "参见稍后的[*安全导航操作符*](guide/template-syntax#safe-navigation-operator \"Safe naviation operator (?.)\")部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGFOROFISAREPEATERDIRECTIVEMDASHAWAYTOPRESENTALISTOFITEMSYOUDEFINEABLOCKOFHTMLTHATDEFINESHOWASINGLEITEMSHOULDBEDISPLAYEDYOUTELLANGULARTOUSETHATBLOCKASATEMPLATEFORRENDERINGEACHITEMINTHELIST", "original": "`NgForOf` is a _repeater_ directive — a way to present a list of items.\nYou define a block of HTML that defines how a single item should be displayed.\nYou tell Angular to use that block as a template for rendering each item in the list.", "translation": "`NgFor` 是一个*重复器*指令 —— 自定义数据显示的一种方式。\n你的目标是展示一个由多个条目组成的列表。首先定义了一个 HTML 块,它规定了单个条目应该如何显示。\n再告诉 Angular 把这个块当做模板,渲染列表中的每个条目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HEREISANEXAMPLEOFNGFOROFAPPLIEDTOASIMPLEDIV:", "original": "Here is an example of `NgForOf` applied to a simple `<div>`:", "translation": "下例中,`NgFor` 应用在一个简单的 `<div>` 上:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANALSOAPPLYANNGFOROFTOACOMPONENTELEMENTASINTHISEXAMPLE:", "original": "You can also apply an `NgForOf` to a component element, as in this example:", "translation": "也可以把 `NgFor` 应用在一个组件元素上,就下例这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "DONTFORGETTHEASTERISKINFRONTOFNGFOR", "original": "Don't forget the asterisk (`*`) in front of `ngFor`.", "translation": "不要忘了 `ngFor` 前面的星号 (`*`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETEXTASSIGNEDTONGFORISTHEINSTRUCTIONTHATGUIDESTHEREPEATERPROCESS", "original": "The text assigned to `*ngFor` is the instruction that guides the repeater process.", "translation": "赋值给 `*ngFor` 的文本是用于指导重复器如何工作的指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####NGFORMICROSYNTAX", "original": "#### *ngFor microsyntax", "translation": "#### NgFor 微语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESTRINGASSIGNEDTONGFORISNOTATEMPLATEEXPRESSIONGUIDETEMPLATESYNTAX#TEMPLATEEXPRESSIONSITSAMICROSYNTAXMDASHALITTLELANGUAGEOFITSOWNTHATANGULARINTERPRETSTHESTRINGLETHEROOFHEROESMEANS:", "original": "The string assigned to `*ngFor` is not a [template expression](guide/template-syntax#template-expressions).\nIt's a *microsyntax* — a little language of its own that Angular interprets.\nThe string `\"let hero of heroes\"` means:", "translation": "赋值给 `*ngFor` 的字符串不是[模板表达式](guide/template-syntax#template-expressions)。\n它是一个*微语法* —— 由 Angular 自己解释的小型语言。在这个例子中,字符串 `\"let hero of heroes\"` 的含义是:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "TAKEEACHHEROINTHEHEROESARRAYSTOREITINTHELOCALHEROLOOPINGVARIABLEANDMAKEITAVAILABLETOTHETEMPLATEDHTMLFOREACHITERATION", "original": "> *Take each hero in the `heroes` array, store it in the local `hero` looping variable, and\nmake it available to the templated HTML for each iteration.*", "translation": "> *取出 `heroes` 数组中的每个英雄,把它存入局部变量 `hero` 中,并在每次迭代时对模板 HTML 可用*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULARTRANSLATESTHISINSTRUCTIONINTOANGTEMPLATEAROUNDTHEHOSTELEMENTTHENUSESTHISTEMPLATEREPEATEDLYTOCREATEANEWSETOFELEMENTSANDBINDINGSFOREACHHEROINTHELIST", "original": "Angular translates this instruction into a `<ng-template>` around the host element,\nthen uses this template repeatedly to create a new set of elements and bindings for each `hero`\nin the list.", "translation": "Angular 把这个指令翻译成了一个 `<ng-template>` 包裹的宿主元素,然后使用这个模板重复创建出一组新元素,并且绑定到列表中的每一个 `hero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "LEARNABOUTTHEMICROSYNTAXINTHESTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVES#MICROSYNTAXGUIDE", "original": "Learn about the _microsyntax_ in the [_Structural Directives_](guide/structural-directives#microsyntax) guide.", "translation": "要了解*微语法*的更多知识,参见[*结构型指令*](guide/structural-directives#microsyntax)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###TEMPLATEINPUTVARIABLES", "original": "### Template input variables", "translation": "### 模板输入变量", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THELETKEYWORDBEFOREHEROCREATESATEMPLATEINPUTVARIABLECALLEDHEROTHENGFOROFDIRECTIVEITERATESOVERTHEHEROESARRAYRETURNEDBYTHEPARENTCOMPONENTSHEROESPROPERTYANDSETSHEROTOTHECURRENTITEMFROMTHEARRAYDURINGEACHITERATION", "original": "The `let` keyword before `hero` creates a _template input variable_ called `hero`.\nThe `NgForOf` directive iterates over the `heroes` array returned by the parent component's `heroes` property\nand sets `hero` to the current item from the array during each iteration.", "translation": "`hero` 前的 `let` 关键字创建了一个名叫 `hero` 的*模板输入变量*。\n`ngFor` 指令在由父组件的 `heroes` 属性返回的 `heroes` 数组上迭代,每次迭代都从数组中把当前元素赋值给 `hero` 变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUREFERENCETHEHEROINPUTVARIABLEWITHINTHENGFOROFHOSTELEMENTANDWITHINITSDESCENDANTSTOACCESSTHEHEROSPROPERTIESHEREITISREFERENCEDFIRSTINANINTERPOLATIONANDTHENPASSEDINABINDINGTOTHEHEROPROPERTYOFTHEHERODETAILCOMPONENT", "original": "You reference the `hero` input variable within the `NgForOf` host element\n(and within its descendants) to access the hero's properties.\nHere it is referenced first in an interpolation\nand then passed in a binding to the `hero` property of the `<hero-detail>` component.", "translation": "你可以在 `ngFor` 的宿主元素(及其子元素)中引用模板输入变量 `hero`,从而访问该英雄的属性。\n这里它首先在一个插值表达式中被引用到,然后通过一个绑定把它传给了 `<hero-detail>` 组件的 `hero` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "LEARNMOREABOUTTEMPLATEINPUTVARIABLESINTHESTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVES#TEMPLATEINPUTVARIABLEGUIDE", "original": "Learn more about _template input variables_ in the\n[_Structural Directives_](guide/structural-directives#template-input-variable) guide.", "translation": "要了解更多*模板输入变量*的知识,参见[*结构型指令*](guide/structural-directives#template-input-variable)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####NGFORWITHINDEX", "original": "#### *ngFor with _index_", "translation": "#### 带索引的 `*ngFor`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEINDEXPROPERTYOFTHENGFOROFDIRECTIVECONTEXTRETURNSTHEZEROBASEDINDEXOFTHEITEMINEACHITERATIONYOUCANCAPTURETHEINDEXINATEMPLATEINPUTVARIABLEANDUSEITINTHETEMPLATE", "original": "The `index` property of the `NgForOf` directive context returns the zero-based index of the item in each iteration.\nYou can capture the `index` in a template input variable and use it in the template.", "translation": "`NgFor` 指令上下文中的 `index` 属性返回一个从零开始的索引,表示当前条目在迭代中的顺序。\n你可以通过模板输入变量捕获这个 `index` 值,并把它用在模板中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THENEXTEXAMPLECAPTURESTHEINDEXINAVARIABLENAMEDIANDDISPLAYSITWITHTHEHERONAMELIKETHIS", "original": "The next example captures the `index` in a variable named `i` and displays it with the hero name like this.", "translation": "下面这个例子把 `index` 捕获到了 `i` 变量中,并且把它显示在英雄名字的前面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGFORISIMPLEMENTEDBYTHENGFOROFDIRECTIVEREADMOREABOUTTHEOTHERNGFOROFCONTEXTVALUESSUCHASLASTEVENANDODDINTHENGFOROFAPIREFERENCEAPICOMMONNGFOROF", "original": "`NgFor` is implemented by the `NgForOf` directive. Read more about the other `NgForOf` context values such as `last`, `even`,\nand `odd` in the [NgForOf API reference](api/common/NgForOf).", "translation": "要学习更多的*类似 index* 的值,例如 `last`、`even` 和 `odd`,请参阅 [NgFor API 参考](api/common/NgForOf)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####NGFORWITHTRACKBY", "original": "#### *ngFor with _trackBy_", "translation": "#### 带 `trackBy` 的 `*ngFor`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THENGFOROFDIRECTIVEMAYPERFORMPOORLYESPECIALLYWITHLARGELISTSASMALLCHANGETOONEITEMANITEMREMOVEDORANITEMADDEDCANTRIGGERACASCADEOFDOMMANIPULATIONS", "original": "The `NgForOf` directive may perform poorly, especially with large lists.\nA small change to one item, an item removed, or an item added can trigger a cascade of DOM manipulations.", "translation": "`ngFor` 指令有时候会性能较差,特别是在大型列表中。\n对一个条目的一丁点改动、移除或添加,都会导致级联的 DOM 操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "FOREXAMPLEREQUERYINGTHESERVERCOULDRESETTHELISTWITHALLNEWHEROOBJECTS", "original": "For example, re-querying the server could reset the list with all new hero objects.", "translation": "例如,重新从服务器查询可以刷新包括所有新英雄在内的英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "MOSTIFNOTALLAREPREVIOUSLYDISPLAYEDHEROESYOUKNOWTHISBECAUSETHEIDOFEACHHEROHASNTCHANGEDBUTANGULARSEESONLYAFRESHLISTOFNEWOBJECTREFERENCESITHASNOCHOICEBUTTOTEARDOWNTHEOLDDOMELEMENTSANDINSERTALLNEWDOMELEMENTS", "original": "Most, if not all, are previously displayed heroes.\n*You* know this because the `id` of each hero hasn't changed.\nBut Angular sees only a fresh list of new object references.\nIt has no choice but to tear down the old DOM elements and insert all new DOM elements.", "translation": "他们中的绝大多数(如果不是所有的话)都是以前显示过的英雄。*你*知道这一点,是因为每个英雄的 `id` 没有变化。\n 但在 Angular 看来,它只是一个由新的对象引用构成的新列表,\n 它没有选择,只能清理旧列表、舍弃那些 DOM 元素,并且用新的 DOM 元素来重建一个新列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULARCANAVOIDTHISCHURNWITHTRACKBYADDAMETHODTOTHECOMPONENTTHATRETURNSTHEVALUENGFOROFSHOULDTRACKINTHISCASETHATVALUEISTHEHEROSID", "original": "Angular can avoid this churn with `trackBy`.\nAdd a method to the component that returns the value `NgForOf` _should_ track.\nIn this case, that value is the hero's `id`.", "translation": "如果给它指定一个 `trackBy`,Angular 就可以避免这种折腾。\n往组件中添加一个方法,它会返回 `NgFor`*应该*追踪的值。\n在这里,这个值就是英雄的 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTHEMICROSYNTAXEXPRESSIONSETTRACKBYTOTHISMETHOD", "original": "In the microsyntax expression, set `trackBy` to this method.", "translation": "在微语法中,把 `trackBy` 设置为该方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HEREISANILLUSTRATIONOFTHETRACKBYEFFECTRESETHEROESCREATESNEWHEROESWITHTHESAMEHEROIDSCHANGEIDSCREATESNEWHEROESWITHNEWHEROIDS", "original": "Here is an illustration of the _trackBy_ effect.\n\"Reset heroes\" creates new heroes with the same `hero.id`s.\n\"Change ids\" creates new heroes with new `hero.id`s.", "translation": "这里展示了 `trackBy` 的效果。\n\"Reset heroes\"会创建一个具有相同 `hero.id` 的新英雄。\n\"Change ids\"则会创建一个具有新 `hero.id` 的新英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WITHNOTRACKBYBOTHBUTTONSTRIGGERCOMPLETEDOMELEMENTREPLACEMENT", "original": "* With no `trackBy`, both buttons trigger complete DOM element replacement.", "translation": "如果没有 `trackBy`,这些按钮都会触发完全的 DOM 元素替换。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WITHTRACKBYONLYCHANGINGTHEIDTRIGGERSELEMENTREPLACEMENT", "original": "* With `trackBy`, only changing the `id` triggers element replacement.", "translation": "有了 `trackBy`,则只有修改了 `id` 的按钮才会触发元素替换。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###THENGSWITCHDIRECTIVES", "original": "### The _NgSwitch_ directives", "translation": "### `NgSwitch` 指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGSWITCHISLIKETHEJAVASCRIPTSWITCHSTATEMENTITCANDISPLAYONEELEMENTFROMAMONGSEVERALPOSSIBLEELEMENTSBASEDONASWITCHCONDITIONANGULARPUTSONLYTHESELECTEDELEMENTINTOTHEDOM", "original": "*NgSwitch* is like the JavaScript `switch` statement.\nIt can display _one_ element from among several possible elements, based on a _switch condition_.\nAngular puts only the *selected* element into the DOM.", "translation": "`NgSwitch` 指令类似于 JavaScript 的 `switch` 语句。\n它可以从多个可能的元素中根据*switch 条件*来显示某一个。\nAngular 只会把*选中的*元素放进 DOM 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGSWITCHISACTUALLYASETOFTHREECOOPERATINGDIRECTIVES:NGSWITCHNGSWITCHCASEANDNGSWITCHDEFAULTASSEENINTHISEXAMPLE", "original": "*NgSwitch* is actually a set of three, cooperating directives:\n`NgSwitch`, `NgSwitchCase`, and `NgSwitchDefault` as seen in this example.", "translation": "`NgSwitch` 实际上包括三个相互协作的指令:`NgSwitch`、`NgSwitchCase` 和 `NgSwitchDefault`,例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGSWITCHISTHECONTROLLERDIRECTIVEBINDITTOANEXPRESSIONTHATRETURNSTHESWITCHVALUETHEEMOTIONVALUEINTHISEXAMPLEISASTRINGBUTTHESWITCHVALUECANBEOFANYTYPE", "original": "`NgSwitch` is the controller directive. Bind it to an expression that returns the *switch value*.\nThe `emotion` value in this example is a string, but the switch value can be of any type.", "translation": "`NgSwitch` 是主控指令,要把它绑定到一个返回*候选值*的表达式。\n本例子中的 `emotion` 是个字符串,但实际上这个候选值可以是任意类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BINDTONGSWITCHYOULLGETANERRORIFYOUTRYTOSETNGSWITCHBECAUSENGSWITCHISANATTRIBUTEDIRECTIVENOTASTRUCTURALDIRECTIVEITCHANGESTHEBEHAVIOROFITSCOMPANIONDIRECTIVESITDOESNTTOUCHTHEDOMDIRECTLY", "original": "**Bind to `[ngSwitch]`**. You'll get an error if you try to set `*ngSwitch` because\n`NgSwitch` is an *attribute* directive, not a *structural* directive.\nIt changes the behavior of its companion directives.\nIt doesn't touch the DOM directly.", "translation": "**绑定到 `[ngSwitch]`**。如果试图用 `*ngSwitch` 的形式使用它就会报错,这是因为 `NgSwitch` 是一个*属性型*指令,而不是*结构型指令*。\n它要修改的是所在元素的行为,而不会直接接触 DOM 结构。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BINDTONGSWITCHCASEANDNGSWITCHDEFAULTTHENGSWITCHCASEANDNGSWITCHDEFAULTDIRECTIVESARESTRUCTURALDIRECTIVESBECAUSETHEYADDORREMOVEELEMENTSFROMTHEDOM", "original": "**Bind to `*ngSwitchCase` and `*ngSwitchDefault`**.\nThe `NgSwitchCase` and `NgSwitchDefault` directives are _structural_ directives\nbecause they add or remove elements from the DOM.", "translation": "**绑定到 `*ngSwitchCase` 和 `*ngSwitchDefault`**\n`NgSwitchCase` 和 `NgSwitchDefault` 指令都是*结构型指令*,因为它们会从 DOM 中添加或移除元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGSWITCHCASEADDSITSELEMENTTOTHEDOMWHENITSBOUNDVALUEEQUALSTHESWITCHVALUE", "original": "* `NgSwitchCase` adds its element to the DOM when its bound value equals the switch value.", "translation": "`NgSwitchCase` 会在它绑定到的值等于候选值时,把它所在的元素加入到 DOM 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "NGSWITCHDEFAULTADDSITSELEMENTTOTHEDOMWHENTHEREISNOSELECTEDNGSWITCHCASE", "original": "* `NgSwitchDefault` adds its element to the DOM when there is no selected `NgSwitchCase`.", "translation": "`NgSwitchDefault` 会在没有任何一个 `NgSwitchCase` 被选中时把它所在的元素加入 DOM 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESWITCHDIRECTIVESAREPARTICULARLYUSEFULFORADDINGANDREMOVINGCOMPONENTELEMENTSTHISEXAMPLESWITCHESAMONGFOUREMOTIONALHEROCOMPONENTSDEFINEDINTHEHEROSWITCHCOMPONENTSTSFILEEACHCOMPONENTHASAHEROINPUTPROPERTYGUIDETEMPLATESYNTAX#INPUTSOUTPUTSINPUTPROPERTYWHICHISBOUNDTOTHECURRENTHEROOFTHEPARENTCOMPONENT", "original": "The switch directives are particularly useful for adding and removing *component elements*.\nThis example switches among four \"emotional hero\" components defined in the `hero-switch.components.ts` file.\nEach component has a `hero` [input property](guide/template-syntax#inputs-outputs \"Input property\")\nwhich is bound to the `currentHero` of the parent component.", "translation": "这组指令在要添加或移除*组件元素*时会非常有用。\n这个例子会在 `hero-switch.components.ts` 中定义的四个“感人英雄”组件之间选择。\n每个组件都有一个[输入属性](guide/template-syntax#inputs-outputs \"Input property\")`hero`,它绑定到父组件的 `currentHero` 上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SWITCHDIRECTIVESWORKASWELLWITHNATIVEELEMENTSANDWEBCOMPONENTSTOOFOREXAMPLEYOUCOULDREPLACETHECONFUSEDHEROSWITCHCASEWITHTHEFOLLOWING", "original": "Switch directives work as well with native elements and web components too.\nFor example, you could replace the `<confused-hero>` switch case with the following.", "translation": "这组指令在原生元素和<a href=\"https://developer.mozilla.org/en-US/docs/Web/Web_Components\" target=\"_blank\" title=\"MDN: Web Components\">Web Component</a>上都可以正常工作。\n比如,你可以把 `<confused-hero>` 分支改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##TEMPLATEREFERENCEVARIABLESSPANCLASSSYNTAX#VARSPAN", "original": "## Template reference variables ( <span class=\"syntax\">#var</span> )", "translation": "## 模板引用变量 ( <span class=\"syntax\">#var</span> )", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATEMPLATEREFERENCEVARIABLEISOFTENAREFERENCETOADOMELEMENTWITHINATEMPLATEITCANALSOBEAREFERENCETOANANGULARCOMPONENTORDIRECTIVEORAAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBWEBCOMPONENTSTITLEMDN:WEBCOMPONENTSWEBCOMPONENTA", "original": "A **template reference variable** is often a reference to a DOM element within a template.\nIt can also be a reference to an Angular component or directive or a\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Web_Components\" title=\"MDN: Web Components\">web component</a>.", "translation": "**模板引用变量**通常用来引用模板中的某个 DOM 元素,它还可以引用 Angular 组件或指令或<a href=\"https://developer.mozilla.org/en-US/docs/Web/Web_Components\" target=\"_blank\" title=\"MDN: Web Components\">Web Component</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "USETHEHASHSYMBOL#TODECLAREAREFERENCEVARIABLETHE#PHONEDECLARESAPHONEVARIABLEONANINPUTELEMENT", "original": "Use the hash symbol (#) to declare a reference variable.\nThe `#phone` declares a `phone` variable on an `<input>` element.", "translation": "使用井号 (#) 来声明引用变量。\n`#phone` 的意思就是声明一个名叫 `phone` 的变量来引用 `<input>` 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANREFERTOATEMPLATEREFERENCEVARIABLEANYWHEREINTHETEMPLATETHEPHONEVARIABLEDECLAREDONTHISINPUTISCONSUMEDINABUTTONONTHEOTHERSIDEOFTHETEMPLATE", "original": "You can refer to a template reference variable _anywhere_ in the template.\nThe `phone` variable declared on this `<input>` is\nconsumed in a `<button>` on the other side of the template", "translation": "你可以在模板中的任何地方引用模板引用变量。\n比如声明在 `<input>` 上的 `phone` 变量就是在模板另一侧的 `<button>` 上使用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "H3CLASSNOTOCHOWAREFERENCEVARIABLEGETSITSVALUEH3", "original": "<h3 class=\"no-toc\">How a reference variable gets its value</h3>", "translation": "<h3 class=\"no-toc\">模板引用变量怎么得到它的值?</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INMOSTCASESANGULARSETSTHEREFERENCEVARIABLESVALUETOTHEELEMENTONWHICHITWASDECLAREDINTHEPREVIOUSEXAMPLEPHONEREFERSTOTHEPHONENUMBERINPUTBOXTHEPHONEBUTTONCLICKHANDLERPASSESTHEINPUTVALUETOTHECOMPONENTSCALLPHONEMETHODBUTADIRECTIVECANCHANGETHATBEHAVIORANDSETTHEVALUETOSOMETHINGELSESUCHASITSELFTHENGFORMDIRECTIVEDOESTHAT", "original": "In most cases, Angular sets the reference variable's value to the element on which it was declared.\nIn the previous example, `phone` refers to the _phone number_ `<input>` box.\nThe phone button click handler passes the _input_ value to the component's `callPhone` method.\nBut a directive can change that behavior and set the value to something else, such as itself.\nThe `NgForm` directive does that.", "translation": "大多数情况下,Angular 会把模板引用变量的值设置为声明它的那个元素。\n在上一个例子中,`phone` 引用的是表示*电话号码*的 `<input>` 框。\n\"拨号\"按钮的点击事件处理器把这个 *input* 值传给了组件的 `callPhone` 方法。\n不过,指令也可以修改这种行为,让这个值引用到别处,比如它自身。\n`NgForm` 指令就是这么做的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEFOLLOWINGISASIMPLIFIEDVERSIONOFTHEFORMEXAMPLEINTHEFORMSGUIDEFORMSGUIDE", "original": "The following is a *simplified* version of the form example in the [Forms](guide/forms) guide.", "translation": "下面是[表单](guide/forms)一章中表单范例的*简化版*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATEMPLATEREFERENCEVARIABLEHEROFORMAPPEARSTHREETIMESINTHISEXAMPLESEPARATEDBYALARGEAMOUNTOFHTMLWHATISTHEVALUEOFHEROFORM", "original": "A template reference variable, `heroForm`, appears three times in this example, separated\nby a large amount of HTML.\nWhat is the value of `heroForm`?", "translation": "模板引用变量 `heroForm` 在这个例子中出现了三次,中间隔着一大堆 HTML。\n`heroForm` 的值是什么?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "IFANGULARHADNTTAKENITOVERWHENYOUIMPORTEDTHEFORMSMODULEITWOULDBETHEHTMLFORMELEMENTHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIHTMLFORMELEMENTTHEHEROFORMISACTUALLYAREFERENCETOANANGULARNGFORMAPIFORMSNGFORMAPI:NGFORMDIRECTIVEWITHTHEABILITYTOTRACKTHEVALUEANDVALIDITYOFEVERYCONTROLINTHEFORM", "original": "If Angular hadn't taken it over when you imported the `FormsModule`,\nit would be the [HTMLFormElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement).\nThe `heroForm` is actually a reference to an Angular [NgForm](api/forms/NgForm \"API: NgForm\")\ndirective with the ability to track the value and validity of every control in the form.", "translation": "如果你没有导入过 `FormsModule`,Angular 就不会控制这个表单,那么它就是一个[HTMLFormElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement)实例。\n这里的 `heroForm` 实际上是一个 Angular [NgForm](api/forms/NgForm \"API: NgForm\") 指令的引用,\n因此具备了跟踪表单中的每个控件的值和有效性的能力。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THENATIVEFORMELEMENTDOESNTHAVEAFORMPROPERTYBUTTHENGFORMDIRECTIVEDOESWHICHEXPLAINSHOWYOUCANDISABLETHESUBMITBUTTONIFTHEHEROFORMFORMVALIDISINVALIDANDPASSTHEENTIREFORMCONTROLTREETOTHEPARENTCOMPONENTSONSUBMITMETHOD", "original": "The native `<form>` element doesn't have a `form` property.\nBut the `NgForm` directive does, which explains how you can disable the submit button\nif the `heroForm.form.valid` is invalid and pass the entire form control tree\nto the parent component's `onSubmit` method.", "translation": "原生的 `<form>` 元素没有 `form` 属性,但 `NgForm` 指令有。这就解释了为何当 `heroForm.form.valid` 是无效时你可以禁用提交按钮,\n并能把整个表单控件树传给父组件的 `onSubmit` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "H3CLASSNOTOCTEMPLATEREFERENCEVARIABLEWARNINGNOTESH3", "original": "<h3 class=\"no-toc\">Template reference variable warning notes</h3>", "translation": "<h3 class=\"no-toc\">关于模板引用变量的注意事项</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ATEMPLATEREFERENCEVARIABLE#PHONEISNOTTHESAMEASATEMPLATEINPUTVARIABLELETPHONESUCHASYOUMIGHTSEEINANNGFORGUIDETEMPLATESYNTAX#TEMPLATEINPUTVARIABLELEARNTHEDIFFERENCEINTHESTRUCTURALDIRECTIVESGUIDESTRUCTURALDIRECTIVES#TEMPLATEINPUTVARIABLEGUIDE", "original": "A template _reference_ variable (`#phone`) is _not_ the same as a template _input_ variable (`let phone`)\nsuch as you might see in an [`*ngFor`](guide/template-syntax#template-input-variable).\nLearn the difference in the [_Structural Directives_](guide/structural-directives#template-input-variable) guide.", "translation": "模板*引用*变量 (`#phone`) 和[`*ngFor`](guide/template-syntax#template-input-variable)部分看到过的模板*输入*变量 (`let phone`) 是不同的。\n要了解详情,参见[结构型指令](guide/structural-directives#template-input-variable)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESCOPEOFAREFERENCEVARIABLEISTHEENTIRETEMPLATEDONOTDEFINETHESAMEVARIABLENAMEMORETHANONCEINTHESAMETEMPLATETHERUNTIMEVALUEWILLBEUNPREDICTABLE", "original": "The scope of a reference variable is the _entire template_.\nDo not define the same variable name more than once in the same template.\nThe runtime value will be unpredictable.", "translation": "模板引用变量的作用范围是*整个模板*。\n不要在同一个模板中多次定义同一个变量名,否则它在运行期间的值是无法确定的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANUSETHEREFPREFIXALTERNATIVETO#THISEXAMPLEDECLARESTHEFAXVARIABLEASREFFAXINSTEADOF#FAX", "original": "You can use the `ref-` prefix alternative to `#`.\nThis example declares the `fax` variable as `ref-fax` instead of `#fax`.", "translation": "你也可以用 `ref-` 前缀代替 `#`。\n下面的例子中就用把 `fax` 变量声明成了 `ref-fax` 而不是 `#fax`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##INPUTANDOUTPUTPROPERTIES", "original": "## Input and Output properties", "translation": "## 输入和输出属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANINPUTPROPERTYISASETTABLEPROPERTYANNOTATEDWITHANINPUTDECORATORVALUESFLOWINTOTHEPROPERTYWHENITISDATABOUNDWITHAPROPERTYBINDING#PROPERTYBINDING", "original": "An _Input_ property is a _settable_ property annotated with an `@Input` decorator.\nValues flow _into_ the property when it is data bound with a [property binding](#property-binding)", "translation": "**输入**属性是一个带有 `@Input` 装饰器的**可设置**属性。当它通过[属性绑定](#property-binding)的形式被绑定时,值会“流入”这个属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANOUTPUTPROPERTYISANOBSERVABLEPROPERTYANNOTATEDWITHANOUTPUTDECORATORTHEPROPERTYALMOSTALWAYSRETURNSANANGULAREVENTEMITTERAPICOREEVENTEMITTERVALUESFLOWOUTOFTHECOMPONENTASEVENTSBOUNDWITHANEVENTBINDING#EVENTBINDING", "original": "An _Output_ property is an _observable_ property annotated with an `@Output` decorator.\nThe property almost always returns an Angular [`EventEmitter`](api/core/EventEmitter).\nValues flow _out_ of the component as events bound with an [event binding](#event-binding).", "translation": "**输出**属性是一个带有 `@Output` 装饰器的**可观察对象**型的属性。\n这个属性几乎总是返回 Angular 的[`EventEmitter`](api/core/EventEmitter)。\n当它通过[事件绑定](#event-binding)的形式被绑定时,值会“流出”这个属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANONLYBINDTOANOTHERCOMPONENTORDIRECTIVETHROUGHITSINPUTANDOUTPUTPROPERTIES", "original": "You can only bind to _another_ component or directive through its _Input_ and _Output_ properties.", "translation": "你只能通过它的**输入**和**输出**属性将其绑定到**其它**组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "REMEMBERTHATALLCOMPONENTSAREDIRECTIVES", "original": "Remember that all **components** are **directives**.", "translation": "记住,所有的**组件**都是**指令**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEFOLLOWINGDISCUSSIONREFERSTOCOMPONENTSFORBREVITYANDBECAUSETHISTOPICISMOSTLYACONCERNFORCOMPONENTAUTHORS", "original": "The following discussion refers to _components_ for brevity and \nbecause this topic is mostly a concern for component authors.", "translation": "为简洁起见,以下讨论会涉及到**组件**,因为这个主题主要是组件作者所关心的问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "H3CLASSNOTOCDISCUSSIONH3", "original": "<h3 class=\"no-toc\">Discussion</h3>", "translation": "<h3 class=\"no-toc\">讨论</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUAREUSUALLYBINDINGATEMPLATETOITSOWNCOMPONENTCLASSINSUCHBINDINGEXPRESSIONSTHECOMPONENTSPROPERTYORMETHODISTOTHERIGHTOFTHE", "original": "You are usually binding a template to its _own component class_.\nIn such binding expressions, the component's property or method is to the _right_ of the (`=`).", "translation": "在下面的例子中,`iconUrl` 和 `onSave` 是组件的成员,它们在 `=` 右侧引号语法中被引用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEICONURLANDONSAVEAREMEMBERSOFTHEAPPCOMPONENTCLASSTHEYARENOTDECORATEDWITHINPUTOROUTPUTANGULARDOESNOTOBJECT", "original": "The `iconUrl` and `onSave` are members of the `AppComponent` class.\nThey are _not_ decorated with `@Input()` or `@Output`.\nAngular does not object.", "translation": "`iconUrl` 和 `onSave` 是 `AppComponent` 类的成员。但它们并没有带 `@Input()` 或 `@Output()` 装饰器。\nAngular 不在乎。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANALWAYSBINDTOAPUBLICPROPERTYOFACOMPONENTINITSOWNTEMPLATEITDOESNTHAVETOBEANINPUTOROUTPUTPROPERTY", "original": "**You can always bind to a public property of a component in its own template.**\nIt doesn't have to be an _Input_ or _Output_ property", "translation": "**你总是可以在组件自己的模板中绑定到组件的公共属性,**而不用管它们是否输入(Input)属性或输出(Output)属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ACOMPONENTSCLASSANDTEMPLATEARECLOSELYCOUPLEDTHEYAREBOTHPARTSOFTHESAMETHINGTOGETHERTHEYARETHECOMPONENTEXCHANGESBETWEENACOMPONENTCLASSANDITSTEMPLATEAREINTERNALIMPLEMENTATIONDETAILS", "original": "A component's class and template are closely coupled.\nThey are both parts of the same thing.\nTogether they _are_ the component.\nExchanges between a component class and its template are internal implementation details.", "translation": "这是因为组件类和模板是紧耦合的,它们是同一个东西的两个部分,合起来构成组件。\n组件类及其模板之间的交互属于实现细节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###BINDINGTOADIFFERENTCOMPONENT", "original": "### Binding to a different component", "translation": "### 绑定到其它组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANALSOBINDTOAPROPERTYOFADIFFERENTCOMPONENTINSUCHBINDINGSTHEOTHERCOMPONENTSPROPERTYISTOTHELEFTOFTHE", "original": "You can also bind to a property of a _different_ component.\nIn such bindings, the _other_ component's property is to the _left_ of the (`=`).", "translation": "你也可以绑定到*其它*组件的属性。\n这种绑定形式下,*其它*组件的属性位于等号(`=`)的*左侧*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTHEFOLLOWINGEXAMPLETHEAPPCOMPONENTTEMPLATEBINDSAPPCOMPONENTCLASSMEMBERSTOPROPERTIESOFTHEHERODETAILCOMPONENTWHOSESELECTORISAPPHERODETAIL", "original": "In the following example, the `AppComponent` template binds `AppComponent` class members to properties of the `HeroDetailComponent` whose selector is `'app-hero-detail'`.", "translation": "下面的例子中,`AppComponent` 的模板把 `AppComponent` 类的成员绑定到了 `HeroDetailComponent`(选择器为 `'app-hero-detail'`) 的属性上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEANGULARCOMPILERMAYREJECTTHESEBINDINGSWITHERRORSLIKETHISONE:", "original": "The Angular compiler _may_ reject these bindings with errors like this one:", "translation": "Angular 的编译器*可能*会对这些绑定报错,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUKNOWTHATHERODETAILCOMPONENTHASHEROANDDELETEREQUESTPROPERTIESBUTTHEANGULARCOMPILERREFUSESTORECOGNIZETHEM", "original": "You know that `HeroDetailComponent` has `hero` and `deleteRequest` properties.\nBut the Angular compiler refuses to recognize them.", "translation": "你自己知道 `HeroDetailComponent` 有两个属性 `hero` 和 `detectRequest`,但 Angular 编译器并不知道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEANGULARCOMPILERWONTBINDTOPROPERTIESOFADIFFERENTCOMPONENTUNLESSTHEYAREINPUTOROUTPUTPROPERTIES", "original": "**The Angular compiler won't bind to properties of a different component\nunless they are Input or Output properties**.", "translation": "**Angular 编译器不会绑定到其它组件的属性上 —— 除非这些属性是输入或输出属性。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THERESAGOODREASONFORTHISRULE", "original": "There's a good reason for this rule.", "translation": "这条规则是有充分理由的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ITSOKFORACOMPONENTTOBINDTOITSOWNPROPERTIESTHECOMPONENTAUTHORISINCOMPLETECONTROLOFTHOSEBINDINGS", "original": "It's OK for a component to bind to its _own_ properties.\nThe component author is in complete control of those bindings.", "translation": "组件绑定到它*自己*的属性当然没问题。\n该组件的作者对这些绑定有完全的控制权。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "BUTOTHERCOMPONENTSSHOULDNTHAVETHATKINDOFUNRESTRICTEDACCESSYOUDHAVEAHARDTIMESUPPORTINGYOURCOMPONENTIFANYONECOULDBINDTOANYOFITSPROPERTIESOUTSIDECOMPONENTSSHOULDONLYBEABLETOBINDTOTHECOMPONENTSPUBLICBINDINGAPI", "original": "But other components shouldn't have that kind of unrestricted access.\nYou'd have a hard time supporting your component if anyone could bind to any of its properties.\nOutside components should only be able to bind to the component's public binding API.", "translation": "但是,其它组件不应该进行这种毫无限制的访问。\n如果任何人都可以绑定到你的组件的任何属性上,那么这个组件就很难维护。\n所以,外部组件应该只能绑定到组件的公共(允许绑定) API 上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULARASKSYOUTOBEEXPLICITABOUTTHATAPIITSUPTOYOUTODECIDEWHICHPROPERTIESAREAVAILABLEFORBINDINGBYEXTERNALCOMPONENTS", "original": "Angular asks you to be _explicit_ about that API.\nIt's up to _you_ to decide which properties are available for binding by\nexternal components.", "translation": "Angular 要求你*显式声明*那些 API。\n它让*你*可以自己决定哪些属性是可以被外部组件绑定的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "####TYPESCRIPTPUBLICDOESNTMATTER", "original": "#### TypeScript _public_ doesn't matter", "translation": "#### TypeScript 的 `public` 是没用的", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANTUSETHETYPESCRIPTPUBLICANDPRIVATEACCESSMODIFIERSTOSHAPETHECOMPONENTSPUBLICBINDINGAPI", "original": "You can't use the TypeScript _public_ and _private_ access modifiers to\nshape the component's public binding API.", "translation": "你不能用 TypeScript 的 `public` 和 `private` 访问控制符来标明组件的公共 API。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ALLDATABOUNDPROPERTIESMUSTBETYPESCRIPTPUBLICPROPERTIESANGULARNEVERBINDSTOATYPESCRIPTPRIVATEPROPERTY", "original": "All data bound properties must be TypeScript _public_ properties.\nAngular never binds to a TypeScript _private_ property.", "translation": "所有数据绑定属性必须是 TypeScript 的公共属性,Angular 永远不会绑定到 TypeScript 中的私有属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULARREQUIRESSOMEOTHERWAYTOIDENTIFYPROPERTIESTHATOUTSIDECOMPONENTSAREALLOWEDTOBINDTOTHATOTHERWAYISTHEINPUTANDOUTPUTDECORATORS", "original": "Angular requires some other way to identify properties that _outside_ components are allowed to bind to.\nThat _other way_ is the `@Input()` and `@Output()` decorators.", "translation": "因此,Angular 需要一些其它方式来标记出那些允许被*外部*组件绑定到的属性。\n这种*其它方式*,就是 `@Input()` 和 `@Output()` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###DECLARINGINPUTANDOUTPUTPROPERTIES", "original": "### Declaring Input and Output properties", "translation": "### 声明输入与输出属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTHESAMPLEFORTHISGUIDETHEBINDINGSTOHERODETAILCOMPONENTDONOTFAILBECAUSETHEDATABOUNDPROPERTIESAREANNOTATEDWITHINPUTANDOUTPUTDECORATORS", "original": "In the sample for this guide, the bindings to `HeroDetailComponent` do not fail\nbecause the data bound properties are annotated with `@Input()` and `@Output()` decorators.", "translation": "在本章的例子中,绑定到 `HeroDetailComponent` 不会失败,这是因为这些要进行数据绑定的属性都带有 `@Input()` 和 `@Output()` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ALTERNATIVELYYOUCANIDENTIFYMEMBERSINTHEINPUTSANDOUTPUTSARRAYSOFTHEDIRECTIVEMETADATAASINTHISEXAMPLE:", "original": "Alternatively, you can identify members in the `inputs` and `outputs` arrays\nof the directive metadata, as in this example:", "translation": "另外,还可以在指令元数据的 `inputs` 或 `outputs` 数组中标记出这些成员。比如这个例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###INPUTOROUTPUT", "original": "### Input or output?", "translation": "### 输入还是输出?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INPUTPROPERTIESUSUALLYRECEIVEDATAVALUESOUTPUTPROPERTIESEXPOSEEVENTPRODUCERSSUCHASEVENTEMITTEROBJECTS", "original": "*Input* properties usually receive data values.\n*Output* properties expose event producers, such as `EventEmitter` objects.", "translation": "*输入*属性通常接收数据值。\n*输出*属性暴露事件生产者,如 `EventEmitter` 对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETERMSINPUTANDOUTPUTREFLECTTHEPERSPECTIVEOFTHETARGETDIRECTIVE", "original": "The terms _input_ and _output_ reflect the perspective of the target directive.", "translation": "*输入*和*输出*这两个词是从目标指令的角度来说的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HERODETAILCOMPONENTHEROISANINPUTPROPERTYFROMTHEPERSPECTIVEOFHERODETAILCOMPONENTBECAUSEDATAFLOWSINTOTHATPROPERTYFROMATEMPLATEBINDINGEXPRESSION", "original": "`HeroDetailComponent.hero` is an **input** property from the perspective of `HeroDetailComponent`\nbecause data flows *into* that property from a template binding expression.", "translation": "从 `HeroDetailComponent` 角度来看,`HeroDetailComponent.hero` 是个**输入**属性,\n因为数据流从模板绑定表达式流*入*那个属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HERODETAILCOMPONENTDELETEREQUESTISANOUTPUTPROPERTYFROMTHEPERSPECTIVEOFHERODETAILCOMPONENTBECAUSEEVENTSSTREAMOUTOFTHATPROPERTYANDTOWARDTHEHANDLERINATEMPLATEBINDINGSTATEMENT", "original": "`HeroDetailComponent.deleteRequest` is an **output** property from the perspective of `HeroDetailComponent`\nbecause events stream *out* of that property and toward the handler in a template binding statement.", "translation": "从 `HeroDetailComponent` 角度来看,`HeroDetailComponent.deleteRequest` 是个**输出**属性,\n因为事件从那个属性流*出*,流向模板绑定语句中的处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "H3IDALIASINGIOALIASINGINPUTOUTPUTPROPERTIESH3", "original": "<h3 id='aliasing-io'>Aliasing input/output properties</h3>", "translation": "<h3 id='aliasing-io'>给输入/输出属性起别名</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SOMETIMESTHEPUBLICNAMEOFANINPUTOUTPUTPROPERTYSHOULDBEDIFFERENTFROMTHEINTERNALNAME", "original": "Sometimes the public name of an input/output property should be different from the internal name.", "translation": "有时需要让输入/输出属性的公共名字不同于内部名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISISFREQUENTLYTHECASEWITHATTRIBUTEDIRECTIVESGUIDEATTRIBUTEDIRECTIVESDIRECTIVECONSUMERSEXPECTTOBINDTOTHENAMEOFTHEDIRECTIVEFOREXAMPLEWHENYOUAPPLYADIRECTIVEWITHAMYCLICKSELECTORTOADIVTAGYOUEXPECTTOBINDTOANEVENTPROPERTYTHATISALSOCALLEDMYCLICK", "original": "This is frequently the case with [attribute directives](guide/attribute-directives).\nDirective consumers expect to bind to the name of the directive.\nFor example, when you apply a directive with a `myClick` selector to a `<div>` tag,\nyou expect to bind to an event property that is also called `myClick`.", "translation": "这是使用 [attribute 指令](guide/attribute-directives)时的常见情况。\n指令的使用者期望绑定到指令名。例如,在 `<div>` 上用 `myClick` 选择器应用指令时,\n希望绑定的事件属性也叫 `myClick`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "HOWEVERTHEDIRECTIVENAMEISOFTENAPOORCHOICEFORTHENAMEOFAPROPERTYWITHINTHEDIRECTIVECLASSTHEDIRECTIVENAMERARELYDESCRIBESWHATTHEPROPERTYDOESTHEMYCLICKDIRECTIVENAMEISNOTAGOODNAMEFORAPROPERTYTHATEMITSCLICKMESSAGES", "original": "However, the directive name is often a poor choice for the name of a property within the directive class.\nThe directive name rarely describes what the property does.\nThe `myClick` directive name is not a good name for a property that emits click messages.", "translation": "然而,在指令类中,直接用指令名作为自己的属性名通常都不是好的选择。\n指令名很少能描述这个属性是干嘛的。\n`myClick` 这个指令名对于用来发出 click 消息的属性就算不上一个好名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "FORTUNATELYYOUCANHAVEAPUBLICNAMEFORTHEPROPERTYTHATMEETSCONVENTIONALEXPECTATIONSWHILEUSINGADIFFERENTNAMEINTERNALLYINTHEEXAMPLEIMMEDIATELYABOVEYOUAREACTUALLYBINDINGTHROUGHTHEMYCLICKALIASTOTHEDIRECTIVESOWNCLICKSPROPERTY", "original": "Fortunately, you can have a public name for the property that meets conventional expectations,\nwhile using a different name internally.\nIn the example immediately above, you are actually binding *through the* `myClick` *alias* to\nthe directive's own `clicks` property.", "translation": "幸运的是,可以使用约定俗成的公共名字,同时在内部使用不同的名字。\n在上面例子中,实际上是把 `myClick` 这个别名指向了指令自己的 `clicks` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANSPECIFYTHEALIASFORTHEPROPERTYNAMEBYPASSINGITINTOTHEINPUTOUTPUTDECORATORLIKETHIS:", "original": "You can specify the alias for the property name by passing it into the input/output decorator like this:", "translation": "把别名传进@Input/@Output 装饰器,就可以为属性指定别名,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANALSOALIASPROPERTYNAMESINTHEINPUTSANDOUTPUTSARRAYSYOUWRITEACOLONDELIMITED:STRINGWITHTHEDIRECTIVEPROPERTYNAMEONTHELEFTANDTHEPUBLICALIASONTHERIGHT:", "original": "You can also alias property names in the `inputs` and `outputs` arrays.\nYou write a colon-delimited (`:`) string with\nthe directive property name on the *left* and the public alias on the *right*:", "translation": "也可在 `inputs` 和 `outputs` 数组中为属性指定别名。\n可以写一个冒号 (`:`) 分隔的字符串,*左侧*是指令中的属性名,*右侧*则是公共别名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##TEMPLATEEXPRESSIONOPERATORS", "original": "## Template expression operators", "translation": "## 模板表达式操作符", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETEMPLATEEXPRESSIONLANGUAGEEMPLOYSASUBSETOFJAVASCRIPTSYNTAXSUPPLEMENTEDWITHAFEWSPECIALOPERATORSFORSPECIFICSCENARIOSTHENEXTSECTIONSCOVERTWOOFTHESEOPERATORS:PIPEANDSAFENAVIGATIONOPERATOR", "original": "The template expression language employs a subset of JavaScript syntax supplemented with a few special operators\nfor specific scenarios. The next sections cover two of these operators: _pipe_ and _safe navigation operator_.", "translation": "模板表达式语言使用了 JavaScript 语法的子集,并补充了几个用于特定场景的特殊操作符。\n 下面介绍其中的两个:*管道*和*安全导航操作符*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###THEPIPEOPERATORSPANCLASSSYNTAXSPAN", "original": "### The pipe operator ( <span class=\"syntax\">|</span> )", "translation": "### 管道操作符 ( | )", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THERESULTOFANEXPRESSIONMIGHTREQUIRESOMETRANSFORMATIONBEFOREYOUREREADYTOUSEITINABINDINGFOREXAMPLEYOUMIGHTDISPLAYANUMBERASACURRENCYFORCETEXTTOUPPERCASEORFILTERALISTANDSORTIT", "original": "The result of an expression might require some transformation before you're ready to use it in a binding.\nFor example, you might display a number as a currency, force text to uppercase, or filter a list and sort it.", "translation": "在绑定之前,表达式的结果可能需要一些转换。例如,可能希望把数字显示成金额、强制文本变成大写,或者过滤列表以及进行排序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANGULARPIPESGUIDEPIPESAREAGOODCHOICEFORSMALLTRANSFORMATIONSSUCHASTHESEPIPESARESIMPLEFUNCTIONSTHATACCEPTANINPUTVALUEANDRETURNATRANSFORMEDVALUETHEYREEASYTOAPPLYWITHINTEMPLATEEXPRESSIONSUSINGTHEPIPEOPERATOR:", "original": "Angular [pipes](guide/pipes) are a good choice for small transformations such as these.\nPipes are simple functions that accept an input value and return a transformed value.\nThey're easy to apply within template expressions, using the **pipe operator (`|`)**:", "translation": "Angular [管道](guide/pipes)对像这样的小型转换来说是个明智的选择。\n管道是一个简单的函数,它接受一个输入值,并返回转换结果。\n它们很容易用于模板表达式中,只要使用**管道操作符 (`|`) **就行了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEPIPEOPERATORPASSESTHERESULTOFANEXPRESSIONONTHELEFTTOAPIPEFUNCTIONONTHERIGHT", "original": "The pipe operator passes the result of an expression on the left to a pipe function on the right.", "translation": "管道操作符会把它左侧的表达式结果传给它右侧的管道函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCANCHAINEXPRESSIONSTHROUGHMULTIPLEPIPES:", "original": "You can chain expressions through multiple pipes:", "translation": "还可以通过多个管道串联表达式:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ANDYOUCANALSOAPPLYPARAMETERSGUIDEPIPES#PARAMETERIZINGAPIPETOAPIPE:", "original": "And you can also [apply parameters](guide/pipes#parameterizing-a-pipe) to a pipe:", "translation": "还能对它们使用参数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEJSONPIPEISPARTICULARLYHELPFULFORDEBUGGINGBINDINGS:", "original": "The `json` pipe is particularly helpful for debugging bindings:", "translation": "`json` 管道对调试绑定特别有用:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEGENERATEDOUTPUTWOULDLOOKSOMETHINGLIKETHIS", "original": "The generated output would look something like this", "translation": "它生成的输出是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###THESAFENAVIGATIONOPERATORSPANCLASSSYNTAXSPANANDNULLPROPERTYPATHS", "original": "### The safe navigation operator ( <span class=\"syntax\">?.</span> ) and null property paths", "translation": "### 安全导航操作符 ( ?. ) 和空属性路径", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEANGULARSAFENAVIGATIONOPERATORISAFLUENTANDCONVENIENTWAYTOGUARDAGAINSTNULLANDUNDEFINEDVALUESINPROPERTYPATHSHEREITISPROTECTINGAGAINSTAVIEWRENDERFAILUREIFTHECURRENTHEROISNULL", "original": "The Angular **safe navigation operator (`?.`)** is a fluent and convenient way to\nguard against null and undefined values in property paths.\nHere it is, protecting against a view render failure if the `currentHero` is null.", "translation": "Angular 的**安全导航操作符 (`?.`) **是一种流畅而便利的方式,用来保护出现在属性路径中 null 和 undefined 值。\n下例中,当 `currentHero` 为空时,保护视图渲染器,让它免于失败。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHATHAPPENSWHENTHEFOLLOWINGDATABOUNDTITLEPROPERTYISNULL", "original": "What happens when the following data bound `title` property is null?", "translation": "如果下列数据绑定中 `title` 属性为空,会发生什么?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEVIEWSTILLRENDERSBUTTHEDISPLAYEDVALUEISBLANKYOUSEEONLYTHETITLEISWITHNOTHINGAFTERITTHATISREASONABLEBEHAVIORATLEASTTHEAPPDOESNTCRASH", "original": "The view still renders but the displayed value is blank; you see only \"The title is\" with nothing after it.\nThat is reasonable behavior. At least the app doesn't crash.", "translation": "这个视图仍然被渲染出来,但是显示的值是空;只能看到 “The title is”,它后面却没有任何东西。\n这是合理的行为。至少应用没有崩溃。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SUPPOSETHETEMPLATEEXPRESSIONINVOLVESAPROPERTYPATHASINTHISNEXTEXAMPLETHATDISPLAYSTHENAMEOFANULLHERO", "original": "Suppose the template expression involves a property path, as in this next example\nthat displays the `name` of a null hero.", "translation": "假设模板表达式涉及属性路径,在下例中,显示一个空 (null) 英雄的 `firstName`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "JAVASCRIPTTHROWSANULLREFERENCEERRORANDSODOESANGULAR:", "original": "JavaScript throws a null reference error, and so does Angular:", "translation": "JavaScript 抛出了空引用错误,Angular 也是如此:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WORSETHEENTIREVIEWDISAPPEARS", "original": "Worse, the *entire view disappears*.", "translation": "晕,*整个视图都不见了*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THISWOULDBEREASONABLEBEHAVIORIFTHEHEROPROPERTYCOULDNEVERBENULLIFITMUSTNEVERBENULLANDYETITISNULLTHATSAPROGRAMMINGERRORTHATSHOULDBECAUGHTANDFIXEDTHROWINGANEXCEPTIONISTHERIGHTTHINGTODO", "original": "This would be reasonable behavior if the `hero` property could never be null.\nIf it must never be null and yet it is null,\nthat's a programming error that should be caught and fixed.\nThrowing an exception is the right thing to do.", "translation": "如果确信 `hero` 属性永远不可能为空,可以声称这是合理的行为。\n如果它必须不能为空,但它仍然是空值,实际上是制造了一个编程错误,它应该被捕获和修复。\n这种情况应该抛出异常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ONTHEOTHERHANDNULLVALUESINTHEPROPERTYPATHMAYBEOKFROMTIMETOTIMEESPECIALLYWHENTHEDATAARENULLNOWANDWILLARRIVEEVENTUALLY", "original": "On the other hand, null values in the property path may be OK from time to time,\nespecially when the data are null now and will arrive eventually.", "translation": "另一方面,属性路径中的空值可能会时常发生,特别是数据目前为空但最终会出现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHILEWAITINGFORDATATHEVIEWSHOULDRENDERWITHOUTCOMPLAINTANDTHENULLPROPERTYPATHSHOULDDISPLAYASBLANKJUSTASTHETITLEPROPERTYDOES", "original": "While waiting for data, the view should render without complaint, and\nthe null property path should display as blank just as the `title` property does.", "translation": "当等待数据的时候,视图渲染器不应该抱怨,而应该把这个空属性路径显示为空白,就像上面 `title` 属性那样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "UNFORTUNATELYTHEAPPCRASHESWHENTHECURRENTHEROISNULL", "original": "Unfortunately, the app crashes when the `currentHero` is null.", "translation": "不幸的是,当 `currentHero` 为空的时候,应用崩溃了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCOULDCODEAROUNDTHATPROBLEMWITHNGIFGUIDETEMPLATESYNTAX#NGIF", "original": "You could code around that problem with [*ngIf](guide/template-syntax#ngIf).", "translation": "可以通过用[NgIf](guide/template-syntax#ngIf)代码环绕它来解决这个问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUCOULDTRYTOCHAINPARTSOFTHEPROPERTYPATHWITHKNOWINGTHATTHEEXPRESSIONBAILSOUTWHENITENCOUNTERSTHEFIRSTNULL", "original": "You could try to chain parts of the property path with `&&`, knowing that the expression bails out\nwhen it encounters the first null.", "translation": "或者可以尝试通过 `&&` 来把属性路径的各部分串起来,让它在遇到第一个空值的时候,就返回空。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THESEAPPROACHESHAVEMERITBUTCANBECUMBERSOMEESPECIALLYIFTHEPROPERTYPATHISLONGIMAGINEGUARDINGAGAINSTANULLSOMEWHEREINALONGPROPERTYPATHSUCHASABCD", "original": "These approaches have merit but can be cumbersome, especially if the property path is long.\nImagine guarding against a null somewhere in a long property path such as `a.b.c.d`.", "translation": "这些方法都有价值,但是会显得笨重,特别是当这个属性路径非常长的时候。\n想象一下在一个很长的属性路径(如 `a.b.c.d`)中对空值提供保护。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEANGULARSAFENAVIGATIONOPERATORISAMOREFLUENTANDCONVENIENTWAYTOGUARDAGAINSTNULLSINPROPERTYPATHSTHEEXPRESSIONBAILSOUTWHENITHITSTHEFIRSTNULLVALUETHEDISPLAYISBLANKBUTTHEAPPKEEPSROLLINGWITHOUTERRORS", "original": "The Angular safe navigation operator (`?.`) is a more fluent and convenient way to guard against nulls in property paths.\nThe expression bails out when it hits the first null value.\nThe display is blank, but the app keeps rolling without errors.", "translation": "Angular 安全导航操作符 (`?.`) 是在属性路径中保护空值的更加流畅、便利的方式。\n表达式会在它遇到第一个空值的时候跳出。\n显示是空的,但应用正常工作,而没有发生错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ITWORKSPERFECTLYWITHLONGPROPERTYPATHSSUCHASABCD", "original": "It works perfectly with long property paths such as `a?.b?.c?.d`.", "translation": "在像 `a?.b?.c?.d` 这样的长属性路径中,它工作得很完美。<a href=\"#top-of-page\">back to top</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "###THENONNULLASSERTIONOPERATORSPANCLASSSYNTAXSPAN", "original": "### The non-null assertion operator ( <span class=\"syntax\">!</span> )", "translation": "### 非空断言操作符(<span class=\"syntax\">!</span>)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "ASOFTYPESCRIPT20YOUCANENFORCESTRICTNULLCHECKINGHTTP:WWWTYPESCRIPTLANGORGDOCSHANDBOOKRELEASENOTESTYPESCRIPT20HTMLSTRICTNULLCHECKINGINTYPESCRIPTWITHTHESTRICTNULLCHECKSFLAGTYPESCRIPTTHENENSURESTHATNOVARIABLEISUNINTENTIONALLYNULLORUNDEFINED", "original": "As of Typescript 2.0, you can enforce [strict null checking](http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html \"Strict null checking in TypeScript\") with the `--strictNullChecks` flag. TypeScript then ensures that no variable is _unintentionally_ null or undefined.", "translation": "在 TypeScript 2.0 中,你可以使用 `--strictNullChecks` 标志强制开启[严格空值检查](http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html \"Strict null checking in TypeScript\")。TypeScript 就会确保不存在意料之外的 null 或 undefined。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTHISMODETYPEDVARIABLESDISALLOWNULLANDUNDEFINEDBYDEFAULTTHETYPECHECKERTHROWSANERRORIFYOULEAVEAVARIABLEUNASSIGNEDORTRYTOASSIGNNULLORUNDEFINEDTOAVARIABLEWHOSETYPEDISALLOWSNULLANDUNDEFINED", "original": "In this mode, typed variables disallow null and undefined by default. The type checker throws an error if you leave a variable unassigned or try to assign null or undefined to a variable whose type disallows null and undefined.", "translation": "在这种模式下,有类型的变量默认是不允许 null 或 undefined 值的,如果有未赋值的变量,或者试图把 null 或 undefined 赋值给不允许为空的变量,类型检查器就会抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THETYPECHECKERALSOTHROWSANERRORIFITCANTDETERMINEWHETHERAVARIABLEWILLBENULLORUNDEFINEDATRUNTIMEYOUMAYKNOWTHATCANTHAPPENBUTTHETYPECHECKERDOESNTKNOWYOUTELLTHETYPECHECKERTHATITCANTHAPPENBYAPPLYINGTHEPOSTFIXNONNULLASSERTIONOPERATORHTTP:WWWTYPESCRIPTLANGORGDOCSHANDBOOKRELEASENOTESTYPESCRIPT20HTML#NONNULLASSERTIONOPERATORNONNULLASSERTIONOPERATOR", "original": "The type checker also throws an error if it can't determine whether a variable will be null or undefined at runtime.\nYou may know that can't happen but the type checker doesn't know.\nYou tell the type checker that it can't happen by applying the post-fix\n[_non-null assertion operator (!)_](http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator \"Non-null assertion operator\").", "translation": "如果类型检查器在运行期间无法确定一个变量是 null 或 undefined,那么它也会抛出一个错误。\n你自己可能知道它不会为空,但类型检查器不知道。\n所以你要告诉类型检查器,它不会为空,这时就要用到[*非空断言操作符*](http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator \"Non-null assertion operator\")。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEANGULARNONNULLASSERTIONOPERATORSERVESTHESAMEPURPOSEINANANGULARTEMPLATE", "original": "The _Angular_ **non-null assertion operator (`!`)** serves the same purpose in an Angular template.", "translation": "*Angular* 模板中的**非空断言操作符(`!`)也是同样的用途。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "FOREXAMPLEAFTERYOUUSENGIFGUIDETEMPLATESYNTAX#NGIFTOCHECKTHATHEROISDEFINEDYOUCANASSERTTHATHEROPROPERTIESAREALSODEFINED", "original": "For example, after you use [*ngIf](guide/template-syntax#ngIf) to check that `hero` is defined, you can assert that\n`hero` properties are also defined.", "translation": "例如,在用[*ngIf](guide/template-syntax#ngIf)来检查过 `hero` 是已定义的之后,就可以断言 `hero` 属性一定是已定义的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "WHENTHEANGULARCOMPILERTURNSYOURTEMPLATEINTOTYPESCRIPTCODEITPREVENTSTYPESCRIPTFROMREPORTINGTHATHERONAMEMIGHTBENULLORUNDEFINED", "original": "When the Angular compiler turns your template into TypeScript code,\nit prevents TypeScript from reporting that `hero.name` might be null or undefined.", "translation": "在 Angular 编译器把你的模板转换成 TypeScript 代码时,这个操作符会防止 TypeScript 报告 \"`hero.name` 可能为 null 或 undefined\"的错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "UNLIKETHESAFENAVIGATIONOPERATORGUIDETEMPLATESYNTAX#SAFENAVIGATIONOPERATORSAFENAVIGATIONOPERATORTHENONNULLASSERTIONOPERATORDOESNOTGUARDAGAINSTNULLORUNDEFINEDRATHERITTELLSTHETYPESCRIPTTYPECHECKERTOSUSPENDSTRICTNULLCHECKSFORASPECIFICPROPERTYEXPRESSION", "original": "Unlike the [_safe navigation operator_](guide/template-syntax#safe-navigation-operator \"Safe navigation operator (?.)\"),\nthe **non-null assertion operator** does not guard against null or undefined.\nRather it tells the TypeScript type checker to suspend strict null checks for a specific property expression.", "translation": "与[*安全导航操作符*](guide/template-syntax#safe-navigation-operator \"Safe naviation operator (?.)\")不同的是,**非空断言操作符**不会防止出现 null 或 undefined。\n它只是告诉 TypeScript 的类型检查器对特定的属性表达式,不做 \"严格空值检测\"。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOULLNEEDTHISTEMPLATEOPERATORWHENYOUTURNONSTRICTNULLCHECKSITSOPTIONALOTHERWISE", "original": "You'll need this template operator when you turn on strict null checks. It's optional otherwise.", "translation": "如果你打开了严格控制检测,那就要用到这个模板操作符,而其它情况下则是可选的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "AHREF#TOPOFPAGEBACKTOTOPA", "original": "<a href=\"#top-of-page\">back to top</a>", "translation": "<a href=\"#top-of-page\">回到顶部</a>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##THEANYTYPECASTFUNCTIONANYEXPRESSION", "original": "## The `$any` type cast function (`$any( <expression> )`)", "translation": "## 类型转换函数 `$any` ($any( <表达式> ))", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "SOMETIMESABINDINGEXPRESSIONWILLBEREPORTEDASATYPEERRORANDITISNOTPOSSIBLEORDIFFICULTTOFULLYSPECIFYTHETYPETOSILENCETHEERRORYOUCANUSETHEANYCASTFUNCTIONTOCASTTHEEXPRESSIONTOTHEANYTYPEHTTP:WWWTYPESCRIPTLANGORGDOCSHANDBOOKBASICTYPESHTML#ANY", "original": "Sometimes a binding expression will be reported as a type error and it is not possible or difficult\nto fully specify the type. To silence the error, you can use the `$any` cast function to cast\nthe expression to [the `any` type](http://www.typescriptlang.org/docs/handbook/basic-types.html#any).", "translation": "有时候,绑定表达式可能会报类型错误,并且它不能或很难指定类型。要消除这种报错,你可以使用 `$any` 转换函数来把表达式转换成 [`any` 类型](http://www.typescriptlang.org/docs/handbook/basic-types.html#any)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "INTHISEXAMPLEWHENTHEANGULARCOMPILERTURNSYOURTEMPLATEINTOTYPESCRIPTCODEITPREVENTSTYPESCRIPTFROMREPORTINGTHATMARKERISNOTAMEMBEROFTHEHEROINTERFACE", "original": "In this example, when the Angular compiler turns your template into TypeScript code, \nit prevents TypeScript from reporting that `marker` is not a member of the `Hero`\ninterface.", "translation": "在这个例子中,当 Angular 编译器把模板转换成 TypeScript 代码时,`$any` 表达式可以防止 TypeScript 编译器报错说 `marker` 不是 `Hero` 接口的成员。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEANYCASTFUNCTIONCANBEUSEDINCONJUNCTIONWITHTHISTOALLOWACCESSTOUNDECLAREDMEMBERSOFTHECOMPONENT", "original": "The `$any` cast function can be used in conjunction with `this` to allow access to undeclared members of\nthe component.", "translation": "`$any` 转换函数可以和 `this` 联合使用,以便访问组件中未声明过的成员。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "THEANYCASTFUNCTIONCANBEUSEDANYWHEREINABINDINGEXPRESSIONWHEREAMETHODCALLISVALID", "original": "The `$any` cast function can be used anywhere in a binding expression where a method call is valid.", "translation": "`$any` 转换函数可以在绑定表达式中任何可以进行方法调用的地方使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "YOUVECOMPLETEDTHISSURVEYOFTEMPLATESYNTAXNOWITSTIMETOPUTTHATKNOWLEDGETOWORKONYOUROWNCOMPONENTSANDDIRECTIVES", "original": "You've completed this survey of template syntax.\nNow it's time to put that knowledge to work on your own components and directives.", "translation": "你完成了模板语法的概述。现在,该把如何写组件和指令的知识投入到实际工作当中了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/template-syntax.md" }, { + "key": "#TESTING", "original": "# Testing", "translation": "# 测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing-observables.md" }, { + "key": "#TESTING", "original": "# Testing", "translation": "# 测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISGUIDEOFFERSTIPSANDTECHNIQUESFORUNITANDINTEGRATIONTESTINGANGULARAPPLICATIONS", "original": "This guide offers tips and techniques for unit and integration testing Angular applications.", "translation": "该指南提供了对 Angular 应用进行单元测试和集成测试的技巧和提示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEGUIDEPRESENTSTESTSOFASAMPLECLIAPPLICATIONTHATISMUCHLIKETHETOUROFHEROESTUTORIALTUTORIALTHESAMPLEAPPLICATIONANDALLTESTSINTHISGUIDEAREAVAILABLEFORINSPECTIONANDEXPERIMENTATION:", "original": "The guide presents tests of a sample CLI application that is much like the [_Tour of Heroes_ tutorial](tutorial).\nThe sample application and all tests in this guide are available for inspection and experimentation:", "translation": "该指南中的测试面向的是一个很像[《英雄指南》教程](tutorial)的 CLI 范例应用。\n这个范例应用及其所有测试都可以在下面的链接中进行查看和试用:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "LIVEEXAMPLEEMBEDDEDSTYLESAMPLEAPPLIVEEXAMPLE", "original": "* <live-example embedded-style>Sample app</live-example>", "translation": "<live-example embedded-style>范例应用</live-example>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "LIVEEXAMPLESTACKBLITZSPECSTESTSLIVEEXAMPLE", "original": "* <live-example stackblitz=\"specs\">Tests</live-example>", "translation": "<live-example stackblitz=\"specs\">测试</live-example>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##SETUP", "original": "## Setup", "translation": "## 准备工作", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEANGULARCLIDOWNLOADSANDINSTALLEVERYTHINGYOUNEEDTOTESTANANGULARAPPLICATIONWITHTHEJASMINETESTFRAMEWORKHTTP:JASMINEGITHUBIO24INTRODUCTIONHTML", "original": "The Angular CLI downloads and install everything you need to test an Angular application with the [Jasmine test framework](http://jasmine.github.io/2.4/introduction.html).", "translation": "Angular CLI 会下载并安装试用 [Jasmine 测试框架](http://jasmine.github.io/2.4/introduction.html) 测试 Angular 应用时所需的一切。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEPROJECTYOUCREATEWITHTHECLIISIMMEDIATELYREADYTOTESTJUSTRUNTHISONECLICOMMAND:", "original": "The project you create with the CLI is immediately ready to test.\nJust run this one CLI command:", "translation": "你使用 CLI 创建的项目是可以立即用于测试的。\n运行下列 CLI 命令即可:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENGTESTCOMMANDBUILDSTHEAPPINWATCHMODEANDLAUNCHESTHEKARMATESTRUNNERHTTPS:KARMARUNNERGITHUBIO10INDEXHTML", "original": "The `ng test` command builds the app in _watch mode_,\nand launches the [karma test runner](https://karma-runner.github.io/1.0/index.html).", "translation": "`ng test` 命令在*监视模式*下构建应用,并启动 [karma 测试运行器](https://karma-runner.github.io/1.0/index.html)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECONSOLEOUTPUTLOOKSABITLIKETHIS:", "original": "The console output looks a bit like this:", "translation": "它的控制台输出一般是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THELASTLINEOFTHELOGISTHEMOSTIMPORTANTITSHOWSTHATKARMARANTHREETESTSTHATALLPASSED", "original": "The last line of the log is the most important. \nIt shows that Karma ran three tests that all passed.", "translation": "最后一行很重要。它表示 Karma 运行了三个测试,而且这些测试都通过了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ACHROMEBROWSERALSOOPENSANDDISPLAYSTHETESTOUTPUTINTHEJASMINEHTMLREPORTERLIKETHIS", "original": "A chrome browser also opens and displays the test output in the \"Jasmine HTML Reporter\" like this.", "translation": "它还会打开 Chrome 浏览器并在“ Jasmine HTML 报告器”中显示测试输出,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MOSTPEOPLEFINDTHISBROWSEROUTPUTEASIERTOREADTHANTHECONSOLELOGYOUCANCLICKONATESTROWTORERUNJUSTTHATTESTORCLICKONADESCRIPTIONTORERUNTHETESTSINTHESELECTEDTESTGROUPTESTSUITE", "original": "Most people find this browser output easier to read than the console log.\nYou can click on a test row to re-run just that test or click on a description to re-run the tests in the selected test group (\"test suite\").", "translation": "大多数人都会觉得浏览器中的报告比控制台中的日志更容易阅读。\n你可以点击一行测试,来单独重跑这个测试,或者点击一行描述信息来重跑所选测试组(“测试套件”)中的那些测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MEANWHILETHENGTESTCOMMANDISWATCHINGFORCHANGES", "original": "Meanwhile, the `ng test` command is watching for changes.", "translation": "同时,`ng test` 命令还会监听这些变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOSEETHISINACTIONMAKEASMALLCHANGETOAPPCOMPONENTTSANDSAVETHETESTSRUNAGAINTHEBROWSERREFRESHESANDTHENEWTESTRESULTSAPPEAR", "original": "To see this in action, make a small change to `app.component.ts` and save.\nThe tests run again, the browser refreshes, and the new test results appear.", "translation": "要查看它的实际效果,就对 `app.component.ts` 做一个小修改,并保存它。\n这些测试就会重新运行,浏览器也会刷新,然后新的测试结果就出现了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####CONFIGURATION", "original": "#### Configuration", "translation": "#### 配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECLITAKESCAREOFJASMINEANDKARMACONFIGURATIONFORYOU", "original": "The CLI takes care of Jasmine and karma configuration for you.", "translation": "CLI 会为你生成 Jasmine 和 Karma 的配置文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANFINETUNEMANYOPTIONSBYEDITINGTHEKARMACONFJSFILEINTHEPROJECTROOTFOLDERANDTHETESTTSFILEINTHESRCFOLDER", "original": "You can fine-tune many options by editing the `karma.conf.js` file in the project root folder and\nthe `test.ts` file in the `src/` folder.", "translation": "不过你也可以通过编辑项目根目录下的 `karma.conf.js` 文件以及 `src/` 目录下的 `test.ts` 文件来微调很多选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEKARMACONFJSFILEISAPARTIALKARMACONFIGURATIONFILETHECLICONSTRUCTSTHEFULLRUNTIMECONFIGURATIONINMEMORYBASEDONAPPLICATIONSTRUCTURESPECIFIEDINTHEANGULARCLIJSONFILESUPPLEMENTEDBYKARMACONFJS", "original": "The `karma.conf.js` file is a partial karma configuration file.\nThe CLI constructs the full runtime configuration in memory,based on application structure specified in the `.angular-cli.json` file, supplemented by `karma.conf.js`.", "translation": "`karma.conf.js` 文件是 karma 配置文件的一部分。\nCLI 会基于 `.angular-cli.json` 文件中指定的项目结构和 `karma.conf.js` 文件,来在内存中构建出完整的运行时配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SEARCHTHEWEBFORMOREDETAILSABOUTJASMINEANDKARMACONFIGURATION", "original": "Search the web for more details about Jasmine and karma configuration.", "translation": "要进一步了解 Jasmine 和 Karma 的配置项,请搜索网络。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####OTHERTESTFRAMEWORKS", "original": "#### Other test frameworks", "translation": "#### 其它测试框架", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANALSOUNITTESTANANGULARAPPWITHOTHERTESTINGLIBRARIESANDTESTRUNNERSEACHLIBRARYANDRUNNERHASITSOWNDISTINCTIVEINSTALLATIONPROCEDURESCONFIGURATIONANDSYNTAX", "original": "You can also unit test an Angular app with other testing libraries and test runners.\nEach library and runner has its own distinctive installation procedures, configuration, and syntax.", "translation": "你还可以使用其它的测试库和测试运行器来对 Angular 应用进行单元测试。\n每个库和运行器都有自己特有的安装过程、配置项和语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SEARCHTHEWEBTOLEARNMORE", "original": "Search the web to learn more.", "translation": "要了解更多,请搜索网络。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####TESTFILENAMEANDLOCATION", "original": "#### Test file name and location", "translation": "#### 测试文件名及其位置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "LOOKINSIDETHESRCAPPFOLDER", "original": "Look inside the `src/app` folder.", "translation": "查看 `src/app` 文件夹。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECLIGENERATEDATESTFILEFORTHEAPPCOMPONENTNAMEDAPPCOMPONENTSPECTS", "original": "The CLI generated a test file for the `AppComponent` named `app.component.spec.ts`.", "translation": "CLI 为 `AppComponent` 生成了一个名叫 `app.component.spec.ts` 的测试文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTFILEEXTENSIONMUSTBESPECTSSOTHATTOOLINGCANIDENTIFYITASAFILEWITHTESTSAKAASPECFILE", "original": "The test file extension **must be `.spec.ts`** so that tooling can identify it as a file with tests (AKA, a _spec_ file).", "translation": "测试文件的扩展名**必须是 `.spec.ts`**,这样工具才能识别出它是一个测试文件,也叫规约(spec)文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEAPPCOMPONENTTSANDAPPCOMPONENTSPECTSFILESARESIBLINGSINTHESAMEFOLDERTHEROOTFILENAMESAPPCOMPONENTARETHESAMEFORBOTHFILES", "original": "The `app.component.ts` and `app.component.spec.ts` files are siblings in the same folder.\nThe root file names (`app.component`) are the same for both files.", "translation": "`app.component.ts` 和 `app.component.spec.ts` 文件位于同一个文件夹中,而且相邻。\n其根文件名部分(`app.component`)都是一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ADOPTTHESETWOCONVENTIONSINYOUROWNPROJECTSFOREVERYKINDOFTESTFILE", "original": "Adopt these two conventions in your own projects for _every kind_ of test file.", "translation": "请在你的项目中对*任意类型*的测试文件都坚持这两条约定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##SERVICETESTS", "original": "## Service Tests", "translation": "## 对服务的测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SERVICESAREOFTENTHEEASIESTFILESTOUNITTESTHEREARESOMESYNCHRONOUSANDASYNCHRONOUSUNITTESTSOFTHEVALUESERVICEWRITTENWITHOUTASSISTANCEFROMANGULARTESTINGUTILITIES", "original": "Services are often the easiest files to unit test.\nHere are some synchronous and asynchronous unit tests of the `ValueService`\nwritten without assistance from Angular testing utilities.", "translation": "服务通常是单元测试中最简单的文件类型。\n下面是一些针对 `ValueService` 的同步和异步单元测试,\n编写它们时没有借助来自 Angular 测试工具集的任何协助。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####SERVICESWITHDEPENDENCIES", "original": "#### Services with dependencies", "translation": "#### 带有依赖的服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SERVICESOFTENDEPENDONOTHERSERVICESTHATANGULARINJECTSINTOTHECONSTRUCTORINMANYCASESITEASYTOCREATEANDINJECTTHESEDEPENDENCIESBYHANDWHILECALLINGTHESERVICESCONSTRUCTOR", "original": "Services often depend on other services that Angular injects into the constructor.\nIn many cases, it easy to create and _inject_ these dependencies by hand while\ncalling the service's constructor.", "translation": "服务通常会依赖于一些 Angular 注入到其构造函数中的其它服务。\n多数情况下,创建并在调用该服务的构造函数时,手工创建并注入这些依赖也是很容易的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEMASTERSERVICEISASIMPLEEXAMPLE:", "original": "The `MasterService` is a simple example:", "translation": "`MasterService` 就是一个简单的例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MASTERSERVICEDELEGATESITSONLYMETHODGETVALUETOTHEINJECTEDVALUESERVICE", "original": "`MasterService` delegates its only method, `getValue`, to the injected `ValueService`.", "translation": "`MasterService` 把它唯一的方法 `getValue` 委托给了注入进来的 `ValueService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARESEVERALWAYSTOTESTIT", "original": "Here are several ways to test it.", "translation": "这里是几种测试它的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFIRSTTESTCREATESAVALUESERVICEWITHNEWANDPASSESITTOTHEMASTERSERVICECONSTRUCTOR", "original": "The first test creates a `ValueService` with `new` and passes it to the `MasterService` constructor.", "translation": "第一个测试使用 `new` 创建了 `ValueService`,然后把它传给了 `MasterService` 的构造函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HOWEVERINJECTINGTHEREALSERVICERARELYWORKSWELLASMOSTDEPENDENTSERVICESAREDIFFICULTTOCREATEANDCONTROL", "original": "However, injecting the real service rarely works well as most dependent services are difficult to create and control.", "translation": "不过,对于大多数没这么容易创建和控制的依赖项来说,注入真实的服务很容易出问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INSTEADYOUCANMOCKTHEDEPENDENCYUSEADUMMYVALUEORCREATEASPYHTTPS:JASMINEGITHUBIO20INTRODUCTIONHTML#SECTIONSPIESONTHEPERTINENTSERVICEMETHOD", "original": "Instead you can mock the dependency, use a dummy value, or create a \n[spy](https://jasmine.github.io/2.0/introduction.html#section-Spies) \non the pertinent service method.", "translation": "你可以改用模拟依赖的方式,你可以使用虚值或在相关的服务方法上创建一个[间谍(spy)](https://jasmine.github.io/2.0/introduction.html#section-Spies)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "PREFERSPIESASTHEYAREUSUALLYTHEEASIESTWAYTOMOCKSERVICES", "original": "Prefer spies as they are usually the easiest way to mock services.", "translation": "优先使用间谍,因为它们通常是 Mock 服务时最简单的方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESESTANDARDTESTINGTECHNIQUESAREGREATFORUNITTESTINGSERVICESINISOLATION", "original": "These standard testing techniques are great for unit testing services in isolation.", "translation": "这些标准的测试技巧对于在隔离的环境下对服务进行单元测试非常重要。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HOWEVERYOUALMOSTALWAYSINJECTSERVICEINTOAPPLICATIONCLASSESUSINGANGULARDEPENDENCYINJECTIONANDYOUSHOULDHAVETESTSTHATREFLECTTHATUSAGEPATTERNANGULARTESTINGUTILITIESMAKEITEASYTOINVESTIGATEHOWINJECTEDSERVICESBEHAVE", "original": "However, you almost always inject service into application classes using Angular\ndependency injection and you should have tests that reflect that usage pattern.\nAngular testing utilities make it easy to investigate how injected services behave.", "translation": "不过,你几乎迟早要用 Angular 的依赖注入机制来把服务注入到应用类中去,而且你应该已经有了这类测试。\nAngular 的测试工具集可以让你轻松探查这种注入服务的工作方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####TESTINGSERVICESWITHTHETESTBED", "original": "#### Testing services with the _TestBed_", "translation": "#### 使用 `TestBed`(测试机床)测试服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOURAPPRELIESONANGULARDEPENDENCYINJECTIONDIGUIDEDEPENDENCYINJECTIONTOCREATESERVICESWHENASERVICEHASADEPENDENTSERVICEDIFINDSORCREATESTHATDEPENDENTSERVICEANDIFTHATDEPENDENTSERVICEHASITSOWNDEPENDENCIESDIFINDSORCREATESTHEMASWELL", "original": "Your app relies on Angular [dependency injection (DI)](guide/dependency-injection) \nto create services.\nWhen a service has a dependent service, DI finds or creates that dependent service.\nAnd if that dependent service has its own dependencies, DI finds-or-creates them as well.", "translation": "你的应用中会依赖 Angular 的[依赖注入 (DI)](guide/dependency-injection) 来创建服务。\n当某个服务依赖另一个服务时,DI 就会找到或创建那个被依赖的服务。\n如果那个被依赖的服务还有它自己的依赖,DI 也同样会找到或创建它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ASSERVICECONSUMERYOUDONTWORRYABOUTANYOFTHISYOUDONTWORRYABOUTTHEORDEROFCONSTRUCTORARGUMENTSORHOWTHEYRECREATED", "original": "As service _consumer_, you don't worry about any of this.\nYou don't worry about the order of constructor arguments or how they're created.", "translation": "作为服务的*消费方*,你不需要关心这些细节。\n你不用关心构造函数中的参数顺序或如何创建它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ASASERVICETESTERYOUMUSTATLEASTTHINKABOUTTHEFIRSTLEVELOFSERVICEDEPENDENCIESBUTYOUCANLETANGULARDIDOTHESERVICECREATIONANDDEALWITHCONSTRUCTORARGUMENTORDERWHENYOUUSETHETESTBEDTESTINGUTILITYTOPROVIDEANDCREATESERVICES", "original": "As a service _tester_, you must at least think about the first level of service dependencies\nbut you _can_ let Angular DI do the service creation and deal with constructor argument order\nwhen you use the `TestBed` testing utility to provide and create services.", "translation": "但对于服务的*测试方*来说,你就至少要考虑服务的第一级依赖了。\n不过你*可以*让 Angular DI 来负责服务的创建工作,但当你使用 `TestBed` 测试工具来提供和创建服务时,你仍然需要关心构造函数中的参数顺序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDISTHEMOSTIMPORTANTOFTHEANGULARTESTINGUTILITIESTHETESTBEDCREATESADYNAMICALLYCONSTRUCTEDANGULARTESTMODULETHATEMULATESANANGULARNGMODULEGUIDENGMODULES", "original": "The `TestBed` is the most important of the Angular testing utilities.\nThe `TestBed` creates a dynamically-constructed Angular _test_ module that emulates\nan Angular [@NgModule](guide/ngmodules).", "translation": "`TestBed` 是 Angular 测试工具中最重要的部分。\n`TestBed` 会动态创建一个用来模拟 [@NgModule](guide/ngmodules) 的 Angular *测试*模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDCONFIGURETESTINGMODULEMETHODTAKESAMETADATAOBJECTTHATCANHAVEMOSTOFTHEPROPERTIESOFANNGMODULEGUIDENGMODULES", "original": "The `TestBed.configureTestingModule()` method takes a metadata object that can have most of the properties of an [@NgModule](guide/ngmodules).", "translation": "`TestBed.configureTestingModule()` 方法接收一个元数据对象,其中具有 [@NgModule](guide/ngmodules) 中的绝大多数属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOTESTASERVICEYOUSETTHEPROVIDERSMETADATAPROPERTYWITHANARRAYOFTHESERVICESTHATYOULLTESTORMOCK", "original": "To test a service, you set the `providers` metadata property with an\narray of the services that you'll test or mock.", "translation": "要测试某个服务,就要在元数据的 `providers` 属性中指定一个将要进行测试或模拟的相关服务的数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENINJECTITINSIDEATESTBYCALLINGTESTBEDGETWITHTHESERVICECLASSASTHEARGUMENT", "original": "Then inject it inside a test by calling `TestBed.get()` with the service class as the argument.", "translation": "然后通过调用 `TestBed.get()`(参数为该服务类)把它注入到一个测试中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ORINSIDETHEBEFOREEACHIFYOUPREFERTOINJECTTHESERVICEASPARTOFYOURSETUP", "original": "Or inside the `beforeEach()` if you prefer to inject the service as part of your setup.", "translation": "或者,如果你更倾向于把该服务作为环境准备过程的一部分,就把它放在 `beforeEach()` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENTESTINGASERVICEWITHADEPENDENCYPROVIDETHEMOCKINTHEPROVIDERSARRAY", "original": "When testing a service with a dependency, provide the mock in the `providers` array.", "translation": "如果要测试一个带有依赖项的服务,那就把模拟对象放在 `providers` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHEFOLLOWINGEXAMPLETHEMOCKISASPYOBJECT", "original": "In the following example, the mock is a spy object.", "translation": "在下面的例子中,模拟对象是一个间谍(spy)对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTCONSUMESTHATSPYINTHESAMEWAYITDIDEARLIER", "original": "The test consumes that spy in the same way it did earlier.", "translation": "该测试会像以前一样消费这个间谍对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####TESTINGWITHOUTBEFOREEACH", "original": "#### Testing without _beforeEach()_", "translation": "#### 不使用 `beforeEach` 进行测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MOSTTESTSUITESINTHISGUIDECALLBEFOREEACHTOSETTHEPRECONDITIONSFOREACHITTESTANDRELYONTHETESTBEDTOCREATECLASSESANDINJECTSERVICES", "original": "Most test suites in this guide call `beforeEach()` to set the preconditions for each `it()` test\nand rely on the `TestBed` to create classes and inject services.", "translation": "本指南中的大多数的测试套件都会调用 `beforeEach()` 来为每个 `it()` 测试准备前置条件,并依赖 `TestBed` 来创建类和注入服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERESANOTHERSCHOOLOFTESTINGTHATNEVERCALLSBEFOREEACHANDANDPREFERSTOCREATECLASSESEXPLICITLYRATHERTHANUSETHETESTBED", "original": "There's another school of testing that never calls `beforeEach()` and\nand prefers to create classes explicitly rather than use the `TestBed`.", "translation": "另一些测试教程中也可能让你不要调用 `beforeEach()`,并且更倾向于显式创建类,而不要借助 `TestBed`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESHOWYOUMIGHTREWRITEONEOFTHEMASTERSERVICETESTSINTHATSTYLE", "original": "Here's how you might rewrite one of the `MasterService` tests in that style.", "translation": "下面的例子教你如何把 `MasterService` 的测试改写成那种风格。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BEGINBYPUTTINGREUSABLEPREPARATORYCODEINASETUPFUNCTIONINSTEADOFBEFOREEACH", "original": "Begin by putting re-usable, preparatory code in a _setup_ function instead of `beforeEach()`.", "translation": "通过把可复用的准备代码放进一个单独的 `setup` 函数来代替 `beforeEach()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESETUPFUNCTIONRETURNSANOBJECTLITERALWITHTHEVARIABLESSUCHASMASTERSERVICETHATATESTMIGHTREFERENCEYOUDONTDEFINESEMIGLOBALVARIABLESEGLETMASTERSERVICE:MASTERSERVICEINTHEBODYOFTHEDESCRIBE", "original": "The `setup()` function returns an object literal \nwith the variables, such as `masterService`, that a test might reference.\nYou don't define _semi-global_ variables (e.g., `let masterService: MasterService`) \nin the body of the `describe()`.", "translation": "`setup()` 函数返回一个带有一些变量的对象字面量,比如 `masterService`,测试中可以引用它。\n这样你就不用在 `describe()` 中定义一些*半全局性的*变量了(比如 `let masterService: MasterService` )。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENEACHTESTINVOKESSETUPINITSFIRSTLINEBEFORECONTINUINGWITHSTEPSTHATMANIPULATETHETESTSUBJECTANDASSERTEXPECTATIONS", "original": "Then each test invokes `setup()` in its first line, before continuing\nwith steps that manipulate the test subject and assert expectations.", "translation": "然后,每个测试都会在第一行调用 `setup()`,然后再操纵被测主体以及对期望值进行断言。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOTICEHOWTHETESTUSESDESTRUCTURINGASSIGNMENTHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCEOPERATORSDESTRUCTURINGASSIGNMENTTOEXTRACTTHESETUPVARIABLESTHATITNEEDS", "original": "Notice how the test uses \n[_destructuring assignment_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) \nto extract the setup variables that it needs.", "translation": "注意这些测试是如何使用 [解构赋值](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)\n来提取出所需变量的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MANYDEVELOPERSFEELTHISAPPROACHISCLEANERANDMOREEXPLICITTHANTHETRADITIONALBEFOREEACHSTYLE", "original": "Many developers feel this approach is cleaner and more explicit than the\ntraditional `beforeEach()` style.", "translation": "很多开发者觉得这种方式相比传统的 `beforeEach()` 风格更加干净、更加明确。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ALTHOUGHTHISTESTINGGUIDEFOLLOWSTHETRADITIONSTYLEANDTHEDEFAULTCLISCHEMATICSHTTPS:GITHUBCOMANGULARDEVKITGENERATETESTFILESWITHBEFOREEACHANDTESTBEDFEELFREETOADOPTTHISALTERNATIVEAPPROACHINYOUROWNPROJECTS", "original": "Although this testing guide follows the tradition style and \nthe default [CLI schematics](https://github.com/angular/devkit) \ngenerate test files with `beforeEach()` and `TestBed`,\nfeel free to adopt _this alternative approach_ in your own projects.", "translation": "虽然本章会遵循传统的风格,并且 [CLI](https://github.com/angular/devkit) 生成的默认测试文件也用的是\n`beforeEach()` 和 `TestBed`,不过你可以在自己的项目中自由选择*这种可选方式*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####TESTINGHTTPSERVICES", "original": "#### Testing HTTP services", "translation": "#### 测试 HTTP 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DATASERVICESTHATMAKEHTTPCALLSTOREMOTESERVERSTYPICALLYINJECTANDDELEGATETOTHEANGULARHTTPCLIENTGUIDEHTTPSERVICEFORXHRCALLS", "original": "Data services that make HTTP calls to remote servers typically inject and delegate \nto the Angular [`HttpClient`](guide/http) service for XHR calls.", "translation": "那些会向远端服务器发起 HTTP 调用的数据服务,通常会注入 Angular 的 [`HttpClient`](guide/http) 服务并委托它进行 XHR 调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANTESTADATASERVICEWITHANINJECTEDHTTPCLIENTSPYASYOUWOULDTESTANYSERVICEWITHADEPENDENCY", "original": "You can test a data service with an injected `HttpClient` spy as you would\ntest any service with a dependency.", "translation": "你可以像测试其它带依赖的服务那样,通过注入一个 `HttpClient` 间谍来测试这种数据服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHEROSERVICEMETHODSRETURNOBSERVABLESSUBSCRIBETOTHEMETHODOBSERVABLETOACAUSEITTOEXECUTEANDBASSERTTHATTHEMETHODSUCCEEDSORFAILS", "original": "The `HeroService` methods return _Observables_.\n_Subscribe_ to the method observable to (a) cause it to execute and (b)\nassert that the method succeeds or fails.", "translation": "`HttpService` 中的方法会返回*可观察对象*。*订阅*这些方法返回的可观察对象会让它开始执行,并且断言这些方法是成功了还是失败了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESUBSCRIBEMETHODTAKESASUCCESSANDFAILCALLBACKMAKESUREYOUPROVIDEBOTHCALLBACKSSOTHATYOUCAPTUREERRORS", "original": "The `subscribe()` method takes a success and fail callback.\nMake sure you provide _both_ callbacks so that you capture errors.", "translation": "`subscribe()` 方法接受一个成功回调和一个失败回调。\n你要确保同时提供了这两个回调,以便捕获错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NEGLECTINGTODOSOPRODUCESANASYNCHRONOUSUNCAUGHTOBSERVABLEERRORTHATTHETESTRUNNERWILLLIKELYATTRIBUTETOACOMPLETELYDIFFERENTTEST", "original": "Neglecting to do so produces an asynchronous uncaught observable error that\nthe test runner will likely attribute to a completely different test.", "translation": "如果忽略这些异步调用中未捕获的错误,测试运行器可能会得出截然不同的测试结论。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "EXTENDEDINTERACTIONSBETWEENADATASERVICEANDTHEHTTPCLIENTCANBECOMPLEXANDDIFFICULTTOMOCKWITHSPIES", "original": "Extended interactions between a data service and the `HttpClient` can be complex\nand difficult to mock with spies.", "translation": "如果将来 `HttpClient` 和数据服务之间有更多的交互,则可能会变得复杂,而且难以使用间谍进行模拟。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHTTPCLIENTTESTINGMODULECANMAKETHESETESTINGSCENARIOSMOREMANAGEABLE", "original": "The `HttpClientTestingModule` can make these testing scenarios more manageable.", "translation": "`HttpClientTestingModule` 可以让这些测试场景变得更加可控。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHILETHECODESAMPLEACCOMPANYINGTHISGUIDEDEMONSTRATESHTTPCLIENTTESTINGMODULETHISPAGEDEFERSTOTHEHTTPGUIDEGUIDEHTTP#TESTINGHTTPREQUESTSWHICHCOVERSTESTINGWITHTHEHTTPCLIENTTESTINGMODULEINDETAIL", "original": "While the _code sample_ accompanying this guide demonstrates `HttpClientTestingModule`,\nthis page defers to the [Http guide](guide/http#testing-http-requests),\nwhich covers testing with the `HttpClientTestingModule` in detail.", "translation": "本章的*代码范例*要示范的是 `HttpClientTestingModule`,所以把部分内容移到了 [HttpClient 中](guide/http#testing-http-requests),那里会详细讲解如何用 `HttpClientTestingModule` 进行测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISGUIDESSAMPLECODEALSODEMONSTRATESTESTINGOFTHELEGACYHTTPMODULEINAPPMODELHTTPHEROSERVICESPECTS", "original": "This guide's sample code also demonstrates testing of the _legacy_ `HttpModule`\nin `app/model/http-hero.service.spec.ts`.", "translation": "本章范例代码中的 `app/model/http-hero.service.spec.ts` 还示范了如何使用*传统的* `HttpModule` 进行验证。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##COMPONENTTESTBASICS", "original": "## Component Test Basics", "translation": "## 组件测试基础", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ACOMPONENTUNLIKEALLOTHERPARTSOFANANGULARAPPLICATIONCOMBINESANHTMLTEMPLATEANDATYPESCRIPTCLASSTHECOMPONENTTRULYISTHETEMPLATEANDTHECLASSWORKINGTOGETHERANDTOADEQUATELYTESTACOMPONENTYOUSHOULDTESTTHATTHEYWORKTOGETHERASINTENDED", "original": "A component, unlike all other parts of an Angular application,\ncombines an HTML template and a TypeScript class.\nThe component truly is the template and the class _working together_.\nand to adequately test a component, you should test that they work together\nas intended.", "translation": "组件与 Angular 应用中的其它部分不同,它是由 HTML 模板和 TypeScript 类组成的。\n组件其实是指模板加上与其合作的类。\n要想对组件进行充分的测试,就要测试它们能否如预期的那样协作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SUCHTESTSREQUIRECREATINGTHECOMPONENTSHOSTELEMENTINTHEBROWSERDOMASANGULARDOESANDINVESTIGATINGTHECOMPONENTCLASSSINTERACTIONWITHTHEDOMASDESCRIBEDBYITSTEMPLATE", "original": "Such tests require creating the component's host element in the browser DOM,\nas Angular does, and investigating the component class's interaction with\nthe DOM as described by its template.", "translation": "这些测试需要在浏览器的 DOM 中创建组件的宿主元素(就像 Angular 所做的那样),然后检查组件类和 DOM 的交互是否如同它在模板中所描述的那样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEANGULARTESTBEDFACILITATESTHISKINDOFTESTINGASYOULLSEEINTHESECTIONSBELOWBUTINMANYCASESTESTINGTHECOMPONENTCLASSALONEWITHOUTDOMINVOLVEMENTCANVALIDATEMUCHOFTHECOMPONENTSBEHAVIORINANEASIERMOREOBVIOUSWAY", "original": "The Angular `TestBed` facilitates this kind of testing as you'll see in the sections below.\nBut in many cases, _testing the component class alone_, without DOM involvement,\ncan validate much of the component's behavior in an easier, more obvious way.", "translation": "Angular 的 `TestBed` 为所有这些类型的测试提供了基础设施。\n但是很多情况下,可以*单独测试组件类本身*而不必涉及 DOM,就已经可以用一种更加简单、清晰的方式来验证该组件的大多数行为了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTCLASSTESTING", "original": "### Component class testing", "translation": "### 单独测试组件类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTACOMPONENTCLASSONITSOWNASYOUWOULDTESTASERVICECLASS", "original": "Test a component class on its own as you would test a service class.", "translation": "你可以像测试服务类一样测试组件类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CONSIDERTHISLIGHTSWITCHCOMPONENTWHICHTOGGLESALIGHTONANDOFFREPRESENTEDBYANONSCREENMESSAGEWHENTHEUSERCLICKSTHEBUTTON", "original": "Consider this `LightswitchComponent` which toggles a light on and off\n(represented by an on-screen message) when the user clicks the button.", "translation": "考虑下面这个 `LightswitchComponent`,当用户点击按钮时,它会切换灯的开关状态(用屏幕上的消息展现出来)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUMIGHTDECIDEONLYTOTESTTHATTHECLICKEDMETHODTOGGLESTHELIGHTSONOFFSTATEANDSETSTHEMESSAGEAPPROPRIATELY", "original": "You might decide only to test that the `clicked()` method\ntoggles the light's _on/off_ state and sets the message appropriately.", "translation": "你可能要测试 `clicked()` 方法能否正确切换灯的开关状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISCOMPONENTCLASSHASNODEPENDENCIESTOTESTASERVICEWITHNODEPENDENCIESYOUCREATEITWITHNEWPOKEATITSAPIANDASSERTEXPECTATIONSONITSPUBLICSTATEDOTHESAMEWITHTHECOMPONENTCLASS", "original": "This component class has no dependencies.\nTo test a service with no dependencies, you create it with `new`, poke at its API,\nand assert expectations on its public state.\nDo the same with the component class.", "translation": "该组件类没有依赖。\n要测试一个没有依赖的服务,你会用 `new` 来创建它,调用它的 API,然后对它的公开状态进行断言。\n组件类也可以这么做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREISTHEDASHBOARDHEROCOMPONENTFROMTHETOUROFHEROESTUTORIAL", "original": "Here is the `DashboardHeroComponent` from the _Tour of Heroes_ tutorial.", "translation": "下面这段代码是来自《英雄指南》教程的 `DashboardHeroComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITAPPEARSWITHINTHETEMPLATEOFAPARENTCOMPONENTWHICHBINDSAHEROTOTHEINPUTPROPERTYANDLISTENSFORANEVENTRAISEDTHROUGHTHESELECTEDOUTPUTPROPERTY", "original": "It appears within the template of a parent component,\nwhich binds a _hero_ to the `@Input` property and\nlistens for an event raised through the _selected_ `@Output` property.", "translation": "它呈现在父组件的模板中,那里把一个英雄绑定到了 `@Input` 属性上,并且通过 `@Output` 属性监听*选中英雄*时的事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANTESTTHATTHECLASSCODEWORKSWITHOUTCREATINGTHETHEDASHBOARDHEROCOMPONENTORITSPARENTCOMPONENT", "original": "You can test that the class code works without creating the the `DashboardHeroComponent`\nor its parent component.", "translation": "你可以测试 `DashboardHeroComponent` 类,而不用完整创建它或其父组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENACOMPONENTHASDEPENDENCIESYOUMAYWISHTOUSETHETESTBEDTOBOTHCREATETHECOMPONENTANDITSDEPENDENCIES", "original": "When a component has dependencies, you may wish to use the `TestBed` to both\ncreate the component and its dependencies.", "translation": "当组件有依赖时,你可能要使用 `TestBed` 来同时创建该组件及其依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGWELCOMECOMPONENTDEPENDSONTHEUSERSERVICETOKNOWTHENAMEOFTHEUSERTOGREET", "original": "The following `WelcomeComponent` depends on the `UserService` to know the name of the user to greet.", "translation": "下面的 `WelcomeComponent` 依赖于 `UserService`,并通过它知道要打招呼的那位用户的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUMIGHTSTARTBYCREATINGAMOCKOFTHEUSERSERVICETHATMEETSTHEMINIMUMNEEDSOFTHISCOMPONENT", "original": "You might start by creating a mock of the `UserService` that meets the minimum needs of this component.", "translation": "你可能要先创建一个满足本组件最小需求的模拟板 `UserService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENPROVIDEANDINJECTBOTHTHECOMPONENTANDTHESERVICEINTHETESTBEDCONFIGURATION", "original": "Then provide and inject _both the_ **component** _and the service_ in the `TestBed` configuration.", "translation": "然后在 `TestBed` 的配置中提供并注入该**组件**和该**服务**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENEXERCISETHECOMPONENTCLASSREMEMBERINGTOCALLTHELIFECYCLEHOOKMETHODSGUIDELIFECYCLEHOOKSASANGULARDOESWHENRUNNINGTHEAPP", "original": "Then exercise the component class, remembering to call the [lifecycle hook methods](guide/lifecycle-hooks) as Angular does when running the app.", "translation": "然后使用这个组件类,别忘了像 Angular 运行本应用时那样调用它的[生命周期钩子方法](guide/lifecycle-hooks)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTDOMTESTING", "original": "### Component DOM testing", "translation": "### 组件 DOM 的测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTINGTHECOMPONENTCLASSISASEASYASTESTINGASERVICE", "original": "Testing the component _class_ is as easy as testing a service.", "translation": "测试组件*类*就像测试服务那样简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BUTACOMPONENTISMORETHANJUSTITSCLASSACOMPONENTINTERACTSWITHTHEDOMANDWITHOTHERCOMPONENTSTHECLASSONLYTESTSCANTELLYOUABOUTCLASSBEHAVIORTHEYCANNOTTELLYOUIFTHECOMPONENTISGOINGTORENDERPROPERLYRESPONDTOUSERINPUTANDGESTURESORINTEGRATEWITHITSPARENTANDANDCHILDCOMPONENTS", "original": "But a component is more than just its class.\nA component interacts with the DOM and with other components.\nThe _class-only_ tests can tell you about class behavior.\nThey cannot tell you if the component is going to render properly,\nrespond to user input and gestures, or integrate with its parent and and child components.", "translation": "但组件不仅是这个类。\n组件还要和 DOM 以及其它组件进行交互。\n*只涉及类*的测试可以告诉你组件类的行为是否正常,\n但是不能告诉你组件是否能正常渲染出来、响应用户的输入和查询或与它的父组件和子组件相集成。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NONEOFTHECLASSONLYTESTSABOVECANANSWERKEYQUESTIONSABOUTHOWTHECOMPONENTSACTUALLYBEHAVEONSCREEN", "original": "None of the _class-only_ tests above can answer key questions about how the\ncomponents actually behave on screen.", "translation": "上述*只涉及类*的测试没办法回答这些组件在屏幕上的行为之类的关键性问题:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ISLIGHTSWITCHCLICKEDBOUNDTOANYTHINGSUCHTHATTHEUSERCANINVOKEIT", "original": "* Is `Lightswitch.clicked()` bound to anything such that the user can invoke it?", "translation": "`Lightswitch.clicked()` 是否真的绑定到了某些用户可以接触到的东西?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ISTHELIGHTSWITCHMESSAGEDISPLAYED", "original": "* Is the `Lightswitch.message` displayed?", "translation": "`Lightswitch.message` 是否真的显示出来了?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CANTHEUSERACTUALLYSELECTTHEHERODISPLAYEDBYDASHBOARDHEROCOMPONENT", "original": "* Can the user actually select the hero displayed by `DashboardHeroComponent`?", "translation": "用户真的可以选择 `DashboardHeroComponent` 中显示的某个英雄吗?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ISTHEHERONAMEDISPLAYEDASEXPECTEDIEINUPPERCASE", "original": "* Is the hero name displayed as expected (i.e, in uppercase)?", "translation": "英雄的名字是否如预期般显示出来了?(比如是否大写)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ISTHEWELCOMEMESSAGEDISPLAYEDBYTHETEMPLATEOFWELCOMECOMPONENT", "original": "* Is the welcome message displayed by the template of `WelcomeComponent`?", "translation": "`WelcomeComponent` 的模板是否显示了欢迎信息?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESEMAYNOTBETROUBLINGQUESTIONSFORTHESIMPLECOMPONENTSILLUSTRATEDABOVEBUTMANYCOMPONENTSHAVECOMPLEXINTERACTIONSWITHTHEDOMELEMENTSDESCRIBEDINTHEIRTEMPLATESCAUSINGHTMLTOAPPEARANDDISAPPEARASTHECOMPONENTSTATECHANGES", "original": "These may not be troubling questions for the simple components illustrated above.\nBut many components have complex interactions with the DOM elements\ndescribed in their templates, causing HTML to appear and disappear as\nthe component state changes.", "translation": "这些问题对于上面这种简单的组件来说当然没有问题,\n不过很多组件和它们模板中所描述的 DOM 元素之间会有复杂的交互,当组件的状态发生变化时,会导致一些 HTML 出现和消失。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOANSWERTHESEKINDSOFQUESTIONSYOUHAVETOCREATETHEDOMELEMENTSASSOCIATEDWITHTHECOMPONENTSYOUMUSTEXAMINETHEDOMTOCONFIRMTHATCOMPONENTSTATEDISPLAYSPROPERLYATTHEAPPROPRIATETIMESANDYOUMUSTSIMULATEUSERINTERACTIONWITHTHESCREENTODETERMINEWHETHERTHOSEINTERACTIONSCAUSETHECOMPONENTTOBEHAVEASEXPECTED", "original": "To answer these kinds of questions, you have to create the DOM elements associated\nwith the components, you must examine the DOM to confirm that component state\ndisplays properly at the appropriate times, and you must simulate user interaction\nwith the screen to determine whether those interactions cause the component to\nbehave as expected.", "translation": "要回答这类问题,你就不得不创建那些与组件相关的 DOM 元素了,你必须检查 DOM 来确认组件的状态能在恰当的时机正常显示出来,并且必须通过屏幕来仿真用户的交互,以判断这些交互是否如预期的那般工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOWRITETHESEKINDSOFTESTYOULLUSEADDITIONALFEATURESOFTHETESTBEDASWELLASOTHERTESTINGHELPERS", "original": "To write these kinds of test, you'll use additional features of the `TestBed`\nas well as other testing helpers.", "translation": "要想写这类测试,你就要用到 `TestBed` 的附加功能以及其它测试助手了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####CLIGENERATEDTESTS", "original": "#### CLI-generated tests", "translation": "#### CLI 生成的测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECLICREATESANINITIALTESTFILEFORYOUBYDEFAULTWHENYOUASKITTOGENERATEANEWCOMPONENT", "original": "The CLI creates an initial test file for you by default when you ask it to\ngenerate a new component.", "translation": "当你用 CLI 生成新的组件时,它也会默认创建最初的测试文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FOREXAMPLETHEFOLLOWINGCLICOMMANDGENERATESABANNERCOMPONENTINTHEAPPBANNERFOLDERWITHINLINETEMPLATEANDSTYLES:", "original": "For example, the following CLI command generates a `BannerComponent` in the `app/banner` folder (with inline template and styles):", "translation": "比如,下列 CLI 命令会在 `app/banner` 文件夹中创建带有内联模板和内联样式的 `BannerComponent`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITALSOGENERATESANINITIALTESTFILEFORTHECOMPONENTBANNEREXTERNALCOMPONENTSPECTSTHATLOOKSLIKETHIS:", "original": "It also generates an initial test file for the component, `banner-external.component.spec.ts`, that looks like this:", "translation": "它也会为组件生成最初的测试文件 `banner-external.component.spec.ts`,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####REDUCETHESETUP", "original": "#### Reduce the setup", "translation": "#### 缩减准备代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ONLYTHELASTTHREELINESOFTHISFILEACTUALLYTESTTHECOMPONENTANDALLTHEYDOISASSERTTHATANGULARCANCREATETHECOMPONENT", "original": "Only the last three lines of this file actually test the component\nand all they do is assert that Angular can create the component.", "translation": "这个文件中只有最后三行是真正测试组件的,它们用来断言 Angular 可以创建该组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERESTOFTHEFILEISBOILERPLATESETUPCODEANTICIPATINGMOREADVANCEDTESTSTHATMIGHTBECOMENECESSARYIFTHECOMPONENTEVOLVESINTOSOMETHINGSUBSTANTIAL", "original": "The rest of the file is boilerplate setup code anticipating more advanced tests that _might_ become necessary if the component evolves into something substantial.", "translation": "文件的其它部分都是为更高级的测试二准备的样板代码,当组件逐渐演变成更加实质性的东西时,它们才*可能*变成必备的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOULLLEARNABOUTTHESEADVANCEDTESTFEATURESBELOWFORNOWYOUCANRADICALLYREDUCETHISTESTFILETOAMOREMANAGEABLESIZE:", "original": "You'll learn about these advanced test features below.\nFor now, you can radically reduce this test file to a more manageable size:", "translation": "稍后你讲学到这些高级的测试特性。\n不过目前,你可以先把这些测试文件缩减成更加可控的大小,以便理解:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHISEXAMPLETHEMETADATAOBJECTPASSEDTOTESTBEDCONFIGURETESTINGMODULESIMPLYDECLARESBANNERCOMPONENTTHECOMPONENTTOTEST", "original": "In this example, the metadata object passed to `TestBed.configureTestingModule` \nsimply declares `BannerComponent`, the component to test.", "translation": "在这个例子中,传给 `TestBed.configureTestingModule` 的元数据对象中只声明了 `BannerComponent` —— 待测试的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERESNONEEDTODECLAREORIMPORTANYTHINGELSETHEDEFAULTTESTMODULEISPRECONFIGUREDWITHSOMETHINGLIKETHEBROWSERMODULEFROMANGULARPLATFORMBROWSER", "original": "There's no need to declare or import anything else.\nThe default test module is pre-configured with \nsomething like the `BrowserModule` from `@angular/platform-browser`.", "translation": "不用声明或导入任何其它的东西。\n默认的测试模块中已经预先配置好了一些东西,比如来自 `@angular/platform-browser` 的 `BrowserModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "LATERYOULLCALLTESTBEDCONFIGURETESTINGMODULEWITHIMPORTSPROVIDERSANDMOREDECLARATIONSTOSUITYOURTESTINGNEEDSOPTIONALOVERRIDEMETHODSCANFURTHERFINETUNEASPECTSOFTHECONFIGURATION", "original": "Later you'll call `TestBed.configureTestingModule()` with\nimports, providers, and more declarations to suit your testing needs.\nOptional `override` methods can further fine-tune aspects of the configuration.", "translation": "稍后你将会调用带有导入模块、服务提供商和更多可声明对象的 `TestBed.configureTestingModule()` 来满足测试所需。\n将来还可以用可选的 `override` 方法对这些配置进行微调。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AFTERCONFIGURINGTESTBEDYOUCALLITSCREATECOMPONENTMETHOD", "original": "After configuring `TestBed`, you call its `createComponent()` method.", "translation": "在配置好 `TestBed` 之后,你还可以调用它的 `createComponent()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTBEDCREATECOMPONENTCREATESANINSTANCEOFTHEBANNERCOMPONENTADDSACORRESPONDINGELEMENTTOTHETESTRUNNERDOMANDRETURNSACOMPONENTFIXTURE#COMPONENTFIXTURE", "original": "`TestBed.createComponent()` creates an instance of the `BannerComponent`, \nadds a corresponding element to the test-runner DOM,\nand returns a [`ComponentFixture`](#component-fixture).", "translation": "`TestBed.createComponent()` 会创建一个 `BannerComponent` 的实例,把相应的元素添加到测试运行器的 DOM 中,然后返回一个 [`ComponentFixture`](#component-fixture) 对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DONOTRECONFIGURETESTBEDAFTERCALLINGCREATECOMPONENT", "original": "Do not re-configure `TestBed` after calling `createComponent`.", "translation": "在调用了 `createComponent` 之后就不能再重新配置 `TestBed` 了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECREATECOMPONENTMETHODFREEZESTHECURRENTTESTBEDDEFINITIONCLOSINGITTOFURTHERCONFIGURATION", "original": "The `createComponent` method freezes the current `TestBed`definition, \nclosing it to further configuration.", "translation": "`createComponent` 方法冻结了当前的 `TestBed` 定义,关闭它才能再进行后续配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANNOTCALLANYMORETESTBEDCONFIGURATIONMETHODSNOTCONFIGURETESTINGMODULENORGETNORANYOFTHEOVERRIDEMETHODSIFYOUTRYTESTBEDTHROWSANERROR", "original": "You cannot call any more `TestBed` configuration methods, not `configureTestingModule()`,\nnor `get()`, nor any of the `override...` methods.\nIf you try, `TestBed` throws an error.", "translation": "你不能再调用任何 `TestBed` 的后续配置方法了,不能调 `configureTestingModule()`、不能调 `get()`,\n也不能调用任何 `override...` 方法。\n如果试图这么做,`TestBed` 就会抛出错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPONENTFIXTUREAPICORETESTINGCOMPONENTFIXTUREISATESTHARNESSFORINTERACTINGWITHTHECREATEDCOMPONENTANDITSCORRESPONDINGELEMENT", "original": "The [ComponentFixture](api/core/testing/ComponentFixture) is a test harness for interacting with the created component and its corresponding element.", "translation": "[ComponentFixture](api/core/testing/ComponentFixture) 是一个测试挽具(就像马车缰绳),用来与所创建的组件及其 DOM 元素进行交互。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ACCESSTHECOMPONENTINSTANCETHROUGHTHEFIXTUREANDCONFIRMITEXISTSWITHAJASMINEEXPECTATION:", "original": "Access the component instance through the fixture and confirm it exists with a Jasmine expectation:", "translation": "可以通过测试夹具(fixture)来访问该组件的实例,并用 Jasmine 的 `expect` 语句来确保其存在。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUWILLADDMORETESTSASTHISCOMPONENTEVOLVESRATHERTHANDUPLICATETHETESTBEDCONFIGURATIONFOREACHTESTYOUREFACTORTOPULLTHESETUPINTOAJASMINEBEFOREEACHANDSOMESUPPORTINGVARIABLES:", "original": "You will add more tests as this component evolves.\nRather than duplicate the `TestBed` configuration for each test,\nyou refactor to pull the setup into a Jasmine `beforeEach()` and some supporting variables:", "translation": "随着该组件的成长,你将会添加更多测试。\n除了为每个测试都复制一份 `TestBed` 测试之外,你还可以把它们重构成 Jasmine 的 `beforeEach()` 中的准备语句以及一些支持性变量:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOWADDATESTTHATGETSTHECOMPONENTSELEMENTFROMFIXTURENATIVEELEMENTANDLOOKSFORTHEEXPECTEDTEXT", "original": "Now add a test that gets the component's element from `fixture.nativeElement` and \nlooks for the expected text.", "translation": "现在,添加一个测试,用它从 `fixture.nativeElement` 中获取组件的元素,并查找是否存在所预期的文本内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEVALUEOFCOMPONENTFIXTURENATIVEELEMENTHASTHEANYTYPELATERYOULLENCOUNTERTHEDEBUGELEMENTNATIVEELEMENTANDITTOOHASTHEANYTYPE", "original": "The value of `ComponentFixture.nativeElement` has the `any` type.\nLater you'll encounter the `DebugElement.nativeElement` and it too has the `any` type.", "translation": "`ComponentFixture.nativeElement` 的值是 `any` 类型的。\n稍后你将遇到的 `DebugElement.nativeElement` 也同样是 `any` 类型的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANGULARCANTKNOWATCOMPILETIMEWHATKINDOFHTMLELEMENTTHENATIVEELEMENTISORIFITEVENISANHTMLELEMENTTHEAPPMIGHTBERUNNINGONANONBROWSERPLATFORMSUCHASTHESERVERORAWEBWORKERHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIWEBWORKERSAPIWHERETHEELEMENTMAYHAVEADIMINISHEDAPIORNOTEXISTATALL", "original": "Angular can't know at compile time what kind of HTML element the `nativeElement` is or \nif it even is an HTML element.\nThe app might be running on a _non-browser platform_, such as the server or a\n[Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API),\nwhere the element may have a diminished API or not exist at all.", "translation": "Angular 在编译期间没办法知道 `nativeElement` 是哪种 HTML 元素,甚至是否 HTML 元素(译注:比如可能是 SVG 元素)。\n本应用还可能运行在*非浏览器平台上*,比如服务端渲染或 [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) 那里的元素可能只有一些缩水过的 API,甚至根本不存在。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTSINTHISGUIDEAREDESIGNEDTORUNINABROWSERSOANATIVEELEMENTVALUEWILLALWAYSBEANHTMLELEMENTORONEOFITSDERIVEDCLASSES", "original": "The tests in this guide are designed to run in a browser so a\n`nativeElement` value will always be an `HTMLElement` or \none of its derived classes.", "translation": "本指南中的例子都是为运行在浏览器中而设计的,因此 `nativeElement` 的值一定会是 `HTMLElement` 及其派生类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "KNOWINGTHATITISANHTMLELEMENTOFSOMESORTYOUCANUSETHESTANDARDHTMLQUERYSELECTORTODIVEDEEPERINTOTHEELEMENTTREE", "original": "Knowing that it is an `HTMLElement` of some sort, you can use\nthe standard HTML `querySelector` to dive deeper into the element tree.", "translation": "如果知道了它是某种 `HTMLElement`,你就可以用标准的 `querySelector` 在元素树中进行深挖了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESANOTHERTESTTHATCALLSHTMLELEMENTQUERYSELECTORTOGETTHEPARAGRAPHELEMENTANDLOOKFORTHEBANNERTEXT:", "original": "Here's another test that calls `HTMLElement.querySelector` to get the paragraph element and look for the banner text:", "translation": "下面这个测试就会调用 `HTMLElement.querySelector` 来获取 `<p>` 元素,并在其中查找 Banner 文本:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEANGULARFIXTUREPROVIDESTHECOMPONENTSELEMENTDIRECTLYTHROUGHTHEFIXTURENATIVEELEMENT", "original": "The Angular _fixture_ provides the component's element directly through the `fixture.nativeElement`.", "translation": "Angular 的*夹具*可以通过 `fixture.nativeElement` 直接提供组件的元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISISACTUALLYACONVENIENCEMETHODIMPLEMENTEDASFIXTUREDEBUGELEMENTNATIVEELEMENT", "original": "This is actually a convenience method, implemented as `fixture.debugElement.nativeElement`.", "translation": "它实际上是 `fixture.debugElement.nativeElement` 的一个便利方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERESAGOODREASONFORTHISCIRCUITOUSPATHTOTHEELEMENT", "original": "There's a good reason for this circuitous path to the element.", "translation": "这种访问元素的迂回方式有很好的理由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEPROPERTIESOFTHENATIVEELEMENTDEPENDUPONTHERUNTIMEENVIRONMENTYOUCOULDBERUNNINGTHESETESTSONANONBROWSERPLATFORMTHATDOESNTHAVEADOMORWHOSEDOMEMULATIONDOESNTSUPPORTTHEFULLHTMLELEMENTAPI", "original": "The properties of the `nativeElement` depend upon the runtime environment.\nYou could be running these tests on a _non-browser_ platform that doesn't have a DOM or \nwhose DOM-emulation doesn't support the full `HTMLElement` API.", "translation": "`nativeElement` 的属性取决于运行环境。\n你可以在没有 DOM,或者其 DOM 模拟器无法支持全部 `HTMLElement` API 的平台上运行这些测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANGULARRELIESONTHEDEBUGELEMENTABSTRACTIONTOWORKSAFELYACROSSALLSUPPORTEDPLATFORMSINSTEADOFCREATINGANHTMLELEMENTTREEANGULARCREATESADEBUGELEMENTTREETHATWRAPSTHENATIVEELEMENTSFORTHERUNTIMEPLATFORMTHENATIVEELEMENTPROPERTYUNWRAPSTHEDEBUGELEMENTANDRETURNSTHEPLATFORMSPECIFICELEMENTOBJECT", "original": "Angular relies on the `DebugElement` abstraction to work safely across _all supported platforms_.\nInstead of creating an HTML element tree, Angular creates a `DebugElement` tree that wraps the _native elements_ for the runtime platform.\nThe `nativeElement` property unwraps the `DebugElement` and returns the platform-specific element object.", "translation": "Angular 依赖于 `DebugElement` 这个抽象层,就可以安全的横跨*其支持的所有平台*。\nAngular 不再创建 HTML 元素树,而是创建 `DebugElement` 树,其中包裹着相应运行平台上的*原生元素*。\n`nativeElement` 属性会解开 `DebugElement`,并返回平台相关的元素对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BECAUSETHESAMPLETESTSFORTHISGUIDEAREDESIGNEDTORUNONLYINABROWSERANATIVEELEMENTINTHESETESTSISALWAYSANHTMLELEMENTWHOSEFAMILIARMETHODSANDPROPERTIESYOUCANEXPLOREWITHINATEST", "original": "Because the sample tests for this guide are designed to run only in a browser,\na `nativeElement` in these tests is always an `HTMLElement`\nwhose familiar methods and properties you can explore within a test.", "translation": "因为本章的这些测试都设计为只运行在浏览器中,因此这些测试中的 `nativeElement` 总是 `HTMLElement`,\n你可以在测试中使用那些熟悉的方法和属性进行浏览。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHEPREVIOUSTESTREIMPLEMENTEDWITHFIXTUREDEBUGELEMENTNATIVEELEMENT:", "original": "Here's the previous test, re-implemented with `fixture.debugElement.nativeElement`:", "translation": "下面是对上一个测试改用 `fixture.debugElement.nativeElement` 进行的重新实现:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDEBUGELEMENTHASOTHERMETHODSANDPROPERTIESTHATAREUSEFULINTESTSASYOULLSEEELSEWHEREINTHISGUIDE", "original": "The `DebugElement` has other methods and properties that\nare useful in tests, as you'll see elsewhere in this guide.", "translation": "`DebugElement` 还有其它的方法和属性,它们在测试中也很有用,你将在本章的其它测试中看到它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUIMPORTTHEDEBUGELEMENTSYMBOLFROMTHEANGULARCORELIBRARY", "original": "You import the `DebugElement` symbol from the Angular core library.", "translation": "你要从 Angular 核心库中导入 `DebugElement` 符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ALTHOUGHTHETESTSINTHISGUIDEALLRUNINTHEBROWSERSOMEAPPSMIGHTRUNONADIFFERENTPLATFORMATLEASTSOMEOFTHETIME", "original": "Although the tests in this guide all run in the browser,\nsome apps might run on a different platform at least some of the time.", "translation": "虽然本章中的测试都是运行在浏览器中的,不过有些应用可能会运行在其它平台上(至少一部分时间是这样)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FOREXAMPLETHECOMPONENTMIGHTRENDERFIRSTONTHESERVERASPARTOFASTRATEGYTOMAKETHEAPPLICATIONLAUNCHFASTERONPOORLYCONNECTEDDEVICESTHESERVERSIDERENDERERMIGHTNOTSUPPORTTHEFULLHTMLELEMENTAPIIFITDOESNTSUPPORTQUERYSELECTORTHEPREVIOUSTESTCOULDFAIL", "original": "For example, the component might render first on the server as part of a strategy to make the application launch faster on poorly connected devices. The server-side renderer might not support the full HTML element API.\nIf it doesn't support `querySelector`, the previous test could fail.", "translation": "比如,作为加快慢速网络设备上应用启动速度的一种策略,组件可能要先在服务器上渲染。服务端渲染可能无法支持完全的 HTML API。\n如果它不支持 `querySelector`,那么前一个测试就会失败。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDEBUGELEMENTOFFERSQUERYMETHODSTHATWORKFORALLSUPPORTEDPLATFORMSTHESEQUERYMETHODSTAKEAPREDICATEFUNCTIONTHATRETURNSTRUEWHENANODEINTHEDEBUGELEMENTTREEMATCHESTHESELECTIONCRITERIA", "original": "The `DebugElement` offers query methods that work for all supported platforms.\nThese query methods take a _predicate_ function that returns `true` when a node in the `DebugElement` tree matches the selection criteria.", "translation": "`DebugElement` 提供了可以工作在所有受支持的平台上的查询方法。\n这些查询方法接受一个谓词(predicate)函数,如果 `DebugElement` 树中的节点满足某个筛选条件,它就返回 `true`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCREATEAPREDICATEWITHTHEHELPOFABYCLASSIMPORTEDFROMALIBRARYFORTHERUNTIMEPLATFORMHERESTHEBYIMPORTFORTHEBROWSERPLATFORM:", "original": "You create a _predicate_ with the help of a `By` class imported from a\nlibrary for the runtime platform. Here's the `By` import for the browser platform:", "translation": "你可以在从库中导入的 `By` 类的帮助下为该运行平台创建谓词函数。下面这个 `By` 是从浏览器平台导入的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGEXAMPLEREIMPLEMENTSTHEPREVIOUSTESTWITHDEBUGELEMENTQUERYANDTHEBROWSERSBYCSSMETHOD", "original": "The following example re-implements the previous test with\n`DebugElement.query()` and the browser's `By.css` method.", "translation": "下面这个例子使用 `DebugElement.query()` 和浏览器的 `By.css` 方法重新实现了前一个测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SOMENOTEWORTHYOBSERVATIONS:", "original": "Some noteworthy observations:", "translation": "值得注意的地方有:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEBYCSSSTATICMETHODSELECTSDEBUGELEMENTNODESWITHASTANDARDCSSSELECTORHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBGUIDECSSGETTINGSTARTEDSELECTORSCSSSELECTORS", "original": "* The `By.css()` static method selects `DebugElement` nodes \nwith a [standard CSS selector](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors \"CSS selectors\").", "translation": "`By.css()` 静态方法使用[标准 CSS 选择器](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors \"CSS selectors\")选择了一些 `DebugElement` 节点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEQUERYRETURNSADEBUGELEMENTFORTHEPARAGRAPH", "original": "* The query returns a `DebugElement` for the paragraph.", "translation": "这次查询返回了 `<p>` 元素的一个 `DebugElement`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUMUSTUNWRAPTHATRESULTTOGETTHEPARAGRAPHELEMENT", "original": "* You must unwrap that result to get the paragraph element.", "translation": "你必须解包此结果,以获取这个 `<p>` 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENYOUREFILTERINGBYCSSSELECTORANDONLYTESTINGPROPERTIESOFABROWSERSNATIVEELEMENTTHEBYCSSAPPROACHMAYBEOVERKILL", "original": "When you're filtering by CSS selector and only testing properties of a browser's _native element_, the `By.css` approach may be overkill.", "translation": "当你要通过 CSS 选择器过滤,并且只打算测试浏览器的*原生元素*的属性时,`By.css` 这种方法就有点多余了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITSOFTENEASIERANDMORECLEARTOFILTERWITHASTANDARDHTMLELEMENTMETHODSUCHASQUERYSELECTORORQUERYSELECTORALLASYOULLSEEINTHENEXTSETOFTESTS", "original": "It's often easier and more clear to filter with a standard `HTMLElement` method \nsuch as `querySelector()` or `querySelectorAll()`, \nas you'll see in the next set of tests.", "translation": "使用标准的 `HTMLElement` 方法,比如 `querySelector()` 或 `querySelectorAll()` 通常会更简单、更清晰。\n你在下一组测试中就会体会到这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##COMPONENTTESTSCENARIOS", "original": "## Component Test Scenarios", "translation": "## 组件测试场景", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGSECTIONSCOMPRISINGMOSTOFTHISGUIDEEXPLORECOMMONCOMPONENTTESTINGSCENARIOS", "original": "The following sections, comprising most of this guide, explore common\ncomponent testing scenarios", "translation": "下面这些部分构成了本指南的大部分内容,它们将探讨一些常见的组件测试场景。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTBINDING", "original": "### Component binding", "translation": "### 组件绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECURRENTBANNERCOMPONENTPRESENTSSTATICTITLETEXTINTHEHTMLTEMPLATE", "original": "The current `BannerComponent` presents static title text in the HTML template.", "translation": "当前的 `BannerComponent` 在 HTML 模板中展示了静态标题内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AFTERAFEWCHANGESTHEBANNERCOMPONENTPRESENTSADYNAMICTITLEBYBINDINGTOTHECOMPONENTSTITLEPROPERTYLIKETHIS", "original": "After a few changes, the `BannerComponent` presents a dynamic title by binding to\nthe component's `title` property like this.", "translation": "稍作修改之后,`BannerComponent` 也可以通过绑定到组件的 `title` 属性来展示动态标题。就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SIMPLEASTHISISYOUDECIDETOADDATESTTOCONFIRMTHATCOMPONENTACTUALLYDISPLAYSTHERIGHTCONTENTWHEREYOUTHINKITSHOULD", "original": "Simple as this is, you decide to add a test to confirm that component \nactually displays the right content where you think it should.", "translation": "很简单,你决定添加一个测试来确定这个组件真的像你预期的那样显示出了正确的内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####QUERYFORTHELTH1GT", "original": "#### Query for the _<h1>_", "translation": "#### 查询 `<h1>`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOULLWRITEASEQUENCEOFTESTSTHATINSPECTTHEVALUEOFTHEH1ELEMENTTHATWRAPSTHETITLEPROPERTYINTERPOLATIONBINDING", "original": "You'll write a sequence of tests that inspect the value of the `<h1>` element\nthat wraps the _title_ property interpolation binding.", "translation": "你将会写一系列测试来探查 `<h1>` 元素的值,这个值包含在了带有 `title` 属性的插值表达式绑定中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUUPDATETHEBEFOREEACHTOFINDTHATELEMENTWITHASTANDARDHTMLQUERYSELECTORANDASSIGNITTOTHEH1VARIABLE", "original": "You update the `beforeEach` to find that element with a standard HTML `querySelector`\nand assign it to the `h1` variable.", "translation": "你要修改 `beforeEach` 来使用标准的 HTML `querySelector` 来找到钙元素,并把它赋值给 `h1` 变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####CREATECOMPONENTDOESNOTBINDDATA", "original": "#### _createComponent()_ does not bind data", "translation": "#### `createComponent()` 函数不会绑定数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FORYOURFIRSTTESTYOUDLIKETOSEETHATTHESCREENDISPLAYSTHEDEFAULTTITLEYOURINSTINCTISTOWRITEATESTTHATIMMEDIATELYINSPECTSTHEH1LIKETHIS:", "original": "For your first test you'd like to see that the screen displays the default `title`.\nYour instinct is to write a test that immediately inspects the `<h1>` like this:", "translation": "你的第一个测试希望看到屏幕显示出了默认的 `title`。\n你本能的写出如下测试来立即审查这个 `<h1>` 元素:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THATTESTFAILSWITHTHEMESSAGE:", "original": "_That test fails_ with the message:", "translation": "但*测试失败了*,给出如下信息:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BINDINGHAPPENSWHENANGULARPERFORMSCHANGEDETECTION", "original": "Binding happens when Angular performs **change detection**.", "translation": "因为绑定是在 Angular 执行**变更检测**时才发生的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INPRODUCTIONCHANGEDETECTIONKICKSINAUTOMATICALLYWHENANGULARCREATESACOMPONENTORTHEUSERENTERSAKEYSTROKEORANASYNCHRONOUSACTIVITYEGAJAXCOMPLETES", "original": "In production, change detection kicks in automatically\nwhen Angular creates a component or the user enters a keystroke or\nan asynchronous activity (e.g., AJAX) completes.", "translation": "在产品阶段,当 Angular 创建组件、用户输入或者异步动作(比如 AJAX)完成时,会自动触发变更检测。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDCREATECOMPONENTDOESNOTTRIGGERCHANGEDETECTIONAFACTCONFIRMEDINTHEREVISEDTEST:", "original": "The `TestBed.createComponent` does _not_ trigger change detection.\na fact confirmed in the revised test:", "translation": "但 `TestBed.createComponent` *不能*触发变更检测。\n可以在这个修改后的测试中确定这一点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUMUSTTELLTHETESTBEDTOPERFORMDATABINDINGBYCALLINGFIXTUREDETECTCHANGESONLYTHENDOESTHEH1HAVETHEEXPECTEDTITLE", "original": "You must tell the `TestBed` to perform data binding by calling `fixture.detectChanges()`.\nOnly then does the `<h1>` have the expected title.", "translation": "你必须通过调用 `fixture.detectChanges()` 来要求 `TestBed` 执行数据绑定。\n然后 `<h1>` 中才会具有所期望的标题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DELAYEDCHANGEDETECTIONISINTENTIONALANDUSEFULITGIVESTHETESTERANOPPORTUNITYTOINSPECTANDCHANGETHESTATEOFTHECOMPONENTBEFOREANGULARINITIATESDATABINDINGANDCALLSLIFECYCLEHOOKSGUIDELIFECYCLEHOOKS", "original": "Delayed change detection is intentional and useful.\nIt gives the tester an opportunity to inspect and change the state of\nthe component _before Angular initiates data binding and calls [lifecycle hooks](guide/lifecycle-hooks)_.", "translation": "这种迟到的变更检测是故意设计的,而且很有用。\n它给了测试者一个机会,*在 Angular 初始化数据绑定以及调用[生命周期钩子](guide/lifecycle-hooks)之前*探查并改变组件的状态。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESANOTHERTESTTHATCHANGESTHECOMPONENTSTITLEPROPERTYBEFORECALLINGFIXTUREDETECTCHANGES", "original": "Here's another test that changes the component's `title` property _before_ calling `fixture.detectChanges()`.", "translation": "下面这个测试中,会在调用 `fixture.detectChanges()` *之前*修改组件的 `title` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####AUTOMATICCHANGEDETECTION", "original": "#### Automatic change detection", "translation": "#### 自动变更检测", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEBANNERCOMPONENTTESTSFREQUENTLYCALLDETECTCHANGESSOMETESTERSPREFERTHATTHEANGULARTESTENVIRONMENTRUNCHANGEDETECTIONAUTOMATICALLY", "original": "The `BannerComponent` tests frequently call `detectChanges`.\nSome testers prefer that the Angular test environment run change detection automatically.", "translation": "`BannerComponent` 的这些测试需要频繁调用 `detectChanges`。\n有些测试者更喜欢让 Angular 测试环境自动运行变更检测。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THATSPOSSIBLEBYCONFIGURINGTHETESTBEDWITHTHECOMPONENTFIXTUREAUTODETECTPROVIDERFIRSTIMPORTITFROMTHETESTINGUTILITYLIBRARY:", "original": "That's possible by configuring the `TestBed` with the `ComponentFixtureAutoDetect` provider.\nFirst import it from the testing utility library:", "translation": "使用 `ComponentFixtureAutoDetect` 服务提供商来配置 `TestBed` 就可以做到这一点。\n首先从测试工具库中导入它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENADDITTOTHEPROVIDERSARRAYOFTHETESTINGMODULECONFIGURATION:", "original": "Then add it to the `providers` array of the testing module configuration:", "translation": "然后把它添加到测试模块配置的 `providers` 数组中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARETHREETESTSTHATILLUSTRATEHOWAUTOMATICCHANGEDETECTIONWORKS", "original": "Here are three tests that illustrate how automatic change detection works.", "translation": "下列测试阐明了自动变更检测的工作原理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFIRSTTESTSHOWSTHEBENEFITOFAUTOMATICCHANGEDETECTION", "original": "The first test shows the benefit of automatic change detection.", "translation": "第一个测试程序展示了自动检测的好处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESECONDANDTHIRDTESTREVEALANIMPORTANTLIMITATIONTHEANGULARTESTINGENVIRONMENTDOESNOTKNOWTHATTHETESTCHANGEDTHECOMPONENTSTITLETHECOMPONENTFIXTUREAUTODETECTSERVICERESPONDSTOASYNCHRONOUSACTIVITIESSUCHASPROMISERESOLUTIONTIMERSANDDOMEVENTSBUTADIRECTSYNCHRONOUSUPDATEOFTHECOMPONENTPROPERTYISINVISIBLETHETESTMUSTCALLFIXTUREDETECTCHANGESMANUALLYTOTRIGGERANOTHERCYCLEOFCHANGEDETECTION", "original": "The second and third test reveal an important limitation.\nThe Angular testing environment does _not_ know that the test changed the component's `title`.\nThe `ComponentFixtureAutoDetect` service responds to _asynchronous activities_ such as promise resolution, timers, and DOM events.\nBut a direct, synchronous update of the component property is invisible.\nThe test must call `fixture.detectChanges()` manually to trigger another cycle of change detection.", "translation": "第二和第三个测试程序显示了它重要的局限性。\nAngular 测试环境**不会**知道测试程序改变了组件的 `title` 属性。\n自动检测只对异步行为比如承诺的解析、计时器和 DOM 事件作出反应。\n但是直接修改组件属性值的这种同步更新是不会触发**自动检测**的。\n测试程序必须手动调用 `fixture.detectChange()`,来触发新一轮的变更检测周期。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RATHERTHANWONDERWHENTHETESTFIXTUREWILLORWONTPERFORMCHANGEDETECTIONTHESAMPLESINTHISGUIDEALWAYSCALLDETECTCHANGESEXPLICITLYTHEREISNOHARMINCALLINGDETECTCHANGESMOREOFTENTHANISSTRICTLYNECESSARY", "original": "Rather than wonder when the test fixture will or won't perform change detection,\nthe samples in this guide _always call_ `detectChanges()` _explicitly_.\nThere is no harm in calling `detectChanges()` more often than is strictly necessary.", "translation": "相比于受测试工具有没有执行变更检测的困扰,本章中的例子更愿意**总是显式**调用 `detectChanges()`。\n即使是在不需要的时候,频繁调用 `detectChanges()` 也没有任何坏处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####CHANGEANINPUTVALUEWITHDISPATCHEVENT", + "original": "#### Change an input value with _dispatchEvent()_", + "translation": "#### 使用 `dispatchEvent()` 修改输入值", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" + }, + { + "key": "TOSIMULATEUSERINPUTYOUCANFINDTHEINPUTELEMENTANDSETITSVALUEPROPERTY", + "original": "To simulate user input, you can find the input element and set its `value` property.", + "translation": "要想模拟用户输入,你就要找到 `<input>` 元素并设置它的 `value` 属性。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" + }, + { + "key": "YOUWILLCALLFIXTUREDETECTCHANGESTOTRIGGERANGULARSCHANGEDETECTIONBUTTHEREISANESSENTIALINTERMEDIATESTEP", + "original": "You will call `fixture.detectChanges()` to trigger Angular's change detection.\nBut there is an essential, intermediate step.", + "translation": "你要调用 `fixture.detectChanges()` 来触发 Angular 的变更检测。\n但那只是一个基本的中间步骤。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" + }, + { + "key": "ANGULARDOESNTKNOWTHATYOUSETTHEINPUTELEMENTSVALUEPROPERTYITWONTREADTHATPROPERTYUNTILYOURAISETHEELEMENTSINPUTEVENTBYCALLINGDISPATCHEVENTTHENYOUCALLDETECTCHANGES", + "original": "Angular doesn't know that you set the input element's `value` property.\nIt won't read that property until you raise the element's `input` event by calling `dispatchEvent()`. \n_Then_ you call `detectChanges()`.", + "translation": "Angular 不知道你设置了这个 `<input>` 元素的 `value` 属性。\n在你通过调用 `dispatchEvent()` 触发了该输入框的 `input` 事件之前,它不能读到那个值。\n*调用完之后*你再调用 `detectChanges()`。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" + }, + { + "key": "THEFOLLOWINGEXAMPLEDEMONSTRATESTHEPROPERSEQUENCE", + "original": "The following example demonstrates the proper sequence.", + "translation": "下面的例子演示了这个调用顺序。", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" + }, + { + "key": "###COMPONENTWITHEXTERNALFILES", "original": "### Component with external files", "translation": "### 带有外部文件的组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEBANNERCOMPONENTABOVEISDEFINEDWITHANINLINETEMPLATEANDINLINECSSSPECIFIEDINTHECOMPONENTTEMPLATEANDCOMPONENTSTYLESPROPERTIESRESPECTIVELY", "original": "The `BannerComponent` above is defined with an _inline template_ and _inline css_, specified in the `@Component.template` and `@Component.styles` properties respectively.", "translation": "上面的 `BannerComponent` 定义了一个*内联模板*和*内联 CSS*,分别是在 `@Component.template` 和 `@Component.styles` 属性中指定的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MANYCOMPONENTSSPECIFYEXTERNALTEMPLATESANDEXTERNALCSSWITHTHECOMPONENTTEMPLATEURLANDCOMPONENTSTYLEURLSPROPERTIESRESPECTIVELYASTHEFOLLOWINGVARIANTOFBANNERCOMPONENTDOES", "original": "Many components specify _external templates_ and _external css_ with the\n`@Component.templateUrl` and `@Component.styleUrls` properties respectively,\nas the following variant of `BannerComponent` does.", "translation": "很多组件会分别用 `@Component.templateUrl` 和 `@Component.styleUrls` 属性来指定*外部模板*和*外部 CSS*,就像下面这个 `BannerComponent` 的变体中所做的一样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISSYNTAXTELLSTHEANGULARCOMPILERTOREADTHEEXTERNALFILESDURINGCOMPONENTCOMPILATION", "original": "This syntax tells the Angular compiler to read the external files during component compilation.", "translation": "这个语法告诉 Angular 编译器在编译期间读取外部文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THATSNOTAPROBLEMWHENYOURUNTHECLINGTESTCOMMANDBECAUSEITCOMPILESTHEAPPBEFORERUNNINGTHETESTS", "original": "That's not a problem when you run the CLI `ng test` command because it\n_compiles the app before running the tests_.", "translation": "当你运行 CLI 的 `ng test` 命令的时候这毫无问题,因为它会*在运行测试之前先编译该应用*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HOWEVERIFYOURUNTHETESTSINANONCLIENVIRONMENTTESTSOFTHISCOMPONENTMAYFAILFOREXAMPLEIFYOURUNTHEBANNERCOMPONENTTESTSINAWEBCODINGENVIRONMENTSUCHASPLUNKERHTTP:PLNKRCOYOULLSEEAMESSAGELIKETHISONE:", "original": "However, if you run the tests in a **non-CLI environment**,\ntests of this component may fail.\nFor example, if you run the `BannerComponent` tests in a web coding environment such as [plunker](http://plnkr.co/), you'll see a message like this one:", "translation": "不过,如果你在**非 CLI 环境下**运行这些测试,那么对该组件的测试就可能失败。\n比如,如果你在像 [plunker](http://plnkr.co/) 这样的 Web 编程环境下运行 `BannerComponent` 的测试,就会看到如下信息:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUGETTHISTESTFAILUREMESSAGEWHENTHERUNTIMEENVIRONMENTCOMPILESTHESOURCECODEDURINGTHETESTSTHEMSELVES", "original": "You get this test failure message when the runtime environment \ncompiles the source code _during the tests themselves_.", "translation": "如果在*测试自身期间*,运行环境试图编译源码,就会出现这个测试错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOCORRECTTHEPROBLEMCALLCOMPILECOMPONENTSASEXPLAINEDBELOW#COMPILECOMPONENTS", "original": "To correct the problem, call `compileComponents()` as explained [below](#compile-components).", "translation": "要解决这个问题,可以像[稍后](#compile-components)解释的那样调用一次 `compileComponents()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTWITHADEPENDENCY", "original": "### Component with a dependency", "translation": "### 带依赖的组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "COMPONENTSOFTENHAVESERVICEDEPENDENCIES", "original": "Components often have service dependencies.", "translation": "组件经常依赖其他服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEWELCOMECOMPONENTDISPLAYSAWELCOMEMESSAGETOTHELOGGEDINUSERITKNOWSWHOTHEUSERISBASEDONAPROPERTYOFTHEINJECTEDUSERSERVICE:", "original": "The `WelcomeComponent` displays a welcome message to the logged in user.\nIt knows who the user is based on a property of the injected `UserService`:", "translation": "`WelcomeComponent` 为登陆的用户显示一条欢迎信息。它从注入的 `UserService` 的属性得知用户的身份:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEWELCOMECOMPONENTHASDECISIONLOGICTHATINTERACTSWITHTHESERVICELOGICTHATMAKESTHISCOMPONENTWORTHTESTINGHERESTHETESTINGMODULECONFIGURATIONFORTHESPECFILEAPPWELCOMEWELCOMECOMPONENTSPECTS:", "original": "The `WelcomeComponent` has decision logic that interacts with the service, logic that makes this component worth testing.\nHere's the testing module configuration for the spec file, `app/welcome/welcome.component.spec.ts`:", "translation": "`WelcomeComponent` 带有与服务交互的决策逻辑,这些逻辑让该组件值得测试。\n下面是 `app/welcome/welcome.component.spec.ts` 中的测试模块配置:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISTIMEINADDITIONTODECLARINGTHECOMPONENTUNDERTESTTHECONFIGURATIONADDSAUSERSERVICEPROVIDERTOTHEPROVIDERSLISTBUTNOTTHEREALUSERSERVICE", "original": "This time, in addition to declaring the _component-under-test_,\nthe configuration adds a `UserService` provider to the `providers` list.\nBut not the real `UserService`.", "translation": "这次,在测试配置里不但声明了被测试的组件,而且在 `providers` 数组中添加了 `UserService` 依赖。但不是真实的 `UserService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####PROVIDESERVICETESTDOUBLES", "original": "#### Provide service test doubles", "translation": "#### 提供服务的测试替身", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ACOMPONENTUNDERTESTDOESNTHAVETOBEINJECTEDWITHREALSERVICESINFACTITISUSUALLYBETTERIFTHEYARETESTDOUBLESSTUBSFAKESSPIESORMOCKSTHEPURPOSEOFTHESPECISTOTESTTHECOMPONENTNOTTHESERVICEANDREALSERVICESCANBETROUBLE", "original": "A _component-under-test_ doesn't have to be injected with real services.\nIn fact, it is usually better if they are test doubles (stubs, fakes, spies, or mocks).\nThe purpose of the spec is to test the component, not the service,\nand real services can be trouble.", "translation": "被测试的组件不一定要注入真正的服务。实际上,服务的替身(Stub - 桩, Fake - 假冒品, Spy - 间谍或者 Mock - 模拟对象)通常会更加合适。\nspec 的主要目的是测试组件,而不是服务。真实的服务可能连自身都有问题,不应该让它干扰对组件的测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INJECTINGTHEREALUSERSERVICECOULDBEANIGHTMARETHEREALSERVICEMIGHTASKTHEUSERFORLOGINCREDENTIALSANDATTEMPTTOREACHANAUTHENTICATIONSERVERTHESEBEHAVIORSCANBEHARDTOINTERCEPTITISFAREASIERANDSAFERTOCREATEANDREGISTERATESTDOUBLEINPLACEOFTHEREALUSERSERVICE", "original": "Injecting the real `UserService` could be a nightmare.\nThe real service might ask the user for login credentials and\nattempt to reach an authentication server.\nThese behaviors can be hard to intercept.\nIt is far easier and safer to create and register a test double in place of the real `UserService`.", "translation": "注入真实的 `UserService` 有可能很麻烦。真实的服务可能询问用户登录凭据,也可能试图连接认证服务器。\n可能很难处理这些行为。所以在真实的 `UserService` 的位置创建和注册 `UserService` 替身,会让测试更加容易和安全。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISPARTICULARTESTSUITESUPPLIESAMINIMALMOCKOFTHEUSERSERVICETHATSATISFIESTHENEEDSOFTHEWELCOMECOMPONENTANDITSTESTS:", "original": "This particular test suite supplies a minimal mock of the `UserService` that satisfies the needs of the `WelcomeComponent`\nand its tests:", "translation": "这个测试套件提供了 `UserService` 的一个最小化模拟对象,它能满足 `WelcomeComponent` 及其测试的需求:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####GETINJECTEDSERVICES", "original": "#### Get injected services", "translation": "#### 获取注入的服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTSNEEDACCESSTOTHESTUBUSERSERVICEINJECTEDINTOTHEWELCOMECOMPONENT", "original": "The tests need access to the (stub) `UserService` injected into the `WelcomeComponent`.", "translation": "测试程序需要访问被注入到 `WelcomeComponent` 中的 `UserService`(stub 类)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANGULARHASAHIERARCHICALINJECTIONSYSTEMTHERECANBEINJECTORSATMULTIPLELEVELSFROMTHEROOTINJECTORCREATEDBYTHETESTBEDDOWNTHROUGHTHECOMPONENTTREE", "original": "Angular has a hierarchical injection system.\nThere can be injectors at multiple levels, from the root injector created by the `TestBed`\ndown through the component tree.", "translation": "Angular 的注入系统是层次化的。\n可以有很多层注入器,从根 `TestBed` 创建的注入器下来贯穿整个组件树。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESAFESTWAYTOGETTHEINJECTEDSERVICETHEWAYTHATALWAYSWORKSISTOGETITFROMTHEINJECTOROFTHECOMPONENTUNDERTESTTHECOMPONENTINJECTORISAPROPERTYOFTHEFIXTURESDEBUGELEMENT", "original": "The safest way to get the injected service, the way that **_always works_**,\nis to **get it from the injector of the _component-under-test_**.\nThe component injector is a property of the fixture's `DebugElement`.", "translation": "最安全并**总是有效**的获取注入服务的方法,是**从被测组件的注入器获取**。\n组件注入器是 fixture 的 `DebugElement` 的属性之一。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUMAYALSOBEABLETOGETTHESERVICEFROMTHEROOTINJECTORVIATESTBEDGETTHISISEASIERTOREMEMBERANDLESSVERBOSEBUTITONLYWORKSWHENANGULARINJECTSTHECOMPONENTWITHTHESERVICEINSTANCEINTHETESTSROOTINJECTOR", "original": "You _may_ also be able to get the service from the root injector via `TestBed.get()`.\nThis is easier to remember and less verbose.\nBut it only works when Angular injects the component with the service instance in the test's root injector.", "translation": "你也可能通过 `TestBed.get()` 来使用根注入器获取该服务。\n这样更容易记住而且不那么啰嗦。\n不过这只有当 Angular 组件需要的恰好是该测试的根注入器时才能正常工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHISTESTSUITETHEONLYPROVIDEROFUSERSERVICEISTHEROOTTESTINGMODULESOITISSAFETOCALLTESTBEDGETASFOLLOWS:", "original": "In this test suite, the _only_ provider of `UserService` is the root testing module,\nso it is safe to call `TestBed.get()` as follows:", "translation": "在这个测试套件中,`UserService` *唯一*的提供商就是根测试模块中的,因此调用 `TestBed.get()` 就是安全的,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FORAUSECASEINWHICHTESTBEDGETDOESNOTWORKSEETHESECTIONOVERRIDEACOMPONENTSPROVIDERS#COMPONENTOVERRIDEWHICHEXPLAINSWHENANDWHYYOUMUSTGETTHESERVICEFROMTHECOMPONENTSINJECTORINSTEAD", "original": "For a use case in which `TestBed.get()` does not work,\nsee the section [_Override a component's providers_](#component-override), which\nexplains when and why you must get the service from the component's injector instead.", "translation": "对于那些不能用 `TestBed.get()` 的测试用例,请参见[改写组件的提供商](#component-override)一节,那里解释了何时以及为何必须改从组件自身的注入器中获取服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####ALWAYSGETTHESERVICEFROMANINJECTOR", "original": "#### Always get the service from an injector", "translation": "#### 总是从注入其中获取服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DONOTREFERENCETHEUSERSERVICESTUBOBJECTTHATSPROVIDEDTOTHETESTINGMODULEINTHEBODYOFYOURTESTITDOESNOTWORKTHEUSERSERVICEINSTANCEINJECTEDINTOTHECOMPONENTISACOMPLETELYDIFFERENTOBJECTACLONEOFTHEPROVIDEDUSERSERVICESTUB", "original": "Do _not_ reference the `userServiceStub` object\nthat's provided to the testing module in the body of your test.\n**It does not work!**\nThe `userService` instance injected into the component is a completely _different_ object,\na clone of the provided `userServiceStub`.", "translation": "请不要引用测试代码里提供给测试模块的 `userServiceStub` 对象。**这样不行!**\n被注入组件的 `userService` 实例是完全**不一样**的对象,它提供的是 `userServiceStub` 的克隆。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####FINALSETUPANDTESTS", "original": "#### Final setup and tests", "translation": "#### 最终的准备及测试代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHECOMPLETEBEFOREEACHUSINGTESTBEDGET:", "original": "Here's the complete `beforeEach()`, using `TestBed.get()`:", "translation": "下面是使用 `TestBed.get()` 的完整的 `beforeEach()`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANDHEREARESOMETESTS:", "original": "And here are some tests:", "translation": "下面是一些测试程序:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFIRSTISASANITYTESTITCONFIRMSTHATTHESTUBBEDUSERSERVICEISCALLEDANDWORKING", "original": "The first is a sanity test; it confirms that the stubbed `UserService` is called and working.", "translation": "第一个测试程序是合法测试程序,它确认这个被模拟的 `UserService` 是否被调用和工作正常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESECONDPARAMETERTOTHEJASMINEMATCHEREGEXPECTEDNAMEISANOPTIONALFAILURELABELIFTHEEXPECTATIONFAILSJASMINEDISPLAYSAPPENDSTHISLABELTOTHEEXPECTATIONFAILUREMESSAGEINASPECWITHMULTIPLEEXPECTATIONSITCANHELPCLARIFYWHATWENTWRONGANDWHICHEXPECTATIONFAILED", "original": "The second parameter to the Jasmine matcher (e.g., `'expected name'`) is an optional failure label.\nIf the expectation fails, Jasmine displays appends this label to the expectation failure message.\nIn a spec with multiple expectations, it can help clarify what went wrong and which expectation failed.", "translation": "Jasmine 匹配器的第二个参数(比如 `'expected name'`)是一个可选的失败标签。\n如果这个期待语句失败了,Jasmine 就会把这个标签追加到这条个期待语句的失败信息后面。\n对于具有多个期待语句的规约,它可以帮助澄清到底什么出错了,以及哪个期待语句失败了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEREMAININGTESTSCONFIRMTHELOGICOFTHECOMPONENTWHENTHESERVICERETURNSDIFFERENTVALUESTHESECONDTESTVALIDATESTHEEFFECTOFCHANGINGTHEUSERNAMETHETHIRDTESTCHECKSTHATTHECOMPONENTDISPLAYSTHEPROPERMESSAGEWHENTHEREISNOLOGGEDINUSER", "original": "The remaining tests confirm the logic of the component when the service returns different values.\nThe second test validates the effect of changing the user name.\nThe third test checks that the component displays the proper message when there is no logged-in user.", "translation": "接下来的测试程序确认当服务返回不同的值时组件的逻辑是否工作正常。\n第二个测试程序验证变换用户名字的效果。\n第三个测试程序检查如果用户没有登录,组件是否显示正确消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTWITHASYNCSERVICE", "original": "### Component with async service", "translation": "### 带有异步服务的组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHISSAMPLETHEABOUTCOMPONENTTEMPLATEHOSTSATWAINCOMPONENTTHETWAINCOMPONENTDISPLAYSMARKTWAINQUOTES", "original": "In this sample, the `AboutComponent` template hosts a `TwainComponent`.\nThe `TwainComponent` displays Mark Twain quotes.", "translation": "在这个例子中,`AboutComponent` 的模板中还有一个 `TwainComponent`。\n`TwainComponent` 用于显示引自马克·吐温的话。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOTETHATVALUEOFTHECOMPONENTSQUOTEPROPERTYPASSESTHROUGHANASYNCPIPETHATMEANSTHEPROPERTYRETURNSEITHERAPROMISEORANOBSERVABLE", "original": "Note that value of the component's `quote` property passes through an `AsyncPipe`.\nThat means the property returns either a `Promise` or an `Observable`.", "translation": "注意该组件的 `quote` 属性的值是通过 `AsyncPipe` 传进来的。\n这意味着该属性或者返回 `Promise` 或者返回 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHISEXAMPLETHETWAINCOMPONENTGETQUOTEMETHODTELLSYOUTHATTHEQUOTEPROPERTYRETURNSANOBSERVABLE", "original": "In this example, the `TwainComponent.getQuote()` method tells you that \nthe `quote` property returns an `Observable`.", "translation": "在这个例子中,`TwainComponent.getQuote()` 方法告诉你 `quote` 方法返回的是 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETWAINCOMPONENTGETSQUOTESFROMANINJECTEDTWAINSERVICETHECOMPONENTSTARTSTHERETURNEDOBSERVABLEWITHAPLACEHOLDERVALUEBEFORETHESERVICECANRETURNSITSFIRSTQUOTE", "original": "The `TwainComponent` gets quotes from an injected `TwainService`.\nThe component starts the returned `Observable` with a placeholder value (`'...'`),\nbefore the service can returns its first quote.", "translation": "`TwainComponent` 会从一个注入进来的 `TwainService` 来获取这些引文。\n在服务返回第一条引文之前,该组件会先返回一个占位值(`'...'`)的 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECATCHERRORINTERCEPTSSERVICEERRORSPREPARESANERRORMESSAGEANDRETURNSTHEPLACEHOLDERVALUEONTHESUCCESSCHANNELITMUSTWAITATICKTOSETTHEERRORMESSAGEINORDERTOAVOIDUPDATINGTHATMESSAGETWICEINTHESAMECHANGEDETECTIONCYCLE", "original": "The `catchError` intercepts service errors, prepares an error message,\nand returns the placeholder value on the success channel.\nIt must wait a tick to set the `errorMessage` \nin order to avoid updating that message twice in the same change detection cycle.", "translation": "`catchError` 会拦截服务中的错误,准备错误信息,并在成功分支中返回占位值。\n它必须等一拍(tick)才能设置 `errorMessage`,以免在同一个变更检测周期中两次修改这个消息而导致报错。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESEAREALLFEATURESYOULLWANTTOTEST", "original": "These are all features you'll want to test.", "translation": "这就是你要测试的全部特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####TESTINGWITHASPY", "original": "#### Testing with a spy", "translation": "#### 使用间谍(Spy)进行测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENTESTINGACOMPONENTONLYTHESERVICESPUBLICAPISHOULDMATTERINGENERALTESTSTHEMSELVESSHOULDNOTMAKECALLSTOREMOTESERVERSTHEYSHOULDEMULATESUCHCALLSTHESETUPINTHISAPPTWAINTWAINCOMPONENTSPECTSSHOWSONEWAYTODOTHAT:", "original": "When testing a component, only the service's public API should matter.\nIn general, tests themselves should not make calls to remote servers.\nThey should emulate such calls. The setup in this `app/twain/twain.component.spec.ts` shows one way to do that:", "translation": "当测试组件时,只应该关心服务的公共 API。\n通常来说,测试不应该自己向远端服务器发起调用。\n它们应该对这些调用进行仿真。`app/twain/twain.component.spec.ts` 中的准备代码展示了实现方式之一:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FOCUSONTHESPY", "original": "Focus on the spy.", "translation": "重点看这个间谍对象(spy)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESPYISDESIGNEDSUCHTHATANYCALLTOGETQUOTERECEIVESANOBSERVABLEWITHATESTQUOTEUNLIKETHEREALGETQUOTEMETHODTHISSPYBYPASSESTHESERVERANDRETURNSASYNCHRONOUSOBSERVABLEWHOSEVALUEISAVAILABLEIMMEDIATELY", "original": "The spy is designed such that any call to `getQuote` receives an Observable with a test quote.\nUnlike the real `getQuote()` method, this spy bypasses the server\nand returns a synchronous Observable whose value is available immediately.", "translation": "这个间谍的设计是:任何对 `getQuote` 的调用都会收到一个包含测试引文的可观察对象。\n和真正的 `getQuote()` 方法不同,这个间谍跳过了服务器,直接返回了一个能立即解析出值的同步型可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANWRITEMANYUSEFULTESTSWITHTHISSPYEVENTHOUGHITSOBSERVABLEISSYNCHRONOUS", "original": "You can write many useful tests with this spy, even though its `Observable` is synchronous.", "translation": "虽然它的 `Observable` 是同步的,不过你仍然可以使用这个间谍对象写出很多有用的测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####SYNCHRONOUSTESTS", "original": "#### Synchronous tests", "translation": "#### 同步测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AKEYADVANTAGEOFASYNCHRONOUSOBSERVABLEISTHATYOUCANOFTENTURNASYNCHRONOUSPROCESSESINTOSYNCHRONOUSTESTS", "original": "A key advantage of a synchronous `Observable` is that \nyou can often turn asynchronous processes into synchronous tests.", "translation": "同步 `Observable` 的一大优点就是你可以把那些异步的流程转换成同步测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BECAUSETHESPYRESULTRETURNSSYNCHRONOUSLYTHEGETQUOTEMETHODUPDATESTHEMESSAGEONSCREENIMMEDIATELYAFTERTHEFIRSTCHANGEDETECTIONCYCLEDURINGWHICHANGULARCALLSNGONINIT", "original": "Because the spy result returns synchronously, the `getQuote()` method updates\nthe message on screen immediately _after_\nthe first change detection cycle during which Angular calls `ngOnInit`.", "translation": "因为间谍对象的结果是同步返回的,所以 `getQuote()` 方法会在 Angular 调用 `ngOnInit` 时触发的首次变更检测周期后立即修改屏幕上的消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOURENOTSOLUCKYWHENTESTINGTHEERRORPATHALTHOUGHTHESERVICESPYWILLRETURNANERRORSYNCHRONOUSLYTHECOMPONENTMETHODCALLSSETTIMEOUTTHETESTMUSTWAITATLEASTONEFULLTURNOFTHEJAVASCRIPTENGINEBEFORETHEVALUEBECOMESAVAILABLETHETESTMUSTBECOMEASYNCHRONOUS", "original": "You're not so lucky when testing the error path.\nAlthough the service spy will return an error synchronously,\nthe component method calls `setTimeout()`.\nThe test must wait at least one full turn of the JavaScript engine before the\nvalue becomes available. The test must become _asynchronous_.", "translation": "但测试出错路径的时候就没这么幸运了。\n虽然该服务的间谍也会返回一个同步的错误对象,但是组件的那个方法中调用了 `setTimeout()`。\n这个测试必须至少等待 JavaScript 引擎的一个周期,那个值才会变成可用状态。因此这个测试变成了*异步的*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####ASYNCTESTWITHFAKEASYNC", "original": "#### Async test with _fakeAsync()_", "translation": "#### 使用 `fakeAsync()` 进行异步测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGTESTCONFIRMSTHEEXPECTEDBEHAVIORWHENTHESERVICERETURNSANERROROBSERVABLE", "original": "The following test confirms the expected behavior when the service returns an `ErrorObservable`.", "translation": "下列测试用于确保当服务返回 `ErrorObservable` 的时候也能有符合预期的行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOTETHATTHEITFUNCTIONRECEIVESANARGUMENTOFTHEFOLLOWINGFORM", "original": "Note that the `it()` function receives an argument of the following form.", "translation": "注意这个 `it()` 函数接收了一个如下形式的参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFAKEASYNCFUNCTIONENABLESALINEARCODINGSTYLEBYRUNNINGTHETESTBODYINASPECIALFAKEASYNCTESTZONETHETESTBODYAPPEARSTOBESYNCHRONOUSTHEREISNONESTEDSYNTAXLIKEAPROMISETHENTODISRUPTTHEFLOWOFCONTROL", "original": "The `fakeAsync` function enables a linear coding style by running the test body in a special _fakeAsync test zone_.\nThe test body appears to be synchronous.\nThere is no nested syntax (like a `Promise.then()`) to disrupt the flow of control.", "translation": "`fakeAsync` 函数通过在一个特殊的*`fakeAsync` 测试区域(zone)*中运行测试体来启用线性代码风格。\n测试体看上去是同步的。\n这里没有嵌套式语法(如 `Promise.then()`)来打断控制流。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####THETICKFUNCTION", "original": "#### The _tick()_ function", "translation": "#### `tick()` 函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUDOHAVETOCALLTICKTOADVANCETHEVIRTUALCLOCK", "original": "You do have to call `tick()` to advance the (virtual) clock.", "translation": "你必须调用 `tick()` 函数来向前推动(虚拟)时钟。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CALLINGTICKSIMULATESTHEPASSAGEOFTIMEUNTILALLPENDINGASYNCHRONOUSACTIVITIESFINISHINTHISCASEITWAITSFORTHEERRORHANDLERSSETTIMEOUT", "original": "Calling `tick()` simulates the passage of time until all pending asynchronous activities finish.\nIn this case, it waits for the error handler's `setTimeout()`;", "translation": "调用 `tick()` 会模拟时光的流逝,直到所有未决的异步活动都结束为止。\n在这个例子中,它会等待错误处理器中的 `setTimeout()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETICKFUNCTIONISONEOFTHEANGULARTESTINGUTILITIESTHATYOUIMPORTWITHTESTBEDITSACOMPANIONTOFAKEASYNCANDYOUCANONLYCALLITWITHINAFAKEASYNCBODY", "original": "The `tick` function is one of the Angular testing utilities that you import with `TestBed`.\nIt's a companion to `fakeAsync` and you can only call it within a `fakeAsync` body.", "translation": "`tick` 函数是你通过 `TestBed` 中引入的 Angular 测试工具集之一。\n它总是和 `fakeAsync` 一起使用,你也只能在 `fakeAsync` 的函数体中调用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####ASYNCOBSERVABLES", "original": "#### Async observables", "translation": "#### 异步的可观察对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUMIGHTBESATISFIEDWITHTHETESTCOVERAGEOFTHESETESTS", "original": "You might be satisfied with the test coverage of these tests.", "translation": "你可能对这些测试的覆盖率已经很满足了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BUTYOUMIGHTBETROUBLEDBYTHEFACTTHATTHEREALSERVICEDOESNTQUITEBEHAVETHISWAYTHEREALSERVICESENDSREQUESTSTOAREMOTESERVERASERVERTAKESTIMETORESPONDANDTHERESPONSECERTAINLYWONTBEAVAILABLEIMMEDIATELYASINTHEPREVIOUSTWOTESTS", "original": "But you might be troubled by the fact that the real service doesn't quite behave this way.\nThe real service sends requests to a remote server.\nA server takes time to respond and the response certainly won't be available immediately\nas in the previous two tests.", "translation": "不过你可能会因为真实的服务没有按这种方式工作而困扰。\n真实的服务器会把请求发送给远端服务器。\n服务需要花一些时间来作出响应,它的响应当然也不会真的像前面两个测试中那样立即可用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOURTESTSWILLREFLECTTHEREALWORLDMOREFAITHFULLYIFYOURETURNANASYNCHRONOUSOBSERVABLEFROMTHEGETQUOTESPYLIKETHIS", "original": "Your tests will reflect the real world more faithfully if you return an _asynchronous_ observable\nfrom the `getQuote()` spy like this.", "translation": "如果你在 `getQuote()` 间谍中返回一个*异步*可观察对象,那它就能更忠诚的反映出真实的世界了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####ASYNCOBSERVABLEHELPERS", "original": "#### Async observable helpers", "translation": "#### 可观察对象的异步助手", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEASYNCOBSERVABLEWASPRODUCEDBYANASYNCDATAHELPERTHEASYNCDATAHELPERISAUTILITYFUNCTIONTHATYOULLHAVETOWRITEYOURSELFORYOUCANCOPYTHISONEFROMTHESAMPLECODE", "original": "The async observable was produced by an `asyncData` helper\nThe `asyncData` helper is a utility function that you'll have to write yourself.\nOr you can copy this one from the sample code.", "translation": "这个异步的可观察对象是用 `asyncData` 辅助函数生成的。\n`asyncData` 助手是一个工具函数,你可以自己写一个,也可以从下面的范例代码中复制一份。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISHELPERSOBSERVABLEEMITSTHEDATAVALUEINTHENEXTTURNOFTHEJAVASCRIPTENGINE", "original": "This helper's observable emits the `data` value in the next turn of the JavaScript engine.", "translation": "这个辅助函数的可观察对象会在 JavaScript 引擎的下一个工作周期中发出 `data` 的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RXJSDEFERHTTP:REACTIVEXIODOCUMENTATIONOPERATORSDEFERHTMLRETURNSANOBSERVABLEITTAKESAFACTORYFUNCTIONTHATRETURNSEITHERAPROMISEORANOBSERVABLEWHENSOMETHINGSUBSCRIBESTODEFERSOBSERVABLEITADDSTHESUBSCRIBERTOANEWOBSERVABLECREATEDWITHTHATFACTORY", "original": "[RxJS `defer()`](http://reactivex.io/documentation/operators/defer.html) returns an observable.\nIt takes a factory function that returns either a promise or an observable.\nWhen something subscribes to _defer_'s observable,\nit adds the subscriber to a new observable created with that factory.", "translation": "[RxJS `defer()`](http://reactivex.io/documentation/operators/defer.html) (延期)返回一个可观察对象。\n它获取一个工厂函数,这个工厂函数或者返回 Promise 或者返回 Observable。\n当有人订阅了这个 `defer` 的可观察对象时,它就会把这个订阅者添加到由那个工厂函数创建的新的可观察对象中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RXJSDEFERTRANSFORMTHEPROMISERESOLVEINTOANEWOBSERVABLETHATLIKEHTTPCLIENTEMITSONCEANDCOMPLETESSUBSCRIBERSWILLBEUNSUBSCRIBEDAFTERTHEYRECEIVETHEDATAVALUE", "original": "RxJS `defer()` transform the `Promise.resolve()` into a new observable that, \nlike `HttpClient`, emits once and completes.\nSubscribers will be unsubscribed after they receive the data value.", "translation": "RxJS `defer()` 会把 `Promise.resolve()` 转换成一个新的可观察对象,然后像 `HttpClient` 那样的发出一个值,然后结束。\n订阅者将会在接收到这个数据值之后自动被取消订阅。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERESASIMILARHELPERFORPRODUCINGANASYNCERROR", "original": "There's a similar helper for producing an async error.", "translation": "下面是一个类似的用于产生异步错误的辅助函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####MOREASYNCTESTS", "original": "#### More async tests", "translation": "#### 更多异步测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOWTHATTHEGETQUOTESPYISRETURNINGASYNCOBSERVABLESMOSTOFYOURTESTSWILLHAVETOBEASYNCASWELL", "original": "Now that the `getQuote()` spy is returning async observables,\nmost of your tests will have to be async as well.", "translation": "现在,`getQuote()` 间谍会返回一个异步的可观察对象,你的大多数测试也同样要变成异步的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESAFAKEASYNCTESTTHATDEMONSTRATESTHEDATAFLOWYOUDEXPECTINTHEREALWORLD", "original": "Here's a `fakeAsync()` test that demonstrates the data flow you'd expect \nin the real world.", "translation": "下面这个 `fakeAsync()` 测试演示了你所期待的和真实世界中一样的数据流。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOTICETHATTHEQUOTEELEMENTDISPLAYSTHEPLACEHOLDERVALUEAFTERNGONINITTHEFIRSTQUOTEHASNTARRIVEDYET", "original": "Notice that the quote element displays the placeholder value (`'...'`) after `ngOnInit()`.\nThe first quote hasn't arrived yet.", "translation": "注意,这个 `<quote>` 元素应该在 `ngOnInit()` 之后显示占位值(`'...'`),\n但第一个引文却没有出现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOFLUSHTHEFIRSTQUOTEFROMTHEOBSERVABLEYOUCALLTICKTHENCALLDETECTCHANGESTOTELLANGULARTOUPDATETHESCREEN", "original": "To flush the first quote from the observable, you call `tick()`.\nThen call `detectChanges()` to tell Angular to update the screen.", "translation": "要刷出可观察对象中的第一个引文,你就要先调用 `tick()`,然后调用 `detectChanges()` 来要求 Angular 刷新屏幕。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENYOUCANASSERTTHATTHEQUOTEELEMENTDISPLAYSTHEEXPECTEDTEXT", "original": "Then you can assert that the quote element displays the expected text.", "translation": "然后你就可以断言这个 `<quote>` 元素应该显示所预期的文字了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####ASYNCTESTWITHASYNC", "original": "#### Async test with _async()_", "translation": "#### 使用 `async()` 进行异步测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFAKEASYNCUTILITYFUNCTIONHASAFEWLIMITATIONSINPARTICULARITWONTWORKIFTHETESTBODYMAKESANXHRCALL", "original": "The `fakeAsync()` utility function has a few limitations.\nIn particular, it won't work if the test body makes an `XHR` call.", "translation": "`fakeAsync()` 工具函数有一些限制。\n特别是,如果测试中发起了 `XHR` 调用,它就没用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "XHRCALLSWITHINATESTARERARESOYOUCANGENERALLYSTICKWITHFAKEASYNCBUTIFYOUEVERDONEEDTOCALLXHRYOULLWANTTOKNOWABOUTASYNC", "original": "`XHR` calls within a test are rare so you can generally stick with `fakeAsync()`.\nBut if you ever do need to call `XHR`, you'll want to know about `async()`.", "translation": "测试中的 `XHR` 调用比较罕见,所以你通常会使用 `fakeAsync()`。\n不过你可能迟早会需要调用 `XHR`,那就来了解一些 `async()` 的知识吧。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDCOMPILECOMPONENTSMETHODSEEBELOW#COMPILECOMPONENTSCALLSXHRTOREADEXTERNALTEMPLATEANDCSSFILESDURINGJUSTINTIMECOMPILATIONWRITETESTSTHATCALLCOMPILECOMPONENTSWITHTHEASYNCUTILITY", "original": "The `TestBed.compileComponents()` method (see [below](#compile-components)) calls `XHR`\nto read external template and css files during \"just-in-time\" compilation.\nWrite tests that call `compileComponents()` with the `async()` utility.", "translation": "`TestBed.compileComponents()` 方法(参见[稍后](#compile-components))就会在 JIT 编译期间调用 `XHR` 来读取外部模板和 CSS 文件。\n如果写调用了 `compileComponents()` 的测试,就要用到 `async()` 工具函数了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHEPREVIOUSFAKEASYNCTESTREWRITTENWITHTHEASYNCUTILITY", "original": "Here's the previous `fakeAsync()` test, re-written with the `async()` utility.", "translation": "下面是用 `async()` 工具函数重写的以前的 `fakeAsync()` 测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEASYNCUTILITYHIDESSOMEASYNCHRONOUSBOILERPLATEBYARRANGINGFORTHETESTERSCODETORUNINASPECIALASYNCTESTZONEYOUDONTHAVETOPASSJASMINESDONEINTOTHETESTANDCALLDONEINPROMISEOROBSERVABLECALLBACKS", "original": "The `async()` utility hides some asynchronous boilerplate by arranging for the tester's code \nto run in a special _async test zone_.\nYou don't have to pass Jasmine's `done()` into the test and call `done()` \nin promise or observable callbacks.", "translation": "`async()` 工具函数通过把测试人员的代码放进在一个特殊的*async 测试区域*中,节省了一些用于异步调用的样板代码。\n你不必把 Jasmine 的 `done()` 传给这个测试,并在承诺(Promise)或可观察对象的回调中调用 `done()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BUTTHETESTSASYNCHRONOUSNATUREISREVEALEDBYTHECALLTOFIXTUREWHENSTABLEWHICHBREAKSTHELINEARFLOWOFCONTROL", "original": "But the test's asynchronous nature is revealed by the call to `fixture.whenStable()`,\nwhich breaks the linear flow of control.", "translation": "但是对 `fixture.whenStable()` 的调用揭示了该测试的异步本性,它将会打破线性的控制流。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTMUSTWAITFORTHEGETQUOTEOBSERVABLETOEMITTHENEXTQUOTEINSTEADOFCALLINGTICKITCALLSFIXTUREWHENSTABLE", "original": "The test must wait for the `getQuote()` observable to emit the next quote.\nInstead of calling `tick()`, it calls `fixture.whenStable()`.", "translation": "该测试必须等待 `getQuote()` 的可观察对象发出下一条引言。\n它不再调用 `tick()`,而是调用 `fixture.whenStable()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFIXTUREWHENSTABLERETURNSAPROMISETHATRESOLVESWHENTHEJAVASCRIPTENGINESTASKQUEUEBECOMESEMPTYINTHISEXAMPLETHETASKQUEUEBECOMESEMPTYWHENTHEOBSERVABLEEMITSTHEFIRSTQUOTE", "original": "The `fixture.whenStable()` returns a promise that resolves when the JavaScript engine's\ntask queue becomes empty. \nIn this example, the task queue becomes empty when the observable emits the first quote.", "translation": "`fixture.whenStable()` 返回一个承诺,这个承诺会在 JavaScript 引擎的任务队列变为空白时被解析。\n在这个例子中,一旦这个可观察对象发出了第一条引言,这个任务队列就会变为空。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTRESUMESWITHINTHEPROMISECALLBACKWHICHCALLSDETECTCHANGESTOUPDATETHEQUOTEELEMENTWITHTHEEXPECTEDTEXT", "original": "The test resumes within the promise callback, which calls `detectChanges()` to \nupdate the quote element with the expected text.", "translation": "该测试在这个承诺的回调中继续执行,它会调用 `detectChanges()` 来用预期的文本内容修改 `<quote>` 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHILETHEASYNCANDFAKEASYNCFUNCTIONSGREATLYSIMPLIFYANGULARASYNCHRONOUSTESTINGYOUCANSTILLFALLBACKTOTHETRADITIONALTECHNIQUEANDPASSITAFUNCTIONTHATTAKESADONECALLBACKHTTP:JASMINEGITHUBIO20INTRODUCTIONHTML#SECTIONASYNCHRONOUSSUPPORT", "original": "While the `async` and `fakeAsync` functions greatly\nsimplify Angular asynchronous testing,\nyou can still fall back to the traditional technique\nand pass `it` a function that takes a\n[`done` callback](http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support).", "translation": "虽然 `async` 和 `fakeAsync` 函数极大地简化了 Angular 的异步测试,不过你仍然可以回退到传统的技术中。\n也就是说给 `it` 额外传入一个函数型参数,这个函数接受一个 [`done` 回调](http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOWYOUARERESPONSIBLEFORCHAININGPROMISESHANDLINGERRORSANDCALLINGDONEATTHEAPPROPRIATEMOMENTS", "original": "Now you are responsible for chaining promises, handling errors, and calling `done()` at the appropriate moments.", "translation": "现在,你就要负责对 Promise 进行链接、处理错误,并在适当的时机调用 `done()` 了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WRITINGTESTFUNCTIONSWITHDONEISMORECUMBERSOMETHANASYNCANDFAKEASYNCBUTITISOCCASIONALLYNECESSARYFOREXAMPLEYOUCANTCALLASYNCORFAKEASYNCWHENTESTINGCODETHATINVOLVESTHEINTERVALTIMERORTHERXJSDELAYOPERATOR", "original": "Writing test functions with `done()`, is more cumbersome than `async`and `fakeAsync`.\nBut it is occasionally necessary.\nFor example, you can't call `async` or `fakeAsync` when testing\ncode that involves the `intervalTimer()` or the RxJS `delay()` operator.", "translation": "写带有 `done()` 的测试函数会比 `async` 和 `fakeAsync` 方式更加冗长。\n不过有些时候它是必要的。\n比如,你不能在那些涉及到 `intervalTimer()` 或 RxJS 的 `delay()` 操作符时调用 `async` 或 `fakeAsync` 函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARETWOMOVERVERSIONSOFTHEPREVIOUSTESTWRITTENWITHDONETHEFIRSTONESUBSCRIBESTOTHEOBSERVABLEEXPOSEDTOTHETEMPLATEBYTHECOMPONENTSQUOTEPROPERTY", "original": "Here are two mover versions of the previous test, written with `done()`.\nThe first one subscribes to the `Observable` exposed to the template by the component's `quote` property.", "translation": "下面是对前面的测试用 `done()` 重写后的两个版本。\n第一个会订阅由组件的 `quote` 属性暴露给模板的那个 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERXJSLASTOPERATOREMITSTHEOBSERVABLESLASTVALUEBEFORECOMPLETINGWHICHWILLBETHETESTQUOTETHESUBSCRIBECALLBACKCALLSDETECTCHANGESTOUPDATETHEQUOTEELEMENTWITHTHETESTQUOTEINTHESAMEMANNERASTHEEARLIERTESTS", "original": "The RxJS `last()` operator emits the observable's last value before completing, which will be the test quote.\nThe `subscribe` callback calls `detectChanges()` to \nupdate the quote element with the test quote, in the same manner as the earlier tests.", "translation": "RxJS 的 `last()` 操作符会在结束之前发出这个可观察对象的最后一个值,也就是那条测试引文。\n`subscribe` 回调中会像以前一样调用 `detectChanges()` 用这条测试引文更新 `<quote>` 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INSOMETESTSYOUREMOREINTERESTEDINHOWANINJECTEDSERVICEMETHODWASCALLEDANDWHATVALUESITRETURNEDTHANWHATAPPEARSONSCREEN", "original": "In some tests, you're more interested in how an injected service method was called and what values it returned,\nthan what appears on screen.", "translation": "有些测试中,相对于在屏幕上展示了什么,你可能会更关心所注入服务的某个方法是如何被调用的,以及它的返回值是什么。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ASERVICESPYSUCHASTHEQETQUOTESPYOFTHEFAKETWAINSERVICECANGIVEYOUTHATINFORMATIONANDMAKEASSERTIONSABOUTTHESTATEOFTHEVIEW", "original": "A service spy, such as the `qetQuote()` spy of the fake `TwainService`,\ncan give you that information and make assertions about the state of the view.", "translation": "服务的间谍,比如假冒服务 `TwainService` 的 `getQuote()` 间谍,可以给你那些信息,并且对视图的状态做出断言。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTMARBLETESTS", "original": "### Component marble tests", "translation": "### 组件的宝石测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEPREVIOUSTWAINCOMPONENTTESTSSIMULATEDANASYNCHRONOUSOBSERVABLERESPONSEFROMTHETWAINSERVICEWITHTHEASYNCDATAANDASYNCERRORUTILITIES", "original": "The previous `TwainComponent` tests simulated an asynchronous observable response\nfrom the `TwainService` with the `asyncData` and `asyncError` utilities.", "translation": "前面的 `TwainComponent` 测试中使用 `TwainService` 中的 `asyncData` 和 `asyncError` 工具函数仿真了可观察对象的异步响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESEARESHORTSIMPLEFUNCTIONSTHATYOUCANWRITEYOURSELFUNFORTUNATELYTHEYRETOOSIMPLEFORMANYCOMMONSCENARIOSANOBSERVABLEOFTENEMITSMULTIPLETIMESPERHAPSAFTERASIGNIFICANTDELAYACOMPONENTMAYCOORDINATEMULTIPLEOBSERVABLESWITHOVERLAPPINGSEQUENCESOFVALUESANDERRORS", "original": "These are short, simple functions that you can write yourself.\nUnfortunately, they're too simple for many common scenarios.\nAn observable often emits multiple times, perhaps after a significant delay.\nA component may coordinate multiple observables\nwith overlapping sequences of values and errors.", "translation": "那些都是你自己写的简短函数。\n很不幸,它们对于很多常见场景来说都太过简单了。\n可观察对象通常会发出很多次值,还可能会在显著的延迟之后。\n组件可能要协调多个由正常值和错误值组成的重叠序列的可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RXJSMARBLETESTINGISAGREATWAYTOTESTOBSERVABLESCENARIOSBOTHSIMPLEANDCOMPLEXYOUVELIKELYSEENTHEMARBLEDIAGRAMSHTTP:RXMARBLESCOMTHATILLUSTRATEHOWOBSERVABLESWORKMARBLETESTINGUSESASIMILARMARBLELANGUAGETOSPECIFYTHEOBSERVABLESTREAMSANDEXPECTATIONSINYOURTESTS", "original": "**RxJS marble testing** is a great way to test observable scenarios,\nboth simple and complex.\nYou've likely seen the [marble diagrams](http://rxmarbles.com/)\nthat illustrate how observables work.\nMarble testing uses a similar marble language to\nspecify the observable streams and expectations in your tests.", "translation": "**RxJS 的宝石测试**是测试各种可观察对象场景的最佳方式 —— 无论简单还是复杂。\n你可以看看[宝石图](http://rxmarbles.com/),它揭示了可观察对象的工作原理。\n宝石测试使用类似的宝石语言来在你的测试中指定可观察对象流和对它们的期待。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGEXAMPLESREVISITTWOOFTHETWAINCOMPONENTTESTSWITHMARBLETESTING", "original": "The following examples revisit two of the `TwainComponent` tests\nwith marble testing.", "translation": "下面的例子使用宝石测试重写了 `TwainComponent` 的两个测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "STARTBYINSTALLINGTHEJASMINEMARBLESNPMPACKAGETHENIMPORTTHESYMBOLSYOUNEED", "original": "Start by installing the `jasmine-marbles` npm package.\nThen import the symbols you need.", "translation": "首先安装 `jasmine-marbles` 这个 npm 包,然后倒入所需的符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHECOMPLETETESTFORGETTINGAQUOTE:", "original": "Here's the complete test for getting a quote:", "translation": "下面是对获取引文功能的完整测试:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOTICETHATTHEJASMINETESTISSYNCHRONOUSTHERESNOFAKEASYNCMARBLETESTINGUSESATESTSCHEDULERTOSIMULATETHEPASSAGEOFTIMEINASYNCHRONOUSTEST", "original": "Notice that the Jasmine test is synchronous. There's no `fakeAsync()`.\nMarble testing uses a test scheduler to simulate the passage of time\nin a synchronous test.", "translation": "注意,这个 Jasmine 测试是同步的。没有调用 `fakeAsync()`。\n宝石测试使用了一个测试调度程序来用同步的方式模拟时间的流逝。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEBEAUTYOFMARBLETESTINGISINTHEVISUALDEFINITIONOFTHEOBSERVABLESTREAMSTHISTESTDEFINESACOLDOBSERVABLE#COLDOBSERVABLETHATWAITSTHREEFRAMES#MARBLEFRAMEEMITSAVALUEXANDCOMPLETESINTHESECONDARGUMENTYOUMAPTHEVALUEMARKERXTOTHEEMITTEDVALUETESTQUOTE", "original": "The beauty of marble testing is in the visual definition of the observable streams.\nThis test defines a [_cold_ observable](#cold-observable) that waits \nthree [frames](#marble-frame) (`---`),\nemits a value (`x`), and completes (`|`).\nIn the second argument you map the value marker (`x`) to the emitted value (`testQuote`).", "translation": "宝石测试的美妙之处在于它给出了可观察对象流的可视化定义。\n这个测试定义了一个[*冷的*可观察对象](#cold-observable),它等待三[帧](#marble-frame) (`---`),然后发出一个值(`x`),然后结束(`|`)。\n在第二个参数中,你把值标记(`x`)换成了实际发出的值(`testQuote`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEMARBLELIBRARYCONSTRUCTSTHECORRESPONDINGOBSERVABLEWHICHTHETESTSETSASTHEGETQUOTESPYSRETURNVALUE", "original": "The marble library constructs the corresponding observable, which the\ntest sets as the `getQuote` spy's return value.", "translation": "这个宝石库会构造出相应的可观察对象,测试代码会把它当做 `getQuote` 间谍的返回值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENYOUREREADYTOACTIVATETHEMARBLEOBSERVABLESYOUTELLTHETESTSCHEDULERTOFLUSHITSQUEUEOFPREPAREDTASKSLIKETHIS", "original": "When you're ready to activate the marble observables,\nyou tell the `TestScheduler` to _flush_ its queue of prepared tasks like this.", "translation": "当你已经准备好激活这个宝石库构造出的可观察对象时,只要让 `TestScheduler` 去*刷新*准备好的任务队列就可以了。代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISSTEPSERVESAPURPOSEANALOGOUSTOTICKANDWHENSTABLEINTHEEARLIERFAKEASYNCANDASYNCEXAMPLESTHEBALANCEOFTHETESTISTHESAMEASTHOSEEXAMPLES", "original": "This step serves a purpose analogous to `tick()` and `whenStable()` in the\nearlier `fakeAsync()` and `async()` examples.\nThe balance of the test is the same as those examples.", "translation": "这个步骤的目的类似于前面的 `fakeAsync()` 和 `async()` 范例中的 `tick()` 和 `whenStable()`。\n这种测试的权衡方式也和那些例子中是一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####MARBLEERRORTESTING", "original": "#### Marble error testing", "translation": "#### 宝石错误测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHEMARBLETESTINGVERSIONOFTHEGETQUOTEERRORTEST", "original": "Here's the marble testing version of the `getQuote()` error test.", "translation": "下面是 `getQuote()` 错误测试的宝石测试版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITSSTILLANASYNCTESTCALLINGFAKEASYNCANDTICKBECAUSETHECOMPONENTITSELFCALLSSETTIMEOUTWHENPROCESSINGERRORS", "original": "It's still an async test, calling `fakeAsync()` and `tick()`, because the component itself\ncalls `setTimeout()` when processing errors.", "translation": "它仍然是异步测试,要调用 `fakeAsync()` 和 `tick()`,这是因为组件自身在处理错误的时候调用 `setTimeout()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "LOOKATTHEMARBLEOBSERVABLEDEFINITION", "original": "Look at the marble observable definition.", "translation": "看看宝石库生成的可观察对象的定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISISACOLDOBSERVABLETHATWAITSTHREEFRAMESANDTHENEMITSANERRORTHEHASH#INDICATESTHETIMINGOFTHEERRORTHATISSPECIFIEDINTHETHIRDARGUMENTTHESECONDARGUMENTISNULLBECAUSETHEOBSERVABLENEVEREMITSAVALUE", "original": "This is a _cold_ observable that waits three frames and then emits an error,\nThe hash (`#`) indicates the timing of the error that is specified in the third argument.\nThe second argument is null because the observable never emits a value.", "translation": "它是一个*冷的*可观察对象,它等待三帧,然后发出一个错误。\n井号(`#`)标记出了发出错误的时间点,这个错误是在第三个参数中指定的。\n第二个参数是空的,因为这个可观察对象永远不会发出正常值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####LEARNABOUTMARBLETESTING", "original": "#### Learn about marble testing", "translation": "#### 深入学习宝石测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AMARBLEFRAMEISAVIRTUALUNITOFTESTINGTIMEEACHSYMBOLX#MARKSTHEPASSINGOFONEFRAME", "original": "A _marble frame_ is a virtual unit of testing time.\nEach symbol (`-`, `x`, `|`, `#`) marks the passing of one frame.", "translation": "*宝石帧*是测试时序中的虚拟单元。\n每个符号(`-`,`x`,`|`,`#`)都表示一帧过去了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ACOLDOBSERVABLEDOESNTPRODUCEVALUESUNTILYOUSUBSCRIBETOITMOSTOFYOURAPPLICATIONOBSERVABLESARECOLDALLHTTPCLIENTGUIDEHTTPMETHODSRETURNCOLDOBSERVABLES", "original": "A _cold_ observable doesn't produce values until you subscribe to it.\nMost of your application observables are cold.\nAll [_HttpClient_](guide/http) methods return cold observables.", "translation": "*冷的*可观察对象不会生成值,除非你订阅它。\n应用中的大多数可观察对象都是冷的。\n所有 [`HttpClient`](guide/http)的方法返回的都是冷的可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AHOTOBSERVABLEISALREADYPRODUCINGVALUESBEFOREYOUSUBSCRIBETOITTHEROUTEREVENTSAPIROUTERROUTER#EVENTSOBSERVABLEWHICHREPORTSROUTERACTIVITYISAHOTOBSERVABLE", "original": "A _hot_ observable is already producing values _before_ you subscribe to it.\nThe [_Router.events_](api/router/Router#events) observable, \nwhich reports router activity, is a _hot_ observable.", "translation": "*热的*可观察对象在你订阅它之前就会生成值。\n[`Router.events`](api/router/Router#events) 可观察对象会主动汇报路由器的活动,它就是个*热的*可观察对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RXJSMARBLETESTINGISARICHSUBJECTBEYONDTHESCOPEOFTHISGUIDELEARNABOUTITONTHEWEBSTARTINGWITHTHEOFFICIALDOCUMENTATIONHTTPS:GITHUBCOMREACTIVEXRXJSBLOBMASTERDOCWRITINGMARBLETESTSMD", "original": "RxJS marble testing is a rich subject, beyond the scope of this guide.\nLearn about it on the web, starting with the \n[official documentation](https://github.com/ReactiveX/rxjs/blob/master/doc/writing-marble-tests.md).", "translation": "RxJS 的宝石测试是一个内容丰富的主题,超出了本章的范围。\n要想在网络上进一步学习它,可以从 [official documentation](https://github.com/ReactiveX/rxjs/blob/master/doc/writing-marble-tests.md) 开始。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTWITHINPUTSANDOUTPUTS", "original": "### Component with inputs and outputs", "translation": "### 带有输入输出参数的组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ACOMPONENTWITHINPUTSANDOUTPUTSTYPICALLYAPPEARSINSIDETHEVIEWTEMPLATEOFAHOSTCOMPONENTTHEHOSTUSESAPROPERTYBINDINGTOSETTHEINPUTPROPERTYANDANEVENTBINDINGTOLISTENTOEVENTSRAISEDBYTHEOUTPUTPROPERTY", "original": "A component with inputs and outputs typically appears inside the view template of a host component.\nThe host uses a property binding to set the input property and an event binding to\nlisten to events raised by the output property.", "translation": "带有导入和导出的组件通常出现在宿主组件的视图模板中。\n宿主使用属性绑定来设置输入属性,使用事件绑定来监听输出属性触发的事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTINGGOALISTOVERIFYTHATSUCHBINDINGSWORKASEXPECTEDTHETESTSSHOULDSETINPUTVALUESANDLISTENFOROUTPUTEVENTS", "original": "The testing goal is to verify that such bindings work as expected.\nThe tests should set input values and listen for output events.", "translation": "测试的目的是验证这样的绑定和期待的那样正常工作。\n测试程序应该设置导入值并监听导出事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDASHBOARDHEROCOMPONENTISATINYEXAMPLEOFACOMPONENTINTHISROLEITDISPLAYSANINDIVIDUALHEROPROVIDEDBYTHEDASHBOARDCOMPONENTCLICKINGTHATHEROTELLSTHEDASHBOARDCOMPONENTTHATTHEUSERHASSELECTEDTHEHERO", "original": "The `DashboardHeroComponent` is a tiny example of a component in this role.\nIt displays an individual hero provided by the `DashboardComponent`.\nClicking that hero tells the `DashboardComponent` that the user has selected the hero.", "translation": "`DashboardHeroComponent` 是非常小的这种类型的例子组件。\n它显示由 `DashboardCompoent` 提供的英雄个体。\n点击英雄告诉 `DashbaordComponent` 用户已经选择了这个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDASHBOARDHEROCOMPONENTISEMBEDDEDINTHEDASHBOARDCOMPONENTTEMPLATELIKETHIS:", "original": "The `DashboardHeroComponent` is embedded in the `DashboardComponent` template like this:", "translation": "`DashboardHeroComponent` 是这样内嵌在 `DashboardCompoent` 的模板中的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDASHBOARDHEROCOMPONENTAPPEARSINANNGFORREPEATERWHICHSETSEACHCOMPONENTSHEROINPUTPROPERTYTOTHELOOPINGVALUEANDLISTENSFORTHECOMPONENTSSELECTEDEVENT", "original": "The `DashboardHeroComponent` appears in an `*ngFor` repeater, which sets each component's `hero` input property\nto the looping value and listens for the component's `selected` event.", "translation": "`DashboardHeroComponent` 在 `*ngFor` 循环中出现,把每个组件的 `hero` input 属性设置为迭代的值,并监听组件的 `selected` 事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHECOMPONENTSFULLDEFINITION:", "original": "Here's the component's full definition:", "translation": "下面是该组件的完整定义:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHILETESTINGACOMPONENTTHISSIMPLEHASLITTLEINTRINSICVALUEITSWORTHKNOWINGHOWYOUCANUSEONEOFTHESEAPPROACHES:", "original": "While testing a component this simple has little intrinsic value, it's worth knowing how.\nYou can use one of these approaches:", "translation": "虽然测试这么简单的组件没有什么内在价值,但是它的测试程序是值得学习的。\n 有下列候选测试方案:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTITASUSEDBYDASHBOARDCOMPONENT", "original": "* Test it as used by `DashboardComponent`.", "translation": "把它当作被 `DashbaordComponent` 使用的组件来测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTITASASTANDALONECOMPONENT", "original": "* Test it as a stand-alone component.", "translation": "把它当作独立的组件来测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTITASUSEDBYASUBSTITUTEFORDASHBOARDCOMPONENT", "original": "* Test it as used by a substitute for `DashboardComponent`.", "translation": "把它当作被 `DashbaordComponent` 的替代组件使用的组件来测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AQUICKLOOKATTHEDASHBOARDCOMPONENTCONSTRUCTORDISCOURAGESTHEFIRSTAPPROACH:", "original": "A quick look at the `DashboardComponent` constructor discourages the first approach:", "translation": "简单看看 `DashbaordComponent` 的构造函数就否决了第一种方案:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDASHBOARDCOMPONENTDEPENDSONTHEANGULARROUTERANDTHEHEROSERVICEYOUDPROBABLYHAVETOREPLACETHEMBOTHWITHTESTDOUBLESWHICHISALOTOFWORKTHEROUTERSEEMSPARTICULARLYCHALLENGING", "original": "The `DashboardComponent` depends on the Angular router and the `HeroService`.\nYou'd probably have to replace them both with test doubles, which is a lot of work.\nThe router seems particularly challenging.", "translation": "`DashbaordComponent` 依赖 Angular 路由器和 `HeroService` 服务。\n你必须使用测试替身替换它们两个,似乎过于复杂了。\n路由器尤其具有挑战性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDISCUSSIONBELOW#ROUTINGCOMPONENTCOVERSTESTINGCOMPONENTSTHATREQUIRETHEROUTER", "original": "The [discussion below](#routing-component) covers testing components that require the router.", "translation": "[稍后的讨论](#routing-component)涵盖了那些需要路由器的测试组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEIMMEDIATEGOALISTOTESTTHEDASHBOARDHEROCOMPONENTNOTTHEDASHBOARDCOMPONENTSOTRYTHESECONDANDTHIRDOPTIONS", "original": "The immediate goal is to test the `DashboardHeroComponent`, not the `DashboardComponent`,\nso, try the second and third options.", "translation": "当前的任务是测试 `DashboardHeroComponent` 组件,而非 `DashbaordComponent`,所以无需做不必要的努力。\n那就试试第二和第三种方案。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####TESTDASHBOARDHEROCOMPONENTSTANDALONE", "original": "#### Test _DashboardHeroComponent_ stand-alone", "translation": "#### 单独测试 `DashboardHeroComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHEMEATOFTHESPECFILESETUP", "original": "Here's the meat of the spec file setup.", "translation": "下面是 spec 文件的准备语句中的重点部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOTEHOWTHESETUPCODEASSIGNSATESTHEROEXPECTEDHEROTOTHECOMPONENTSHEROPROPERTYEMULATINGTHEWAYTHEDASHBOARDCOMPONENTWOULDSETITVIATHEPROPERTYBINDINGINITSREPEATER", "original": "Note how the setup code assigns a test hero (`expectedHero`) to the component's `hero` property,\nemulating the way the `DashboardComponent` would set it \nvia the property binding in its repeater.", "translation": "注意代码是如何将模拟英雄(`expectedHero`)赋值给组件的 `hero` 属性的,模拟了 `DashbaordComponent` 在它的迭代器中通过属性绑定的赋值方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGTESTVERIFIESTHATTHEHERONAMEISPROPAGATEDTOTHETEMPLATEVIAABINDING", "original": "The following test verifies that the hero name is propagated to the template via a binding.", "translation": "下面的测试会验证英雄的名字已经通过绑定的方式传播到模板中了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BECAUSETHETEMPLATE#DASHBOARDHEROCOMPONENTPASSESTHEHERONAMETHROUGHTHEANGULARUPPERCASEPIPETHETESTMUSTMATCHTHEELEMENTVALUEWITHTHEUPPERCASEDNAME", "original": "Because the [template](#dashboard-hero-component) passes the hero name through the Angular `UpperCasePipe`,\nthe test must match the element value with the upper-cased name.", "translation": "因为[模板](#dashboard-hero-component)通过 Angular 的 `UpperCasePipe` 传入了英雄的名字,所以这个测试必须匹配该元素的值中包含了大写形式的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISSMALLTESTDEMONSTRATESHOWANGULARTESTSCANVERIFYACOMPONENTSVISUALREPRESENTATIONMDASHSOMETHINGNOTPOSSIBLEWITHCOMPONENTCLASSTESTS#COMPONENTCLASSTESTINGMDASHATLOWCOSTANDWITHOUTRESORTINGTOMUCHSLOWERANDMORECOMPLICATEDENDTOENDTESTS", "original": "This small test demonstrates how Angular tests can verify a component's visual\nrepresentation—something not possible with\n[component class tests](#component-class-testing)—at\nlow cost and without resorting to much slower and more complicated end-to-end tests.", "translation": "这个小测试示范了 Angular 的测试如何以较低的成本验证组件的视觉表现(它们不能通过[组件类测试](#component-class-testing)进行验证)。\n而不用借助那些更慢、更复杂的端到端测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####CLICKING", "original": "#### Clicking", "translation": "#### 点击", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CLICKINGTHEHEROSHOULDRAISEASELECTEDEVENTTHATTHEHOSTCOMPONENTDASHBOARDCOMPONENTPRESUMABLYCANHEAR:", "original": "Clicking the hero should raise a `selected` event that \nthe host component (`DashboardComponent` presumably) can hear:", "translation": "点击这个英雄将会发出一个 `selected` 事件,而宿主元素(可能是 `DashboardComponent`)可能会听到它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPONENTSSELECTEDPROPERTYRETURNSANEVENTEMITTERWHICHLOOKSLIKEANRXJSSYNCHRONOUSOBSERVABLETOCONSUMERSTHETESTSUBSCRIBESTOITEXPLICITLYJUSTASTHEHOSTCOMPONENTDOESIMPLICITLY", "original": "The component's `selected` property returns an `EventEmitter`, \nwhich looks like an RxJS synchronous `Observable` to consumers. \nThe test subscribes to it _explicitly_ just as the host component does _implicitly_.", "translation": "该组件的 `selected` 属性返回一个 `EventEmitter`,对消费者来说它和 RxJS 的同步 `Observable` 很像。\n该测试会*显式*订阅它,而宿主组件会*隐式*订阅它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IFTHECOMPONENTBEHAVESASEXPECTEDCLICKINGTHEHEROSELEMENTSHOULDTELLTHECOMPONENTSSELECTEDPROPERTYTOEMITTHEHEROOBJECT", "original": "If the component behaves as expected, clicking the hero's element\nshould tell the component's `selected` property to emit the `hero` object.", "translation": "如果该组件的行为符合预期,点击英雄所在的元素就会告诉组件的 `selected` 属性发出这个 `hero` 对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTDETECTSTHATEVENTTHROUGHITSSUBSCRIPTIONTOSELECTED", "original": "The test detects that event through its subscription to `selected`.", "translation": "这个测试会通过订阅 `selected` 来检测是否确实如此。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHERODEINTHEPREVIOUSTESTISADEBUGELEMENTTHATREPRESENTSTHEHERODIV", "original": "The `heroDe` in the previous test is a `DebugElement` that represents the hero `<div>`.", "translation": "前面测试中的 `heroDe` 是一个指向英雄条目 `<div>` 的 `DebugElement`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITHASANGULARPROPERTIESANDMETHODSTHATABSTRACTINTERACTIONWITHTHENATIVEELEMENTTHISTESTCALLSTHEDEBUGELEMENTTRIGGEREVENTHANDLERWITHTHECLICKEVENTNAMETHECLICKEVENTBINDINGRESPONDSBYCALLINGDASHBOARDHEROCOMPONENTCLICK", "original": "It has Angular properties and methods that abstract interaction with the native element.\nThis test calls the `DebugElement.triggerEventHandler` with the \"click\" event name.\nThe \"click\" event binding responds by calling `DashboardHeroComponent.click()`.", "translation": "它有一些用于抽象与原生元素交互的 Angular 属性和方法。\n这个测试会使用事件名称 `click` 来调用 `DebugElement.triggerEventHandler`。\n`click` 的事件绑定到了 `DashboardHeroComponent.click()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEANGULARDEBUGELEMENTTRIGGEREVENTHANDLERCANRAISEANYDATABOUNDEVENTBYITSEVENTNAMETHESECONDPARAMETERISTHEEVENTOBJECTPASSEDTOTHEHANDLER", "original": "The Angular `DebugElement.triggerEventHandler` can raise _any data-bound event_ by its _event name_.\nThe second parameter is the event object passed to the handler.", "translation": "Angular 的 `DebugElement.triggerEventHandler` 可以用**事件的名字**触发**任何数据绑定事件**。\n第二个参数是传递给事件处理器的事件对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTTRIGGEREDACLICKEVENTWITHANULLEVENTOBJECT", "original": "The test triggered a \"click\" event with a `null` event object.", "translation": "该测试使用事件对象 `null` 触发了一次 `click` 事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTASSUMESCORRECTLYINTHISCASETHATTHERUNTIMEEVENTHANDLERMDASHTHECOMPONENTSCLICKMETHODMDASHDOESNTCAREABOUTTHEEVENTOBJECT", "original": "The test assumes (correctly in this case) that the runtime\nevent handler—the component's `click()` method—doesn't\ncare about the event object.", "translation": "测试程序假设(在这里应该这样)运行时间的事件处理器(组件的 `click()` 方法)不关心事件对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "OTHERHANDLERSARELESSFORGIVINGFOREXAMPLETHEROUTERLINKDIRECTIVEEXPECTSANOBJECTWITHABUTTONPROPERTYTHATIDENTIFIESWHICHMOUSEBUTTONIFANYWASPRESSEDDURINGTHECLICKTHEROUTERLINKDIRECTIVETHROWSANERRORIFTHEEVENTOBJECTISMISSING", "original": "Other handlers are less forgiving. For example, the `RouterLink`\ndirective expects an object with a `button` property\nthat identifies which mouse button (if any) was pressed during the click.\nThe `RouterLink` directive throws an error if the event object is missing.", "translation": "其它处理器的要求比较严格。比如,`RouterLink` 指令期望一个带有 `button` 属性的对象,该属性用于指出点击时按下的是哪个鼠标按钮。\n如果不给出这个事件对象,`RouterLink` 指令就会抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####CLICKTHEELEMENT", "original": "#### Click the element", "translation": "#### 点击该元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGTESTALTERNATIVECALLSTHENATIVEELEMENTSOWNCLICKMETHODWHICHISPERFECTLYFINEFORTHISCOMPONENT", "original": "The following test alternative calls the native element's own `click()` method,\nwhich is perfectly fine for _this component_.", "translation": "下面这个测试改为调用原生元素自己的 `click()` 方法,它对于*这个组件*来说相当完美。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####CLICKHELPER", "original": "#### _click()_ helper", "translation": "#### _click()_ 辅助函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CLICKINGABUTTONANANCHORORANARBITRARYHTMLELEMENTISACOMMONTESTTASK", "original": "Clicking a button, an anchor, or an arbitrary HTML element is a common test task.", "translation": "点击按钮、链接或者任意 HTML 元素是很常见的测试任务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MAKETHATCONSISTENTANDEASYBYENCAPSULATINGTHECLICKTRIGGERINGPROCESSINAHELPERSUCHASTHECLICKFUNCTIONBELOW:", "original": "Make that consistent and easy by encapsulating the _click-triggering_ process \nin a helper such as the `click()` function below:", "translation": "把*点击事件*的处理过程包装到如下的 `click()` 辅助函数中,可以让这项任务更一致、更简单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFIRSTPARAMETERISTHEELEMENTTOCLICKIFYOUWISHYOUCANPASSACUSTOMEVENTOBJECTASTHESECONDPARAMETERTHEDEFAULTISAPARTIALAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIMOUSEEVENTBUTTONLEFTBUTTONMOUSEEVENTOBJECTAACCEPTEDBYMANYHANDLERSINCLUDINGTHEROUTERLINKDIRECTIVE", "original": "The first parameter is the _element-to-click_. If you wish, you can pass a\ncustom event object as the second parameter. The default is a (partial)\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\">left-button mouse event object</a>\naccepted by many handlers including the `RouterLink` directive.", "translation": "第一个参数是**用来点击的元素**。如果你愿意,可以将自定义的事件对象传递给第二个参数。\n默认的是(局部的)<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\" target=\"_blank\">鼠标左键事件对象</a>,\n它被许多事件处理器接受,包括 `RouterLink` 指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECLICKHELPERFUNCTIONISNOTONEOFTHEANGULARTESTINGUTILITIESITSAFUNCTIONDEFINEDINTHISGUIDESSAMPLECODEALLOFTHESAMPLETESTSUSEITIFYOULIKEITADDITTOYOUROWNCOLLECTIONOFHELPERS", "original": "The `click()` helper function is **not** one of the Angular testing utilities.\nIt's a function defined in _this guide's sample code_.\nAll of the sample tests use it.\nIf you like it, add it to your own collection of helpers.", "translation": "`click()` 辅助函数**不是**Angular 测试工具之一。\n它是在**本章的例子代码**中定义的函数方法,被所有测试例子所用。\n如果你喜欢它,将它添加到你自己的辅助函数集。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHEPREVIOUSTESTREWRITTENUSINGTHECLICKHELPER", "original": "Here's the previous test, rewritten using the click helper.", "translation": "下面是把前面的测试用 `click` 辅助函数重写后的版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTINSIDEATESTHOST", "original": "### Component inside a test host", "translation": "### 位于测试宿主中的组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEPREVIOUSTESTSPLAYEDTHEROLEOFTHEHOSTDASHBOARDCOMPONENTTHEMSELVESBUTDOESTHEDASHBOARDHEROCOMPONENTWORKCORRECTLYWHENPROPERLYDATABOUNDTOAHOSTCOMPONENT", "original": "The previous tests played the role of the host `DashboardComponent` themselves.\nBut does the `DashboardHeroComponent` work correctly when properly data-bound to a host component?", "translation": "前面的这些测试都是自己扮演宿主元素 `DashboardComponent` 的角色。\n但是当 `DashboardHeroComponent` 真的绑定到某个宿主元素时还能正常工作吗?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCOULDTESTWITHTHEACTUALDASHBOARDCOMPONENTBUTDOINGSOCOULDREQUIREALOTOFSETUPESPECIALLYWHENITSTEMPLATEFEATURESANNGFORREPEATEROTHERCOMPONENTSLAYOUTHTMLADDITIONALBINDINGSACONSTRUCTORTHATINJECTSMULTIPLESERVICESANDITSTARTSINTERACTINGWITHTHOSESERVICESRIGHTAWAY", "original": "You could test with the actual `DashboardComponent`.\nBut doing so could require a lot of setup, \nespecially when its template features an `*ngFor` repeater, \nother components, layout HTML, additional bindings, \na constructor that injects multiple services, \nand it starts interacting with those services right away.", "translation": "固然,你也可以测试真实的 `DashboardComponent`。\n但要想这么做需要做很多准备工作,特别是它的模板中使用了某些特性,如 `*ngFor`、\n其它组件、布局 HTML、附加绑定、注入了多个服务的构造函数、如何用正确的方式与那些服务交互等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IMAGINETHEEFFORTTODISABLETHESEDISTRACTIONSJUSTTOPROVEAPOINTTHATCANBEMADESATISFACTORILYWITHATESTHOSTLIKETHISONE:", "original": "Imagine the effort to disable these distractions, just to prove a point \nthat can be made satisfactorily with a _test host_ like this one:", "translation": "想出这么多需要努力排除的干扰,只是为了证明一点 —— 可以像这样造出一个令人满意的*测试宿主*:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISTESTHOSTBINDSTODASHBOARDHEROCOMPONENTASTHEDASHBOARDCOMPONENTWOULDBUTWITHOUTTHENOISEOFTHEROUTERTHEHEROSERVICEORTHENGFORREPEATER", "original": "This test host binds to `DashboardHeroComponent` as the `DashboardComponent` would \nbut without the noise of the `Router`, the `HeroService`, or the `*ngFor` repeater.", "translation": "这个测试宿主像 `DashboardComponent` 那样绑定了 `DashboardHeroComponent`,但是没有 `Router`、\n没有 `HeroService`,也没有 `*ngFor`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTHOSTSETSTHECOMPONENTSHEROINPUTPROPERTYWITHITSTESTHEROITBINDSTHECOMPONENTSSELECTEDEVENTWITHITSONSELECTEDHANDLERWHICHRECORDSTHEEMITTEDHEROINITSSELECTEDHEROPROPERTY", "original": "The test host sets the component's `hero` input property with its test hero.\nIt binds the component's `selected` event with its `onSelected` handler,\nwhich records the emitted hero in its `selectedHero` property.", "translation": "这个测试宿主使用其测试用的英雄设置了组件的输入属性 `hero`。\n它使用 `onSelected` 事件处理器绑定了组件的 `selected` 事件,其中把事件中发出的英雄记录到了 `selectedHero` 属性中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "LATERTHETESTSWILLBEABLETOEASILYCHECKSELECTEDHEROTOVERIFYTHATTHEDASHBOARDHEROCOMPONENTSELECTEDEVENTEMITTEDTHEEXPECTEDHERO", "original": "Later, the tests will be able to easily check `selectedHero` to verify that the\n`DashboardHeroComponent.selected` event emitted the expected hero.", "translation": "稍后,这个测试就可以轻松检查 `selectedHero` 以验证 `DashboardHeroComponent.selected` 事件确实发出了所期望的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESETUPFORTHETESTHOSTTESTSISSIMILARTOTHESETUPFORTHESTANDALONETESTS:", "original": "The setup for the _test-host_ tests is similar to the setup for the stand-alone tests:", "translation": "这个*测试宿主*中的准备代码和独立测试中的准备过程类似:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISTESTINGMODULECONFIGURATIONSHOWSTHREEIMPORTANTDIFFERENCES:", "original": "This testing module configuration shows three important differences:", "translation": "这个测试模块的配置信息有三个重要的不同点:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1ITDECLARESBOTHTHEDASHBOARDHEROCOMPONENTANDTHETESTHOSTCOMPONENT", "original": "1. It _declares_ both the `DashboardHeroComponent` and the `TestHostComponent`.", "translation": "它同时**声明**了 `DashboardHeroComponent` 和 `TestHostComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1ITCREATESTHETESTHOSTCOMPONENTINSTEADOFTHEDASHBOARDHEROCOMPONENT", "original": "1. It _creates_ the `TestHostComponent` instead of the `DashboardHeroComponent`.", "translation": "它**创建**了 `TestHostComponent`,而非 `DashboardHeroComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1THETESTHOSTCOMPONENTSETSTHEDASHBOARDHEROCOMPONENTHEROWITHABINDING", "original": "1. The `TestHostComponent` sets the `DashboardHeroComponent.hero` with a binding.", "translation": "`TestHostComponent` 通过绑定机制设置了 `DashboardHeroComponent.hero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECREATECOMPONENTRETURNSAFIXTURETHATHOLDSANINSTANCEOFTESTHOSTCOMPONENTINSTEADOFANINSTANCEOFDASHBOARDHEROCOMPONENT", "original": "The `createComponent` returns a `fixture` that holds an instance of `TestHostComponent` instead of an instance of `DashboardHeroComponent`.", "translation": "`createComponent` 返回的 `fixture` 里有 `TestHostComponent` 实例,而非 `DashboardHeroComponent` 组件实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CREATINGTHETESTHOSTCOMPONENTHASTHESIDEEFFECTOFCREATINGADASHBOARDHEROCOMPONENTBECAUSETHELATTERAPPEARSWITHINTHETEMPLATEOFTHEFORMERTHEQUERYFORTHEHEROELEMENTHEROELSTILLFINDSITINTHETESTDOMALBEITATGREATERDEPTHINTHEELEMENTTREETHANBEFORE", "original": "Creating the `TestHostComponent` has the side-effect of creating a `DashboardHeroComponent`\nbecause the latter appears within the template of the former.\nThe query for the hero element (`heroEl`) still finds it in the test DOM,\nalbeit at greater depth in the element tree than before.", "translation": "当然,创建 `TestHostComponent` 有创建 `DashboardHeroComponent` 的副作用,因为后者出现在前者的模板中。\n英雄元素(`heroEl`)的查询语句仍然可以在测试 DOM 中找到它,尽管元素树比以前更深。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTSTHEMSELVESAREALMOSTIDENTICALTOTHESTANDALONEVERSION:", "original": "The tests themselves are almost identical to the stand-alone version:", "translation": "这些测试本身和它们的孤立版本几乎相同:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ONLYTHESELECTEDEVENTTESTDIFFERSITCONFIRMSTHATTHESELECTEDDASHBOARDHEROCOMPONENTHEROREALLYDOESFINDITSWAYUPTHROUGHTHEEVENTBINDINGTOTHEHOSTCOMPONENT", "original": "Only the selected event test differs. It confirms that the selected `DashboardHeroComponent` hero\nreally does find its way up through the event binding to the host component.", "translation": "只有 selected 事件的测试不一样。它确保被选择的 `DashboardHeroComponent` 英雄确实通过事件绑定被传递到宿主组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###ROUTINGCOMPONENT", "original": "### Routing component", "translation": "### 路由组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AROUTINGCOMPONENTISACOMPONENTTHATTELLSTHEROUTERTONAVIGATETOANOTHERCOMPONENTTHEDASHBOARDCOMPONENTISAROUTINGCOMPONENTBECAUSETHEUSERCANNAVIGATETOTHEHERODETAILCOMPONENTBYCLICKINGONONEOFTHEHEROBUTTONSONTHEDASHBOARD", "original": "A _routing component_ is a component that tells the `Router` to navigate to another component.\nThe `DashboardComponent` is a _routing component_ because the user can\nnavigate to the `HeroDetailComponent` by clicking on one of the _hero buttons_ on the dashboard.", "translation": "所谓*路由组件*就是指会要求 `Router` 导航到其它组件的组件。\n`DashboardComponent` 就是一个*路由组件*,因为用户可以通过点击仪表盘中的某个*英雄按钮*来导航到 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ROUTINGISPRETTYCOMPLICATEDTESTINGTHEDASHBOARDCOMPONENTSEEMEDDAUNTINGINPARTBECAUSEITINVOLVESTHEROUTERWHICHITINJECTSTOGETHERWITHTHEHEROSERVICE", "original": "Routing is pretty complicated.\nTesting the `DashboardComponent` seemed daunting in part because it involves the `Router`,\nwhich it injects together with the `HeroService`.", "translation": "路由确实很复杂。\n测试 `DashboardComponent` 看上去有点令人生畏,因为它牵扯到和 `HeroService` 一起注入进来的 `Router`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MOCKINGTHEHEROSERVICEWITHASPYISAFAMILIARSTORY#COMPONENTWITHASYNCSERVICEBUTTHEROUTERHASACOMPLICATEDAPIANDISENTWINEDWITHOTHERSERVICESANDAPPLICATIONPRECONDITIONSMIGHTITBEDIFFICULTTOMOCK", "original": "Mocking the `HeroService` with a spy is a [familiar story](#component-with-async-service).\nBut the `Router` has a complicated API and is entwined with other services and application preconditions. Might it be difficult to mock?", "translation": "使用间谍来 Mock `HeroService` 是一个[熟悉的故事](#component-with-async-service)。\n但是 `Router` 的 API 很复杂,并且与其它服务和应用的前置条件纠缠在一起。它应该很难进行 Mock 吧?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FORTUNATELYNOTINTHISCASEBECAUSETHEDASHBOARDCOMPONENTISNTDOINGMUCHWITHTHEROUTER", "original": "Fortunately, not in this case because the `DashboardComponent` isn't doing much with the `Router`", "translation": "庆幸的是,在这个例子中不会,因为 `DashboardComponent` 并没有深度使用 `Router`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISISOFTENTHECASEWITHROUTINGCOMPONENTSASARULEYOUTESTTHECOMPONENTNOTTHEROUTERANDCAREONLYIFTHECOMPONENTNAVIGATESWITHTHERIGHTADDRESSUNDERTHEGIVENCONDITIONS", "original": "This is often the case with _routing components_.\nAs a rule you test the component, not the router,\nand care only if the component navigates with the right address under the given conditions.", "translation": "这是*路由组件*中的通例。\n一般来说,你应该测试组件而不是路由器,应该只关心组件有没有根据给定的条件导航到正确的地址。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "PROVIDINGAROUTERSPYFORTHISCOMPONENTTESTSUITEHAPPENSTOBEASEASYASPROVIDINGAHEROSERVICESPY", "original": "Providing a router spy for _this component_ test suite happens to be as easy\nas providing a `HeroService` spy.", "translation": "为*这个组件*的测试套件提供路由器的间谍就像它提供 `HeroService` 的间谍一样简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGTESTCLICKSTHEDISPLAYEDHEROANDCONFIRMSTHATROUTERNAVIGATEBYURLISCALLEDWITHTHEEXPECTEDURL", "original": "The following test clicks the displayed hero and confirms that \n`Router.navigateByUrl` is called with the expected url.", "translation": "下面这个测试会点击正在显示的英雄,并确认 `Router.navigateByUrl` 曾用所期待的 URL 调用过。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###ROUTEDCOMPONENTS", "original": "### Routed components", "translation": "### 路由目标组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AROUTEDCOMPONENTISTHEDESTINATIONOFAROUTERNAVIGATIONITCANBETRICKIERTOTESTESPECIALLYWHENTHEROUTETOTHECOMPONENTINCLUDESPARAMETERSTHEHERODETAILCOMPONENTISAROUTEDCOMPONENTTHATISTHEDESTINATIONOFSUCHAROUTE", "original": "A _routed component_ is the destination of a `Router` navigation.\nIt can be trickier to test, especially when the route to the component _includes parameters_.\nThe `HeroDetailComponent` is a _routed component_ that is the destination of such a route.", "translation": "*路由目标组件*是指 `Router` 导航到的目标。\n它测试起来可能很复杂,特别是当路由到的这个组件*包含参数*的时候。\n`HeroDetailComponent` 就是一个*路由目标组件*,它是某个路由定义指向的目标。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENAUSERCLICKSADASHBOARDHEROTHEDASHBOARDCOMPONENTTELLSTHEROUTERTONAVIGATETOHEROES:IDTHE:IDISAROUTEPARAMETERWHOSEVALUEISTHEIDOFTHEHEROTOEDIT", "original": "When a user clicks a _Dashboard_ hero, the `DashboardComponent` tells the `Router`\nto navigate to `heroes/:id`.\nThe `:id` is a route parameter whose value is the `id` of the hero to edit.", "translation": "当用户点击*仪表盘*中的英雄时,`DashboardComponent` 会要求 `Router` 导航到 `heroes/:id`。\n`:id` 是一个路由参数,它的值就是所要编辑的英雄的 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEROUTERMATCHESTHATURLTOAROUTETOTHEHERODETAILCOMPONENTITCREATESANACTIVATEDROUTEOBJECTWITHTHEROUTINGINFORMATIONANDINJECTSITINTOANEWINSTANCEOFTHEHERODETAILCOMPONENT", "original": "The `Router` matches that URL to a route to the `HeroDetailComponent`.\nIt creates an `ActivatedRoute` object with the routing information and\ninjects it into a new instance of the `HeroDetailComponent`.", "translation": "该 `Router` 会根据那个 URL 匹配到一个指向 `HeroDetailComponent` 的路由。\n它会创建一个带有路由信息的 `ActivatedRoute` 对象,并把它注入到一个 `HeroDetailComponent` 的新实例中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESTHEHERODETAILCOMPONENTCONSTRUCTOR:", "original": "Here's the `HeroDetailComponent` constructor:", "translation": "下面是 `HeroDetailComponent` 的构造函数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHERODETAILCOMPONENTNEEDSTHEIDPARAMETERSOITCANFETCHTHECORRESPONDINGHEROVIATHEHERODETAILSERVICE", "original": "The `HeroDetail` component needs the `id` parameter so it can fetch \nthe corresponding hero via the `HeroDetailService`.", "translation": "`HeroDetailComponent` 组件需要一个 `id` 参数,以便通过 `HeroDetailService` 获取相应的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPONENTHASTOGETTHEIDFROMTHEACTIVATEDROUTEPARAMMAPPROPERTYWHICHISANOBSERVABLE", "original": "The component has to get the `id` from the `ActivatedRoute.paramMap` property\nwhich is an _Observable_.", "translation": "该组件只能从 `ActivatedRoute.paramMap` 属性中获取这个 `id`,这个属性是一个 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITCANTJUSTREFERENCETHEIDPROPERTYOFTHEACTIVATEDROUTEPARAMMAPTHECOMPONENTHASTOSUBSCRIBETOTHEACTIVATEDROUTEPARAMMAPOBSERVABLEANDBEPREPAREDFORTHEIDTOCHANGEDURINGITSLIFETIME", "original": "It can't just reference the `id` property of the `ActivatedRoute.paramMap`.\nThe component has to _subscribe_ to the `ActivatedRoute.paramMap` observable and be prepared\nfor the `id` to change during its lifetime.", "translation": "它不能仅仅引用 `ActivatedRoute.paramMap` 的 `id` 属性。\n该组件不得不*订阅* `ActivatedRoute.paramMap` 这个可观察对象,要做好它在生命周期中随时会发生变化的准备。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEROUTERGUIDEROUTER#ROUTEPARAMETERSGUIDECOVERSACTIVATEDROUTEPARAMMAPINMOREDETAIL", "original": "The [Router](guide/router#route-parameters) guide covers `ActivatedRoute.paramMap` in more detail.", "translation": "[路由与导航](guide/router#route-parameters)一章中详细讲解了 `ActivatedRoute.paramMap`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTSCANEXPLOREHOWTHEHERODETAILCOMPONENTRESPONDSTODIFFERENTIDPARAMETERVALUESBYMANIPULATINGTHEACTIVATEDROUTEINJECTEDINTOTHECOMPONENTSCONSTRUCTOR", "original": "Tests can explore how the `HeroDetailComponent` responds to different `id` parameter values\nby manipulating the `ActivatedRoute` injected into the component's constructor.", "translation": "通过操纵注入到组件构造函数中的这个 `ActivatedRoute`,测试可以探查 `HeroDetailComponent` 是如何对不同的 `id` 参数值做出响应的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUKNOWHOWTOSPYONTHEROUTERANDADATASERVICE", "original": "You know how to spy on the `Router` and a data service.", "translation": "你已经知道了如何给 `Router` 和数据服务安插间谍。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOULLTAKEADIFFERENTAPPROACHWITHACTIVATEDROUTEBECAUSE", "original": "You'll take a different approach with `ActivatedRoute` because", "translation": "不过对于 `ActivatedRoute`,你要采用另一种方式,因为:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "PARAMMAPRETURNSANOBSERVABLETHATCANEMITMORETHANONEVALUEDURINGATEST", "original": "* `paramMap` returns an `Observable` that can emit more than one value \nduring a test.", "translation": "在测试期间,`paramMap` 会返回一个能发出多个值的 `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUNEEDTHEROUTERHELPERFUNCTIONCONVERTTOPARAMMAPTOCREATEAPARAMMAP", "original": "* You need the router helper function, `convertToParamMap()`, to create a `ParamMap`.", "translation": "你需要路由器的辅助函数 `convertToParamMap()` 来创建 `ParamMap`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "OTHERROUTEDCOMPONENTSTESTSNEEDATESTDOUBLEFORACTIVATEDROUTE", "original": "* Other _routed components_ tests need a test double for `ActivatedRoute`.", "translation": "针对*路由目标组件*的其它测试需要一个 `ActivatedRoute` 的测试替身。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESEDIFFERENCESARGUEFORAREUSABLESTUBCLASS", "original": "These differences argue for a re-usable stub class.", "translation": "这些差异表明你需要一个可复用的桩类(stub)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFOLLOWINGACTIVATEDROUTESTUBCLASSSERVESASATESTDOUBLEFORACTIVATEDROUTE", "original": "The following `ActivatedRouteStub` class serves as a test double for `ActivatedRoute`.", "translation": "下面的 `ActivatedRouteStub` 类就是作为 `ActivatedRoute` 类的测试替身使用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CONSIDERPLACINGSUCHHELPERSINATESTINGFOLDERSIBLINGTOTHEAPPFOLDERTHISSAMPLEPUTSACTIVATEDROUTESTUBINTESTINGACTIVATEDROUTESTUBTS", "original": "Consider placing such helpers in a `testing` folder sibling to the `app` folder.\nThis sample puts `ActivatedRouteStub` in `testing/activated-route-stub.ts`.", "translation": "考虑把这类辅助函数放进一个紧邻 `app` 文件夹的 `testing` 文件夹。\n这个例子把 `ActivatedRouteStub` 放在了 `testing/activated-route-stub.ts` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CONSIDERWRITINGAMORECAPABLEVERSIONOFTHISSTUBCLASSWITHTHEMARBLETESTINGLIBRARY#MARBLETESTING", "original": "Consider writing a more capable version of this stub class with\n the [_marble testing library_](#marble-testing).", "translation": "可以考虑使用[宝石测试库](#marble-testing)来为此测试桩编写一个更强力的版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####TESTINGWITHACTIVATEDROUTESTUB", "original": "#### Testing with _ActivatedRouteStub_", "translation": "#### 使用 `ActivatedRouteStub` 进行测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESATESTDEMONSTRATINGTHECOMPONENTSBEHAVIORWHENTHEOBSERVEDIDREFERSTOANEXISTINGHERO:", "original": "Here's a test demonstrating the component's behavior when the observed `id` refers to an existing hero:", "translation": "下面的测试程序是演示组件在被观察的 `id` 指向现有英雄时的行为:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECREATECOMPONENTMETHODANDPAGEOBJECTAREDISCUSSEDBELOW#PAGEOBJECTRELYONYOURINTUITIONFORNOW", "original": "The `createComponent()` method and `page` object are discussed [below](#page-object).\nRely on your intuition for now.", "translation": "`createComponent()` 方法和 `page` 对象会在[稍后](#page-object)进行讨论。\n不过目前,你只要凭直觉来理解就行了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENTHEIDCANNOTBEFOUNDTHECOMPONENTSHOULDREROUTETOTHEHEROLISTCOMPONENT", "original": "When the `id` cannot be found, the component should re-route to the `HeroListComponent`.", "translation": "当找不到 `id` 的时候,组件应该重新路由到 `HeroListComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTSUITESETUPPROVIDEDTHESAMEROUTERSPYDESCRIBEDABOVE#ROUTINGCOMPONENTWHICHSPIESONTHEROUTERWITHOUTACTUALLYNAVIGATING", "original": "The test suite setup provided the same router spy [described above](#routing-component) which spies on the router without actually navigating.", "translation": "测试套件的准备代码提供了一个和[前面](#routing-component)一样的路由器间谍,它会充当路由器的角色,而不用发起实际的导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISTESTEXPECTSTHECOMPONENTTOTRYTONAVIGATETOTHEHEROLISTCOMPONENT", "original": "This test expects the component to try to navigate to the `HeroListComponent`.", "translation": "这个测试中会期待该组件尝试导航到 `HeroListComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHILETHISAPPDOESNTHAVEAROUTETOTHEHERODETAILCOMPONENTTHATOMITSTHEIDPARAMETERITMIGHTADDSUCHAROUTESOMEDAYTHECOMPONENTSHOULDDOSOMETHINGREASONABLEWHENTHEREISNOID", "original": "While this app doesn't have a route to the `HeroDetailComponent` that omits the `id` parameter, it might add such a route someday.\nThe component should do something reasonable when there is no `id`.", "translation": "虽然本应用没有在缺少 `id` 参数的时候,继续导航到 `HeroDetailComponent` 的路由,但是,将来它可能会添加这样的路由。\n当没有 `id` 时,该组件应该作出合理的反应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHISIMPLEMENTATIONTHECOMPONENTSHOULDCREATEANDDISPLAYANEWHERONEWHEROESHAVEID0ANDABLANKNAMETHISTESTCONFIRMSTHATTHECOMPONENTBEHAVESASEXPECTED:", "original": "In this implementation, the component should create and display a new hero.\nNew heroes have `id=0` and a blank `name`. This test confirms that the component behaves as expected:", "translation": "在本例中,组件应该创建和显示新英雄。\n新英雄的 `id` 为零,`name` 为空。本测试程序确认组件是按照预期的这样做的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###NESTEDCOMPONENTTESTS", "original": "### Nested component tests", "translation": "### 对嵌套组件的测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "COMPONENTTEMPLATESOFTENHAVENESTEDCOMPONENTSWHOSETEMPLATESMAYCONTAINMORECOMPONENTS", "original": "Component templates often have nested components, whose templates\nmay contain more components.", "translation": "组件的模板中通常还会有嵌套组件,嵌套组件的模板还可能包含更多组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPONENTTREECANBEVERYDEEPANDMOSTOFTHETIMETHENESTEDCOMPONENTSPLAYNOROLEINTESTINGTHECOMPONENTATTHETOPOFTHETREE", "original": "The component tree can be very deep and, most of the time, the nested components\nplay no role in testing the component at the top of the tree.", "translation": "这棵组件树可能非常深,并且大多数时候在测试这棵树顶部的组件时,这些嵌套的组件都无关紧要。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEAPPCOMPONENTFOREXAMPLEDISPLAYSANAVIGATIONBARWITHANCHORSANDTHEIRROUTERLINKDIRECTIVES", "original": "The `AppComponent`, for example, displays a navigation bar with anchors and their `RouterLink` directives.", "translation": "比如,`AppComponent` 会显示一个带有链接及其 `RouterLink` 指令的导航条。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHILETHEAPPCOMPONENTCLASSISEMPTYYOUMAYWANTTOWRITEUNITTESTSTOCONFIRMTHATTHELINKSAREWIREDPROPERLYTOTHEROUTERLINKDIRECTIVESPERHAPSFORTHEREASONSEXPLAINEDBELOW#WHYSTUBBEDROUTERLINKTESTS", "original": "While the `AppComponent` _class_ is empty,\nyou may want to write unit tests to confirm that the links are wired properly \nto the `RouterLink` directives, perhaps for the reasons [explained below](#why-stubbed-routerlink-tests).", "translation": "虽然 `AppComponent` *类*是空的,不过,由于[稍后解释的原因](#why-stubbed-routerlink-tests),你可能会希望写个单元测试来确认这些链接是否正确使用了 `RouterLink` 指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOVALIDATETHELINKSYOUDONTNEEDTHEROUTERTONAVIGATEANDYOUDONTNEEDTHEROUTEROUTLETTOMARKWHERETHEROUTERINSERTSROUTEDCOMPONENTS", "original": "To validate the links, you don't need the `Router` to navigate and you don't\nneed the `<router-outlet>` to mark where the `Router` inserts _routed components_.", "translation": "要想验证这些链接,你不必用 `Router` 进行导航,也不必使用 `<router-outlet>` 来指出 `Router` 应该把*路由目标组件*插入到什么地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEBANNERCOMPONENTANDWELCOMECOMPONENTINDICATEDBYAPPBANNERANDAPPWELCOMEAREALSOIRRELEVANT", "original": "The `BannerComponent` and `WelcomeComponent` \n(indicated by `<app-banner>` and `<app-welcome>`) are also irrelevant.", "translation": "而 `BannerComponent` 和 `WelcomeComponent`(写作 `<app-banner>` 和 `<app-welcome>`)也同样风马牛不相及。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YETANYTESTTHATCREATESTHEAPPCOMPONENTINTHEDOMWILLALSOCREATEINSTANCESOFTHESETHREECOMPONENTSANDIFYOULETTHATHAPPENYOULLHAVETOCONFIGURETHETESTBEDTOCREATETHEM", "original": "Yet any test that creates the `AppComponent` in the DOM will also create instances of\nthese three components and, if you let that happen, \nyou'll have to configure the `TestBed` to create them.", "translation": "然而,任何测试,只要能在 DOM 中创建 `AppComponent`,也就同样能创建这三个组件的实例。如果要创建它们,你就要配置 `TestBed`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IFYOUNEGLECTTODECLARETHEMTHEANGULARCOMPILERWONTRECOGNIZETHEAPPBANNERAPPWELCOMEANDROUTEROUTLETTAGSINTHEAPPCOMPONENTTEMPLATEANDWILLTHROWANERROR", "original": "If you neglect to declare them, the Angular compiler won't recognize the \n`<app-banner>`, `<app-welcome>`, and `<router-outlet>` tags in the `AppComponent` template\nand will throw an error.", "translation": "如果你忘了声明它们,Angular 编译器就无法在 `AppComponent` 模板中识别出 `<app-banner>`、`<app-welcome>` 和 `<router-outlet>` 标记,并抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IFYOUDECLARETHEREALCOMPONENTSYOULLALSOHAVETODECLARETHEIRNESTEDCOMPONENTSANDPROVIDEFORALLSERVICESINJECTEDINANYCOMPONENTINTHETREE", "original": "If you declare the real components, you'll also have to declare _their_ nested components\nand provide for _all_ services injected in _any_ component in the tree.", "translation": "如果你声明的这些都是真实的组件,那么也同样要声明*它们*的嵌套组件,并要为这棵组件树中的*任何*组件提供要注入的*所有*服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THATSTOOMUCHEFFORTJUSTTOANSWERAFEWSIMPLEQUESTIONSABOUTLINKS", "original": "That's too much effort just to answer a few simple questions about links.", "translation": "如果只是想回答有关链接的一些简单问题,做这些显然就太多了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISSECTIONDESCRIBESTWOTECHNIQUESFORMINIMIZINGTHESETUPUSETHEMALONEORINCOMBINATIONTOSTAYFOCUSEDONTHETESTINGTHEPRIMARYCOMPONENT", "original": "This section describes two techniques for minimizing the setup.\nUse them, alone or in combination, to stay focused on the testing the primary component.", "translation": "本节会讲减少此类准备工作的两项技术。\n单独使用或组合使用它们,可以让这些测试聚焦于要测试的主要组件上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "#####STUBBINGUNNEEDEDCOMPONENTS", "original": "##### Stubbing unneeded components", "translation": "##### 对不需要的组件提供桩(stub)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHEFIRSTTECHNIQUEYOUCREATEANDDECLARESTUBVERSIONSOFTHECOMPONENTSANDDIRECTIVETHATPLAYLITTLEORNOROLEINTHETESTS", "original": "In the first technique, you create and declare stub versions of the components\nand directive that play little or no role in the tests.", "translation": "这项技术中,你要为那些在测试中无关紧要的组件或指令创建和声明一些测试桩。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESTUBSELECTORSMATCHTHESELECTORSFORTHECORRESPONDINGREALCOMPONENTSBUTTHEIRTEMPLATESANDCLASSESAREEMPTY", "original": "The stub selectors match the selectors for the corresponding real components.\nBut their templates and classes are empty.", "translation": "这些测试桩的选择器要和其对应的真实组件一致,但其模板和类是空的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENDECLARETHEMINTHETESTBEDCONFIGURATIONNEXTTOTHECOMPONENTSDIRECTIVESANDPIPESTHATNEEDTOBEREAL", "original": "Then declare them in the `TestBed` configuration next to the\ncomponents, directives, and pipes that need to be real.", "translation": "然后在 `TestBed` 的配置中那些真正有用的组件、指令、管道之后声明它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEAPPCOMPONENTISTHETESTSUBJECTSOOFCOURSEYOUDECLARETHEREALVERSION", "original": "The `AppComponent` is the test subject, so of course you declare the real version.", "translation": "`AppComponent` 是该测试的主角,因此当然要用它的真实版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEROUTERLINKDIRECTIVESTUBDESCRIBEDLATER#ROUTERLINKISATESTVERSIONOFTHEREALROUTERLINKTHATHELPSWITHTHELINKTESTS", "original": "The `RouterLinkDirectiveStub`, [described later](#routerlink), is a test version\nof the real `RouterLink` that helps with the link tests.", "translation": "而 `RouterLinkDirectiveStub`([稍后讲解](#routerlink))是一个真实的 `RouterLink` 的测试版,它能帮你对链接进行测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERESTARESTUBS", "original": "The rest are stubs.", "translation": "其它都是测试桩。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHESECONDAPPROACHADDNOERRORSSCHEMATOTHETESTBEDSCHEMASMETADATA", "original": "In the second approach, add `NO_ERRORS_SCHEMA` to the `TestBed.schemas` metadata.", "translation": "第二种办法就是把 `NO_ERRORS_SCHEMA` 添加到 `TestBed.schemas` 的元数据中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENOERRORSSCHEMATELLSTHEANGULARCOMPILERTOIGNOREUNRECOGNIZEDELEMENTSANDATTRIBUTES", "original": "The `NO_ERRORS_SCHEMA` tells the Angular compiler to ignore unrecognized elements and attributes.", "translation": "`NO_ERRORS_SCHEMA` 会要求 Angular 编译器忽略不认识的那些元素和属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPILERWILLRECOGNIZETHEAPPROOTELEMENTANDTHEROUTERLINKATTRIBUTEBECAUSEYOUDECLAREDACORRESPONDINGAPPCOMPONENTANDROUTERLINKDIRECTIVESTUBINTHETESTBEDCONFIGURATION", "original": "The compiler will recognize the `<app-root>` element and the `routerLink` attribute\nbecause you declared a corresponding `AppComponent` and `RouterLinkDirectiveStub`\nin the `TestBed` configuration.", "translation": "编译器将会识别出 `<app-root>` 元素和 `RouterLink` 属性,因为你在 `TestBed` 的配置中声明了相应的\n`AppComponent` 和 `RouterLinkDirectiveStub`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BUTTHECOMPILERWONTTHROWANERRORWHENITENCOUNTERSAPPBANNERAPPWELCOMEORROUTEROUTLETITSIMPLYRENDERSTHEMASEMPTYTAGSANDTHEBROWSERIGNORESTHEM", "original": "But the compiler won't throw an error when it encounters `<app-banner>`, `<app-welcome>`, or `<router-outlet>`.\nIt simply renders them as empty tags and the browser ignores them.", "translation": "但编译器在遇到 `<app-banner>`、`<app-welcome>` 或 `<router-outlet>` 时不会报错。\n它只会把它们渲染成空白标签,而浏览器会忽略这些标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUNOLONGERNEEDTHESTUBCOMPONENTS", "original": "You no longer need the stub components.", "translation": "你不用再提供桩组件了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####USEBOTHTECHNIQUESTOGETHER", "original": "#### Use both techniques together", "translation": "#### 同时使用这两项技术", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESEARETECHNIQUESFORSHALLOWCOMPONENTTESTINGSONAMEDBECAUSETHEYREDUCETHEVISUALSURFACEOFTHECOMPONENTTOJUSTTHOSEELEMENTSINTHECOMPONENTSTEMPLATETHATMATTERFORTESTS", "original": "These are techniques for _Shallow Component Testing_ , \nso-named because they reduce the visual surface of the component to just those elements\nin the component's template that matter for tests.", "translation": "这些是进行*浅层*测试要用到的技术,之所以叫浅层测试是因为只包含本测试所关心的这个组件模板中的元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENOERRORSSCHEMAAPPROACHISTHEEASIEROFTHETWOBUTDONTOVERUSEIT", "original": "The `NO_ERRORS_SCHEMA` approach is the easier of the two but don't overuse it.", "translation": "`NO_ERRORS_SCHEMA` 方法在这两者中比较简单,但也不要过度使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENOERRORSSCHEMAALSOPREVENTSTHECOMPILERFROMTELLINGYOUABOUTTHEMISSINGCOMPONENTSANDATTRIBUTESTHATYOUOMITTEDINADVERTENTLYORMISSPELLEDYOUCOULDWASTEHOURSCHASINGPHANTOMBUGSTHATTHECOMPILERWOULDHAVECAUGHTINANINSTANT", "original": "The `NO_ERRORS_SCHEMA` also prevents the compiler from telling you about the missing \ncomponents and attributes that you omitted inadvertently or misspelled.\nYou could waste hours chasing phantom bugs that the compiler would have caught in an instant.", "translation": "`NO_ERRORS_SCHEMA` 还会阻止编译器告诉你因为的疏忽或拼写错误而缺失的组件和属性。\n你如果人工找出这些 bug 可能要浪费几个小时,但编译器可以立即捕获它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESTUBCOMPONENTAPPROACHHASANOTHERADVANTAGEWHILETHESTUBSINTHISEXAMPLEWEREEMPTYYOUCOULDGIVETHEMSTRIPPEDDOWNTEMPLATESANDCLASSESIFYOURTESTSNEEDTOINTERACTWITHTHEMINSOMEWAY", "original": "The _stub component_ approach has another advantage.\nWhile the stubs in _this_ example were empty,\nyou could give them stripped-down templates and classes if your tests\nneed to interact with them in some way.", "translation": "*桩组件*方式还有其它优点。\n虽然*这个*例子中的桩是空的,但你如果想要和它们用某种形式互动,也可以给它们一些裁剪过的模板和类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INPRACTICEYOUWILLCOMBINETHETWOTECHNIQUESINTHESAMESETUPASSEENINTHISEXAMPLE", "original": "In practice you will combine the two techniques in the same setup,\nas seen in this example.", "translation": "在实践中,你可以在准备代码中组合使用这两种技术,例子如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEANGULARCOMPILERCREATESTHEBANNERCOMPONENTSTUBFORTHEAPPBANNERELEMENTANDAPPLIESTHEROUTERLINKSTUBDIRECTIVETOTHEANCHORSWITHTHEROUTERLINKATTRIBUTEBUTITIGNORESTHEAPPWELCOMEANDROUTEROUTLETTAGS", "original": "The Angular compiler creates the `BannerComponentStub` for the `<app-banner>` element\nand applies the `RouterLinkStubDirective` to the anchors with the `routerLink` attribute,\nbut it ignores the `<app-welcome>` and `<router-outlet>` tags.", "translation": "Angular 编译器会为 `<app-banner>` 元素创建 `BannerComponentStub`,并把 `RouterLinkStubDirective` 应用到带有 `routerLink` 属性的链接上,不过它会忽略 `<app-welcome>` 和 `<router-outlet>` 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###COMPONENTSWITHROUTERLINK", "original": "### Components with _RouterLink_", "translation": "### 带有 `RouterLink` 的组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEREALROUTERLINKDIRECTIVEISQUITECOMPLICATEDANDENTANGLEDWITHOTHERCOMPONENTSANDDIRECTIVESOFTHEROUTERMODULEITREQUIRESCHALLENGINGSETUPTOMOCKANDUSEINTESTS", "original": "The real `RouterLinkDirective` is quite complicated and entangled with other components\nand directives of the `RouterModule`.\nIt requires challenging setup to mock and use in tests.", "translation": "真实的 `RouterLinkDirective` 太复杂了,而且与 `RouterModule` 中的其它组件和指令有着千丝万缕的联系。\n要在准备阶段 Mock 它以及在测试中使用它具有一定的挑战性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEROUTERLINKDIRECTIVESTUBINTHISSAMPLECODEREPLACESTHEREALDIRECTIVEWITHANALTERNATIVEVERSIONDESIGNEDTOVALIDATETHEKINDOFANCHORTAGWIRINGSEENINTHEAPPCOMPONENTTEMPLATE", "original": "The `RouterLinkDirectiveStub` in this sample code replaces the real directive\nwith an alternative version designed to validate the kind of anchor tag wiring\nseen in the `AppComponent` template.", "translation": "这段范例代码中的 `RouterLinkDirectiveStub` 用一个代用品替换了真实的指令,这个代用品用来验证 `AppComponent` 中所用链接的类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEURLBOUNDTOTHEROUTERLINKATTRIBUTEFLOWSINTOTHEDIRECTIVESLINKPARAMSPROPERTY", "original": "The URL bound to the `[routerLink]` attribute flows in to the directive's `linkParams` property.", "translation": "这个 URL 被绑定到了 `[routerLink]` 属性,它的值流入了该指令的 `linkParams` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHOSTMETADATAPROPERTYWIRESTHECLICKEVENTOFTHEHOSTELEMENTTHEAANCHORELEMENTSINAPPCOMPONENTTOTHESTUBDIRECTIVESONCLICKMETHOD", "original": "The `host` metadata property wires the click event of the host element \n(the `<a>` anchor elements in `AppComponent`) to the stub directive's `onClick` method.", "translation": "它的元数据中的 `host` 属性把宿主元素(即 `AppComponent` 中的 `<a>` 元素)的 `click` 事件关联到了这个桩指令的 `onClick` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CLICKINGTHEANCHORSHOULDTRIGGERTHEONCLICKMETHODWHICHSETSTHESTUBSTELLTALENAVIGATEDTOPROPERTYTESTSINSPECTNAVIGATEDTOTOCONFIRMTHATCLICKINGTHEANCHORSETTHEEXPECTEDROUTEDEFINITION", "original": "Clicking the anchor should trigger the `onClick()` method, \nwhich sets the stub's telltale `navigatedTo` property.\nTests inspect `navigatedTo` to confirm that clicking the anchor\nset the expected route definition.", "translation": "点击这个链接应该触发 `onClick()` 方法,其中会设置该桩指令中的警示器属性 `navigatedTo`。\n测试中检查 `navigatedTo` 以确认点击该链接确实如预期的那样根据路由定义设置了该属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHETHERTHEROUTERISCONFIGUREDPROPERLYTONAVIGATEWITHTHATROUTEDEFINITIONISAQUESTIONFORASEPARATESETOFTESTS", "original": "Whether the router is configured properly to navigate with that route definition is a\nquestion for a separate set of tests.", "translation": "路由器的配置是否正确和是否能按照那些路由定义进行导航,是测试中一组独立的问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####BYDIRECTIVEANDINJECTEDDIRECTIVES", "original": "#### _By.directive_ and injected directives", "translation": "#### `By.directive` 与注入的指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ALITTLEMORESETUPTRIGGERSTHEINITIALDATABINDINGANDGETSREFERENCESTOTHENAVIGATIONLINKS:", "original": "A little more setup triggers the initial data binding and gets references to the navigation links:", "translation": "再一步配置触发了数据绑定的初始化,获取导航链接的引用:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THREEPOINTSOFSPECIALINTEREST:", "original": "Three points of special interest:", "translation": "有三点特别重要:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1YOUCANLOCATETHEANCHORELEMENTSWITHANATTACHEDDIRECTIVEUSINGBYDIRECTIVE", "original": "1. You can locate the anchor elements with an attached directive using `By.directive`.", "translation": "你可以使用 `By.directive` 来定位一个带附属指令的链接元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1THEQUERYRETURNSDEBUGELEMENTWRAPPERSAROUNDTHEMATCHINGELEMENTS", "original": "1. The query returns `DebugElement` wrappers around the matching elements.", "translation": "该查询返回包含了匹配元素的 `DebugElement` 包装器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1EACHDEBUGELEMENTEXPOSESADEPENDENCYINJECTORWITHTHESPECIFICINSTANCEOFTHEDIRECTIVEATTACHEDTOTHATELEMENT", "original": "1. Each `DebugElement` exposes a dependency injector with the\n specific instance of the directive attached to that element.", "translation": "每个 `DebugElement` 都会导出该元素中的一个依赖注入器,其中带有指定的指令实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEAPPCOMPONENTLINKSTOVALIDATEAREASFOLLOWS:", "original": "The `AppComponent` links to validate are as follows:", "translation": "`AppComponent` 中要验证的链接如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARESOMETESTSTHATCONFIRMTHOSELINKSAREWIREDTOTHEROUTERLINKDIRECTIVESASEXPECTED:", "original": "Here are some tests that confirm those links are wired to the `routerLink` directives\nas expected:", "translation": "下面这些测试用来确认那些链接是否如预期般连接到了 `RouterLink` 指令中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECLICKTESTINTHISEXAMPLEISMISLEADINGITTESTSTHEROUTERLINKDIRECTIVESTUBRATHERTHANTHECOMPONENTTHISISACOMMONFAILINGOFDIRECTIVESTUBS", "original": "The \"click\" test _in this example_ is misleading.\nIt tests the `RouterLinkDirectiveStub` rather than the _component_.\nThis is a common failing of directive stubs.", "translation": "其实*这个例子中*的“click”测试误入歧途了。\n它测试的重点其实是 `RouterLinkDirectiveStub` ,而不是该组件。\n这是写桩指令时常见的错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITHASALEGITIMATEPURPOSEINTHISGUIDEITDEMONSTRATESHOWTOFINDAROUTERLINKELEMENTCLICKITANDINSPECTARESULTWITHOUTENGAGINGTHEFULLROUTERMACHINERYTHISISASKILLYOUMAYNEEDTOTESTAMORESOPHISTICATEDCOMPONENTONETHATCHANGESTHEDISPLAYRECALCULATESPARAMETERSORREARRANGESNAVIGATIONOPTIONSWHENTHEUSERCLICKSTHELINK", "original": "It has a legitimate purpose in this guide.\nIt demonstrates how to find a `RouterLink` element, click it, and inspect a result,\nwithout engaging the full router machinery.\nThis is a skill you may need to test a more sophisticated component, one that changes the display,\nre-calculates parameters, or re-arranges navigation options when the user clicks the link.", "translation": "在本章中,它有存在的必要。\n它演示了如何在不涉及完整路由器机制的情况下,如何找到 `RouterLink` 元素、点击它并检查结果。\n要测试更复杂的组件,你可能需要具备这样的能力,能改变视图和重新计算参数,或者当用户点击链接时,有能力重新安排导航选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####WHATGOODARETHESETESTS", "original": "#### What good are these tests?", "translation": "#### 这些测试有什么优点?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "STUBBEDROUTERLINKTESTSCANCONFIRMTHATACOMPONENTWITHLINKSANDANOUTLETISSETUPPROPERLYTHATTHECOMPONENTHASTHELINKSITSHOULDHAVEANDTHATTHEYAREALLPOINTINGINTHEEXPECTEDDIRECTIONTHESETESTSDONOTCONCERNWHETHERTHEAPPWILLSUCCEEDINNAVIGATINGTOTHETARGETCOMPONENTWHENTHEUSERCLICKSALINK", "original": "Stubbed `RouterLink` tests can confirm that a component with links and an outlet is setup properly,\nthat the component has the links it should have, and that they are all pointing in the expected direction.\nThese tests do not concern whether the app will succeed in navigating to the target component when the user clicks a link.", "translation": "用 `RouterLink` 的桩指令进行测试可以确认带有链接和 outlet 的组件的设置的正确性,确认组件有应该有的链接,确认它们都指向了正确的方向。\n这些测试程序不关心用户点击链接时,也不关心应用是否会成功的导航到目标组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "STUBBINGTHEROUTERLINKANDROUTEROUTLETISTHEBESTOPTIONFORSUCHLIMITEDTESTINGGOALSRELYINGONTHEREALROUTERWOULDMAKETHEMBRITTLETHEYCOULDFAILFORREASONSUNRELATEDTOTHECOMPONENTFOREXAMPLEANAVIGATIONGUARDCOULDPREVENTANUNAUTHORIZEDUSERFROMVISITINGTHEHEROLISTCOMPONENTTHATSNOTTHEFAULTOFTHEAPPCOMPONENTANDNOCHANGETOTHATCOMPONENTCOULDCURETHEFAILEDTEST", "original": "Stubbing the RouterLink and RouterOutlet is the best option for such limited testing goals.\nRelying on the real router would make them brittle.\nThey could fail for reasons unrelated to the component.\nFor example, a navigation guard could prevent an unauthorized user from visiting the `HeroListComponent`.\nThat's not the fault of the `AppComponent` and no change to that component could cure the failed test.", "translation": "对于这些有限的测试目标,使用 RouterLink 桩指令和 RouterOutlet 桩组件 是最佳选择。\n依靠真正的路由器会让它们很脆弱。\n它们可能因为与组件无关的原因而失败。\n例如,一个导航守卫可能防止没有授权的用户访问 `HeroListComponent`。\n这并不是 `AppComponent` 的过错,并且无论该组件怎么改变都无法修复这个失败的测试程序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ADIFFERENTBATTERYOFTESTSCANEXPLOREWHETHERTHEAPPLICATIONNAVIGATESASEXPECTEDINTHEPRESENCEOFCONDITIONSTHATINFLUENCEGUARDSSUCHASWHETHERTHEUSERISAUTHENTICATEDANDAUTHORIZED", "original": "A _different_ battery of tests can explore whether the application navigates as expected\nin the presence of conditions that influence guards such as whether the user is authenticated and authorized.", "translation": "不同的测试程序可以探索在不同条件下(比如像检查用户是否认证),该应用是否和期望的那样导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AFUTUREGUIDEUPDATEWILLEXPLAINHOWTOWRITESUCHTESTSWITHTHEROUTERTESTINGMODULE", "original": "A future guide update will explain how to write such\ntests with the `RouterTestingModule`.", "translation": "未来对本章的更新将介绍如何使用 `RouterTestingModule` 来编写这样的测试程序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###USEAPAGEOBJECT", "original": "### Use a _page_ object", "translation": "### 使用页面(page)对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHERODETAILCOMPONENTISASIMPLEVIEWWITHATITLETWOHEROFIELDSANDTWOBUTTONS", "original": "The `HeroDetailComponent` is a simple view with a title, two hero fields, and two buttons.", "translation": "`HeroDetailComponent` 是带有标题、两个英雄字段和两个按钮的简单视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BUTTHERESPLENTYOFTEMPLATECOMPLEXITYEVENINTHISSIMPLEFORM", "original": "But there's plenty of template complexity even in this simple form.", "translation": "但即使是这么简单的表单,其模板中也涉及到不少复杂性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTSTHATEXERCISETHECOMPONENTNEED", "original": "Tests that exercise the component need ...", "translation": "这些供练习用的组件需要 ……", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOWAITUNTILAHEROARRIVESBEFOREELEMENTSAPPEARINTHEDOM", "original": "* to wait until a hero arrives before elements appear in the DOM.", "translation": "等获取到英雄之后才能让元素出现在 DOM 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AREFERENCETOTHETITLETEXT", "original": "* a reference to the title text.", "translation": "一个对标题文本的引用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AREFERENCETOTHENAMEINPUTBOXTOINSPECTANDSETIT", "original": "* a reference to the name input box to inspect and set it.", "translation": "一个对 name 输入框的引用,以便对它进行探查和修改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "REFERENCESTOTHETWOBUTTONSSOTHEYCANCLICKTHEM", "original": "* references to the two buttons so they can click them.", "translation": "引用两个按钮,以便点击它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SPIESFORSOMEOFTHECOMPONENTANDROUTERMETHODS", "original": "* spies for some of the component and router methods.", "translation": "为组件和路由器的方法安插间谍。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "EVENASMALLFORMSUCHASTHISONECANPRODUCEAMESSOFTORTUREDCONDITIONALSETUPANDCSSELEMENTSELECTION", "original": "Even a small form such as this one can produce a mess of tortured conditional setup and CSS element selection.", "translation": "即使是像这样一个很小的表单,也能产生令人疯狂的错综复杂的条件设置和 CSS 元素选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TAMETHECOMPLEXITYWITHAPAGECLASSTHATHANDLESACCESSTOCOMPONENTPROPERTIESANDENCAPSULATESTHELOGICTHATSETSTHEM", "original": "Tame the complexity with a `Page` class that handles access to component properties\nand encapsulates the logic that sets them.", "translation": "可以使用 `Page` 类来征服这种复杂性。`Page` 类可以处理对组件属性的访问,并对设置这些属性的逻辑进行封装。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREISSUCHAPAGECLASSFORTHEHERODETAILCOMPONENTSPECTS", "original": "Here is such a `Page` class for the `hero-detail.component.spec.ts`", "translation": "下面是一个供 `hero-detail.component.spec.ts` 使用的 `Page` 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOWTHEIMPORTANTHOOKSFORCOMPONENTMANIPULATIONANDINSPECTIONARENEATLYORGANIZEDANDACCESSIBLEFROMANINSTANCEOFPAGE", "original": "Now the important hooks for component manipulation and inspection are neatly organized and accessible from an instance of `Page`.", "translation": "现在,用来操作和检查组件的重要钩子都被井然有序的组织起来了,可以通过 `page` 实例来使用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ACREATECOMPONENTMETHODCREATESAPAGEOBJECTANDFILLSINTHEBLANKSONCETHEHEROARRIVES", "original": "A `createComponent` method creates a `page` object and fills in the blanks once the `hero` arrives.", "translation": "`createComponent` 方法创建 `page`,在 `hero` 到来时,自动填补空白。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHERODETAILCOMPONENTTESTS#TESTSWTESTDOUBLEINANEARLIERSECTIONDEMONSTRATEHOWCREATECOMPONENTANDPAGEKEEPTHETESTSSHORTANDONMESSAGETHEREARENODISTRACTIONS:NOWAITINGFORPROMISESTORESOLVEANDNOSEARCHINGTHEDOMFORELEMENTVALUESTOCOMPARE", "original": "The [_HeroDetailComponent_ tests](#tests-w-test-double) in an earlier section demonstrate how `createComponent` and `page`\nkeep the tests short and _on message_.\nThere are no distractions: no waiting for promises to resolve and no searching the DOM for element values to compare.", "translation": "前面小节中的 [`HeroDetailComponent` 测试](#tests-w-test-double)示范了如何 `createComponent`,而 `page` 让这些测试保持简短而富有表达力。\n而且还不用分心:不用等待承诺被解析,不必在 DOM 中找出元素的值才能进行比较。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREAREAFEWMOREHERODETAILCOMPONENTTESTSTOREINFORCETHEPOINT", "original": "Here are a few more `HeroDetailComponent` tests to reinforce the point.", "translation": "还有更多的 `HeroDetailComponent` 测试可以证明这一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###CALLINGCOMPILECOMPONENTS", "original": "### Calling _compileComponents()_", "translation": "### 调用 `compileComponents()`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANIGNORETHISSECTIONIFYOUONLYRUNTESTSWITHTHECLINGTESTCOMMANDBECAUSETHECLICOMPILESTHEAPPLICATIONBEFORERUNNINGTHETESTS", "original": "You can ignore this section if you _only_ run tests with the CLI `ng test` command\nbecause the CLI compiles the application before running the tests.", "translation": "如果你*只想*使用 CLI 的 `ng test` 命令来运行测试,那么可以忽略这一节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IFYOURUNTESTSINANONCLIENVIRONMENTTHETESTSMAYFAILWITHAMESSAGELIKETHISONE:", "original": "If you run tests in a **non-CLI environment**, the tests may fail with a message like this one:", "translation": "如果你在**非 CLI 环境**中运行测试,这些测试可能会报错,错误信息如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEROOTOFTHEPROBLEMISATLEASTONEOFTHECOMPONENTSINVOLVEDINTHETESTSPECIFIESANEXTERNALTEMPLATEORCSSFILEASTHEFOLLOWINGVERSIONOFTHEBANNERCOMPONENTDOES", "original": "The root of the problem is at least one of the components involved in the test\nspecifies an external template or CSS file as \nthe following version of the `BannerComponent` does.", "translation": "问题的根源在于这个测试中至少有一个组件引用了外部模板或外部 CSS 文件,就像下面这个 `BannerComponent` 所示:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTFAILSWHENTHETESTBEDTRIESTOCREATETHECOMPONENT", "original": "The test fails when the `TestBed` tries to create the component.", "translation": "当 `TestBed` 视图创建组件时,这个测试失败了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RECALLTHATTHEAPPHASNTBEENCOMPILEDSOWHENYOUCALLCREATECOMPONENTTHETESTBEDCOMPILESIMPLICITLY", "original": "Recall that the app hasn't been compiled. \nSo when you call `createComponent()`, the `TestBed` compiles implicitly.", "translation": "回想一下,这个应用从未编译过。\n所以当你调用 `createComponent()` 的时候,`TestBed` 就会进行隐式编译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THATSNOTAPROBLEMWHENTHESOURCECODEISINMEMORYBUTTHEBANNERCOMPONENTREQUIRESEXTERNALFILESTHATTHECOMPILEMUSTREADFROMTHEFILESYSTEMANINHERENTLYASYNCHRONOUSOPERATION", "original": "That's not a problem when the source code is in memory.\nBut the `BannerComponent` requires external files\nthat the compile must read from the file system, \nan inherently _asynchronous_ operation.", "translation": "当它的源码都在内存中的时候,这样做没问题。\n不过 `BannerComponent` 需要一些外部文件,编译时必须从文件系统中读取它,而这是一个天生的*异步*操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IFTHETESTBEDWEREALLOWEDTOCONTINUETHETESTSWOULDRUNANDFAILMYSTERIOUSLYBEFORETHECOMPILERCOULDFINISHED", "original": "If the `TestBed` were allowed to continue, the tests would run and fail mysteriously\nbefore the compiler could finished.", "translation": "如果 `TestBed` 继续执行,这些测试就会继续运行,并在编译器完成这些异步工作之前导致莫名其妙的失败。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEPREEMPTIVEERRORMESSAGETELLSYOUTOCOMPILEEXPLICITLYWITHCOMPILECOMPONENTS", "original": "The preemptive error message tells you to compile explicitly with `compileComponents()`.", "translation": "这些错误信息告诉你要使用 `compileComponents()` 进行显式的编译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####COMPILECOMPONENTSISASYNC", "original": "#### _compileComponents()_ is async", "translation": "#### `compileComponents()` 是异步的", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUMUSTCALLCOMPILECOMPONENTSWITHINANASYNCHRONOUSTESTFUNCTION", "original": "You must call `compileComponents()` within an asynchronous test function.", "translation": "你必须在异步测试函数中调用 `compileComponents()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IFYOUNEGLECTTOMAKETHETESTFUNCTIONASYNCEGFORGETTOUSEASYNCASDESCRIBEDBELOWYOULLSEETHISERRORMESSAGE", "original": "If you neglect to make the test function async \n(e.g., forget to use `async()` as described below),\nyou'll see this error message", "translation": "如果你忘了把测试函数标为异步的(比如忘了像稍后的代码中那样使用 `async()`),就会看到下列错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ATYPICALAPPROACHISTODIVIDETHESETUPLOGICINTOTWOSEPARATEBEFOREEACHFUNCTIONS:", "original": "A typical approach is to divide the setup logic into two separate `beforeEach()` functions:", "translation": "典型的做法是把准备逻辑拆成两个独立的 `beforeEach()` 函数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1ANASYNCBEFOREEACHTHATCOMPILESTHECOMPONENTS", "original": "1. An async `beforeEach()` that compiles the components", "translation": "异步的 `beforeEach()` 负责编译组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1ASYNCHRONOUSBEFOREEACHTHATPERFORMSTHEREMAININGSETUP", "original": "1. A synchronous `beforeEach()` that performs the remaining setup.", "translation": "同步的 `beforeEach()` 负责执行其余的准备代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TOFOLLOWTHISPATTERNIMPORTTHEASYNCHELPERWITHTHEOTHERTESTINGSYMBOLS", "original": "To follow this pattern, import the `async()` helper with the other testing symbols.", "translation": "要想使用这种模式,就要和其它符号一起从测试库中导入 `async()` 辅助函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####THEASYNCBEFOREEACH", "original": "#### The async _beforeEach_", "translation": "#### 异步的 `beforeEach`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WRITETHEFIRSTASYNCBEFOREEACHLIKETHIS", "original": "Write the first async `beforeEach` like this.", "translation": "像下面这样编写第一个异步的 `beforeEach`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEASYNCHELPERFUNCTIONTAKESAPARAMETERLESSFUNCTIONWITHTHEBODYOFTHESETUP", "original": "The `async()` helper function takes a parameterless function with the body of the setup.", "translation": "`async()` 辅助函数接受一个无参函数,其内容是准备代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDCONFIGURETESTINGMODULEMETHODRETURNSTHETESTBEDCLASSSOYOUCANCHAINCALLSTOOTHERTESTBEDSTATICMETHODSSUCHASCOMPILECOMPONENTS", "original": "The `TestBed.configureTestingModule()` method returns the `TestBed` class so you can chain\ncalls to other `TestBed` static methods such as `compileComponents()`.", "translation": "`TestBed.configureTestingModule()` 方法返回 `TestBed` 类,所以你可以链式调用其它 `TestBed` 中的静态方法,比如 `compileComponents()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTHISEXAMPLETHEBANNERCOMPONENTISTHEONLYCOMPONENTTOCOMPILEOTHEREXAMPLESCONFIGURETHETESTINGMODULEWITHMULTIPLECOMPONENTSANDMAYIMPORTAPPLICATIONMODULESTHATHOLDYETMORECOMPONENTSANYOFTHEMCOULDBEREQUIREEXTERNALFILES", "original": "In this example, the `BannerComponent` is the only component to compile.\nOther examples configure the testing module with multiple components\nand may import application modules that hold yet more components.\nAny of them could be require external files.", "translation": "在这个例子中,`BannerComponent` 是仅有的待编译组件。\n其它例子中可能会使用多个组件来配置测试模块,并且可能引入某些具有其它组件的应用模块。\n它们中的任何一个都可能需要外部文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDCOMPILECOMPONENTSMETHODASYNCHRONOUSLYCOMPILESALLCOMPONENTSCONFIGUREDINTHETESTINGMODULE", "original": "The `TestBed.compileComponents` method asynchronously compiles all components configured in the testing module.", "translation": "`TestBed.compileComponents` 方法会异步编译测试模块中配置过的所有组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DONOTRECONFIGURETHETESTBEDAFTERCALLINGCOMPILECOMPONENTS", "original": "Do not re-configure the `TestBed` after calling `compileComponents()`.", "translation": "在调用了 `compileComponents()` 之后就不能再重新配置 `TestBed` 了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CALLINGCOMPILECOMPONENTSCLOSESTHECURRENTTESTBEDINSTANCETOFURTHERCONFIGURATIONYOUCANNOTCALLANYMORETESTBEDCONFIGURATIONMETHODSNOTCONFIGURETESTINGMODULENORANYOFTHEOVERRIDEMETHODSTHETESTBEDTHROWSANERRORIFYOUTRY", "original": "Calling `compileComponents()` closes the current `TestBed` instance to further configuration.\nYou cannot call any more `TestBed` configuration methods, not `configureTestingModule()`\nnor any of the `override...` methods. The `TestBed` throws an error if you try.", "translation": "调用 `compileComponents()` 会关闭当前的 `TestBed` 实例,不再允许进行配置。\n你不能再调用任何 `TestBed` 中的配置方法,既不能调 `configureTestingModule()`,也不能调用任何 `override...` 方法。如果你试图这么做,`TestBed` 就会抛出错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MAKECOMPILECOMPONENTSTHELASTSTEPBEFORECALLINGTESTBEDCREATECOMPONENT", "original": "Make `compileComponents()` the last step\nbefore calling `TestBed.createComponent()`.", "translation": "确保 `compileComponents()` 是调用 `TestBed.createComponent()` 之前的最后一步。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####THESYNCHRONOUSBEFOREEACH", "original": "#### The synchronous _beforeEach_", "translation": "#### 同步的 `beforeEach`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESECONDSYNCHRONOUSBEFOREEACHCONTAINSTHEREMAININGSETUPSTEPSWHICHINCLUDECREATINGTHECOMPONENTANDQUERYINGFORELEMENTSTOINSPECT", "original": "The second, synchronous `beforeEach()` contains the remaining setup steps, \nwhich include creating the component and querying for elements to inspect.", "translation": "第二个同步 `beforeEach()` 的例子包含剩下的准备步骤,\n包括创建组件和查询那些要检查的元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANCOUNTONTHETESTRUNNERTOWAITFORTHEFIRSTASYNCHRONOUSBEFOREEACHTOFINISHBEFORECALLINGTHESECOND", "original": "You can count on the test runner to wait for the first asynchronous `beforeEach` to finish before calling the second.", "translation": "测试运行器(runner)会先等待第一个异步 `beforeEach` 函数执行完再调用第二个。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####CONSOLIDATEDSETUP", "original": "#### Consolidated setup", "translation": "#### 整理过的准备代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUCANCONSOLIDATETHETWOBEFOREEACHFUNCTIONSINTOASINGLEASYNCBEFOREEACH", "original": "You can consolidate the two `beforeEach()` functions into a single, async `beforeEach()`.", "translation": "你可以把这两个 `beforeEach()` 函数重整成一个异步的 `beforeEach()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPILECOMPONENTSMETHODRETURNSAPROMISESOYOUCANPERFORMTHESYNCHRONOUSSETUPTASKSAFTERCOMPILATIONBYMOVINGTHESYNCHRONOUSCODEINTOATHENCALLBACK", "original": "The `compileComponents()` method returns a promise so you can perform the\nsynchronous setup tasks _after_ compilation by moving the synchronous code\ninto a `then(...)` callback.", "translation": "`compileComponents()` 方法返回一个承诺,所以你可以通过把同步代码移到 `then(...)` 回调中,\n以便在编译完成*之后* 执行那些同步准备任务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####COMPILECOMPONENTSISHARMLESS", "original": "#### _compileComponents()_ is harmless", "translation": "#### `compileComponents()` 是无害的", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERESNOHARMINCALLINGCOMPILECOMPONENTSWHENITSNOTREQUIRED", "original": "There's no harm in calling `compileComponents()` when it's not required.", "translation": "在不需要 `compileComponents()` 的时候调用它也不会有害处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPONENTTESTFILEGENERATEDBYTHECLICALLSCOMPILECOMPONENTSEVENTHOUGHITISNEVERREQUIREDWHENRUNNINGNGTEST", "original": "The component test file generated by the CLI calls `compileComponents()`\neven though it is never required when running `ng test`.", "translation": "虽然在运行 `ng test` 时永远都不需要调用 `compileComponents()`,但 CLI 生成的组件测试文件还是会调用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTSINTHISGUIDEONLYCALLCOMPILECOMPONENTSWHENNECESSARY", "original": "The tests in this guide only call `compileComponents` when necessary.", "translation": "但这篇指南中的这些测试只会在必要时才调用 `compileComponents`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###SETUPWITHMODULEIMPORTS", "original": "### Setup with module imports", "translation": "### 准备模块的 `imports`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "EARLIERCOMPONENTTESTSCONFIGUREDTHETESTINGMODULEWITHAFEWDECLARATIONSLIKETHIS:", "original": "Earlier component tests configured the testing module with a few `declarations` like this:", "translation": "此前的组件测试程序使用了一些 `declarations` 来配置模块,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDASHBOARDCOMPONENTISSIMPLEITNEEDSNOHELPBUTMORECOMPLEXCOMPONENTSOFTENDEPENDONOTHERCOMPONENTSDIRECTIVESPIPESANDPROVIDERSANDTHESEMUSTBEADDEDTOTHETESTINGMODULETOO", "original": "The `DashboardComponent` is simple. It needs no help.\nBut more complex components often depend on other components, directives, pipes, and providers\nand these must be added to the testing module too.", "translation": "`DashbaordComponent` 非常简单。它不需要帮助。\n但是更加复杂的组件通常依赖其它组件、指令、管道和提供商,\n所以这些必须也被添加到测试模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FORTUNATELYTHETESTBEDCONFIGURETESTINGMODULEPARAMETERPARALLELSTHEMETADATAPASSEDTOTHENGMODULEDECORATORWHICHMEANSYOUCANALSOSPECIFYPROVIDERSANDIMPORTS", "original": "Fortunately, the `TestBed.configureTestingModule` parameter parallels\nthe metadata passed to the `@NgModule` decorator\nwhich means you can also specify `providers` and `imports`.", "translation": "幸运的是,`TestBed.configureTestingModule` 参数与传入 `@NgModule` 装饰器的元数据一样,也就是所你也可以指定 `providers` 和 `imports`.", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHERODETAILCOMPONENTREQUIRESALOTOFHELPDESPITEITSSMALLSIZEANDSIMPLECONSTRUCTIONINADDITIONTOTHESUPPORTITRECEIVESFROMTHEDEFAULTTESTINGMODULECOMMONMODULEITNEEDS:", "original": "The `HeroDetailComponent` requires a lot of help despite its small size and simple construction.\nIn addition to the support it receives from the default testing module `CommonModule`, it needs:", "translation": "虽然 `HeroDetailComponent` 很小,结构也很简单,但是它需要很多帮助。\n 除了从默认测试模块 `CommonModule` 中获得的支持,它还需要:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NGMODELANDFRIENDSINTHEFORMSMODULETOENABLETWOWAYDATABINDING", "original": "* `NgModel` and friends in the `FormsModule` to enable two-way data binding.", "translation": "`FormsModule` 里的 `NgModel` 和其它,来进行双向数据绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETITLECASEPIPEFROMTHESHAREDFOLDER", "original": "* The `TitleCasePipe` from the `shared` folder.", "translation": "`shared` 目录里的 `TitleCasePipe`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ROUTERSERVICESWHICHTHESETESTSARESTUBBING", "original": "* Router services (which these tests are stubbing).", "translation": "一些路由器服务(测试程序将 stub 伪造它们)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERODATAACCESSSERVICESALSOSTUBBED", "original": "* Hero data access services (also stubbed).", "translation": "英雄数据访问服务(同样被 stub 伪造了)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ONEAPPROACHISTOCONFIGURETHETESTINGMODULEFROMTHEINDIVIDUALPIECESASINTHISEXAMPLE:", "original": "One approach is to configure the testing module from the individual pieces as in this example:", "translation": "一种方法是在测试模块中一一配置,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOTICETHATTHEBEFOREEACHISASYNCHRONOUSANDCALLSTESTBEDCOMPILECOMPONENTSBECAUSETHEHERODETAILCOMPONENTHASANEXTERNALTEMPLATEANDCSSFILE", "original": "Notice that the `beforeEach()` is asynchronous and calls `TestBed.compileComponents`\nbecause the `HeroDetailComponent` has an external template and css file.", "translation": "注意,`beforeEach()` 是异步的,它调用 `TestBed.compileComponents` 是因为 `HeroDetailComponent` 有外部模板和 CSS 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ASEXPLAINEDINCALLINGCOMPILECOMPONENTS#COMPILECOMPONENTSABOVETHESETESTSCOULDBERUNINANONCLIENVIRONMENTWHEREANGULARWOULDHAVETOCOMPILETHEMINTHEBROWSER", "original": "As explained in [_Calling compileComponents()_](#compile-components) above,\nthese tests could be run in a non-CLI environment\nwhere Angular would have to compile them in the browser.", "translation": "如前面的[调用 `compileComponents()`](#compile-components) 中所解释的那样,这些测试可以运行在非 CLI 环境下,那里 Angular 并不会在浏览器中编译它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####IMPORTASHAREDMODULE", "original": "#### Import a shared module", "translation": "#### 导入共享模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BECAUSEMANYAPPCOMPONENTSNEEDTHEFORMSMODULEANDTHETITLECASEPIPETHEDEVELOPERCREATEDASHAREDMODULETOCOMBINETHESEANDOTHERFREQUENTLYREQUESTEDPARTS", "original": "Because many app components need the `FormsModule` and the `TitleCasePipe`, the developer created\na `SharedModule` to combine these and other frequently requested parts.", "translation": "因为很多应用组件都需要 `FormsModule` 和 `TitleCasePipe`,所以开发者创建了 `SharedModule` 来把它们及其它常用的部分组合在一起。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTCONFIGURATIONCANUSETHESHAREDMODULETOOASSEENINTHISALTERNATIVESETUP:", "original": "The test configuration can use the `SharedModule` too as seen in this alternative setup:", "translation": "这些测试配置也可以使用 `SharedModule`,如下所示:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITSABITTIGHTERANDSMALLERWITHFEWERIMPORTSTATEMENTSNOTSHOWN", "original": "It's a bit tighter and smaller, with fewer import statements (not shown).", "translation": "它的导入声明少一些(未显示),稍微干净一些,小一些。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####IMPORTAFEATUREMODULE", "original": "#### Import a feature module", "translation": "#### 导入特性模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHERODETAILCOMPONENTISPARTOFTHEHEROMODULEFEATUREMODULEGUIDEFEATUREMODULESTHATAGGREGATESMOREOFTHEINTERDEPENDENTPIECESINCLUDINGTHESHAREDMODULETRYATESTCONFIGURATIONTHATIMPORTSTHEHEROMODULELIKETHISONE:", "original": "The `HeroDetailComponent` is part of the `HeroModule` [Feature Module](guide/feature-modules) that aggregates more of the interdependent pieces\nincluding the `SharedModule`.\nTry a test configuration that imports the `HeroModule` like this one:", "translation": "`HeroDetailComponent` 是 `HeroModule` 这个[特性模块](guide/feature-modules)的一部分,它聚合了更多相互依赖的片段,包括 `SharedModule`。\n试试下面这个导入了 `HeroModule` 的测试配置:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THATSREALLYCRISPONLYTHETESTDOUBLESINTHEPROVIDERSREMAINEVENTHEHERODETAILCOMPONENTDECLARATIONISGONE", "original": "That's _really_ crisp. Only the _test doubles_ in the `providers` remain. Even the `HeroDetailComponent` declaration is gone.", "translation": "这样特别清爽。只有 `providers` 里面的测试替身被保留。连 `HeroDetailComponent` 声明都消失了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INFACTIFYOUTRYTODECLAREITANGULARWILLTHROWANERRORBECAUSEHERODETAILCOMPONENTISDECLAREDINBOTHTHEHEROMODULEANDTHEDYNAMICTESTMODULECREATEDBYTHETESTBED", "original": "In fact, if you try to declare it, Angular will throw an error because\n`HeroDetailComponent` is declared in both the `HeroModule` and the `DynamicTestModule`\ncreated by the `TestBed`.", "translation": "事实上,如果你试图声明它,Angular 就会抛出一个错误,因为 `HeroDetailComponent` 同时声明在了 `HeroModule` 和 `TestBed` 创建的 `DynamicTestModule` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IMPORTINGTHECOMPONENTSFEATUREMODULECANBETHEEASIESTWAYTOCONFIGURETESTSWHENTHEREAREMANYMUTUALDEPENDENCIESWITHINTHEMODULEANDTHEMODULEISSMALLASFEATUREMODULESTENDTOBE", "original": "Importing the component's feature module can be the easiest way to configure tests\nwhen there are many mutual dependencies within the module and \nthe module is small, as feature modules tend to be.", "translation": "如果模块中有很多共同依赖,并且该模块很小(这也是特性模块的应有形态),那么直接导入组件的特性模块可以成为配置这些测试的简易方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "###OVERRIDECOMPONENTPROVIDERS", "original": "### Override component providers", "translation": "### 改写组件的服务提供商", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHERODETAILCOMPONENTPROVIDESITSOWNHERODETAILSERVICE", "original": "The `HeroDetailComponent` provides its own `HeroDetailService`.", "translation": "`HeroDetailComponent` 提供自己的 `HeroDetailService` 服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITSNOTPOSSIBLETOSTUBTHECOMPONENTSHERODETAILSERVICEINTHEPROVIDERSOFTHETESTBEDCONFIGURETESTINGMODULETHOSEAREPROVIDERSFORTHETESTINGMODULENOTTHECOMPONENTTHEYPREPARETHEDEPENDENCYINJECTORATTHEFIXTURELEVEL", "original": "It's not possible to stub the component's `HeroDetailService` in the `providers` of the `TestBed.configureTestingModule`.\nThose are providers for the _testing module_, not the component. They prepare the dependency injector at the _fixture level_.", "translation": "在 `TestBed.configureTestingModule` 的 `providers` 中 stub 伪造组件的 `HeroDetailService` 是不可行的。\n这些是**测试模块**的提供商,而非组件的。组件级别的供应商应该在**fixture 级别**准备的依赖注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANGULARCREATESTHECOMPONENTWITHITSOWNINJECTORWHICHISACHILDOFTHEFIXTUREINJECTORITREGISTERSTHECOMPONENTSPROVIDERSTHEHERODETAILSERVICEINTHISCASEWITHTHECHILDINJECTOR", "original": "Angular creates the component with its _own_ injector, which is a _child_ of the fixture injector.\nIt registers the component's providers (the `HeroDetailService` in this case) with the child injector.", "translation": "Angular 会使用自己的注入器来创建这些组件,这个注入器是夹具的注入器的子注入器。\n它使用这个子注入器注册了该组件服务提供商(这里是 `HeroDetailService` )。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ATESTCANNOTGETTOCHILDINJECTORSERVICESFROMTHEFIXTUREINJECTORANDTESTBEDCONFIGURETESTINGMODULECANTCONFIGURETHEMEITHER", "original": "A test cannot get to child injector services from the fixture injector.\nAnd `TestBed.configureTestingModule` can't configure them either.", "translation": "测试没办法从测试夹具的注入器中获取子注入器中的服务,而 `TestBed.configureTestingModule` 也没法配置它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANGULARHASBEENCREATINGNEWINSTANCESOFTHEREALHERODETAILSERVICEALLALONG", "original": "Angular has been creating new instances of the real `HeroDetailService` all along!", "translation": "Angular 始终都在创建真实 `HeroDetailService` 的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESETESTSCOULDFAILORTIMEOUTIFTHEHERODETAILSERVICEMADEITSOWNXHRCALLSTOAREMOTESERVERTHEREMIGHTNOTBEAREMOTESERVERTOCALL", "original": "These tests could fail or timeout if the `HeroDetailService` made its own XHR calls to a remote server.\nThere might not be a remote server to call.", "translation": "如果 `HeroDetailService` 向远程服务器发出自己的 XHR 请求,这些测试可能会失败或者超时。\n这个远程服务器可能根本不存在。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FORTUNATELYTHEHERODETAILSERVICEDELEGATESRESPONSIBILITYFORREMOTEDATAACCESSTOANINJECTEDHEROSERVICE", "original": "Fortunately, the `HeroDetailService` delegates responsibility for remote data access to an injected `HeroService`.", "translation": "幸运的是,`HeroDetailService` 将远程数据访问的责任交给了注入进来的 `HeroService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEPREVIOUSTESTCONFIGURATION#FEATUREMODULEIMPORTREPLACESTHEREALHEROSERVICEWITHATESTHEROSERVICETHATINTERCEPTSSERVERREQUESTSANDFAKESTHEIRRESPONSES", "original": "The [previous test configuration](#feature-module-import) replaces the real `HeroService` with a `TestHeroService`\nthat intercepts server requests and fakes their responses.", "translation": "[前面的测试配置](#feature-module-import)使用 `TestHeroService` 替换了真实的 `HeroService`,它拦截了发往服务器的请求,并伪造了服务器的响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHATIFYOUARENTSOLUCKYWHATIFFAKINGTHEHEROSERVICEISHARDWHATIFHERODETAILSERVICEMAKESITSOWNSERVERREQUESTS", "original": "What if you aren't so lucky. What if faking the `HeroService` is hard?\nWhat if `HeroDetailService` makes its own server requests?", "translation": "如果你没有这么幸运怎么办?如果伪造 `HeroService` 很难怎么办?如果 `HeroDetailService` 自己发出服务器请求怎么办?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDOVERRIDECOMPONENTMETHODCANREPLACETHECOMPONENTSPROVIDERSWITHEASYTOMANAGETESTDOUBLESASSEENINTHEFOLLOWINGSETUPVARIATION:", "original": "The `TestBed.overrideComponent` method can replace the component's `providers` with easy-to-manage _test doubles_\nas seen in the following setup variation:", "translation": "`TestBed.overrideComponent` 方法可以将组件的 `providers` 替换为容易管理的**测试替身**,参见下面的变体准备代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOTICETHATTESTBEDCONFIGURETESTINGMODULENOLONGERPROVIDESAFAKEHEROSERVICEBECAUSEITSNOTNEEDED#SPYSTUB", "original": "Notice that `TestBed.configureTestingModule` no longer provides a (fake) `HeroService` because it's [not needed](#spy-stub).", "translation": "注意,`TestBed.configureTestingModule` 不再提供(伪造的)`HeroService`,因为[并不需要](#spy-stub)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####THEOVERRIDECOMPONENTMETHOD", "original": "#### The _overrideComponent_ method", "translation": "#### `overrideComponent` 方法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FOCUSONTHEOVERRIDECOMPONENTMETHOD", "original": "Focus on the `overrideComponent` method.", "translation": "注意这个 `overrideComponent` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITTAKESTWOARGUMENTS:THECOMPONENTTYPETOOVERRIDEHERODETAILCOMPONENTANDANOVERRIDEMETADATAOBJECTTHEOVERIDEMETADATAOBJECT#METADATAOVERRIDEOBJECTISAGENERICDEFINEDASFOLLOWS:", "original": "It takes two arguments: the component type to override (`HeroDetailComponent`) and an override metadata object.\nThe [overide metadata object](#metadata-override-object) is a generic defined as follows:", "translation": "它接受两个参数:要改写的组件类(`HeroDetailComponent`),以及用于改写的元数据对象:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AMETADATAOVERRIDEOBJECTCANEITHERADDANDREMOVEELEMENTSINMETADATAPROPERTIESORCOMPLETELYRESETTHOSEPROPERTIESTHISEXAMPLERESETSTHECOMPONENTSPROVIDERSMETADATA", "original": "A metadata override object can either add-and-remove elements in metadata properties or completely reset those properties.\nThis example resets the component's `providers` metadata.", "translation": "元数据重载对象可以添加和删除元数据属性的项目,也可以彻底重设这些属性。\n这个例子重新设置了组件的 `providers` 元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETYPEPARAMETERTISTHEKINDOFMETADATAYOUDPASSTOTHECOMPONENTDECORATOR:", "original": "The type parameter, `T`, is the kind of metadata you'd pass to the `@Component` decorator:", "translation": "这个类型参数,`T`,是你会传递给 `@Component` 装饰器的元数据的类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####PROVIDEASPYSTUBHERODETAILSERVICESPY", "original": "#### Provide a _spy stub_ (_HeroDetailServiceSpy_)", "translation": "#### 提供 ` 间谍桩 ` (`HeroDetailServiceSpy`)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISEXAMPLECOMPLETELYREPLACESTHECOMPONENTSPROVIDERSARRAYWITHANEWARRAYCONTAININGAHERODETAILSERVICESPY", "original": "This example completely replaces the component's `providers` array with a new array containing a `HeroDetailServiceSpy`.", "translation": "这个例子把组件的 `providers` 数组完全替换成了一个包含 `HeroDetailServiceSpy` 的新数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHERODETAILSERVICESPYISASTUBBEDVERSIONOFTHEREALHERODETAILSERVICETHATFAKESALLNECESSARYFEATURESOFTHATSERVICEITNEITHERINJECTSNORDELEGATESTOTHELOWERLEVELHEROSERVICESOTHERESNONEEDTOPROVIDEATESTDOUBLEFORTHAT", "original": "The `HeroDetailServiceSpy` is a stubbed version of the real `HeroDetailService`\nthat fakes all necessary features of that service.\nIt neither injects nor delegates to the lower level `HeroService`\nso there's no need to provide a test double for that.", "translation": "`HeroDetailServiceSpy` 是实际 `HeroDetailService` 服务的桩版本,它伪造了该服务的所有必要特性。\n但它既不需要注入也不会委托给低层的 `HeroService` 服务,因此不用为 `HeroService` 提供测试替身。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THERELATEDHERODETAILCOMPONENTTESTSWILLASSERTTHATMETHODSOFTHEHERODETAILSERVICEWERECALLEDBYSPYINGONTHESERVICEMETHODSACCORDINGLYTHESTUBIMPLEMENTSITSMETHODSASSPIES:", "original": "The related `HeroDetailComponent` tests will assert that methods of the `HeroDetailService`\nwere called by spying on the service methods.\nAccordingly, the stub implements its methods as spies:", "translation": "通过对该服务的方法进行刺探,`HeroDetailComponent` 的关联测试将会对 `HeroDetailService` 是否被调用过进行断言。\n因此,这个桩类会把它的方法实现为刺探方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####THEOVERRIDETESTS", "original": "#### The override tests", "translation": "#### 改写测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NOWTHETESTSCANCONTROLTHECOMPONENTSHERODIRECTLYBYMANIPULATINGTHESPYSTUBSTESTHEROANDCONFIRMTHATSERVICEMETHODSWERECALLED", "original": "Now the tests can control the component's hero directly by manipulating the spy-stub's `testHero`\nand confirm that service methods were called.", "translation": "现在,测试程序可以通过操控 stub 的 `testHero`,直接控制组件的英雄,并确保服务的方法被调用过。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####MOREOVERRIDES", "original": "#### More overrides", "translation": "#### 更多的改写", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDOVERRIDECOMPONENTMETHODCANBECALLEDMULTIPLETIMESFORTHESAMEORDIFFERENTCOMPONENTSTHETESTBEDOFFERSSIMILAROVERRIDEDIRECTIVEOVERRIDEMODULEANDOVERRIDEPIPEMETHODSFORDIGGINGINTOANDREPLACINGPARTSOFTHESEOTHERCLASSES", "original": "The `TestBed.overrideComponent` method can be called multiple times for the same or different components.\nThe `TestBed` offers similar `overrideDirective`, `overrideModule`, and `overridePipe` methods\nfor digging into and replacing parts of these other classes.", "translation": "`TestBed.overrideComponent` 方法可以在相同或不同的组件中被反复调用。\n`TestBed` 还提供了类似的 `overrideDirective`、`overrideModule` 和 `overridePipe` 方法,用来深入并重载这些其它类的部件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "EXPLORETHEOPTIONSANDCOMBINATIONSONYOUROWN", "original": "Explore the options and combinations on your own.", "translation": "自己探索这些选项和组合。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##ATTRIBUTEDIRECTIVETESTING", "original": "## Attribute Directive Testing", "translation": "## 属性型指令的测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANATTRIBUTEDIRECTIVEMODIFIESTHEBEHAVIOROFANELEMENTCOMPONENTORANOTHERDIRECTIVEITSNAMEREFLECTSTHEWAYTHEDIRECTIVEISAPPLIED:ASANATTRIBUTEONAHOSTELEMENT", "original": "An _attribute directive_ modifies the behavior of an element, component or another directive.\nIts name reflects the way the directive is applied: as an attribute on a host element.", "translation": "**属性指令**修改元素、组件和其它指令的行为。正如它们的名字所示,它们是作为宿主元素的属性来被使用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESAMPLEAPPLICATIONSHIGHLIGHTDIRECTIVESETSTHEBACKGROUNDCOLOROFANELEMENTBASEDONEITHERADATABOUNDCOLORORADEFAULTCOLORLIGHTGRAYITALSOSETSACUSTOMPROPERTYOFTHEELEMENTCUSTOMPROPERTYTOTRUEFORNOREASONOTHERTHANTOSHOWTHATITCAN", "original": "The sample application's `HighlightDirective` sets the background color of an element\nbased on either a data bound color or a default color (lightgray).\nIt also sets a custom property of the element (`customProperty`) to `true`\nfor no reason other than to show that it can.", "translation": "本例子应用的 `HighlightDirective` 使用数据绑定的颜色或者默认颜色来设置元素的背景色。\n它同时设置元素的 `customProperty` 属性为 `true`,这里仅仅是为了显示它能这么做而已,并无其它原因。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITSUSEDTHROUGHOUTTHEAPPLICATIONPERHAPSMOSTSIMPLYINTHEABOUTCOMPONENT:", "original": "It's used throughout the application, perhaps most simply in the `AboutComponent`:", "translation": "它的使用贯穿整个应用,也许最简单的使用在 `AboutComponent` 里:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TESTINGTHESPECIFICUSEOFTHEHIGHLIGHTDIRECTIVEWITHINTHEABOUTCOMPONENTREQUIRESONLYTHETECHNIQUESEXPLOREDABOVEINPARTICULARTHESHALLOWTEST#NESTEDCOMPONENTTESTSAPPROACH", "original": "Testing the specific use of the `HighlightDirective` within the `AboutComponent` requires only the\ntechniques explored above (in particular the [\"Shallow test\"](#nested-component-tests) approach).", "translation": "要想在 `AboutComponent` 中测试 `HighlightDirective` 的具体用法,只要使用在[“浅层测试”](#nested-component-tests)部分用过的技术即可。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HOWEVERTESTINGASINGLEUSECASEISUNLIKELYTOEXPLORETHEFULLRANGEOFADIRECTIVESCAPABILITIESFINDINGANDTESTINGALLCOMPONENTSTHATUSETHEDIRECTIVEISTEDIOUSBRITTLEANDALMOSTASUNLIKELYTOAFFORDFULLCOVERAGE", "original": "However, testing a single use case is unlikely to explore the full range of a directive's capabilities.\nFinding and testing all components that use the directive is tedious, brittle, and almost as unlikely to afford full coverage.", "translation": "但是,测试单一的用例一般无法探索该指令的全部能力。\n查找和测试所有使用该指令的组件非常繁琐和脆弱,并且通常无法覆盖所有组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CLASSONLYTESTSMIGHTBEHELPFULBUTATTRIBUTEDIRECTIVESLIKETHISONETENDTOMANIPULATETHEDOMISOLATEDUNITTESTSDONTTOUCHTHEDOMANDTHEREFOREDONOTINSPIRECONFIDENCEINTHEDIRECTIVESEFFICACY", "original": "_Class-only tests_ might be helpful,\nbut attribute directives like this one tend to manipulate the DOM.\nIsolated unit tests don't touch the DOM and, therefore,\ndo not inspire confidence in the directive's efficacy.", "translation": "*只针对类的测试*可能很有用,\n但是像这个一样的属性型指令肯定要操纵 DOM。\n隔离出的单元测试不能接触 DOM,因此也就没办法证明该指令的有效性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ABETTERSOLUTIONISTOCREATEANARTIFICIALTESTCOMPONENTTHATDEMONSTRATESALLWAYSTOAPPLYTHEDIRECTIVE", "original": "A better solution is to create an artificial test component that demonstrates all ways to apply the directive.", "translation": "更好的方法是创建一个能展示该指令所有用法的人造测试组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEINPUTCASEBINDSTHEHIGHLIGHTDIRECTIVETOTHENAMEOFACOLORVALUEINTHEINPUTBOXTHEINITIALVALUEISTHEWORDCYANWHICHSHOULDBETHEBACKGROUNDCOLOROFTHEINPUTBOX", "original": "The `<input>` case binds the `HighlightDirective` to the name of a color value in the input box.\nThe initial value is the word \"cyan\" which should be the background color of the input box.", "translation": "`<input>` 用例将 `HighlightDirective` 绑定到输入框里输入的颜色名字。\n初始只是单词“cyan”,所以输入框的背景色应该是 cyan。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARESOMETESTSOFTHISCOMPONENT:", "original": "Here are some tests of this component:", "translation": "下面是一些该组件的测试程序:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AFEWTECHNIQUESARENOTEWORTHY:", "original": "A few techniques are noteworthy:", "translation": "一些技巧值得注意:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEBYDIRECTIVEPREDICATEISAGREATWAYTOGETTHEELEMENTSTHATHAVETHISDIRECTIVEWHENTHEIRELEMENTTYPESAREUNKNOWN", "original": "* The `By.directive` predicate is a great way to get the elements that have this directive _when their element types are unknown_.", "translation": "当**已知元素类型**时,`By.directive` 是一种获取拥有这个指令的元素的好方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEAHREFHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBCSS:NOT:NOTPSEUDOCLASSAINBYCSSH2:NOTHIGHLIGHTHELPSFINDH2ELEMENTSTHATDONOTHAVETHEDIRECTIVEBYCSS:NOTHIGHLIGHTFINDSANYELEMENTTHATDOESNOTHAVETHEDIRECTIVE", "original": "* The <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/:not\">`:not` pseudo-class</a>\nin `By.css('h2:not([highlight])')` helps find `<h2>` elements that _do not_ have the directive.\n`By.css('*:not([highlight])')` finds _any_ element that does not have the directive.", "translation": "`By.css('h2:not([highlight])')` 里的<a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/:not\" target=\"_blank\">`:not` 伪类(pseudo-class)</a>帮助查找**不带**该指令的 `<h2>` 元素。`By.css('*:not([highlight])')` 查找**所有**不带该指令的元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DEBUGELEMENTSTYLESAFFORDSACCESSTOELEMENTSTYLESEVENINTHEABSENCEOFAREALBROWSERTHANKSTOTHEDEBUGELEMENTABSTRACTIONBUTFEELFREETOEXPLOITTHENATIVEELEMENTWHENTHATSEEMSEASIERORMORECLEARTHANTHEABSTRACTION", "original": "* `DebugElement.styles` affords access to element styles even in the absence of a real browser, thanks to the `DebugElement` abstraction.\nBut feel free to exploit the `nativeElement` when that seems easier or more clear than the abstraction.", "translation": "`DebugElement.styles` 甚至不用借助真实的浏览器也可以访问元素的样式,感谢 `DebugElement` 提供的这层抽象!\n 但是如果直接使用 `nativeElement` 会比这层抽象更简单、更清晰,也可以放心大胆的使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANGULARADDSADIRECTIVETOTHEINJECTOROFTHEELEMENTTOWHICHITISAPPLIEDTHETESTFORTHEDEFAULTCOLORUSESTHEINJECTOROFTHESECONDH2TOGETITSHIGHLIGHTDIRECTIVEINSTANCEANDITSDEFAULTCOLOR", "original": "* Angular adds a directive to the injector of the element to which it is applied.\nThe test for the default color uses the injector of the second `<h2>` to get its `HighlightDirective` instance\nand its `defaultColor`.", "translation": "Angular 将指令添加到它的元素的注入器中。默认颜色的测试程序使用第二个 `<h2>` 的注入器来获取它的 `HighlightDirective` 实例以及它的 `defaultColor`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DEBUGELEMENTPROPERTIESAFFORDSACCESSTOTHEARTIFICIALCUSTOMPROPERTYTHATISSETBYTHEDIRECTIVE", "original": "* `DebugElement.properties` affords access to the artificial custom property that is set by the directive.", "translation": "`DebugElement.properties` 让你可以访问由指令设置的自定义属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##PIPETESTING", "original": "## Pipe Testing", "translation": "## 管道测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "PIPESAREEASYTOTESTWITHOUTTHEANGULARTESTINGUTILITIES", "original": "Pipes are easy to test without the Angular testing utilities.", "translation": "管道很容易测试,无需 Angular 测试工具。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "APIPECLASSHASONEMETHODTRANSFORMTHATMANIPULATESTHEINPUTVALUEINTOATRANSFORMEDOUTPUTVALUETHETRANSFORMIMPLEMENTATIONRARELYINTERACTSWITHTHEDOMMOSTPIPESHAVENODEPENDENCEONANGULAROTHERTHANTHEPIPEMETADATAANDANINTERFACE", "original": "A pipe class has one method, `transform`, that manipulates the input\nvalue into a transformed output value.\nThe `transform` implementation rarely interacts with the DOM.\nMost pipes have no dependence on Angular other than the `@Pipe`\nmetadata and an interface.", "translation": "管道类有一个方法,`transform`,用来转换输入值到输出值。\n`transform` 的实现很少与 DOM 交互。\n除了 `@Pipe` 元数据和一个接口外,大部分管道不依赖 Angular。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CONSIDERATITLECASEPIPETHATCAPITALIZESTHEFIRSTLETTEROFEACHWORDHERESANAIVEIMPLEMENTATIONWITHAREGULAREXPRESSION", "original": "Consider a `TitleCasePipe` that capitalizes the first letter of each word.\nHere's a naive implementation with a regular expression.", "translation": "假设 `TitleCasePipe` 将每个单词的第一个字母变成大写。\n下面是使用正则表达式实现的简单代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANYTHINGTHATUSESAREGULAREXPRESSIONISWORTHTESTINGTHOROUGHLYUSESIMPLEJASMINETOEXPLORETHEEXPECTEDCASESANDTHEEDGECASES", "original": "Anything that uses a regular expression is worth testing thoroughly.\nUse simple Jasmine to explore the expected cases and the edge cases.", "translation": "任何使用正则表达式的类都值得彻底的进行测试。\n使用 Jasmine 来探索预期的用例和极端的用例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####WRITEDOMTESTSTOO", "original": "#### Write DOM tests too", "translation": "#### 也能编写 DOM 测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THESEARETESTSOFTHEPIPEINISOLATIONTHEYCANTTELLIFTHETITLECASEPIPEISWORKINGPROPERLYASAPPLIEDINTHEAPPLICATIONCOMPONENTS", "original": "These are tests of the pipe _in isolation_.\nThey can't tell if the `TitleCasePipe` is working properly as applied in the application components.", "translation": "有些管道的测试程序是**孤立的**。\n它们不能验证 `TitleCasePipe` 是否在应用到组件上时是否工作正常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CONSIDERADDINGCOMPONENTTESTSSUCHASTHISONE:", "original": "Consider adding component tests such as this one:", "translation": "考虑像这样添加组件测试程序:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##TESTDEBUGGING", "original": "## Test debugging", "translation": "## 测试程序的调试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DEBUGSPECSINTHEBROWSERINTHESAMEWAYTHATYOUDEBUGANAPPLICATION", "original": "Debug specs in the browser in the same way that you debug an application.", "translation": "在浏览器中,像调试应用一样调试测试程序 spec。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1REVEALTHEKARMABROWSERWINDOWHIDDENEARLIER", "original": "1. Reveal the karma browser window (hidden earlier).", "translation": "显示 `Karma` 的浏览器窗口(之前被隐藏了)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1CLICKTHEDEBUGBUTTONITOPENSANEWBROWSERTABANDRERUNSTHETESTS", "original": "1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests.", "translation": "点击“DEBUG”按钮;它打开一页新浏览器标签并重新开始运行测试程序", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1OPENTHEBROWSERSDEVELOPERTOOLSCTRLSHIFTIONWINDOWSCOMMANDOPTIONIINOSX", "original": "1. Open the browser's “Developer Tools” (`Ctrl-Shift-I` on windows; `Command-Option-I` in OSX).", "translation": "打开浏览器的“Developer Tools”(Windows 上的 Ctrl-Shift-I 或者 OSX 上的 `Command-Option-I)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1PICKTHESOURCESSECTION", "original": "1. Pick the \"sources\" section.", "translation": "选择“sources”页", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1OPENTHE1STSPECTSTESTFILECONTROLCOMMANDPTHENSTARTTYPINGTHENAMEOFTHEFILE", "original": "1. Open the `1st.spec.ts` test file (Control/Command-P, then start typing the name of the file).", "translation": "打开 `1st.spec.ts` 测试文件(Control/Command-P, 然后输入文件名字)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1SETABREAKPOINTINTHETEST", "original": "1. Set a breakpoint in the test.", "translation": "在测试程序中设置断点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "1REFRESHTHEBROWSERANDITSTOPSATTHEBREAKPOINT", "original": "1. Refresh the browser, and it stops at the breakpoint.", "translation": "刷新浏览器...然后它就会停在断点上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##TESTINGUTILITYAPIS", "original": "## Testing Utility APIs", "translation": "## 测试工具 API", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISSECTIONTAKESINVENTORYOFTHEMOSTUSEFULANGULARTESTINGFEATURESANDSUMMARIZESWHATTHEYDO", "original": "This section takes inventory of the most useful Angular testing features and summarizes what they do.", "translation": "本节将最有用的 Angular 测试功能提取出来,并总结了它们的作用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEANGULARTESTINGUTILITIESINCLUDETHETESTBEDTHECOMPONENTFIXTUREANDAHANDFULOFFUNCTIONSTHATCONTROLTHETESTENVIRONMENTTHETESTBED#TESTBEDAPISUMMARYANDCOMPONENTFIXTURE#COMPONENTFIXTUREAPISUMMARYCLASSESARECOVEREDSEPARATELY", "original": "The Angular testing utilities include the `TestBed`, the `ComponentFixture`, and a handful of functions that control the test environment.\nThe [_TestBed_](#testbed-api-summary) and [_ComponentFixture_](#component-fixture-api-summary) classes are covered separately.", "translation": "Angular 的测试工具集包括 `TestBed`、`ComponentFixture` 和一些用来控制测试环境的便捷函数。\n[`TestBed`](#testbed-api-summary) 和 [`ComponentFixture`](#component-fixture-api-summary) 部分单独讲过它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HERESASUMMARYOFTHESTANDALONEFUNCTIONSINORDEROFLIKELYUTILITY:", "original": "Here's a summary of the stand-alone functions, in order of likely utility:", "translation": "下面是一些独立函数的总结,以使用频率排序:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FUNCTION", "original": "Function", "translation": "函数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RUNSTHEBODYOFATESTITORSETUPBEFOREEACHFUNCTIONWITHINASPECIALASYNCTESTZONESEEDISCUSSIONABOVE#ASYNC", "original": "Runs the body of a test (`it`) or setup (`beforeEach`) function within a special _async test zone_.\n See [discussion above](#async).", "translation": "在一个特殊的* async 测试区域*中运行测试(`it`)的函数体或准备函数(`beforeEach`)。\n 参见[前面的讨论](#async)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RUNSTHEBODYOFATESTITWITHINASPECIALFAKEASYNCTESTZONEENABLINGALINEARCONTROLFLOWCODINGSTYLESEEDISCUSSIONABOVE#FAKEASYNC", "original": "Runs the body of a test (`it`) within a special _fakeAsync test zone_, enabling\n a linear control flow coding style. See [discussion above](#fake-async).", "translation": "在一个特殊的* fakeAsync 测试区域*中运行测试(`it`)的函数体,以便启用线性风格的控制流。\n 参见[前面的讨论](#fake-async)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SIMULATESTHEPASSAGEOFTIMEANDTHECOMPLETIONOFPENDINGASYNCHRONOUSACTIVITIESBYFLUSHINGBOTHTIMERANDMICROTASKQUEUESWITHINTHEFAKEASYNCTESTZONE", "original": "Simulates the passage of time and the completion of pending asynchronous activities\n by flushing both _timer_ and _micro-task_ queues within the _fakeAsync test zone_.", "translation": "通过在* fakeAsync 测试区域*中刷新定时器和微任务(micro-task)队列来仿真时间的流逝以及异步活动的完成。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECURIOUSDEDICATEDREADERMIGHTENJOYTHISLENGTHYBLOGPOSTTASKSMICROTASKSQUEUESANDSCHEDULESHTTPS:JAKEARCHIBALDCOM2015TASKSMICROTASKSQUEUESANDSCHEDULES", "original": "The curious, dedicated reader might enjoy this lengthy blog post,\n [\"_Tasks, microtasks, queues and schedules_\"](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/).", "translation": "好奇和执着的读者可能会喜欢这篇长博客:\n \"<a href=\"https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/\"\n target=\"_blank\">_Tasks, microtasks, queues and schedules_</a>\".", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ACCEPTSANOPTIONALARGUMENTTHATMOVESTHEVIRTUALCLOCKFORWARDBYTHESPECIFIEDNUMBEROFMILLISECONDSCLEARINGASYNCHRONOUSACTIVITIESSCHEDULEDWITHINTHATTIMEFRAMESEEDISCUSSIONABOVE#TICK", "original": "Accepts an optional argument that moves the virtual clock forward\n by the specified number of milliseconds,\n clearing asynchronous activities scheduled within that timeframe.\n See [discussion above](#tick).", "translation": "接受一个可选参数,它可以把虚拟时钟往前推进特定的微秒数。\n 清除调度到那个时间帧中的异步活动。\n 参见[前面的讨论](#tick)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INJECTSONEORMORESERVICESFROMTHECURRENTTESTBEDINJECTORINTOATESTFUNCTIONITCANNOTINJECTASERVICEPROVIDEDBYTHECOMPONENTITSELFSEEDISCUSSIONOFTHEDEBUGELEMENTINJECTOR#GETINJECTEDSERVICES", "original": "Injects one or more services from the current `TestBed` injector into a test function.\n It cannot inject a service provided by the component itself.\n See discussion of the [debugElement.injector](#get-injected-services).", "translation": "从当前的 `TestBed` 注入器中把一个或多个服务注入到一个测试函数中。\n 它不能用于注入组件自身提供的服务。\n 参见 [`debugElement.injector`](#get-injected-services) 部分的讨论。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENAFAKEASYNCTESTENDSWITHPENDINGTIMEREVENTTASKSQUEUEDSETTIMEOUTANDSETINTERVALCALLBACKSTHETESTFAILSWITHACLEARERRORMESSAGE", "original": "When a `fakeAsync` test ends with pending timer event _tasks_ (queued `setTimeOut` and `setInterval` callbacks),\n the test fails with a clear error message.", "translation": "当 `fakeAsync` 测试程序以正在运行的计时器事件**任务**(排队中的 `setTimeOut` 和 `setInterval` 的回调)结束时,\n 测试会失败,并显示一条明确的错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INGENERALATESTSHOULDENDWITHNOQUEUEDTASKSWHENPENDINGTIMERTASKSAREEXPECTEDCALLDISCARDPERIODICTASKSTOFLUSHTHETASKQUEUEANDAVOIDTHEERROR", "original": "In general, a test should end with no queued tasks.\n When pending timer tasks are expected, call `discardPeriodicTasks` to flush the _task_ queue\n and avoid the error.", "translation": "一般来讲,测试程序应该以无排队任务结束。\n 当待执行计时器任务存在时,调用 `discardPeriodicTasks` 来触发**任务**队列,防止该错误发生。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENAFAKEASYNCTESTENDSWITHPENDINGMICROTASKSSUCHASUNRESOLVEDPROMISESTHETESTFAILSWITHACLEARERRORMESSAGE", "original": "When a `fakeAsync` test ends with pending _micro-tasks_ such as unresolved promises,\n the test fails with a clear error message.", "translation": "当 `fakeAsync` 测试程序以待执行**微任务**(比如未解析的承诺)结束时,测试会失败并显示明确的错误信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INGENERALATESTSHOULDWAITFORMICROTASKSTOFINISHWHENPENDINGMICROTASKSAREEXPECTEDCALLFLUSHMICROTASKSTOFLUSHTHEMICROTASKQUEUEANDAVOIDTHEERROR", "original": "In general, a test should wait for micro-tasks to finish.\n When pending microtasks are expected, call `flushMicrotasks` to flush the _micro-task_ queue\n and avoid the error.", "translation": "一般来说,测试应该等待微任务结束。\n 当待执行微任务存在时,调用 `flushMicrotasks` 来触发**微任务**队列,防止该错误发生。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "APROVIDERTOKENFORASERVICETHATTURNSONAUTOMATICCHANGEDETECTION#AUTOMATICCHANGEDETECTION", "original": "A provider token for a service that turns on [automatic change detection](#automatic-change-detection).", "translation": "一个服务提供商令牌,用于开启[自动变更检测](#automatic-change-detection)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "GETSTHECURRENTINSTANCEOFTHETESTBEDUSUALLYUNNECESSARYBECAUSETHESTATICCLASSMETHODSOFTHETESTBEDCLASSARETYPICALLYSUFFICIENTTHETESTBEDINSTANCEEXPOSESAFEWRARELYUSEDMEMBERSTHATARENOTAVAILABLEASSTATICMETHODS", "original": "Gets the current instance of the `TestBed`.\n Usually unnecessary because the static class methods of the `TestBed` class are typically sufficient.\n The `TestBed` instance exposes a few rarely used members that are not available as\n static methods.", "translation": "获取当前 `TestBed` 实例。\n 通常用不上,因为 `TestBed` 的静态类方法已经够用。\n `TestBed` 实例有一些很少需要用到的方法,它们没有对应的静态方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####TESTBEDCLASSSUMMARY", "original": "#### _TestBed_ class summary", "translation": "#### `TestBed` 类小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDCLASSISONEOFTHEPRINCIPALANGULARTESTINGUTILITIESITSAPIISQUITELARGEANDCANBEOVERWHELMINGUNTILYOUVEEXPLOREDITALITTLEATATIMEREADTHEEARLYPARTOFTHISGUIDEFIRSTTOGETTHEBASICSBEFORETRYINGTOABSORBTHEFULLAPI", "original": "The `TestBed` class is one of the principal Angular testing utilities.\nIts API is quite large and can be overwhelming until you've explored it,\na little at a time. Read the early part of this guide first\nto get the basics before trying to absorb the full API.", "translation": "`TestBed` 类是 Angular 测试工具的主要类之一。它的 API 很庞大,可能有点过于复杂,直到你一点一点的探索它们。\n阅读本章前面的部分,了解了基本的知识以后,再试着了解完整 API。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEMODULEDEFINITIONPASSEDTOCONFIGURETESTINGMODULEISASUBSETOFTHENGMODULEMETADATAPROPERTIES", "original": "The module definition passed to `configureTestingModule`\nis a subset of the `@NgModule` metadata properties.", "translation": "传递给 `configureTestingModule` 的模块定义是 `@NgModule` 元数据属性的子集。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "EACHOVERRIDEMETHODTAKESAMETADATAOVERRIDETWHERETISTHEKINDOFMETADATAAPPROPRIATETOTHEMETHODTHATISTHEPARAMETEROFANNGMODULECOMPONENTDIRECTIVEORPIPE", "original": "Each override method takes a `MetadataOverride<T>` where `T` is the kind of metadata\nappropriate to the method, that is, the parameter of an `@NgModule`,\n`@Component`, `@Directive`, or `@Pipe`.", "translation": "每一个重载方法接受一个 `MetadataOverride<T>`,这里 `T` 是适合这个方法的元数据类型,也就是 `@NgModule`、`@Component`、`@Directive` 或者 `@Pipe` 的参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDAPICONSISTSOFSTATICCLASSMETHODSTHATEITHERUPDATEORREFERENCEAGLOBALINSTANCEOFTHETESTBED", "original": "The `TestBed` API consists of static class methods that either update or reference a _global_ instance of the`TestBed`.", "translation": "`TestBed` 的 API 包含了一系列静态类方法,它们更新或者引用**全局**的 `TestBed` 实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INTERNALLYALLSTATICMETHODSCOVERMETHODSOFTHECURRENTRUNTIMETESTBEDINSTANCEWHICHISALSORETURNEDBYTHEGETTESTBEDFUNCTION", "original": "Internally, all static methods cover methods of the current runtime `TestBed` instance,\nwhich is also returned by the `getTestBed()` function.", "translation": "在内部,所有静态方法在 `getTestBed()` 函数返回的当前运行时间的 `TestBed` 实例上都有对应的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CALLTESTBEDMETHODSWITHINABEFOREEACHTOENSUREAFRESHSTARTBEFOREEACHINDIVIDUALTEST", "original": "Call `TestBed` methods _within_ a `beforeEach()` to ensure a fresh start before each individual test.", "translation": "在 `BeforeEach()` 内调用 `TestBed` 方法,这样确保在运行每个单独测试时,都有崭新的开始。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARETHEMOSTIMPORTANTSTATICMETHODSINORDEROFLIKELYUTILITY", "original": "Here are the most important static methods, in order of likely utility.", "translation": "这里列出了最重要的静态方法,以使用频率排序:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "METHODS", "original": "Methods", "translation": "方法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTINGSHIMSKARMATESTSHIMBROWSERTESTSHIMESTABLISHTHEINITIALTESTENVIRONMENTGUIDETESTINGANDADEFAULTTESTINGMODULETHEDEFAULTTESTINGMODULEISCONFIGUREDWITHBASICDECLARATIVESANDSOMEANGULARSERVICESUBSTITUTESTHATEVERYTESTERNEEDS", "original": "The testing shims (`karma-test-shim`, `browser-test-shim`)\n establish the [initial test environment](guide/testing) and a default testing module.\n The default testing module is configured with basic declaratives and some Angular service substitutes that every tester needs.", "translation": "测试垫片(`karma-test-shim`, `browser-test-shim`)创建了[初始测试环境](guide/testing)和默认测试模块。\n 默认测试模块是使用基本声明和一些 Angular 服务替代品,它们是所有测试程序都需要的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CALLCONFIGURETESTINGMODULETOREFINETHETESTINGMODULECONFIGURATIONFORAPARTICULARSETOFTESTSBYADDINGANDREMOVINGIMPORTSDECLARATIONSOFCOMPONENTSDIRECTIVESANDPIPESANDPROVIDERS", "original": "Call `configureTestingModule` to refine the testing module configuration for a particular set of tests\n by adding and removing imports, declarations (of components, directives, and pipes), and providers.", "translation": "调用 `configureTestingModule` 来为一套特定的测试定义测试模块配置,添加和删除导入、(组件、指令和管道的)声明和服务提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "COMPILETHETESTINGMODULEASYNCHRONOUSLYAFTERYOUVEFINISHEDCONFIGURINGITYOUMUSTCALLTHISMETHODIFANYOFTHETESTINGMODULECOMPONENTSHAVEATEMPLATEURLORSTYLEURLSBECAUSEFETCHINGCOMPONENTTEMPLATEANDSTYLEFILESISNECESSARILYASYNCHRONOUSSEEABOVE#COMPILECOMPONENTS", "original": "Compile the testing module asynchronously after you've finished configuring it.\n You **must** call this method if _any_ of the testing module components have a `templateUrl`\n or `styleUrls` because fetching component template and style files is necessarily asynchronous.\n See [above](#compile-components).", "translation": "在配置好测试模块之后,异步编译它。\n 如果测试模块中的*任何一个*组件具有 `templateUrl` 或 `styleUrls`,那么你**必须**调用这个方法,因为获取组件的模板或样式文件必须是异步的。\n 参见[前面的讨论](#compile-components)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AFTERCALLINGCOMPILECOMPONENTSTHETESTBEDCONFIGURATIONISFROZENFORTHEDURATIONOFTHECURRENTSPEC", "original": "After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec.", "translation": "调用完 `compileComponents` 之后,`TestBed` 的配置就会在当前测试期间被冻结。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CREATEANINSTANCEOFACOMPONENTOFTYPETBASEDONTHECURRENTTESTBEDCONFIGURATIONAFTERCALLINGCOMPILECOMPONENTTHETESTBEDCONFIGURATIONISFROZENFORTHEDURATIONOFTHECURRENTSPEC", "original": "Create an instance of a component of type `T` based on the current `TestBed` configuration.\n After calling `compileComponent`, the `TestBed` configuration is frozen for the duration of the current spec.", "translation": "基于当前 `TestBed` 的配置创建一个类型为 T 的组件实例。\n 一旦调用,`TestBed` 的配置就会在当前测试期间被冻结。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "REPLACEMETADATAFORTHEGIVENNGMODULERECALLTHATMODULESCANIMPORTOTHERMODULESTHEOVERRIDEMODULEMETHODCANREACHDEEPLYINTOTHECURRENTTESTINGMODULETOMODIFYONEOFTHESEINNERMODULES", "original": "Replace metadata for the given `NgModule`. Recall that modules can import other modules.\n The `overrideModule` method can reach deeply into the current testing module to\n modify one of these inner modules.", "translation": "替换指定的 `NgModule` 的元数据。回想一下,模块可以导入其他模块。\n `overrideModule` 方法可以深入到当前测试模块深处,修改其中一个内部模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "REPLACEMETADATAFORTHEGIVENCOMPONENTCLASSWHICHCOULDBENESTEDDEEPLYWITHINANINNERMODULE", "original": "Replace metadata for the given component class, which could be nested deeply\n within an inner module.", "translation": "替换指定组件类的元数据,该组件类可能嵌套在一个很深的内部模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "REPLACEMETADATAFORTHEGIVENDIRECTIVECLASSWHICHCOULDBENESTEDDEEPLYWITHINANINNERMODULE", "original": "Replace metadata for the given directive class, which could be nested deeply\n within an inner module.", "translation": "替换指定指令类的元数据,该指令可能嵌套在一个很深的内部模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "REPLACEMETADATAFORTHEGIVENPIPECLASSWHICHCOULDBENESTEDDEEPLYWITHINANINNERMODULE", "original": "Replace metadata for the given pipe class, which could be nested deeply\n within an inner module.", "translation": "替换指定管道类的元数据,该管道可能嵌套在一个很深的内部模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RETRIEVEASERVICEFROMTHECURRENTTESTBEDINJECTOR", "original": "Retrieve a service from the current `TestBed` injector.", "translation": "从当前 `TestBed` 注入器获取一个服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEINJECTFUNCTIONISOFTENADEQUATEFORTHISPURPOSEBUTINJECTTHROWSANERRORIFITCANTPROVIDETHESERVICE", "original": "The `inject` function is often adequate for this purpose.\n But `inject` throws an error if it can't provide the service.", "translation": "`inject` 函数通常都能胜任这项工作,但是如果它没法提供该服务时就会抛出一个异常。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHATIFTHESERVICEISOPTIONAL", "original": "What if the service is optional?", "translation": "如果该服务是可选的呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDGETMETHODTAKESANOPTIONALSECONDPARAMETERTHEOBJECTTORETURNIFANGULARCANTFINDTHEPROVIDERNULLINTHISEXAMPLE:", "original": "The `TestBed.get()` method takes an optional second parameter,\n the object to return if Angular can't find the provider\n (`null` in this example):", "translation": "`TestBed.get()` 方法可以接受可选的第二参数,当 Angular 找不到指定的服务提供商时,就会返回该对象(下面这个例子中是 `null` ):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AFTERCALLINGGETTHETESTBEDCONFIGURATIONISFROZENFORTHEDURATIONOFTHECURRENTSPEC", "original": "After calling `get`, the `TestBed` configuration is frozen for the duration of the current spec.", "translation": "一旦调用,`TestBed` 的配置就会在当前测试期间被冻结。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "INITIALIZETHETESTINGENVIRONMENTFORTHEENTIRETESTRUN", "original": "Initialize the testing environment for the entire test run.", "translation": "为整套测试的运行初始化测试环境。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTINGSHIMSKARMATESTSHIMBROWSERTESTSHIMCALLITFORYOUSOTHEREISRARELYAREASONFORYOUTOCALLITYOURSELF", "original": "The testing shims (`karma-test-shim`, `browser-test-shim`) call it for you\n so there is rarely a reason for you to call it yourself.", "translation": "测试垫片(`karma-test-shim`, `browser-test-shim`)会为你调用它,所以你很少需要自己调用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUMAYCALLTHISMETHODEXACTLYONCEIFYOUMUSTCHANGETHISDEFAULTINTHEMIDDLEOFYOURTESTRUNCALLRESETTESTENVIRONMENTFIRST", "original": "You may call this method _exactly once_. If you must change\n this default in the middle of your test run, call `resetTestEnvironment` first.", "translation": "这个方法只能被调用**一次**。如果确实需要在测试程序运行期间改变这个默认设置,那么先调用 `resetTestEnvironment`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SPECIFYTHEANGULARCOMPILERFACTORYAPLATFORMREFANDADEFAULTANGULARTESTINGMODULEALTERNATIVESFORNONBROWSERPLATFORMSAREAVAILABLEINTHEGENERALFORMANGULARPLATFORMPLATFORMNAMETESTINGPLATFORMNAME", "original": "Specify the Angular compiler factory, a `PlatformRef`, and a default Angular testing module.\n Alternatives for non-browser platforms are available in the general form\n `@angular/platform-<platform_name>/testing/<platform_name>`.", "translation": "指定 Angular 编译器工厂,`PlatformRef`,和默认 Angular 测试模块。\n 以 `@angular/platform-<platform_name>/testing/<platform_name>` 的形式提供非浏览器平台的替代品。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RESETTHEINITIALTESTENVIRONMENTINCLUDINGTHEDEFAULTTESTINGMODULE", "original": "Reset the initial test environment, including the default testing module.", "translation": "重设初始测试环境,包括默认测试模块在内。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "AFEWOFTHETESTBEDINSTANCEMETHODSARENOTCOVEREDBYSTATICTESTBEDCLASSMETHODSTHESEARERARELYNEEDED", "original": "A few of the `TestBed` instance methods are not covered by static `TestBed` _class_ methods.\nThese are rarely needed.", "translation": "少数 `TestBed` 实例方法没有对应的静态方法。它们很少被使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####THECOMPONENTFIXTURE", "original": "#### The _ComponentFixture_", "translation": "#### `ComponentFixture` 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THETESTBEDCREATECOMPONENTTCREATESANINSTANCEOFTHECOMPONENTTANDRETURNSASTRONGLYTYPEDCOMPONENTFIXTUREFORTHATCOMPONENT", "original": "The `TestBed.createComponent<T>`\ncreates an instance of the component `T`\nand returns a strongly typed `ComponentFixture` for that component.", "translation": "`TestBed.createComponent<T>` 会创建一个组件 `T` 的实例,并为该组件返回一个强类型的 `ComponentFixture`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPONENTFIXTUREPROPERTIESANDMETHODSPROVIDEACCESSTOTHECOMPONENTITSDOMREPRESENTATIONANDASPECTSOFITSANGULARENVIRONMENT", "original": "The `ComponentFixture` properties and methods provide access to the component,\nits DOM representation, and aspects of its Angular environment.", "translation": "`ComponentFixture` 的属性和方法提供了对组件、它的 DOM 和它的 Angular 环境方面的访问。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####COMPONENTFIXTUREPROPERTIES", "original": "#### _ComponentFixture_ properties", "translation": "#### `ComponentFixture` 的属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARETHEMOSTIMPORTANTPROPERTIESFORTESTERSINORDEROFLIKELYUTILITY", "original": "Here are the most important properties for testers, in order of likely utility.", "translation": "下面是对测试最重要的属性,以使用频率排序:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "PROPERTIES", "original": "Properties", "translation": "属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEINSTANCEOFTHECOMPONENTCLASSCREATEDBYTESTBEDCREATECOMPONENT", "original": "The instance of the component class created by `TestBed.createComponent`.", "translation": "被 `TestBed.createComponent` 创建的组件类实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDEBUGELEMENTASSOCIATEDWITHTHEROOTELEMENTOFTHECOMPONENT", "original": "The `DebugElement` associated with the root element of the component.", "translation": "与组件根元素关联的 `DebugElement`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDEBUGELEMENTPROVIDESINSIGHTINTOTHECOMPONENTANDITSDOMELEMENTDURINGTESTANDDEBUGGINGITSACRITICALPROPERTYFORTESTERSTHEMOSTINTERESTINGMEMBERSARECOVEREDBELOW#DEBUGELEMENTDETAILS", "original": "The `debugElement` provides insight into the component and its DOM element during test and debugging.\n It's a critical property for testers. The most interesting members are covered [below](#debug-element-details).", "translation": "`debugElement` 提供了在测试和调试期间深入探查组件及其 DOM 元素的功能。\n 它对于测试者是一个极其重要的属性。它的大多数主要成员在[后面](#debug-element-details)都有讲解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THENATIVEDOMELEMENTATTHEROOTOFTHECOMPONENT", "original": "The native DOM element at the root of the component.", "translation": "组件的原生根 DOM 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECHANGEDETECTORREFFORTHECOMPONENT", "original": "The `ChangeDetectorRef` for the component.", "translation": "组件的 `ChangeDetectorRef`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECHANGEDETECTORREFISMOSTVALUABLEWHENTESTINGACOMPONENTTHATHASTHECHANGEDETECTIONSTRATEGYONPUSHMETHODORTHECOMPONENTSCHANGEDETECTIONISUNDERYOURPROGRAMMATICCONTROL", "original": "The `ChangeDetectorRef` is most valuable when testing a\n component that has the `ChangeDetectionStrategy.OnPush` method\n or the component's change detection is under your programmatic control.", "translation": "在测试一个拥有 `ChangeDetectionStrategy.OnPush` 的组件,或者在组件的变化测试在你的程序控制下时,`ChangeDetectorRef` 是最重要的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####COMPONENTFIXTUREMETHODS", "original": "#### _ComponentFixture_ methods", "translation": "#### `ComponentFixture` 的方法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEFIXTUREMETHODSCAUSEANGULARTOPERFORMCERTAINTASKSONTHECOMPONENTTREECALLTHESEMETHODTOTRIGGERANGULARBEHAVIORINRESPONSETOSIMULATEDUSERACTION", "original": "The _fixture_ methods cause Angular to perform certain tasks on the component tree.\nCall these method to trigger Angular behavior in response to simulated user action.", "translation": "**fixture** 方法使 Angular 对组件树执行某些任务。\n在触发 Angular 行为来模拟的用户行为时,调用这些方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARETHEMOSTUSEFULMETHODSFORTESTERS", "original": "Here are the most useful methods for testers.", "translation": "下面是对测试最有用的方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "METHODS", "original": "Methods", "translation": "方法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TRIGGERACHANGEDETECTIONCYCLEFORTHECOMPONENT", "original": "Trigger a change detection cycle for the component.", "translation": "为组件触发一轮变化检查。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CALLITTOINITIALIZETHECOMPONENTITCALLSNGONINITANDAFTERYOURTESTCODECHANGETHECOMPONENTSDATABOUNDPROPERTYVALUESANGULARCANTSEETHATYOUVECHANGEDPERSONCOMPONENTNAMEANDWONTUPDATETHENAMEBINDINGUNTILYOUCALLDETECTCHANGES", "original": "Call it to initialize the component (it calls `ngOnInit`) and after your\n test code, change the component's data bound property values.\n Angular can't see that you've changed `personComponent.name` and won't update the `name`\n binding until you call `detectChanges`.", "translation": "调用它来初始化组件(它调用 `ngOnInit`)。或者在你的测试代码改变了组件的数据绑定属性值后调用它。\n Angular 不能检测到你已经改变了 `personComponent.name` 属性,也不会更新 `name` 的绑定,直到你调用了 `detectChanges`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RUNSCHECKNOCHANGESAFTERWARDSTOCONFIRMTHATTHEREARENOCIRCULARUPDATESUNLESSCALLEDASDETECTCHANGESFALSE", "original": "Runs `checkNoChanges`afterwards to confirm that there are no circular updates unless\n called as `detectChanges(false)`;", "translation": "之后,运行 `checkNoChanges`,来确认没有循环更新,除非它被这样调用:`detectChanges(false)`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SETTHISTOTRUEWHENYOUWANTTHEFIXTURETODETECTCHANGESAUTOMATICALLY", "original": "Set this to `true` when you want the fixture to detect changes automatically.", "translation": "设置 fixture 是否应该自动试图检测变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENAUTODETECTISTRUETHETESTFIXTURECALLSDETECTCHANGESIMMEDIATELYAFTERCREATINGTHECOMPONENTTHENITLISTENSFORPERTINENTZONEEVENTSANDCALLSDETECTCHANGESACCORDINGLYWHENYOURTESTCODEMODIFIESCOMPONENTPROPERTYVALUESDIRECTLYYOUPROBABLYSTILLHAVETOCALLFIXTUREDETECTCHANGESTOTRIGGERDATABINDINGUPDATES", "original": "When autodetect is `true`, the test fixture calls `detectChanges` immediately\n after creating the component. Then it listens for pertinent zone events\n and calls `detectChanges` accordingly.\n When your test code modifies component property values directly,\n you probably still have to call `fixture.detectChanges` to trigger data binding updates.", "translation": "当自动检测打开时,测试 fixture 监听 **zone** 事件,并调用 `detectChanges`。\n 当你的测试代码直接修改了组件属性值时,你还是要调用 `fixture.detectChanges` 来触发数据绑定更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDEFAULTISFALSETESTERSWHOPREFERFINECONTROLOVERTESTBEHAVIORTENDTOKEEPITFALSE", "original": "The default is `false`. Testers who prefer fine control over test behavior\n tend to keep it `false`.", "translation": "默认值是 `false`,喜欢对测试行为进行精细控制的测试者一般保持它为 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DOACHANGEDETECTIONRUNTOMAKESURETHEREARENOPENDINGCHANGESTHROWSANEXCEPTIONSIFTHEREARE", "original": "Do a change detection run to make sure there are no pending changes.\n Throws an exceptions if there are.", "translation": "运行一次变更检测来确认没有待处理的变化。如果有未处理的变化,它将抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IFTHEFIXTUREISCURRENTLYSTABLERETURNSTRUEIFTHEREAREASYNCTASKSTHATHAVENOTCOMPLETEDRETURNSFALSE", "original": "If the fixture is currently _stable_, returns `true`.\n If there are async tasks that have not completed, returns `false`.", "translation": "如果 fixture 当前是**稳定的**,则返回 `true`。\n 如果有异步任务没有完成,则返回 `false`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "RETURNSAPROMISETHATRESOLVESWHENTHEFIXTUREISSTABLE", "original": "Returns a promise that resolves when the fixture is stable.", "translation": "返回一个承诺,在 fixture 稳定时解析。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TORESUMETESTINGAFTERCOMPLETIONOFASYNCHRONOUSACTIVITYORASYNCHRONOUSCHANGEDETECTIONHOOKTHATPROMISESEEABOVE#WHENSTABLE", "original": "To resume testing after completion of asynchronous activity or\n asynchronous change detection, hook that promise.\n See [above](#when-stable).", "translation": "要想在完成了异步活动或异步变更检测之后再继续测试,可以对那个承诺对象进行挂钩。\n 参见 [前面](#when-stable)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TRIGGERCOMPONENTDESTRUCTION", "original": "Trigger component destruction.", "translation": "触发组件的销毁。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDEBUGELEMENTPROVIDESCRUCIALINSIGHTSINTOTHECOMPONENTSDOMREPRESENTATION", "original": "The `DebugElement` provides crucial insights into the component's DOM representation.", "translation": "`DebugElement` 提供了对组件的 DOM 的访问。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "FROMTHETESTROOTCOMPONENTSDEBUGELEMENTRETURNEDBYFIXTUREDEBUGELEMENTYOUCANWALKANDQUERYTHEFIXTURESENTIREELEMENTANDCOMPONENTSUBTREES", "original": "From the test root component's `DebugElement` returned by `fixture.debugElement`,\nyou can walk (and query) the fixture's entire element and component subtrees.", "translation": "`fixture.debugElement` 返回测试根组件的 `DebugElement`,通过它你可以访问(查询)fixture 的整个元素和组件子树。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "HEREARETHEMOSTUSEFULDEBUGELEMENTMEMBERSFORTESTERSINAPPROXIMATEORDEROFUTILITY:", "original": "Here are the most useful `DebugElement` members for testers, in approximate order of utility:", "translation": "下面是 `DebugElement` 最有用的成员,以使用频率排序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "MEMBER", "original": "Member", "translation": "成员", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DESCRIPTION", "original": "Description", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECORRESPONDINGDOMELEMENTINTHEBROWSERNULLFORWEBWORKERS", "original": "The corresponding DOM element in the browser (null for WebWorkers).", "translation": "与浏览器中 DOM 元素对应(WebWorkers 时,值为 null)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CALLINGQUERYPREDICATE:PREDICATEDEBUGELEMENTRETURNSTHEFIRSTDEBUGELEMENTTHATMATCHESTHEPREDICATE#QUERYPREDICATEATANYDEPTHINTHESUBTREE", "original": "Calling `query(predicate: Predicate<DebugElement>)` returns the first `DebugElement`\n that matches the [predicate](#query-predicate) at any depth in the subtree.", "translation": "调用 `query(predicate: Predicate<DebugElement>)` 会在子树的任意深度中查找能和[谓词函数](#query-predicate)匹配的第一个 `DebugElement`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "CALLINGQUERYALLPREDICATE:PREDICATEDEBUGELEMENTRETURNSALLDEBUGELEMENTSTHATMATCHESTHEPREDICATE#QUERYPREDICATEATANYDEPTHINSUBTREE", "original": "Calling `queryAll(predicate: Predicate<DebugElement>)` returns all `DebugElements`\n that matches the [predicate](#query-predicate) at any depth in subtree.", "translation": "调用 `queryAll(predicate: Predicate<DebugElement>)` 会在子树的任意深度中查找能和[谓词函数](#query-predicate)匹配的所有 `DebugElement`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEHOSTDEPENDENCYINJECTORFOREXAMPLETHEROOTELEMENTSCOMPONENTINSTANCEINJECTOR", "original": "The host dependency injector.\n For example, the root element's component instance injector.", "translation": "宿主依赖注入器。\n 比如,根元素的组件实例注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEELEMENTSOWNCOMPONENTINSTANCEIFITHASONE", "original": "The element's own component instance, if it has one.", "translation": "元素自己的组件实例(如果有)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ANOBJECTTHATPROVIDESPARENTCONTEXTFORTHISELEMENTOFTENANANCESTORCOMPONENTINSTANCETHATGOVERNSTHISELEMENT", "original": "An object that provides parent context for this element.\n Often an ancestor component instance that governs this element.", "translation": "为元素提供父级上下文的对象。\n 通常是控制该元素的祖级组件实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENANELEMENTISREPEATEDWITHINNGFORTHECONTEXTISANNGFORROWWHOSEIMPLICITPROPERTYISTHEVALUEOFTHEROWINSTANCEVALUEFOREXAMPLETHEHEROINNGFORLETHEROOFHEROES", "original": "When an element is repeated within `*ngFor`, the context is an `NgForRow` whose `$implicit`\n property is the value of the row instance value.\n For example, the `hero` in `*ngFor=\"let hero of heroes\"`.", "translation": "当一个元素被 `*ngFor` 重复,它的上下文为 `NgForRow`,它的 `$implicit` 属性值是该行的实例值。\n 比如,`*ngFor=\"let hero of heroes\"` 里的 `hero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEIMMEDIATEDEBUGELEMENTCHILDRENWALKTHETREEBYDESCENDINGTHROUGHCHILDREN", "original": "The immediate `DebugElement` children. Walk the tree by descending through `children`.", "translation": "`DebugElement` 的直接子元素。可以通过继续深入 `children` 来遍历这棵树。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DEBUGELEMENTALSOHASCHILDNODESALISTOFDEBUGNODEOBJECTSDEBUGELEMENTDERIVESFROMDEBUGNODEOBJECTSANDTHEREAREOFTENMORENODESTHANELEMENTSTESTERSCANUSUALLYIGNOREPLAINNODES", "original": "`DebugElement` also has `childNodes`, a list of `DebugNode` objects.\n `DebugElement` derives from `DebugNode` objects and there are often\n more nodes than elements. Testers can usually ignore plain nodes.", "translation": "`DebugElement` 还有 `childNodes`,即 `DebugNode` 对象列表。\n `DebugElement` 从 `DebugNode` 对象衍生,而且通常节点(node)比元素多。测试者通常忽略赤裸节点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDEBUGELEMENTPARENTNULLIFTHISISTHEROOTELEMENT", "original": "The `DebugElement` parent. Null if this is the root element.", "translation": "`DebugElement` 的父级。如果 `DebugElement` 是根元素,`parent` 为 null。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEELEMENTTAGNAMEIFITISANELEMENT", "original": "The element tag name, if it is an element.", "translation": "元素的标签名字,如果它是一个元素的话。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "TRIGGERSTHEEVENTBYITSNAMEIFTHEREISACORRESPONDINGLISTENERINTHEELEMENTSLISTENERSCOLLECTIONTHESECONDPARAMETERISTHEEVENTOBJECTEXPECTEDBYTHEHANDLERSEEABOVE#TRIGGEREVENTHANDLER", "original": "Triggers the event by its name if there is a corresponding listener\n in the element's `listeners` collection.\n The second parameter is the _event object_ expected by the handler.\n See [above](#trigger-event-handler).", "translation": "如果在该元素的 `listeners` 集合中有相应的监听器,就根据名字触发这个事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "IFTHEEVENTLACKSALISTENERORTHERESSOMEOTHERPROBLEMCONSIDERCALLINGNATIVEELEMENTDISPATCHEVENTEVENTOBJECT", "original": "If the event lacks a listener or there's some other problem,\n consider calling `nativeElement.dispatchEvent(eventObject)`.", "translation": "如果事件缺乏监听器,或者有其它问题,考虑调用 `nativeElement.dispatchEvent(eventObject)`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECALLBACKSATTACHEDTOTHECOMPONENTSOUTPUTPROPERTIESANDORTHEELEMENTSEVENTPROPERTIES", "original": "The callbacks attached to the component's `@Output` properties and/or the element's event properties.", "translation": "元素的 `@Output` 属性以及/或者元素的事件属性所附带的回调函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THISCOMPONENTSINJECTORLOOKUPTOKENSINCLUDESTHECOMPONENTITSELFPLUSTHETOKENSTHATTHECOMPONENTLISTSINITSPROVIDERSMETADATA", "original": "This component's injector lookup tokens.\n Includes the component itself plus the tokens that the component lists in its `providers` metadata.", "translation": "组件注入器的查询令牌。\n 包括组件自己的令牌和组件的 `providers` 元数据中列出来的令牌。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHERETOFINDTHISELEMENTINTHESOURCECOMPONENTTEMPLATE", "original": "Where to find this element in the source component template.", "translation": "source 是在源组件模板中查询这个元素的处所。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "DICTIONARYOFOBJECTSASSOCIATEDWITHTEMPLATELOCALVARIABLESEG#FOOKEYEDBYTHELOCALVARIABLENAME", "original": "Dictionary of objects associated with template local variables (e.g. `#foo`),\n keyed by the local variable name.", "translation": "与模板本地变量(比如 `#foo`)关联的词典对象,关键字与本地变量名字配对。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEDEBUGELEMENTQUERYPREDICATEANDDEBUGELEMENTQUERYALLPREDICATEMETHODSTAKEAPREDICATETHATFILTERSTHESOURCEELEMENTSSUBTREEFORMATCHINGDEBUGELEMENT", "original": "The `DebugElement.query(predicate)` and `DebugElement.queryAll(predicate)` methods take a\npredicate that filters the source element's subtree for matching `DebugElement`.", "translation": "`DebugElement.query(predicate)` 和 `DebugElement.queryAll(predicate)` 方法接受一个条件方法,\n它过滤源元素的子树,返回匹配的 `DebugElement`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEPREDICATEISANYMETHODTHATTAKESADEBUGELEMENTANDRETURNSATRUTHYVALUETHEFOLLOWINGEXAMPLEFINDSALLDEBUGELEMENTSWITHAREFERENCETOATEMPLATELOCALVARIABLENAMEDCONTENT:", "original": "The predicate is any method that takes a `DebugElement` and returns a _truthy_ value.\nThe following example finds all `DebugElements` with a reference to a template local variable named \"content\":", "translation": "这个条件方法是任何接受一个 `DebugElement` 并返回真值的方法。\n下面的例子查询所有拥有名为 `content` 的模块本地变量的所有 `DebugElement`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THEANGULARBYCLASSHASTHREESTATICMETHODSFORCOMMONPREDICATES:", "original": "The Angular `By` class has three static methods for common predicates:", "translation": "Angular 的 `By` 类为常用条件方法提供了三个静态方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BYALLRETURNALLELEMENTS", "original": "* `By.all` - return all elements.", "translation": "`By.all` - 返回所有元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BYCSSSELECTORRETURNELEMENTSWITHMATCHINGCSSSELECTORS", "original": "* `By.css(selector)` - return elements with matching CSS selectors.", "translation": "`By.css(selector)` - 返回符合 CSS 选择器的元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BYDIRECTIVEDIRECTIVERETURNELEMENTSTHATANGULARMATCHEDTOANINSTANCEOFTHEDIRECTIVECLASS", "original": "* `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.", "translation": "`By.directive(directive)` - 返回 Angular 能匹配一个指令类实例的所有元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "##FREQUENTLYASKEDQUESTIONS", "original": "## Frequently Asked Questions", "translation": "## 常见问题", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####WHYPUTSPECFILENEXTTOTHEFILEITTESTS", "original": "#### Why put spec file next to the file it tests?", "translation": "#### 为什么要把测试文件和被测文件放在一起?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITSAGOODIDEATOPUTUNITTESTSPECFILESINTHESAMEFOLDERASTHEAPPLICATIONSOURCECODEFILESTHATTHEYTEST:", "original": "It's a good idea to put unit test spec files in the same folder\nas the application source code files that they test:", "translation": "将单元测试的 spec 配置文件放到与应用程序源代码文件所在的同一个文件夹中是个好主意,因为:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "SUCHTESTSAREEASYTOFIND", "original": "* Such tests are easy to find.", "translation": "这样的测试程序很容易被找到", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "YOUSEEATAGLANCEIFAPARTOFYOURAPPLICATIONLACKSTESTS", "original": "* You see at a glance if a part of your application lacks tests.", "translation": "你可以一眼看出应用程序的那些部分缺乏测试程序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "NEARBYTESTSCANREVEALHOWAPARTWORKSINCONTEXT", "original": "* Nearby tests can reveal how a part works in context.", "translation": "临近的测试程序可以展示代码是如何在上下文中工作的", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENYOUMOVETHESOURCEINEVITABLEYOUREMEMBERTOMOVETHETEST", "original": "* When you move the source (inevitable), you remember to move the test.", "translation": "当你移动代码(无可避免)时,你记得一起移动测试程序", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHENYOURENAMETHESOURCEFILEINEVITABLEYOUREMEMBERTORENAMETHETESTFILE", "original": "* When you rename the source file (inevitable), you remember to rename the test file.", "translation": "当你重命名源代码文件(无可避免),你记得重命名测试程序文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####WHENWOULDIPUTSPECSINATESTFOLDER", "original": "#### When would I put specs in a test folder?", "translation": "#### 什么时候我该把测试文件放进单独的 `test` 文件夹中?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "APPLICATIONINTEGRATIONSPECSCANTESTTHEINTERACTIONSOFMULTIPLEPARTSSPREADACROSSFOLDERSANDMODULESTHEYDONTREALLYBELONGTOANYPARTINPARTICULARSOTHEYDONTHAVEANATURALHOMENEXTTOANYONEFILE", "original": "Application integration specs can test the interactions of multiple parts\nspread across folders and modules.\nThey don't really belong to any part in particular, so they don't have a\nnatural home next to any one file.", "translation": "应用程序的整合测试 spec 文件可以测试横跨多个目录和模块的多个部分之间的互动。\n它们不属于任何部分,很自然,没有特别的地方存放它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "ITSOFTENBETTERTOCREATEANAPPROPRIATEFOLDERFORTHEMINTHETESTSDIRECTORY", "original": "It's often better to create an appropriate folder for them in the `tests` directory.", "translation": "通常,在 `test` 目录中为它们创建一个合适的目录比较好。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "OFCOURSESPECSTHATTESTTHETESTHELPERSBELONGINTHETESTFOLDERNEXTTOTHEIRCORRESPONDINGHELPERFILES", "original": "Of course specs that test the test helpers belong in the `test` folder,\nnext to their corresponding helper files.", "translation": "当然,**测试助手对象**的测试 spec 文件也属于 `test` 目录,与它们对应的助手文件相邻。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "####WHYNOTRELYONE2ETESTSOFDOMINTEGRATION", "original": "#### Why not rely on E2E tests of DOM integration?", "translation": "#### 为什么不依赖 E2E 测试来保障 DOM 集成后的正确性?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "THECOMPONENTDOMTESTSDESCRIBEINTHISGUIDEOFTENREQUIREEXTENSIVESETUPANDADVANCEDTECHNIQUESWHEREASTHECLASSONLYTEST#COMPONENTCLASSTESTINGWERECOMPARATIVELYSIMPLE", "original": "The component DOM tests describe in this guide often require extensive setup and \nadvanced techniques where as the [class-only test](#component-class-testing)\nwere comparatively simple.", "translation": "本指南中讲的组件 DOM 测试通常需要大量的准备工作以及高级技巧,不像[只针对类的测试](#component-class-testing)那样简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "WHYNOTDEFERDOMINTEGRATIONTESTSTOENDTOENDE2ETESTING", "original": "Why not defer DOM integration tests to end-to-end (E2E) testing?", "translation": "为什么不等到端到端(E2E)测试阶段再对 DOM 进行集成测试呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "E2ETESTSAREGREATFORHIGHLEVELVALIDATIONOFTHEENTIRESYSTEMBUTTHEYCANTGIVEYOUTHECOMPREHENSIVETESTCOVERAGETHATYOUDEXPECTFROMUNITTESTS", "original": "E2E tests are great for high-level validation of the entire system.\nBut they can't give you the comprehensive test coverage that you'd expect from unit tests.", "translation": "E2E 测试对于整个系统的高层验证非常好用。\n但是它们没法给你像单元测试这样全面的测试覆盖率。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "E2ETESTSAREDIFFICULTTOWRITEANDPERFORMPOORLYCOMPAREDTOUNITTESTSTHEYBREAKEASILYOFTENDUETOCHANGESORMISBEHAVIORFARREMOVEDFROMTHESITEOFBREAKAGE", "original": "E2E tests are difficult to write and perform poorly compared to unit tests.\nThey break easily, often due to changes or misbehavior far removed from the site of breakage.", "translation": "E2E 测试很难写,并且执行性能也赶不上单元测试。\n它们很容易被破坏,而且经常是因为某些远离故障点的修改或不当行为而导致的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "E2ETESTSCANTEASILYREVEALHOWYOURCOMPONENTSBEHAVEWHENTHINGSGOWRONGSUCHASMISSINGORBADDATALOSTCONNECTIVITYANDREMOTESERVICEFAILURES", "original": "E2E tests can't easily reveal how your components behave when things go wrong,\nsuch as missing or bad data, lost connectivity, and remote service failures.", "translation": "当出错时,E2E 测试不能轻松揭露你的组件出了什么问题,\n比如丢失或错误的数据、网络失去连接或远端服务器挂了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "E2ETESTSFORAPPSTHATUPDATEADATABASESENDANINVOICEORCHARGEACREDITCARDREQUIRESPECIALTRICKSANDBACKDOORSTOPREVENTACCIDENTALCORRUPTIONOFREMOTERESOURCESITCANEVENBEHARDTONAVIGATETOTHECOMPONENTYOUWANTTOTEST", "original": "E2E tests for apps that update a database, \nsend an invoice, or charge a credit card require special tricks and back-doors to prevent\naccidental corruption of remote resources.\nIt can even be hard to navigate to the component you want to test.", "translation": "如果 E2E 的测试对象要更新数据库、发送发票或收取信用卡,就需要一些特殊的技巧和后门来防止远程资源被意外破坏。\n它甚至可能都难以导航到你要测试的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "BECAUSEOFTHESEMANYOBSTACLESYOUSHOULDTESTDOMINTERACTIONWITHUNITTESTINGTECHNIQUESASMUCHASPOSSIBLE", "original": "Because of these many obstacles, you should test DOM interaction\nwith unit testing techniques as much as possible.", "translation": "由于存在这么多障碍,你应该尽可能使用单元测试技术来测试 DOM 交互。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/testing.md" }, { + "key": "#TYPESCRIPTCONFIGURATION", "original": "# TypeScript Configuration", "translation": "# TypeScript 配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "TYPESCRIPTISAPRIMARYLANGUAGEFORANGULARAPPLICATIONDEVELOPMENTITISASUPERSETOFJAVASCRIPTWITHDESIGNTIMESUPPORTFORTYPESAFETYANDTOOLING", "original": "TypeScript is a primary language for Angular application development.\nIt is a superset of JavaScript with design-time support for type safety and tooling.", "translation": "TypeScript 是 Angular 应用开发中使用的主语言。\n它是 JavaScript 的“方言”之一,为类型安全和工具化而做了设计期支持。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "BROWSERSCANTEXECUTETYPESCRIPTDIRECTLYTYPESCRIPTMUSTBETRANSPILEDINTOJAVASCRIPTUSINGTHETSCCOMPILERWHICHREQUIRESSOMECONFIGURATION", "original": "Browsers can't execute TypeScript directly. Typescript must be \"transpiled\" into JavaScript using the *tsc* compiler,\nwhich requires some configuration.", "translation": "浏览器不能直接执行 TypeScript。它得先用 *tsc* 编译器转译(transpile)成 JavaScript,而且编译器需要进行一些配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "THISPAGECOVERSSOMEASPECTSOFTYPESCRIPTCONFIGURATIONANDTHETYPESCRIPTENVIRONMENTTHATAREIMPORTANTTOANGULARDEVELOPERSINCLUDINGDETAILSABOUTTHEFOLLOWINGFILES:", "original": "This page covers some aspects of TypeScript configuration and the TypeScript environment\nthat are important to Angular developers, including details about the following files:", "translation": "本页面会涵盖 TypeScript 配置与环境的某些方面,这些对 Angular 开发者是很重要的。具体来说包括下列文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "TSCONFIGJSONGUIDETYPESCRIPTCONFIGURATION#TSCONFIGMDASHTYPESCRIPTCOMPILERCONFIGURATION", "original": "* [tsconfig.json](guide/typescript-configuration#tsconfig)—TypeScript compiler configuration.", "translation": "[tsconfig.json](guide/typescript-configuration#tsconfig) - TypeScript 编译器配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "TYPINGSGUIDETYPESCRIPTCONFIGURATION#TYPINGSMDASHTYPESSCRIPTDECLARATIONFILES", "original": "* [typings](guide/typescript-configuration#typings)—TypesScript declaration files.", "translation": "[typings](guide/typescript-configuration#typings) - TypesScript 类型声明文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "##TSCONFIGJSON", "original": "## *tsconfig.json*", "translation": "## *tsconfig.json* 文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "TYPICALLYYOUADDATYPESCRIPTCONFIGURATIONFILECALLEDTSCONFIGJSONTOYOURPROJECTTOGUIDETHECOMPILERASITGENERATESJAVASCRIPTFILES", "original": "Typically, you add a TypeScript configuration file called `tsconfig.json` to your project to\nguide the compiler as it generates JavaScript files.", "translation": "你通常会往项目中加入一个 TypeScript 配置文件(`tsconfig.json`),来指导编译器如何生成 JavaScript 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "FORDETAILSABOUTTSCONFIGJSONSEETHEOFFICIALTYPESCRIPTWIKIHTTP:WWWTYPESCRIPTLANGORGDOCSHANDBOOKTSCONFIGJSONHTML", "original": "For details about `tsconfig.json`, see the official\n[TypeScript wiki](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html).", "translation": "要了解关于 `tsconfig.json` 的详情,请参阅官方提供的\n[TypeScript wiki](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "THESETUPGUIDESETUPGUIDEUSESTHEFOLLOWINGTSCONFIGJSON:", "original": "The [Setup](guide/setup) guide uses the following `tsconfig.json`:", "translation": "在[搭建本地开发环境](guide/setup)中创建过如下的 `tsconfig.json`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "THISFILECONTAINSOPTIONSANDFLAGSTHATAREESSENTIALFORANGULARAPPLICATIONS", "original": "This file contains options and flags that are essential for Angular applications.", "translation": "该文件中的选项和标志是写 Angular 应用程序的基础。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "###NOIMPLICITANYANDSUPPRESSIMPLICITANYINDEXERRORS", "original": "### *noImplicitAny* and *suppressImplicitAnyIndexErrors*", "translation": "### *noImplicitAny* 与 *suppressImplicitAnyIndexErrors*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "TYPESCRIPTDEVELOPERSDISAGREEABOUTWHETHERTHENOIMPLICITANYFLAGSHOULDBETRUEORFALSETHEREISNOCORRECTANSWERANDYOUCANCHANGETHEFLAGLATERBUTYOURCHOICENOWCANMAKEADIFFERENCEINLARGERPROJECTSSOITMERITSDISCUSSION", "original": "TypeScript developers disagree about whether the `noImplicitAny` flag should be `true` or `false`.\nThere is no correct answer and you can change the flag later.\nBut your choice now can make a difference in larger projects, so it merits discussion.", "translation": "TypeScript 开发者们在 `noImplicitAny` 标志应该是 `true` 还是 `false` 上存在分歧。\n这没有标准答案,你以后还可以修改这个标志。\n但是你的选择会在大项目中产生显著差异,所以它值得讨论一番。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "WHENTHENOIMPLICITANYFLAGISFALSETHEDEFAULTANDIFTHECOMPILERCANNOTINFERTHEVARIABLETYPEBASEDONHOWITSUSEDTHECOMPILERSILENTLYDEFAULTSTHETYPETOANYTHATSWHATISMEANTBYIMPLICITANY", "original": "When the `noImplicitAny` flag is `false` (the default), and if\nthe compiler cannot infer the variable type based on how it's used,\nthe compiler silently defaults the type to `any`. That's what is meant by *implicit `any`*.", "translation": "当 `noImplicitAny` 标志是 `false`(默认值)时,\n如果编译器无法根据变量的用途推断出变量的类型,它就会悄悄的把变量类型默认为 `any`。这就是*隐式 `any`*的含义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "THEDOCUMENTATIONSETUPSETSTHENOIMPLICITANYFLAGTOTRUEWHENTHENOIMPLICITANYFLAGISTRUEANDTHETYPESCRIPTCOMPILERCANNOTINFERTHETYPEITSTILLGENERATESTHEJAVASCRIPTFILESBUTITALSOREPORTSANERRORMANYSEASONEDDEVELOPERSPREFERTHISSTRICTERSETTINGBECAUSETYPECHECKINGCATCHESMOREUNINTENTIONALERRORSATCOMPILETIME", "original": "The documentation setup sets the `noImplicitAny` flag to `true`.\nWhen the `noImplicitAny` flag is `true` and the TypeScript compiler cannot infer\nthe type, it still generates the JavaScript files, but it also **reports an error**.\nMany seasoned developers prefer this stricter setting because type checking catches more\nunintentional errors at compile time.", "translation": "本文档在环境搭建时将 `noImplicitAny` 标志设置为 `true`。\n当 `noImplicitAny` 标志是 `true` 并且 TypeScript 编译器无法推断出类型时,它仍然会生成 JavaScript 文件。\n但是它也会**报告一个错误**。\n很多饱经沧桑的程序员更喜欢这种严格的设置,因为类型检查能在编译期间捕获更多意外错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "YOUCANSETAVARIABLESTYPETOANYEVENWHENTHENOIMPLICITANYFLAGISTRUE", "original": "You can set a variable's type to `any` even when the `noImplicitAny` flag is `true`.", "translation": "即使 `noImplicitAny` 标志被设置成了 `true`,你也可以把变量的类型设置为 `any`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "WHENTHENOIMPLICITANYFLAGISTRUEYOUMAYGETIMPLICITINDEXERRORSASWELLMOSTDEVELOPERSFEELTHATTHISPARTICULARERRORISMOREANNOYINGTHANHELPFULYOUCANSUPPRESSTHEMWITHTHEFOLLOWINGADDITIONALFLAG:", "original": "When the `noImplicitAny` flag is `true`, you may get *implicit index errors* as well.\nMost developers feel that *this particular error* is more annoying than helpful.\nYou can suppress them with the following additional flag:", "translation": "如果把 `noImplicitAny` 标志设置为了 `true`,你可能会得到*隐式索引错*。\n大多数程序员可能觉得*这种错误*是个烦恼而不是助力。\n你可以使用另一个标志来禁止它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "THEDOCUMENTATIONSETUPSETSTHISFLAGTOTRUEASWELL", "original": "The documentation setup sets this flag to `true` as well.", "translation": "本文档在环境搭建时将 `noImplicitAny` 标志设置为 `true`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "##TYPESCRIPTTYPINGS", "original": "## TypeScript Typings", "translation": "## TypeScript 类型定义(typings)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "MANYJAVASCRIPTLIBRARIESSUCHASJQUERYTHEJASMINETESTINGLIBRARYANDANGULAREXTENDTHEJAVASCRIPTENVIRONMENTWITHFEATURESANDSYNTAXTHATTHETYPESCRIPTCOMPILERDOESNTRECOGNIZENATIVELYWHENTHECOMPILERDOESNTRECOGNIZESOMETHINGITTHROWSANERROR", "original": "Many JavaScript libraries, such as jQuery, the Jasmine testing library, and Angular,\nextend the JavaScript environment with features and syntax\nthat the TypeScript compiler doesn't recognize natively.\nWhen the compiler doesn't recognize something, it throws an error.", "translation": "很多 JavaScript 库,比如 jQuery、Jasmine 测试库和 Angular,会通过新的特性和语法来扩展 JavaScript 环境。\n而 TypeScript 编译器并不能原生的识别它们。\n当编译器不能识别时,它就会抛出一个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "USETYPESCRIPTTYPEDEFINITIONFILESHTTPS:WWWTYPESCRIPTLANGORGDOCSHANDBOOKWRITINGDECLARATIONFILESHTMLMDASHDTSFILESMDASHTOTELLTHECOMPILERABOUTTHELIBRARIESYOULOAD", "original": "Use [TypeScript type definition files](https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html)—`d.ts files`—to tell the compiler about the libraries you load.", "translation": "可以使用[TypeScript 类型定义文件](https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html)\n—— `.d.ts` 文件 —— 来告诉编译器你要加载的库的类型定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "TYPESCRIPTAWAREEDITORSLEVERAGETHESESAMEDEFINITIONFILESTODISPLAYTYPEINFORMATIONABOUTLIBRARYFEATURES", "original": "TypeScript-aware editors leverage these same definition files to display type information about library features.", "translation": "TypeScript 敏感的编辑器借助这些定义文件来显示这些库中各个特性的类型定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "MANYLIBRARIESINCLUDEDEFINITIONFILESINTHEIRNPMPACKAGESWHEREBOTHTHETYPESCRIPTCOMPILERANDEDITORSCANFINDTHEMANGULARISONESUCHLIBRARYTHENODEMODULESANGULARCOREFOLDEROFANYANGULARAPPLICATIONCONTAINSSEVERALDTSFILESTHATDESCRIBEPARTSOFANGULAR", "original": "Many libraries include definition files in their npm packages where both the TypeScript compiler and editors\ncan find them. Angular is one such library.\nThe `node_modules/@angular/core/` folder of any Angular application contains several `d.ts` files that describe parts of Angular.", "translation": "很多库在自己的 npm 包中都包含了它们的类型定义文件,TypeScript 编译器和编辑器都能找到它们。Angular 库也是这样的。\n任何 Angular 应用程序的 `node_modules/@angular/core/` 目录下,都包含几个 `d.ts` 文件,它们描述了 Angular 的各个部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "YOUNEEDDONOTHINGTOGETTYPINGSFILESFORLIBRARYPACKAGESTHATINCLUDEDTSFILESANGULARPACKAGESINCLUDETHEMALREADY", "original": "**You need do nothing to get *typings* files for library packages that include `d.ts` files.\nAngular packages include them already.**", "translation": "**你不需要为那些包含了 `d.ts` 文件的库获取*类型定义*文件 —— Angular 的所有包都是如此。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "###LIBDTS", "original": "### lib.d.ts", "translation": "### lib.d.ts 文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "TYPESCRIPTINCLUDESASPECIALDECLARATIONFILECALLEDLIBDTSTHISFILECONTAINSTHEAMBIENTDECLARATIONSFORVARIOUSCOMMONJAVASCRIPTCONSTRUCTSPRESENTINJAVASCRIPTRUNTIMESANDTHEDOM", "original": "TypeScript includes a special declaration file called `lib.d.ts`. This file contains the ambient declarations for various common JavaScript constructs present in JavaScript runtimes and the DOM.", "translation": "TypeScript 带有一个特殊的声明文件,名为 `lib.d.ts`。该文件包含了 JavaScript 运行库和 DOM 的各种常用 JavaScript 环境声明。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "BASEDONTHETARGETTYPESCRIPTADDSADDITIONALAMBIENTDECLARATIONSLIKEPROMISEIFTHETARGETISES6", "original": "Based on the `--target`, TypeScript adds _additional_ ambient declarations\nlike `Promise` if the target is `es6`.", "translation": "基于 `--target`,TypeScript 添加*额外*的环境声明,例如如果目标为 `es6` 时将添加 `Promise`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "SINCETHEQUICKSTARTISTARGETINGES5YOUCANOVERRIDETHELISTOFDECLARATIONFILESTOBEINCLUDED:", "original": "Since the QuickStart is targeting `es5`, you can override the\nlist of declaration files to be included:", "translation": "因为《快速上手》的目标为 `es5`,所以你可以重写声明文件列表来包含:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "THANKSTOTHATYOUHAVEALLTHEES6TYPINGSEVENWHENTARGETINGES5", "original": "Thanks to that, you have all the `es6` typings even when targeting `es5`.", "translation": "得益于这项设置,即使编译目标设置为 `es5`,你也能获得所有的 `es6` 类型信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "###INSTALLABLETYPINGSFILES", "original": "### Installable typings files", "translation": "### 安装类型定义文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "MANYLIBRARIESMDASHJQUERYJASMINEANDLODASHAMONGTHEMMDASHDONOTINCLUDEDTSFILESINTHEIRNPMPACKAGESFORTUNATELYEITHERTHEIRAUTHORSORCOMMUNITYCONTRIBUTORSHAVECREATEDSEPARATEDTSFILESFORTHESELIBRARIESANDPUBLISHEDTHEMINWELLKNOWNLOCATIONS", "original": "Many libraries—jQuery, Jasmine, and Lodash among them—do *not* include `d.ts` files in their npm packages.\nFortunately, either their authors or community contributors have created separate `d.ts` files for these libraries and\npublished them in well-known locations.", "translation": "遗憾的是,很多库 —— jQuery、Jasmine 和 Lodash 等库 —— 都*没有*在它们自己的 npm 包中包含 `d.ts` 文件。\n 幸运的是,它们的作者或社区中的贡献者已经为这些库创建了独立的 `d.ts` 文件,并且把它们发布到了一个众所周知的位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "YOUCANINSTALLTHESETYPINGSVIANPMUSINGTHETYPESSCOPEDPACKAGEHTTP:WWWTYPESCRIPTLANGORGDOCSHANDBOOKDECLARATIONFILESCONSUMPTIONHTMLANDTYPESCRIPTSTARTINGAT20AUTOMATICALLYRECOGNIZESTHEM", "original": "You can install these typings via `npm` using the\n[`@types/*` scoped package](http://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html)\nand Typescript, starting at 2.0, automatically recognizes them.", "translation": "你还可以通过 `npm` 来使用[`@types/*` 范围化包](http://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html)来安装这些类型信息,\n而 TypeScript 自从 2.0 开始,可以自动识别它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "FORINSTANCETOINSTALLTYPINGSFORJASMINEYOUCOULDDONPMINSTALLTYPESJASMINESAVEDEV", "original": "For instance, to install typings for `jasmine` you could do `npm install @types/jasmine --save-dev`.", "translation": "比如,要安装 `jasmine` 的类型信息,你可以执行 `npm install @types/jasmine --save-dev`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "QUICKSTARTIDENTIFIESTWOTYPINGSORDTSFILES:", "original": "QuickStart identifies two *typings*, or `d.ts`, files:", "translation": "在“快速上手”中曾指定过两个*类型定义*文件(`d.ts`):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "JASMINEHTTP:JASMINEGITHUBIOTYPINGSFORTHEJASMINETESTFRAMEWORK", "original": "* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework.", "translation": "[jasmine](http://jasmine.github.io/)是 Jasmine 测试框架的类型定义", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "NODEHTTPS:WWWNPMJSCOMPACKAGETYPESNODEFORCODETHATREFERENCESOBJECTSINTHENODEJSENVIRONMENTYOUCANVIEWANEXAMPLEINTHEWEBPACKGUIDEWEBPACKPAGE", "original": "* [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *nodejs* environment;\nyou can view an example in the [webpack](guide/webpack) page.", "translation": "[node](https://www.npmjs.com/package/@types/node)是为了在 *nodejs* 环境中引用对象的代码提供的类型定义。在[webpack](guide/webpack)页面可以看到例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "QUICKSTARTDOESNTREQUIRETHESETYPINGSBUTMANYOFTHESAMPLESDO", "original": "QuickStart doesn't require these typings but many of the samples do.", "translation": "“快速上手”本身不需要这些类型定义,但是文档中的很多例子都需要。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "###TARGET", "original": "### *target*", "translation": "### *编译目标(target)*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "BYDEFAULTTHETARGETISES5YOUCANCONFIGURETHETARGETTOES6IFYOUONLYWANTTODEPLOYTHEAPPLICATIONTOES6COMPATIBLEBROWSERBUTIFYOUCONFIGURETHETARGETTOES6INSOMEOLDBROWSERSUCHASIESYNTAXERRORWILLBETHROWN", "original": "By default, the target is `es5`, you can configure the target to `es6` if you only want to deploy the application to\nes6 compatible browser. But if you configure the target to `es6` in some old browser such as `IE`, `Syntax Error` will be thrown.", "translation": "默认情况下,编译目标是 `es5`,如果你只想发布到兼容 es6 的浏览器中,也可以把它配置为 `es6`。\n不过,如果配置为 `es6`,那么一些老的浏览器(如 `IE` )中就会抛出 `Syntax Error` 错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/typescript-configuration.md" }, { + "key": "#ANGULARUNIVERSAL:SERVERSIDERENDERING", "original": "# Angular Universal: server-side rendering", "translation": "# Angular Universal:服务端渲染", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THISGUIDEDESCRIBESANGULARUNIVERSALATECHNOLOGYTHATRUNSYOURANGULARAPPLICATIONONTHESERVER", "original": "This guide describes **Angular Universal**, a technology that runs your Angular application on the server.", "translation": "本指南讲的是**Angular Universal(统一平台)**,一项在服务端运行 Angular 应用的技术。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANORMALANGULARAPPLICATIONEXECUTESINTHEBROWSERRENDERINGPAGESINTHEDOMINRESPONSETOUSERACTIONS", "original": "A normal Angular application executes in the _browser_, rendering pages in the DOM in response to user actions.", "translation": "标准的 Angular 应用会执行在*浏览器*中,它会在 DOM 中渲染页面,以响应用户的操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANGULARUNIVERSALGENERATESSTATICAPPLICATIONPAGESONTHESERVERTHROUGHAPROCESSCALLEDSERVERSIDERENDERINGSSR", "original": "**Angular Universal** generates _static_ application pages on the _server_\nthrough a process called **server-side rendering (SSR)**.", "translation": "而**Angular Universal** 会在*服务端*通过一个被称为**服务端渲染(server-side rendering - SSR)的过程**生成*静态*的应用页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ITCANGENERATEANDSERVETHOSEPAGESINRESPONSETOREQUESTSFROMBROWSERSITCANALSOPREGENERATEPAGESASHTMLFILESTHATYOUSERVELATER", "original": "It can generate and serve those pages in response to requests from browsers.\nIt can also pre-generate pages as HTML files that you serve later.", "translation": "它可以生成这些页面,并在浏览器请求时直接用它们给出响应。\n它也可以把页面预先生成为 HTML 文件,然后把它们作为静态文件供服务器使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THISGUIDEDESCRIBESAUNIVERSALSAMPLEAPPLICATIONTHATLAUNCHESQUICKLYASASERVERRENDEREDPAGEMEANWHILETHEBROWSERDOWNLOADSTHEFULLCLIENTVERSIONANDSWITCHESTOITAUTOMATICALLYAFTERTHECODELOADS", "original": "This guide describes a Universal sample application that launches quickly as a server-rendered page.\nMeanwhile, the browser downloads the full client version and switches to it automatically after the code loads.", "translation": "本指南讲的是一个 Universal 的范例应用,它启动得像服务端渲染好的页面那样快。\n稍后,浏览器就会下载完整的客户端版本,并在代码加载完之后自动切换到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "DOWNLOADTHEFINISHEDSAMPLECODEGENERATEDZIPSUNIVERSALUNIVERSALZIPWHICHRUNSINANODEEXPRESSHTTPS:EXPRESSJSCOMSERVER", "original": "[Download the finished sample code](generated/zips/universal/universal.zip),\nwhich runs in a [node express](https://expressjs.com/) server.", "translation": "你可以[下载最终的范例代码](generated/zips/universal/universal.zip),并将其运行在一个 [node express](https://expressjs.com/) 服务器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###WHYUNIVERSAL", "original": "### Why Universal", "translation": "### 为何需要 Universal", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEREARETHREEMAINREASONSTOCREATEAUNIVERSALVERSIONOFYOURAPP", "original": "There are three main reasons to create a Universal version of your app.", "translation": "有三个主要的理由来为你的应用创建一个 Universal 版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "1FACILITATEWEBCRAWLERSSEO", "original": "1. Facilitate web crawlers (SEO)", "translation": "帮助网络爬虫(SEO)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "1IMPROVEPERFORMANCEONMOBILEANDLOWPOWEREDDEVICES", "original": "1. Improve performance on mobile and low-powered devices", "translation": "提升在手机和低功耗设备上的性能", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "1SHOWTHEFIRSTPAGEQUICKLY", "original": "1. Show the first page quickly", "translation": "迅速显示出第一个页面", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####FACILITATEWEBCRAWLERS", "original": "#### Facilitate web crawlers", "translation": "#### 帮助网络爬虫", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "GOOGLEBINGFACEBOOKTWITTERANDOTHERSOCIALMEDIASITESRELYONWEBCRAWLERSTOINDEXYOURAPPLICATIONCONTENTANDMAKETHATCONTENTSEARCHABLEONTHEWEB", "original": "Google, Bing, Facebook, Twitter and other social media sites rely on web crawlers to index your application content and make that content searchable on the web.", "translation": "Google、Bing、Facebook、Twitter 和其它社交媒体网站都依赖网络爬虫去索引你的应用内容,并且让它的内容可以通过网络搜索到。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THESEWEBCRAWLERSMAYBEUNABLETONAVIGATEANDINDEXYOURHIGHLYINTERACTIVEANGULARAPPLICATIONASAHUMANUSERCOULDDO", "original": "These web crawlers may be unable to navigate and index your highly-interactive, Angular application as a human user could do.", "translation": "这些网络爬虫可能不会像人类那样导航到你的具有高度交互性的 Angular 应用,并为其建立索引。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANGULARUNIVERSALCANGENERATEASTATICVERSIONOFYOURAPPTHATISEASILYSEARCHABLELINKABLEANDNAVIGABLEWITHOUTJAVASCRIPTITALSOMAKESASITEPREVIEWAVAILABLESINCEEACHURLRETURNSAFULLYRENDEREDPAGE", "original": "Angular Universal can generate a static version of your app that is easily searchable, linkable, and navigable without JavaScript.\nIt also makes a site preview available since each URL returns a fully-rendered page.", "translation": "Angular Universal 可以为你生成应用的静态版本,它易搜索、可链接,浏览时也不必借助 JavaScript。\n它也让站点可以被预览,因为每个 URL 返回的都是一个完全渲染好的页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ENABLINGWEBCRAWLERSISOFTENREFERREDTOASSEARCHENGINEOPTIMIZATIONSEOHTTPS:STATICGOOGLEUSERCONTENTCOMMEDIAWWWGOOGLECOMENWEBMASTERSDOCSSEARCHENGINEOPTIMIZATIONSTARTERGUIDEPDF", "original": "Enabling web crawlers is often referred to as\n[Search Engine Optimization (SEO)](https://static.googleusercontent.com/media/www.google.com/en//webmasters/docs/search-engine-optimization-starter-guide.pdf).", "translation": "启用网络爬虫通常被称为[搜索引擎优化 (SEO)](https://static.googleusercontent.com/media/www.google.com/en//webmasters/docs/search-engine-optimization-starter-guide.pdf)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####PERFORMANCEONMOBILEANDLOWPERFORMANCEDEVICES", "original": "#### Performance on mobile and low performance devices", "translation": "#### 提升手机和低功耗设备上的性能", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "SOMEDEVICESDONTSUPPORTJAVASCRIPTOREXECUTEJAVASCRIPTSOPOORLYTHATTHEUSEREXPERIENCEISUNACCEPTABLEFORTHESECASESYOUMAYREQUIREASERVERRENDEREDNOJAVASCRIPTVERSIONOFTHEAPPTHISVERSIONHOWEVERLIMITEDMAYBETHEONLYPRACTICALALTERNATIVEFORPEOPLEWHOOTHERWISEWOULDNOTBEABLETOUSETHEAPPATALL", "original": "Some devices don't support JavaScript or execute JavaScript so poorly that the user experience is unacceptable.\nFor these cases, you may require a server-rendered, no-JavaScript version of the app.\nThis version, however limited, may be the only practical alternative for\npeople who otherwise would not be able to use the app at all.", "translation": "有些设备不支持 JavaScript 或 JavaScript 执行得很差,导致用户体验不可接受。\n对于这些情况,你可能会需要该应用的服务端渲染、无 JavaScript 的版本。\n虽然有一些限制,不过这个版本可能是那些完全没办法使用该应用的人的唯一选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####SHOWTHEFIRSTPAGEQUICKLY", "original": "#### Show the first page quickly", "translation": "#### 快速显示第一页", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "DISPLAYINGTHEFIRSTPAGEQUICKLYCANBECRITICALFORUSERENGAGEMENT", "original": "Displaying the first page quickly can be critical for user engagement.", "translation": "快速显示第一页对于吸引用户是至关重要的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "53OFMOBILESITEVISITSAREABANDONEDHTTPS:WWWDOUBLECLICKBYGOOGLECOMARTICLESMOBILESPEEDMATTERSIFPAGESTAKELONGERTHAN3SECONDSTOLOADYOURAPPMAYHAVETOLAUNCHFASTERTOENGAGETHESEUSERSBEFORETHEYDECIDETODOSOMETHINGELSE", "original": "[53% of mobile site visits are abandoned](https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/) if pages take longer than 3 seconds to load.\nYour app may have to launch faster to engage these users before they decide to do something else.", "translation": "如果页面加载超过了三秒中,那么 [53% 的移动网站会被放弃](https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/)。\n你的应用需要启动的更快一点,以便在用户决定做别的事情之前吸引他们的注意力。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "WITHANGULARUNIVERSALYOUCANGENERATELANDINGPAGESFORTHEAPPTHATLOOKLIKETHECOMPLETEAPPTHEPAGESAREPUREHTMLANDCANDISPLAYEVENIFJAVASCRIPTISDISABLEDTHEPAGESDONOTHANDLEBROWSEREVENTSBUTTHEYDOSUPPORTNAVIGATIONTHROUGHTHESITEUSINGROUTERLINKGUIDEROUTERHTML#ROUTERLINK", "original": "With Angular Universal, you can generate landing pages for the app that look like the complete app.\nThe pages are pure HTML, and can display even if JavaScript is disabled.\nThe pages do not handle browser events, but they _do_ support navigation through the site using [routerLink](guide/router.html#router-link).", "translation": "使用 Angular Universal,你可以为应用生成“着陆页”,它们看起来就和完整的应用一样。\n这些着陆页是纯 HTML,并且即使 JavaScript 被禁用了也能显示。\n这些页面不会处理浏览器事件,不过它们*可以*用 [routerLink](guide/router.html#router-link) 在这个网站中导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "INPRACTICEYOULLSERVEASTATICVERSIONOFTHELANDINGPAGETOHOLDTHEUSERSATTENTIONATTHESAMETIMEYOULLLOADTHEFULLANGULARAPPBEHINDITINTHEMANNEREXPLAINEDBELOW#TRANSITIONTHEUSERPERCEIVESNEARINSTANTPERFORMANCEFROMTHELANDINGPAGEANDGETSTHEFULLINTERACTIVEEXPERIENCEAFTERTHEFULLAPPLOADS", "original": "In practice, you'll serve a static version of the landing page to hold the user's attention.\nAt the same time, you'll load the full Angular app behind it in the manner [explained below](#transition).\nThe user perceives near-instant performance from the landing page\nand gets the full interactive experience after the full app loads.", "translation": "在实践中,你可能要使用一个着陆页的静态版本来保持用户的注意力。\n同时,你也会在幕后加载完整的 Angular 应用,就像[稍后解释的那样](#transition)。\n用户会认为着陆页几乎是立即出现的,而当完整的应用加载完之后,又可以获得完全的交互体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###HOWITWORKS", "original": "### How it works", "translation": "### 工作原理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "TOMAKEAUNIVERSALAPPYOUINSTALLTHEPLATFORMSERVERPACKAGETHEPLATFORMSERVERPACKAGEHASSERVERIMPLEMENTATIONSOFTHEDOMXMLHTTPREQUESTANDOTHERLOWLEVELFEATURESTHATDONOTRELYONABROWSER", "original": "To make a Universal app, you install the `platform-server` package.\nThe `platform-server` package has server implementations of the DOM, `XMLHttpRequest`, and other low-level features that do not rely on a browser.", "translation": "要制作一个 Universal 应用,就要安装 `platform-server` 包。\n`platform-server` 包提供了服务端的 DOM 实现、`XMLHttpRequest` 和其它底层特性,但不再依赖浏览器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUCOMPILETHECLIENTAPPLICATIONWITHTHEPLATFORMSERVERMODULEINSTEADOFTHEPLATFORMBROWSERMODULEANDRUNTHERESULTINGUNIVERSALAPPONAWEBSERVER", "original": "You compile the client application with the `platform-server` module instead of the `platform-browser` module.\nand run the resulting Universal app on a web server.", "translation": "你要使用 `platform-server` 模块而不是 `platform-browser` 模块来编译这个客户端应用,并且在一个 Web 服务器上运行这个 Universal 应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THESERVERANODEEXPRESSHTTPS:EXPRESSJSCOMSERVERINTHISGUIDESEXAMPLEPASSESCLIENTREQUESTSFORAPPLICATIONPAGESTOUNIVERSALSRENDERMODULEFACTORYFUNCTION", "original": "The server (a [Node Express](https://expressjs.com/) server in _this_ guide's example)\npasses client requests for application pages to Universal's `renderModuleFactory` function.", "translation": "服务器(这个例子中使用的是 [Node Express](https://expressjs.com/) 服务器)会把客户端对应用页面的请求传给 `renderModuleFactory` 函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THERENDERMODULEFACTORYFUNCTIONTAKESASINPUTSATEMPLATEHTMLPAGEUSUALLYINDEXHTMLANANGULARMODULECONTAININGCOMPONENTSANDAROUTETHATDETERMINESWHICHCOMPONENTSTODISPLAY", "original": "The `renderModuleFactory` function takes as inputs a *template* HTML page (usually `index.html`),\nan Angular *module* containing components,\nand a *route* that determines which components to display.", "translation": "`renderModuleFactory` 函数接受一个*模板* HTML 页面(通常是 `index.html`)、一个包含组件的 Angular *模块*和一个用于决定该显示哪些组件的*路由*作为输入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEROUTECOMESFROMTHECLIENTSREQUESTTOTHESERVEREACHREQUESTRESULTSINTHEAPPROPRIATEVIEWFORTHEREQUESTEDROUTE", "original": "The route comes from the client's request to the server.\nEach request results in the appropriate view for the requested route.", "translation": "该路由从客户端的请求中传给服务器。\n每次请求都会给出所请求路由的一个适当的视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THERENDERMODULEFACTORYRENDERSTHATVIEWWITHINTHEAPPTAGOFTHETEMPLATECREATINGAFINISHEDHTMLPAGEFORTHECLIENT", "original": "The `renderModuleFactory` renders that view within the `<app>` tag of the template, creating a finished HTML page for the client.", "translation": "`renderModuleFactory` 在模板中的 `<app>` 标记中渲染出哪个视图,并为客户端创建一个完成的 HTML 页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "FINALLYTHESERVERRETURNSTHERENDEREDPAGETOTHECLIENT", "original": "Finally, the server returns the rendered page to the client.", "translation": "最后,服务器就会把渲染好的页面返回给客户端。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###WORKINGAROUNDTHEBROWSERAPIS", "original": "### Working around the browser APIs", "translation": "### 使用浏览器 API", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "BECAUSEAUNIVERSALPLATFORMSERVERAPPDOESNTEXECUTEINTHEBROWSERYOUMAYHAVETOWORKAROUNDSOMEOFTHEBROWSERAPISANDCAPABILITIESTHATAREMISSINGONTHESERVER", "original": "Because a Universal `platform-server` app doesn't execute in the browser, you may have to work around some of the browser APIs and capabilities that are missing on the server.", "translation": "由于 Universal 的 `platform-server` 应用并没有运行在浏览器中,因此那些与浏览器 API 有关的工作都没法在这个服务器中使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUWONTBEABLEREFERENCEBROWSERONLYNATIVEOBJECTSSUCHASWINDOWDOCUMENTNAVIGATORORLOCATIONIFYOUDONTNEEDTHEMONTHESERVERRENDEREDPAGESIDESTEPTHEMWITHCONDITIONALLOGIC", "original": "You won't be able reference browser-only native objects such as `window`, `document`, `navigator` or `location`.\nIf you don't need them on the server-rendered page, side-step them with conditional logic.", "translation": "你不能引用浏览器独有的原生对象,比如 `window`、`document`、`navigator` 或 `location`。\n如果你在服务端渲染的页面中不需要它们,就可以使用条件逻辑跳过它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ALTERNATIVELYLOOKFORANINJECTABLEANGULARABSTRACTIONOVERTHEOBJECTYOUNEEDSUCHASLOCATIONORDOCUMENTITMAYSUBSTITUTEADEQUATELYFORTHESPECIFICAPITHATYOURECALLINGIFANGULARDOESNTPROVIDEITYOUMAYBEABLETOWRITEYOUROWNABSTRACTIONTHATDELEGATESTOTHEBROWSERAPIWHILEINTHEBROWSERANDTOASATISFACTORYALTERNATIVEIMPLEMENTATIONWHILEONTHESERVER", "original": "Alternatively, look for an injectable Angular abstraction over the object you need such as `Location` or `Document`;\nit may substitute adequately for the specific API that you're calling.\nIf Angular doesn't provide it, you may be able to write your own abstraction that delegates to the browser API while in the browser and to a satisfactory alternative implementation while on the server.", "translation": "另一种方式是查找一个可注入的 Angular 对所需对象的抽象服务,比如 `Location` 或 `Document`,它可能作为你调用的指定 API 的等价替身。\n如果 Angular 没有提供它,你也可以写一个自己的抽象层,当在浏览器中运行时,就把它委托给浏览器 API,挡在服务器中运行时,就提供一个符合要求的代用实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "WITHOUTMOUSEORKEYBOARDEVENTSAUNIVERSALAPPCANTRELYONAUSERCLICKINGABUTTONTOSHOWACOMPONENTAUNIVERSALAPPSHOULDDETERMINEWHATTORENDERBASEDSOLELYONTHEINCOMINGCLIENTREQUESTTHISISAGOODARGUMENTFORMAKINGTHEAPPROUTEABLEGUIDEROUTER", "original": "Without mouse or keyboard events, a universal app can't rely on a user clicking a button to show a component.\nA universal app should determine what to render based solely on the incoming client request.\nThis is a good argument for making the app [routeable](guide/router).", "translation": "由于没有鼠标或键盘事件,因此 Universal 应用也不能依赖于用户点击某个按钮来显示每个组件。\nUniversal 应用应该仅仅根据客户端过来的请求决定要渲染的内容。\n把该应用做成[可路由的](guide/router),就是一种好方案。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "BECAUSETHEUSEROFASERVERRENDEREDPAGECANTDOMUCHMORETHANCLICKLINKSYOUSHOULDSWAPINTHEREALCLIENTAPP#TRANSITIONASQUICKLYASPOSSIBLEFORAPROPERINTERACTIVEEXPERIENCE", "original": "Because the user of a server-rendered page can't do much more than click links,\nyou should [swap in the real client app](#transition) as quickly as possible for a proper interactive experience.", "translation": "由于服务端渲染页面的用户只能点击链接,所以你应该尽快让它[切换到真正的客户端应用](#transition),以提供正常的交互体验。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "##THEEXAMPLE", "original": "## The example", "translation": "## 例子", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THETOUROFHEROESTUTORIALISTHEFOUNDATIONFORTHEUNIVERSALSAMPLEDESCRIBEDINTHISGUIDE", "original": "The _Tour of Heroes_ tutorial is the foundation for the Universal sample described in this guide.", "translation": "《英雄指南》教程是本章所讲的 Universal 范例的基础。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THECOREAPPLICATIONFILESAREMOSTLYUNTOUCHEDWITHAFEWEXCEPTIONSDESCRIBEDBELOWYOULLADDMOREFILESTOSUPPORTBUILDINGANDSERVINGWITHUNIVERSAL", "original": "The core application files are mostly untouched, with a few exceptions described below.\nYou'll add more files to support building and serving with Universal.", "translation": "除了下面讲的少量修改之外,应用中的核心文件几乎不用动。\n你只需要添加一些额外的文件来支持使用 Universal 进行构建和提供服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "INTHISEXAMPLETHEANGULARCLICOMPILESANDBUNDLESTHEUNIVERSALVERSIONOFTHEAPPWITHTHEAOTAHEADOFTIMECOMPILERGUIDEAOTCOMPILERANODEEXPRESSWEBSERVERTURNSCLIENTREQUESTSINTOTHEHTMLPAGESRENDEREDBYUNIVERSAL", "original": "In this example, the Angular CLI compiles and bundles the Universal version of the app with the\n[AOT (Ahead-of-Time) compiler](guide/aot-compiler).\nA node/express web server turns client requests into the HTML pages rendered by Universal.", "translation": "在这个例子中,Angular CLI 会使用 [AOT (预先) 编译器](guide/aot-compiler)对该应用的 Universal 版本进行编译和打包。\nNode 的 Express Web 服务器会把客户端请求转换成由 Universal 渲染出的页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUWILLCREATE:", "original": "You will create:", "translation": "你将会创建:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ASERVERSIDEAPPMODULEAPPSERVERMODULETS", "original": "* a server-side app module, `app.server.module.ts`", "translation": "一个服务端的 app 模块 `app.server.module.ts`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANENTRYPOINTFORTHESERVERSIDEMAINSERVERTS", "original": "* an entry point for the server-side, `main.server.ts`", "translation": "一个服务端的入口点 `main.server.ts`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANEXPRESSWEBSERVERTOHANDLEREQUESTSSERVERTS", "original": "* an express web server to handle requests, `server.ts`", "translation": "一个用于处理请求的 express Web 服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ATYPESCRIPTCONFIGFILETSCONFIGSERVERJSON", "original": "* a TypeScript config file, `tsconfig.server.json`", "translation": "一个 TypeScript 配置文件 `tsconfig.server.json`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "AWEBPACKCONFIGFILEFORTHESERVERWEBPACKSERVERCONFIGJS", "original": "* a Webpack config file for the server, `webpack.server.config.js`", "translation": "一个供服务器使用的 Webpack 配置文件 `webpack.server.config.js`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "WHENYOUREDONETHEFOLDERSTRUCTUREWILLLOOKLIKETHIS:", "original": "When you're done, the folder structure will look like this:", "translation": "当做完这些后,文件夹的结构是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { - "original": "", - "translation": "src/\n index.html <t><i>app web page</i></t><t>应用的宿主页</t>\n main.ts <t><i>bootstrapper for client app</i></t><t>客户端应用的引导程序</t>\n main.server.ts <t><i>* bootstrapper for server app</i></t><t>* 服务端应用的引导程序</t>\n tsconfig.app.json <t><i>TypeScript client configuration</i></t><t>TypeScript 的客户端配置</t>\n tsconfig.server.json <t><i>* TypeScript server configuration</i></t><t>* TypeScript 的服务端配置</t>\n tsconfig.spec.json <t><i>TypeScript spec configuration</i></t><t>TypeScript 的测试配置</t>\n style.css <t><i>styles for the app</i></t><t>应用的样式表</t>\n app/ ... <t><i>application code</i></t><t>应用代码</t>\n app.server.module.ts <t><i>* server-side application module</i></t><t>* 服务端的应用模块</t>\nserver.ts <t><i>* express web server</i></t><t>* Express 的服务程序</t>\ntsconfig.json <t><i>TypeScript client configuration</i></t><t>TypeScript 的客户端配置</t>\npackage.json <t><i>npm configuration</i></t><t>npm 配置</t>\nwebpack.server.config.js <t><i>* Webpack server configuration</i></t><t>* Webpack 的服务端配置</t>", + "key": "CODEEXAMPLEFORMATLANGUAGENONELINENUMSFALSESRCINDEXHTMLIAPPWEBPAGEIMAINTSIBOOTSTRAPPERFORCLIENTAPPIMAINSERVERTSIBOOTSTRAPPERFORSERVERAPPITSCONFIGAPPJSONITYPESCRIPTCLIENTCONFIGURATIONITSCONFIGSERVERJSONITYPESCRIPTSERVERCONFIGURATIONITSCONFIGSPECJSONITYPESCRIPTSPECCONFIGURATIONISTYLECSSISTYLESFORTHEAPPIAPPIAPPLICATIONCODEIAPPSERVERMODULETSISERVERSIDEAPPLICATIONMODULEISERVERTSIEXPRESSWEBSERVERITSCONFIGJSONITYPESCRIPTCLIENTCONFIGURATIONIPACKAGEJSONINPMCONFIGURATIONIWEBPACKSERVERCONFIGJSIWEBPACKSERVERCONFIGURATIONICODEEXAMPLE", + "original": "<code-example format=\".\" language=\"none\" linenums=\"false\">\nsrc/\n index.html <i>app web page</i>\n main.ts <i>bootstrapper for client app</i>\n main.server.ts <i>* bootstrapper for server app</i>\n tsconfig.app.json <i>TypeScript client configuration</i>\n tsconfig.server.json <i>* TypeScript server configuration</i>\n tsconfig.spec.json <i>TypeScript spec configuration</i>\n style.css <i>styles for the app</i>\n app/ ... <i>application code</i>\n app.server.module.ts <i>* server-side application module</i>\nserver.ts <i>* express web server</i>\ntsconfig.json <i>TypeScript client configuration</i>\npackage.json <i>npm configuration</i>\nwebpack.server.config.js <i>* Webpack server configuration</i>\n</code-example>", + "translation": "<code-example format=\".\" language=\"none\" linenums=\"false\">\nsrc/\n index.html <t><i>app web page</i></t><t>应用的宿主页</t>\n main.ts <t><i>bootstrapper for client app</i></t><t>客户端应用的引导程序</t>\n main.server.ts <t><i>* bootstrapper for server app</i></t><t>* 服务端应用的引导程序</t>\n tsconfig.app.json <t><i>TypeScript client configuration</i></t><t>TypeScript 的客户端配置</t>\n tsconfig.server.json <t><i>* TypeScript server configuration</i></t><t>* TypeScript 的服务端配置</t>\n tsconfig.spec.json <t><i>TypeScript spec configuration</i></t><t>TypeScript 的测试配置</t>\n style.css <t><i>styles for the app</i></t><t>应用的样式表</t>\n app/ ... <t><i>application code</i></t><t>应用代码</t>\n app.server.module.ts <t><i>* server-side application module</i></t><t>* 服务端的应用模块</t>\nserver.ts <t><i>* express web server</i></t><t>* Express 的服务程序</t>\ntsconfig.json <t><i>TypeScript client configuration</i></t><t>TypeScript 的客户端配置</t>\npackage.json <t><i>npm configuration</i></t><t>npm 配置</t>\nwebpack.server.config.js <t><i>* Webpack server configuration</i></t><t>* Webpack 的服务端配置</t>\n</code-example>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEFILESMARKEDWITHARENEWANDNOTINTHEORIGINALTUTORIALSAMPLETHISGUIDECOVERSTHEMINTHESECTIONSBELOW", "original": "The files marked with `*` are new and not in the original tutorial sample.\nThis guide covers them in the sections below.", "translation": "那些标有 `*` 的文件都是新的,而不是来自原来的范例应用。\n本文稍后的部分会涉及它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "##PREPARATION", "original": "## Preparation", "translation": "## 准备工作", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "DOWNLOADTHETOUROFHEROESGENERATEDZIPSTOHPT6TOHPT6ZIPPROJECTANDINSTALLTHEDEPENDENCIESFROMIT", "original": "Download the [Tour of Heroes](generated/zips/toh-pt6/toh-pt6.zip) project and install the dependencies from it.", "translation": "下载[《英雄指南》](generated/zips/toh-pt6/toh-pt6.zip)项目,并为它安装依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###INSTALLTHETOOLS", "original": "### Install the tools", "translation": "### 安装工具", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "TOGETSTARTEDINSTALLTHESEPACKAGES", "original": "To get started, install these packages.", "translation": "在开始之前,要安装下列包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANGULARPLATFORMSERVERUNIVERSALSERVERSIDECOMPONENTS", "original": "* `@angular/platform-server` - Universal server-side components.", "translation": "`@angular/platform-server` - Universal 的服务端元件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "NGUNIVERSALMODULEMAPNGFACTORYLOADERFORHANDLINGLAZYLOADINGINTHECONTEXTOFASERVERRENDER", "original": "* `@nguniversal/module-map-ngfactory-loader` - For handling lazy-loading in the context of a server-render.", "translation": "`@nguniversal/module-map-ngfactory-loader` - 用于处理服务端渲染环境下的惰性加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "NGUNIVERSALEXPRESSENGINEANEXPRESSENGINEFORUNIVERSALAPPLICATIONS", "original": "* `@nguniversal/express-engine` - An express engine for Universal applications.", "translation": "`@nguniversal/express-engine` - Universal 应用的 Express 引擎。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "TSLOADERTOTRANSPILETHESERVERAPPLICATION", "original": "* `ts-loader` - To transpile the server application", "translation": "`ts-loader` - 用于对服务端应用进行转译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "INSTALLTHEMWITHTHEFOLLOWINGCOMMANDS:", "original": "Install them with the following commands:", "translation": "使用下列命令安装它们:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###MODIFYTHECLIENTAPP", "original": "### Modify the client app", "translation": "### 修改客户端应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "AUNIVERSALAPPCANACTASADYNAMICCONTENTRICHSPLASHSCREENTHATENGAGESTHEUSERITGIVESTHEAPPEARANCEOFANEARINSTANTAPPLICATION", "original": "A Universal app can act as a dynamic, content-rich \"splash screen\" that engages the user.\nIt gives the appearance of a near-instant application.", "translation": "Universal 应用可以扮演一个动态的、内容丰富的 “封面页”,以吸引用户。\n它能让应用看上去几乎是立即呈现出来的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "MEANWHILETHEBROWSERDOWNLOADSTHECLIENTAPPSCRIPTSINBACKGROUNDONCELOADEDANGULARTRANSITIONSFROMTHESTATICSERVERRENDEREDPAGETOTHEDYNAMICALLYRENDEREDVIEWSOFTHEINTERACTIVECLIENTAPP", "original": "Meanwhile, the browser downloads the client app scripts in background.\nOnce loaded, Angular transitions from the static server-rendered page to the dynamically rendered views of the interactive client app.", "translation": "同时,浏览器会在后台下载客户端应用的脚本。\n一旦加载完毕,Angular 就会从静态的服务端渲染的页面无缝转换成动态渲染的可交互的客户端应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUMUSTMAKEAFEWCHANGESTOYOURAPPLICATIONCODETOSUPPORTBOTHSERVERSIDERENDERINGANDTHETRANSITIONTOTHECLIENTAPP", "original": "You must make a few changes to your application code to support both server-side rendering and the transition to the client app.", "translation": "你要对应用代码做少量修改,以支持服务端渲染,并无缝转换成客户端应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####THEROOTAPPMODULE", "original": "#### The root `AppModule`", "translation": "#### 根模块 `AppModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "OPENFILESRCAPPAPPMODULETSANDFINDTHEBROWSERMODULEIMPORTINTHENGMODULEMETADATAREPLACETHATIMPORTWITHTHISONE:", "original": "Open file `src/app/app.module.ts` and find the `BrowserModule` import in the `NgModule` metadata.\nReplace that import with this one:", "translation": "打开 `src/app/app.module.ts` 文件,并在 `NgModule` 的元数据中找到对 `BrowserModule` 的导入。\n把该导入改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANGULARADDSTHEAPPIDVALUEWHICHCANBEANYSTRINGTOTHESTYLENAMESOFTHESERVERRENDEREDPAGESSOTHATTHEYCANBEIDENTIFIEDANDREMOVEDWHENTHECLIENTAPPSTARTS", "original": "Angular adds the `appId` value (which can be _any_ string) to the style-names of the server-rendered pages,\nso that they can be identified and removed when the client app starts.", "translation": "Angular 会把 `appId` 值(它可以是*任何*字符串)添加到服务端渲染页面的样式名中,以便它们在客户端应用启动时可以被找到并移除。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUCANGETRUNTIMEINFORMATIONABOUTTHECURRENTPLATFORMANDTHEAPPIDBYINJECTION", "original": "You can get runtime information about the current platform and the `appId` by injection.", "translation": "你可以通过依赖注入取得关于当前平台和 `appId` 的运行时信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####ABSOLUTEHTTPURLS", "original": "#### Absolute HTTP URLs", "translation": "#### 在 HTTP 中使用绝对地址", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { - "original": "The tutorial's `HeroService` and `HeroSearchService` delegate to the Angular `Http` module to fetch application data.\nThese services send requests to _relative_ URLs such as `api/heroes`.", - "translation": "教程中的 `HeroService` 和 `HeroSearchService` 都委托了 Angular 的 `Http` 模块来获取应用数据。\n那些服务都把请求发送到了*相对* URL,比如 `api/heroes`。", + "key": "THETUTORIALSHEROSERVICEANDHEROSEARCHSERVICEDELEGATETOTHEANGULARHTTPCLIENTMODULETOFETCHAPPLICATIONDATATHESESERVICESSENDREQUESTSTORELATIVEURLSSUCHASAPIHEROES", + "original": "The tutorial's `HeroService` and `HeroSearchService` delegate to the Angular `HttpClient` module to fetch application data.\nThese services send requests to _relative_ URLs such as `api/heroes`.", + "translation": "教程中的 `HeroService` 和 `HeroSearchService` 都委托了 Angular 的 `HttpClient` 模块来获取应用数据。\n那些服务都把请求发送到了*相对* URL,比如 `api/heroes`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { - "original": "In a Universal app, `Http` URLs must be _absolute_ (e.g., `https://my-server.com/api/heroes`)\neven when the Universal web server is capable of handling those requests.", - "translation": "在 Universal 应用中,`Http` 的 URL 必须是*绝对地址*(比如 `https://my-server.com/api/heroes`),\n只有这样,Universal 的 Web 服务器才能处理那些请求。", + "key": "INAUNIVERSALAPPHTTPURLSMUSTBEABSOLUTEFOREXAMPLEHTTPS:MYSERVERCOMAPIHEROESEVENWHENTHEUNIVERSALWEBSERVERISCAPABLEOFHANDLINGTHOSEREQUESTS", + "original": "In a Universal app, HTTP URLs must be _absolute_, for example, `https://my-server.com/api/heroes` \neven when the Universal web server is capable of handling those requests.", + "translation": "在 Universal 应用中,HTTP 的 URL 必须是*绝对地址*(比如 `https://my-server.com/api/heroes`),\n只有这样,Universal 的 Web 服务器才能处理那些请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOULLHAVETOCHANGETHESERVICESTOMAKEREQUESTSWITHABSOLUTEURLSWHENRUNNINGONTHESERVERANDWITHRELATIVEURLSWHENRUNNINGINTHEBROWSER", "original": "You'll have to change the services to make requests with absolute URLs when running on the server\nand with relative URLs when running in the browser.", "translation": "你还要修改这些需要发起请求的服务,当它运行在服务端时使用绝对地址,运行在浏览器中时用相对地址。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ONESOLUTIONISTOPROVIDETHESERVERSRUNTIMEORIGINUNDERTHEANGULARAPPBASEREFTOKENAPICOMMONAPPBASEHREFINJECTITINTOTHESERVICEANDPREPENDTHEORIGINTOTHEREQUESTURL", "original": "One solution is to provide the server's runtime origin under the Angular [`APP_BASE_REF` token](api/common/APP_BASE_HREF),\ninject it into the service, and prepend the origin to the request URL.", "translation": "解决方案之一是通过 Angular 的 [`APP_BASE_REF` 令牌](api/common/APP_BASE_HREF)来提供服务器的源地址(origin),把它注入到服务中,并把这个源地址添加到所请求的 URL 之前。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "STARTBYCHANGINGTHEHEROSERVICECONSTRUCTORTOTAKEASECONDORIGINPARAMETERTHATISOPTIONALLYINJECTEDVIATHEAPPBASEHREFTOKEN", "original": "Start by changing the `HeroService` constructor to take a second `origin` parameter that is optionally injected via the `APP_BASE_HREF` token.", "translation": "先为 `HeroService` 的构造函数添加第二个 `origin` 参数,它是可选的,并通过 `APP_BASE_HREF` 令牌进行注入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "NOTEHOWTHECONSTRUCTORPREPENDSTHEORIGINIFITEXISTSTOTHEHEROESURL", "original": "Note how the constructor prepends the origin (if it exists) to the `heroesUrl`.", "translation": "注意,这个构造函数是如何把这个 `origin`(如果存在)添加到 `heroesUrl` 的前面的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUDONTPROVIDEAPPBASEHREFINTHEBROWSERVERSIONSOTHEHEROESURLREMAINSRELATIVE", "original": "You don't provide `APP_BASE_HREF` in the browser version, so the `heroesUrl` remains relative.", "translation": "在浏览器版本中,你不用提供 `APP_BASE_HREF`,因此 `heroesUrl` 仍然是相对的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUCANIGNOREAPPBASEHREFINTHEBROWSERIFYOUVESPECIFIEDBASEHREFINTHEINDEXHTMLTOSATISFYTHEROUTERSNEEDFORABASEADDRESSASTHETUTORIALSAMPLEDOES", "original": "You can ignore `APP_BASE_HREF` in the browser if you've specified `<base href=\"/\">` in the `index.html`\nto satisfy the router's need for a base address, as the tutorial sample does.", "translation": "如果你在 `index.html` 中为了满足路由器的需求已经指定过了 `<base href=\"/\">`,那就可以在浏览器中忽略 `APP_BASE_HREF`。参见教程的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "##SERVERCODE", "original": "## Server code", "translation": "## 服务端代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "TORUNANANGULARUNIVERSALAPPLICATIONYOULLNEEDASERVERTHATACCEPTSCLIENTREQUESTSANDRETURNSRENDEREDPAGES", "original": "To run an Angular Universal application, you'll need a server that accepts client requests and returns rendered pages.", "translation": "要想运行 Angular 的 Universal 应用,你需要一个服务器,用它来接受客户端的请求,并返回渲染好的页面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###APPSERVERMODULE", "original": "### App server module", "translation": "### 服务端应用模块", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEAPPSERVERMODULECLASSCONVENTIONALLYNAMEDAPPSERVERMODULEISANANGULARMODULETHATWRAPSTHEAPPLICATIONSROOTMODULEAPPMODULESOTHATUNIVERSALCANMEDIATEBETWEENYOURAPPLICATIONANDTHESERVERAPPSERVERMODULEALSOTELLSANGULARHOWTOBOOTSTRAPYOURAPPLICATIONWHENRUNNINGASAUNIVERSALAPP", "original": "The app server module class (conventionally named `AppServerModule`) is an Angular module that wraps the application's root module (`AppModule`) so that Universal can mediate between your application and the server.\n`AppServerModule` also tells Angular how to bootstrap your application when running as a Universal app.", "translation": "服务端应用模块(习惯上叫作 `AppServerModule`)是一个 Angular 模块,它包装了应用的根模块 `AppModule`,以便 Universal 可以在你的应用和服务器之间进行协调。\n`AppServerModule` 还会告诉 Angular 再把你的应用以 Universal 方式运行时,该如何引导它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "CREATEANAPPSERVERMODULETSFILEINTHESRCAPPDIRECTORYWITHTHEFOLLOWINGAPPSERVERMODULECODE:", "original": "Create an `app.server.module.ts` file in the `src/app/` directory with the following `AppServerModule` code:", "translation": "在 `src/app/` 目录下创建 `app.server.module.ts` 文件,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "NOTICETHATITIMPORTSFIRSTTHECLIENTAPPSAPPMODULETHEANGULARUNIVERSALSSERVERMODULEANDTHEMODULEMAPLOADERMODULE", "original": "Notice that it imports first the client app's `AppModule`, the Angular Universal's `ServerModule` and the `ModuleMapLoaderModule`.", "translation": "注意它首先导入了客户端应用的 `AppModule` 和来自 Angular Universal 的 `ServerModule`、`ModuleMapLoaderModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEMODULEMAPLOADERMODULEISASERVERSIDEMODULETHATALLOWSLAZYLOADINGOFROUTES", "original": "The `ModuleMapLoaderModule` is a server-side module that allows lazy-loading of routes.", "translation": "`ModuleMapLoaderModule` 是一个服务端模块,用于实现路由的惰性加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THISISALSOTHEPLACETOREGISTERPROVIDERSTHATARESPECIFICTORUNNINGYOURAPPUNDERUNIVERSAL", "original": "This is also the place to register providers that are specific to running your app under Universal.", "translation": "这里还可以注册那些在 Universal 环境下运行应用时特有的服务提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###UNIVERSALWEBSERVER", "original": "### Universal web server", "translation": "### Universal Web 服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "AUNIVERSALWEBSERVERRESPONDSTOAPPLICATIONPAGEREQUESTSWITHSTATICHTMLRENDEREDBYTHEUNIVERSALTEMPLATEENGINE#UNIVERSALENGINE", "original": "A _Universal_ web server responds to application _page_ requests with static HTML rendered by the [Universal template engine](#universal-engine).", "translation": "*Universal* Web 服务器负责响应对本应用的*页面*请求。它使用的是由 [Universal 模板引擎](#universal-engine)渲染出的 HTML。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ITRECEIVESANDRESPONDSTOHTTPREQUESTSFROMCLIENTSUSUALLYBROWSERSITSERVESSTATICASSETSSUCHASSCRIPTSCSSANDIMAGESITMAYRESPONDTODATAREQUESTSPERHAPSDIRECTLYORASAPROXYTOASEPARATEDATASERVER", "original": "It receives and responds to HTTP requests from clients (usually browsers).\nIt serves static assets such as scripts, css, and images.\nIt may respond to data requests, perhaps directly or as a proxy to a separate data server.", "translation": "它接受并响应来自客户端(通常是浏览器)的 HTTP 请求。\n它还会提供那些静态文件,比如脚本、css 和图片。\n它还可以响应数据请求,可能直接响应也可能将其代理到一个独立的数据服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THESAMPLEWEBSERVERFORTHISGUIDEISBASEDONTHEPOPULAREXPRESSHTTPS:EXPRESSJSCOMFRAMEWORK", "original": "The sample web server for _this_ guide is based on the popular [Express](https://expressjs.com/) framework.", "translation": "本文中的范例 Web 服务器基于常见的 [Express](https://expressjs.com/) 框架。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANYWEBSERVERTECHNOLOGYCANSERVEAUNIVERSALAPPASLONGASITCANCALLUNIVERSALSRENDERMODULEFACTORYTHEPRINCIPLESANDDECISIONPOINTSDISCUSSEDBELOWAPPLYTOANYWEBSERVERTECHNOLOGYTHATYOUCHOSE", "original": "_Any_ web server technology can serve a Universal app as long as it can call Universal's `renderModuleFactory`.\n The principles and decision points discussed below apply to any web server technology that you chose.", "translation": "*任何* Web 服务器技术都可以作为 Universal 应用的服务器,只要它能调用 Universal 的 `renderModuleFactory` 即可。\n 下面讨论的这些原则和决策要点适用于你选择的任何 Web 服务器技术。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "CREATEASERVERTSFILEINTHEROOTDIRECTORYANDADDTHEFOLLOWINGCODE:", "original": "Create a `server.ts` file in the root directory and add the following code:", "translation": "在根目录下创建 `server.ts` 文件,并添加下列代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THISSAMPLESERVERISNOTSECUREBESURETOADDMIDDLEWARETOAUTHENTICATEANDAUTHORIZEUSERSJUSTASYOUWOULDFORANORMALANGULARAPPLICATIONSERVER", "original": "**This sample server is not secure!**\n Be sure to add middleware to authenticate and authorize users\n just as you would for a normal Angular application server.", "translation": "**这个范例服务器是不安全的!**\n 如果你要把它作为正式的 Angular 应用服务器,别忘了添加中间件来对用户进行认证和授权。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####UNIVERSALTEMPLATEENGINE", "original": "#### Universal template engine", "translation": "#### Universal 模板引擎", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEIMPORTANTBITINTHISFILEISTHENGEXPRESSENGINEFUNCTION:", "original": "The important bit in this file is the `ngExpressEngine` function:", "translation": "这个文件中最重要的部分是 `ngExpressEngine` 函数:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THENGEXPRESSENGINEISAWRAPPERAROUNDTHEUNIVERSALSRENDERMODULEFACTORYFUNCTIONTHATTURNSACLIENTSREQUESTSINTOSERVERRENDEREDHTMLPAGESYOULLCALLTHATFUNCTIONWITHINATEMPLATEENGINETHATSAPPROPRIATEFORYOURSERVERSTACK", "original": "The `ngExpressEngine` is a wrapper around the universal's `renderModuleFactory` function that turns a client's requests into server-rendered HTML pages.\nYou'll call that function within a _template engine_ that's appropriate for your server stack.", "translation": "`ngExpressEngine` 是对 Universal 的 `renderModuleFactory` 函数的封装。它会把客户端请求转换成服务端渲染的 HTML 页面。\n你还要在某个适用于你服务端技术栈的*模板引擎*中调用这个函数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEFIRSTPARAMETERISTHEAPPSERVERMODULETHATYOUWROTEEARLIER#APPSERVERMODULEITSTHEBRIDGEBETWEENTHEUNIVERSALSERVERSIDERENDERERANDYOURAPPLICATION", "original": "The first parameter is the `AppServerModule` that you wrote [earlier](#app-server-module).\nIt's the bridge between the Universal server-side renderer and your application.", "translation": "第一个参数是你[以前](#app-server-module)写过的 `AppServerModule`。\n它是 Universal 服务端渲染器和你的应用之间的桥梁。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THESECONDPARAMETERISTHEEXTRAPROVIDERSITISANOPTIONALANGULARDEPENDENCYINJECTIONPROVIDERSAPPLICABLEWHENRUNNINGONTHISSERVER", "original": "The second parameter is the `extraProviders`. It is an optional Angular dependency injection providers, applicable when running on this server.", "translation": "第二个参数是 `extraProviders`。它是在这个服务器上运行时才需要的一些可选的 Angular 依赖注入提供商。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUSUPPLYEXTRAPROVIDERSWHENYOURAPPNEEDSINFORMATIONTHATCANONLYBEDETERMINEDBYTHECURRENTLYRUNNINGSERVERINSTANCE", "original": "You supply `extraProviders` when your app needs information that can only be determined by the currently running server instance.", "translation": "当你的应用需要那些只有当运行在服务器实例中才需要的信息时,就要提供 `extraProviders` 参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEREQUIREDINFORMATIONINTHISCASEISTHERUNNINGSERVERSORIGINPROVIDEDUNDERTHEAPPBASEHREFTOKENSOTHATTHEAPPCANCALCULATEABSOLUTEHTTPURLS#HTTPURLS", "original": "The required information in this case is the running server's origin, provided under the `APP_BASE_HREF` token, so that the app can [calculate absolute HTTP URLs](#http-urls).", "translation": "这里所需的信息就是正在运行的服务器的源地址,它通过 `APP_BASE_HREF` 令牌提供,以便应用可以 [计算出 HTTP URL 的绝对地址](#http-urls)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THENGEXPRESSENGINEFUNCTIONRETURNSAPROMISETHATRESOLVESTOTHERENDEREDPAGE", "original": "The `ngExpressEngine` function returns a _promise_ that resolves to the rendered page.", "translation": "`ngExpressEngine` 函数返回了一个会解析成渲染好的页面的*承诺(Promise)*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ITSUPTOYOURENGINETODECIDEWHATTODOWITHTHATPAGETHISENGINESPROMISECALLBACKRETURNSTHERENDEREDPAGETOTHEWEBSERVER#WEBSERVERWHICHTHENFORWARDSITTOTHECLIENTINTHEHTTPRESPONSE", "original": "It's up to your engine to decide what to do with that page.\n_This engine's_ promise callback returns the rendered page to the [web server](#web-server),\nwhich then forwards it to the client in the HTTP response.", "translation": "接下来你的引擎要决定拿这个页面做点什么。\n*现在这个引擎*的回调函数中,把渲染好的页面返回给了 [Web 服务器](#web-server),然后服务器通过 HTTP 响应把它转发给了客户端。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THISWRAPPERSAREVERYUSEFULTOHIDETHECOMPLEXITYOFTHERENDERMODULEFACTORYTHEREAREMOREWRAPPERSFORDIFFERENTBACKENDTECHNOLOGIESATTHEUNIVERSALREPOSITORYHTTPS:GITHUBCOMANGULARUNIVERSAL", "original": "This wrappers are very useful to hide the complexity of the `renderModuleFactory`. There are more wrappers for different backend technologies\n at the [Universal repository](https://github.com/angular/universal).", "translation": "这个包装器对于隐藏 `renderModuleFactory` 的复杂性非常有帮助。\n 在 [Universal 代码库中](https://github.com/angular/universal)还有更多针对其它后端技术的包装器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####FILTERREQUESTURLS", "original": "#### Filter request URLs", "translation": "#### 过滤请求的 URL", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEWEBSERVERMUSTDISTINGUISHAPPPAGEREQUESTSFROMOTHERKINDSOFREQUESTS", "original": "The web server must distinguish _app page requests_ from other kinds of requests.", "translation": "Web 服务器必须把*对应用页面的请求*和其它类型的请求区分开。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ITSNOTASSIMPLEASINTERCEPTINGAREQUESTTOTHEROOTADDRESSTHEBROWSERCOULDASKFORONEOFTHEAPPLICATIONROUTESSUCHASDASHBOARDHEROESORDETAIL:12INFACTIFTHEAPPWEREONLYRENDEREDBYTHESERVEREVERYAPPLINKCLICKEDWOULDARRIVEATTHESERVERASANAVIGATIONURLINTENDEDFORTHEROUTER", "original": "It's not as simple as intercepting a request to the root address `/`.\nThe browser could ask for one of the application routes such as `/dashboard`, `/heroes`, or `/detail:12`.\nIn fact, if the app were _only_ rendered by the server, _every_ app link clicked would arrive at the server\nas a navigation URL intended for the router.", "translation": "这可不像拦截对根路径 `/` 的请求那么简单。\n浏览器可以请求应用中的任何一个路由地址,比如 `/dashboard`、`/heroes` 或 `/detail:12`。\n事实上,如果应用*只*会通过服务器渲染,那么应用中点击的*任何一个*链接都会发到服务器,就像导航时的地址会发到路由器一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "FORTUNATELYAPPLICATIONROUTESHAVESOMETHINGINCOMMON:THEIRURLSLACKFILEEXTENSIONS", "original": "Fortunately, application routes have something in common: their URLs lack file extensions.", "translation": "幸运的是,应用的路由具有一些共同特征:它们的 URL 一般不带文件扩展名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "DATAREQUESTSALSOLACKEXTENSIONSBUTTHEYREEASYTORECOGNIZEBECAUSETHEYALWAYSBEGINWITHAPI", "original": "Data requests also lack extensions but they're easy to recognize because they always begin with `/api`.", "translation": "数据请求也可能不带扩展名,不过他们很容易识别出来,因为它们总是用 `/api` 开头。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ALLSTATICASSETREQUESTSHAVEAFILEEXTENSIONEGMAINJSORNODEMODULESZONEJSDISTZONEJS", "original": "All static asset requests have a file extension (e.g., `main.js` or `/node_modules/zone.js/dist/zone.js`).", "translation": "所有静态资源请求都具有一个扩展名(比如 `main.js` 或 `/node_modules/zone.js/dist/zone.js`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "SOWECANEASILYRECOGNIZETHETHREETYPESOFREQUESTSANDHANDLETHEMDIFFERENTLY", "original": "So we can easily recognize the three types of requests and handle them differently.", "translation": "所以,我们很容易识别出这三种类型的请求,并用不同的方式处理它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "1DATAREQUESTREQUESTURLTHATBEGINSAPI", "original": "1. data request - request URL that begins `/api`", "translation": "数据请求 - 请求的 URL 用 `/api` 开头", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "2APPNAVIGATIONREQUESTURLWITHNOFILEEXTENSION", "original": "2. app navigation - request URL with no file extension", "translation": "应用导航 - 请求的 URL 不带扩展名", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "3STATICASSETALLOTHERREQUESTS", "original": "3. static asset - all other requests.", "translation": "静态资源 - 所有其它请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANEXPRESSSERVERISAPIPELINEOFMIDDLEWARETHATFILTERSANDPROCESSESURLREQUESTSONEAFTERTHEOTHER", "original": "An Express server is a pipeline of middleware that filters and processes URL requests one after the other.", "translation": "Express 服务器是一系列中间件构成的管道,它会挨个对 URL 请求进行过滤和处理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUCONFIGURETHEEXPRESSSERVERPIPELINEWITHCALLSTOAPPGETLIKETHISONEFORDATAREQUESTS", "original": "You configure the Express server pipeline with calls to `app.get()` like this one for data requests.", "translation": "你通过通过调用 `app.get()` 来配置 Express 服务器的管道,就像下面这个数据请求一样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THISSAMPLESERVERDOESNTHANDLEDATAREQUESTS", "original": "This sample server doesn't handle data requests.", "translation": "这个范例服务器并没有处理数据请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THETUTORIALSINMEMORYWEBAPIMODULEADEMOANDDEVELOPMENTTOOLINTERCEPTSALLHTTPCALLSANDSIMULATESTHEBEHAVIOROFAREMOTEDATASERVERINPRACTICEYOUWOULDREMOVETHATMODULEANDREGISTERYOURWEBAPIMIDDLEWAREONTHESERVERHERE", "original": "The tutorial's \"in-memory web api\" module, a demo and development tool, intercepts all HTTP calls and\nsimulates the behavior of a remote data server.\nIn practice, you would remove that module and register your web api middleware on the server here.", "translation": "本教程的“内存 Web API” 模块(一个演示及开发工具)拦截了所有 HTTP 调用,并且模拟了远端数据服务器的行为。\n在实践中,你应该移除这个模块,并且在服务器上注册你的 Web API 中间件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "UNIVERSALHTTPREQUESTSHAVEDIFFERENTSECURITYREQUIREMENTS", "original": "**Universal HTTP requests have different security requirements**", "translation": "**Universal HTTP 请求具有不同的安全需求**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "HTTPREQUESTSISSUEDFROMABROWSERAPPARENOTTHESAMEASWHENISSUEDBYTHEUNIVERSALAPPONTHESERVER", "original": "HTTP requests issued from a browser app are not the same as when issued by the universal app on the server.", "translation": "从浏览器的应用中发起 HTTP 请求和从服务器的 Universal 应用中发起请求是不一样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "WHENABROWSERMAKESANHTTPREQUESTTHESERVERCANMAKEASSUMPTIONSABOUTCOOKIESXSRFHEADERSETC", "original": "When a browser makes an HTTP request, the server can make assumptions about cookies, XSRF headers, etc.", "translation": "当浏览器发起 HTTP 请求时,服务器可以假设存在 Cookie、XSRF 头等等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "FOREXAMPLETHEBROWSERAUTOMATICALLYSENDSAUTHCOOKIESFORTHECURRENTUSERANGULARUNIVERSALCANNOTFORWARDTHESECREDENTIALSTOASEPARATEDATASERVERIFYOURSERVERHANDLESHTTPREQUESTSYOULLHAVETOADDYOUROWNSECURITYPLUMBING", "original": "For example, the browser automatically sends auth cookies for the current user.\nAngular Universal cannot forward these credentials to a separate data server.\nIf your server handles HTTP requests, you'll have to add your own security plumbing.", "translation": "比如,浏览器会自动发送当前用户的认证 Cookie。\n但 Angular Universal 不能把这些凭证发送给独立的数据服务器。\n如果你的服务器要处理 HTTP 请求,你就得自行添加安全装置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEFOLLOWINGCODEFILTERSFORREQUESTURLSWITHNOEXTENSIONSANDTREATSTHEMASNAVIGATIONREQUESTS", "original": "The following code filters for request URLs with no extensions and treats them as navigation requests.", "translation": "下列代码会过滤出不带扩展名的 URL,并把它们当做导航请求进行处理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####SERVESTATICFILESSAFELY", "original": "#### Serve static files safely", "translation": "#### 安全的提供静态文件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ASINGLEAPPUSETREATSALLOTHERURLSASREQUESTSFORSTATICASSETSSUCHASJAVASCRIPTIMAGEANDSTYLEFILES", "original": "A single `app.use()` treats all other URLs as requests for static assets\nsuch as JavaScript, image, and style files.", "translation": "单独的 `app.use()` 会处理所有其它 URL,比如对 JavaScript 、图片和样式表等静态资源的请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "TOENSURETHATCLIENTSCANONLYDOWNLOADTHEFILESTHATTHEYAREPERMITTEDTOSEEYOUWILLPUTALLCLIENTFACINGASSETFILESINTHEDISTFOLDER#UNIVERSALWEBPACKCONFIGURATIONANDWILLONLYHONORREQUESTSFORFILESFROMTHEDISTFOLDER", "original": "To ensure that clients can only download the files that they are _permitted_ to see, you will [put all client-facing asset files in the `/dist` folder](#universal-webpack-configuration)\nand will only honor requests for files from the `/dist` folder.", "translation": "要保证客户端只能下载那些*允许*他们访问的文件,你应该[把所有面向客户端的资源文件都放在 `/dist` 目录下](#universal-webpack-configuration),并且只允许客户端请求来自 `/dist` 目录下的文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEFOLLOWINGEXPRESSCODEROUTESALLREMAININGREQUESTSTODISTITRETURNSA404NOTFOUNDIFTHEFILEISNOTFOUND", "original": "The following express code routes all remaining requests to `/dist`; it returns a `404 - NOT FOUND` if the file is not found.", "translation": "下列 Express 代码会把剩下的所有请求都路由到 `/dist` 目录下,如果文件未找到,就会返回 `404 - NOT FOUND`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "##CONFIGUREFORUNIVERSAL", "original": "## Configure for Universal", "translation": "## 配置 Universal", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THESERVERAPPLICATIONREQUIRESITSOWNBUILDCONFIGURATION", "original": "The server application requires its own build configuration.", "translation": "这个服务端应用需要自己的构建配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###UNIVERSALTYPESCRIPTCONFIGURATION", "original": "### Universal TypeScript configuration", "translation": "### Universal 的 TypeScript 配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "CREATEATSCONFIGSERVERJSONFILEINTHEPROJECTROOTDIRECTORYTOCONFIGURETYPESCRIPTANDAOTCOMPILATIONOFTHEUNIVERSALAPP", "original": "Create a `tsconfig.server.json` file in the project root directory to configure TypeScript and AOT compilation of the universal app.", "translation": "在项目的根目录下创建一个 `tsconfig.server.json` 文件来配置 TypeScript 和这个 Universal 应用的 AOT 编译选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THISCONFIGEXTENDSFROMTHEROOTSTSCONFIGJSONFILECERTAINSETTINGSARENOTEWORTHYFORTHEIRDIFFERENCES", "original": "This config extends from the root's `tsconfig.json` file. Certain settings are noteworthy for their differences.", "translation": "这个配置扩展了根目录下的 `tsconfig.json` 文件,注意它们在某些设置上的差异。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { - "original": "* The `module` property must be **commonjs** which can be require()'d into our server application.", + "key": "THEMODULEPROPERTYMUSTBECOMMONJSWHICHCANBEREQUIREDINTOOURSERVERAPPLICATION", + "original": "* The `module` property must be **commonjs** which can be required into our server application.", "translation": "`module` 属性必须是 **commonjs**,这样它才能被 `require()` 进你的服务端应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEANGULARCOMPILEROPTIONSSECTIONGUIDESTHEAOTCOMPILER:", "original": "* The `angularCompilerOptions` section guides the AOT compiler:", "translation": "`angularCompilerOptions` 部分有一些面向 AOT 编译器的选项:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ENTRYMODULETHEROOTMODULEOFTHESERVERAPPLICATIONEXPRESSEDASPATHTOFILE#CLASSNAME", "original": "* `entryModule` - the root module of the server application, expressed as `path/to/file#ClassName`.", "translation": "`entryModule` - 服务端应用的根模块,其格式为 `path/to/file#ClassName`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "###UNIVERSALWEBPACKCONFIGURATION", "original": "### Universal Webpack configuration", "translation": "### Universal 的 Webpack 配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "UNIVERSALAPPLICATIONSDOESNTNEEDANYEXTRAWEBPACKCONFIGURATIONTHECLITAKESCAREOFTHATFORYOUBUTSINCETHESERVERISATYPESCRIPTAPPLICATIONYOUWILLUSEWEBPACKTOTRANSPILEIT", "original": "Universal applications doesn't need any extra Webpack configuration, the CLI takes care of that for you,\nbut since the server is a typescript application, you will use Webpack to transpile it.", "translation": "Universal 应用不需要任何额外的 Webpack 配置,CLI 会帮你处理它们,但是由于这个服务器是 TypeScript 应用,所以你要使用 Webpack 来转译它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "CREATEAWEBPACKSERVERCONFIGJSFILEINTHEPROJECTROOTDIRECTORYWITHTHEFOLLOWINGCODE", "original": "Create a `webpack.server.config.js` file in the project root directory with the following code.", "translation": "在项目的根目录下创建一个 `webpack.server.config.js` 文件,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "WEBPACKCONFIGURATIONISARICHTOPICBEYONDTHESCOPEOFTHISGUIDE", "original": "**Webpack configuration** is a rich topic beyond the scope of this guide.", "translation": "**Webpack** 配置超出了本文的讨论范围。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "##BUILDANDRUNWITHUNIVERSAL", "original": "## Build and run with universal", "translation": "## 使用 Universal 构建和运行", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "NOWTHATYOUVECREATEDTHETYPESCRIPTANDWEBPACKCONFIGFILESYOUCANBUILDANDRUNTHEUNIVERSALAPPLICATION", "original": "Now that you've created the TypeScript and Webpack config files, you can build and run the Universal application.", "translation": "现在,你已经创建了 TypeScript 和 Webpack 的配置文件,你可以构建并运行这个 Universal 应用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "FIRSTADDTHEBUILDANDSERVECOMMANDSTOTHESCRIPTSSECTIONOFTHEPACKAGEJSON:", "original": "First add the _build_ and _serve_ commands to the `scripts` section of the `package.json`:", "translation": "首先把 `build` 和 `serve` 命令添加到 `package.json` 的 `scripts` 区:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####BUILD", "original": "#### Build", "translation": "#### 构建", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "FROMTHECOMMANDPROMPTTYPE", "original": "From the command prompt, type", "translation": "在命令行提示中输入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEANGULARCLICOMPILESANDBUNDLESTHEUNIVERSALAPPINTOTWODIFFERENTFOLDERSBROWSERANDSERVERWEBPACKTRANSPILESTHESERVERTSFILEINTOJAVASCRIPT", "original": "The Angular CLI compiles and bundles the universal app into two different folders, `browser` and `server`.\nWebpack transpiles the `server.ts` file into Javascript.", "translation": "Angular CLI 就会把这个 Universal 应用编译进两个目录:`browser` 和 `server`。\nWebpack 会把 `server.ts` 文件转译成 JavaScript。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "####SERVE", "original": "#### Serve", "translation": "#### 启动服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "AFTERBUILDINGTHEAPPLICATIONSTARTTHESERVER", "original": "After building the application, start the server.", "translation": "构建完应用之后,启动服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THECONSOLEWINDOWSHOULDSAY", "original": "The console window should say", "translation": "在控制台窗口中应该看到", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "##UNIVERSALINACTION", "original": "## Universal in action", "translation": "## Universal 实战", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "OPENABROWSERTOHTTP:LOCALHOST:4000YOUSHOULDSEETHEFAMILIARTOUROFHEROESDASHBOARDPAGE", "original": "Open a browser to http://localhost:4000/.\nYou should see the familiar Tour of Heroes dashboard page.", "translation": "打开浏览器,访问 http://localhost:4000/。\n你会看到熟悉的《英雄指南》仪表盘页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "NAVIGATIONVIAROUTERLINKSWORKSCORRECTLYYOUCANGOFROMTHEDASHBOARDTOTHEHEROESPAGEANDBACKYOUCANCLICKONAHEROONTHEDASHBOARDPAGETODISPLAYITSDETAILSPAGE", "original": "Navigation via `routerLinks` works correctly.\nYou can go from the Dashboard to the Heroes page and back.\nYou can click on a hero on the Dashboard page to display its Details page.", "translation": "通过 `routerLink` 能进行正常导航。\n你可以从仪表盘导航到英雄列表页,还可以返回。\n你可以在仪表盘页点击一个英雄,以显示他的详情页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "BUTCLICKSMOUSEMOVESANDKEYBOARDENTRIESAREINERT", "original": "But clicks, mouse-moves, and keyboard entries are inert.", "translation": "但是点击、鼠标移动和键盘操作都不行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "CLICKINGAHEROONTHEHEROESPAGEDOESNOTHING", "original": "* Clicking a hero on the Heroes page does nothing.", "translation": "点击英雄列表页中的英雄没反应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "YOUCANTADDORDELETEAHERO", "original": "* You can't add or delete a hero.", "translation": "你也不能添加或删除英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THESEARCHBOXONTHEDASHBOARDPAGEISIGNORED", "original": "* The search box on the Dashboard page is ignored.", "translation": "仪表盘页面上的搜索框不理你。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THEBACKANDSAVEBUTTONSONTHEDETAILSPAGEDONTWORK", "original": "* The _back_ and _save_ buttons on the Details page don't work.", "translation": "详情页中的 *Back* 和 *Save* 按钮也没反应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "USEREVENTSOTHERTHANROUTERLINKCLICKSARENTSUPPORTEDTHEUSERMUSTWAITFORTHEFULLCLIENTAPPTOARRIVE", "original": "User events other than `routerLink` clicks aren't supported.\nThe user must wait for the full client app to arrive.", "translation": "除了点击 `RouterLink` 之外的用户事件都不支持。用户必须等待完整的客户端应用就绪。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ITWILLNEVERARRIVEUNTILYOUCOMPILETHECLIENTAPPANDMOVETHEOUTPUTINTOTHEDISTFOLDERASTEPYOULLTAKEINJUSTAMOMENT", "original": "It will never arrive until you compile the client app\nand move the output into the `dist/` folder,\na step you'll take in just a moment.", "translation": "直到你编译出客户端应用,并把它们的输出移到 `dist/` 目录下,这个客户端应用才会就绪。\n你自己稍微花点时间完成这步就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "##THROTTLING", "original": "## Throttling", "translation": "## 限流", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THETRANSITIONFROMTHESERVERRENDEREDAPPTOTHECLIENTAPPHAPPENSQUICKLYONADEVELOPMENTMACHINEYOUCANSIMULATEASLOWERNETWORKTOSEETHETRANSITIONMORECLEARLYANDBETTERAPPRECIATETHELAUNCHSPEEDADVANTAGEOFAUNIVERSALAPPRUNNINGONALOWPOWEREDPOORLYCONNECTEDDEVICE", "original": "The transition from the server-rendered app to the client app happens quickly on a development machine.\nYou can simulate a slower network to see the transition more clearly and\nbetter appreciate the launch-speed advantage of a universal app running on a low powered, poorly connected device.", "translation": "在开发机上,从服务端渲染应用到客户端应用的转换完成的太快了。\n你可以模拟一个慢速网络,来把这个转换过程看得更清楚一点,以便更好地欣赏在性能低、网络烂的设备上 Universal 应用的启动速度优势。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "OPENTHECHROMEDEVTOOLSANDGOTOTHENETWORKTABFINDTHENETWORKTHROTTLINGHTTPS:DEVELOPERSGOOGLECOMWEBTOOLSCHROMEDEVTOOLSNETWORKPERFORMANCEREFERENCE#THROTTLINGDROPDOWNONTHEFARRIGHTOFTHEMENUBAR", "original": "Open the Chrome Dev Tools and go to the Network tab.\nFind the [Network Throttling](https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#throttling) dropdown on the far right of the menu bar.", "translation": "打开 Chrome 开发工具,并打开 Network 页。\n在菜单栏的最右侧找到 [Network Throttling(网络限流)](https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#throttling) 下拉框。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "TRYONEOFTHE3GSPEEDSTHESERVERRENDEREDAPPSTILLLAUNCHESQUICKLYBUTTHEFULLCLIENTAPPMAYTAKESECONDSTOLOAD", "original": "Try one of the \"3G\" speeds.\nThe server-rendered app still launches quickly but the full client app may take seconds to load.", "translation": "随便试一个 “3G” 速度。\n服务端渲染的应用将会立即启动,不过加载完整的客户端应用可能要花几秒钟。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "THISGUIDESHOWEDYOUHOWTOTAKEANEXISTINGANGULARAPPLICATIONANDMAKEITINTOAUNIVERSALAPPTHATDOESSERVERSIDERENDERINGITALSOEXPLAINEDSOMEOFTHEKEYREASONSFORDOINGSO", "original": "This guide showed you how to take an existing Angular application and make it into a Universal app that does server-side rendering.\nIt also explained some of the key reasons for doing so.", "translation": "本文为你演示了如何把一个现有 Angular 应用转换成支持服务端渲染的 Universal 应用。\n还解释了为何要这么做的一些关键原因。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "FACILITATEWEBCRAWLERSSEO", "original": "- Facilitate web crawlers (SEO)", "translation": "帮助网络爬虫(SEO)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "SUPPORTLOWBANDWIDTHORLOWPOWERDEVICES", "original": "- Support low-bandwidth or low-power devices", "translation": "支持低带宽或低功耗设备", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "FASTFIRSTPAGELOAD", "original": "- Fast first page load", "translation": "快速加载首屏", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "ANGULARUNIVERSALCANGREATLYIMPROVETHEPERCEIVEDSTARTUPPERFORMANCEOFYOURAPPTHESLOWERTHENETWORKTHEMOREADVANTAGEOUSITBECOMESTOHAVEUNIVERSALDISPLAYTHEFIRSTPAGETOTHEUSER", "original": "Angular Universal can greatly improve the perceived startup performance of your app.\nThe slower the network, the more advantageous it becomes to have Universal display the first page to the user.", "translation": "Angular Universal 可以大幅提升应用的启动性能观感。\n在越是慢速的网络下,使用 Universal 来为用户展现首屏就越能体现出更大的优势。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/universal.md" }, { + "key": "#UPGRADINGFROMANGULARJS", "original": "# Upgrading from AngularJS", "translation": "# 从 AngularJS 升级", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARISTHENAMEFORTHEANGULAROFTODAYANDTOMORROWANGULARJSISTHENAMEFORALLV1XVERSIONSOFANGULAR", "original": "_Angular_ is the name for the Angular of today and tomorrow.\n_AngularJS_ is the name for all v1.x versions of Angular.", "translation": "*Angular* 这个名字专指现在和未来的 Angular 版本,而 *AngularJS* 专指 Angular 的所有 v1.x 版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARJSAPPSAREGREATALWAYSCONSIDERTHEBUSINESSCASEBEFOREMOVINGTOANGULARANIMPORTANTPARTOFTHATCASEISTHETIMEANDEFFORTTOGETTHERETHISGUIDEDESCRIBESTHEBUILTINTOOLSFOREFFICIENTLYMIGRATINGANGULARJSPROJECTSOVERTOTHEANGULARPLATFORMAPIECEATATIME", "original": "AngularJS apps are great.\nAlways consider the business case before moving to Angular.\nAn important part of that case is the time and effort to get there.\nThis guide describes the built-in tools for efficiently migrating AngularJS projects over to the\nAngular platform, a piece at a time.", "translation": "有很多大型 AngularJS 应用。\n在决定迁移到 Angular 之前,首先要深入思考业务案例。\n在这些案例中,最重要的部分之一是时间和需要付出的努力。\n本章描述用于把 AngularJS 应用高效迁移到 Angular 平台的内置工具,每次讲一点点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SOMEAPPLICATIONSWILLBEEASIERTOUPGRADETHANOTHERSANDTHEREAREMANYWAYSTOMAKEITEASIERFORYOURSELFITISPOSSIBLETOPREPAREANDALIGNANGULARJSAPPLICATIONSWITHANGULAREVENBEFOREBEGINNINGTHEUPGRADEPROCESSTHESEPREPARATIONSTEPSAREALLABOUTMAKINGTHECODEMOREDECOUPLEDMOREMAINTAINABLEANDBETTERALIGNEDWITHMODERNDEVELOPMENTTOOLSTHATMEANSINADDITIONTOMAKINGTHEUPGRADEEASIERYOUWILLALSOIMPROVETHEEXISTINGANGULARJSAPPLICATIONS", "original": "Some applications will be easier to upgrade than others, and there are\nmany ways to make it easier for yourself. It is possible to\nprepare and align AngularJS applications with Angular even before beginning\nthe upgrade process. These preparation steps are all about making the code\nmore decoupled, more maintainable, and better aligned with modern development\ntools. That means in addition to making the upgrade easier,\nyou will also improve the existing AngularJS applications.", "translation": "有些应用可能比其它的升级起来简单,还有一些方法能让把这项工作变得更简单。\n即使在正式开始升级过程之前,可以提前准备 AngularJS 的程序,让它向 Angular 看齐。\n这些准备步骤几乎都是关于如何让代码更加松耦合、更有可维护性,以及用现代开发工具提高速度的。\n这意味着,这种准备工作不仅能让最终的升级变得更简单,而且还能提升 AngularJS 程序的质量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ONEOFTHEKEYSTOASUCCESSFULUPGRADEISTODOITINCREMENTALLYBYRUNNINGTHETWOFRAMEWORKSSIDEBYSIDEINTHESAMEAPPLICATIONANDPORTINGANGULARJSCOMPONENTSTOANGULARONEBYONETHISMAKESITPOSSIBLETOUPGRADEEVENLARGEANDCOMPLEXAPPLICATIONSWITHOUTDISRUPTINGOTHERBUSINESSBECAUSETHEWORKCANBEDONECOLLABORATIVELYANDSPREADOVERAPERIODOFTIMETHEUPGRADEMODULEINANGULARHASBEENDESIGNEDTOMAKEINCREMENTALUPGRADINGSEAMLESS", "original": "One of the keys to a successful upgrade is to do it incrementally,\nby running the two frameworks side by side in the same application, and\nporting AngularJS components to Angular one by one. This makes it possible\nto upgrade even large and complex applications without disrupting other\nbusiness, because the work can be done collaboratively and spread over\na period of time. The `upgrade` module in Angular has been designed to\nmake incremental upgrading seamless.", "translation": "成功升级的关键之一是增量式的实现它,通过在同一个应用中一起运行这两个框架,并且逐个把 AngularJS 的组件迁移到 Angular 中。\n这意味着可以在不必打断其它业务的前提下,升级更大、更复杂的应用程序,因为这项工作可以多人协作完成,在一段时间内逐渐铺开。\nAngular `upgrade` 模块的设计目标就是让你渐进、无缝的完成升级。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "##PREPARATION", "original": "## Preparation", "translation": "## 准备工作", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEREAREMANYWAYSTOSTRUCTUREANGULARJSAPPLICATIONSWHENYOUBEGINTOUPGRADETHESEAPPLICATIONSTOANGULARSOMEWILLTURNOUTTOBEMUCHMOREEASYTOWORKWITHTHANOTHERSTHEREAREAFEWKEYTECHNIQUESANDPATTERNSTHATYOUCANAPPLYTOFUTUREPROOFAPPSEVENBEFOREYOUBEGINTHEMIGRATION", "original": "There are many ways to structure AngularJS applications. When you begin\nto upgrade these applications to Angular, some will turn out to be\nmuch more easy to work with than others. There are a few key techniques\nand patterns that you can apply to future proof apps even before you\nbegin the migration.", "translation": "AngularJS 应用程序的组织方式有很多种。当你想把它们升级到 Angular 的时候,\n有些做起来会比其它的更容易些。即使在开始升级之前,也有一些关键的技术和模式可以让你将来升级时更轻松。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###FOLLOWTHEANGULARJSSTYLEGUIDE", "original": "### Follow the AngularJS Style Guide", "translation": "### 遵循 AngularJS 风格指南", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEANGULARJSSTYLEGUIDEHTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMDCOLLECTSPATTERNSANDPRACTICESTHATHAVEBEENPROVENTORESULTINCLEANERANDMOREMAINTAINABLEANGULARJSAPPLICATIONSITCONTAINSAWEALTHOFINFORMATIONABOUTHOWTOWRITEANDORGANIZEANGULARJSCODEANDEQUALLYIMPORTANTLYHOWNOTTOWRITEANDORGANIZEANGULARJSCODE", "original": "The [AngularJS Style Guide](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md)\ncollects patterns and practices that have been proven to result in\ncleaner and more maintainable AngularJS applications. It contains a wealth\nof information about how to write and organize AngularJS code - and equally\nimportantly - how **not** to write and organize AngularJS code.", "translation": "[AngularJS 风格指南](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md)收集了一些已证明能写出干净且可维护的 AngularJS 程序的模式与实践。\n它包含了很多关于如何书写和组织 AngularJS 代码的有价值信息,同样重要的是,**不应该**采用的书写和组织 AngularJS 代码的方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARISAREIMAGINEDVERSIONOFTHEBESTPARTSOFANGULARJSINTHATSENSEITSGOALSARETHESAMEASTHEANGULARJSSTYLEGUIDES:TOPRESERVETHEGOODPARTSOFANGULARJSANDTOAVOIDTHEBADPARTSTHERESALOTMORETOANGULARTHANJUSTTHATOFCOURSEBUTTHISDOESMEANTHATFOLLOWINGTHESTYLEGUIDEHELPSMAKEYOURANGULARJSAPPMORECLOSELYALIGNEDWITHANGULAR", "original": "Angular is a reimagined version of the best parts of AngularJS. In that\nsense, its goals are the same as the AngularJS Style Guide's: To preserve\nthe good parts of AngularJS, and to avoid the bad parts. There's a lot\nmore to Angular than just that of course, but this does mean that\n*following the style guide helps make your AngularJS app more closely\naligned with Angular*.", "translation": "Angular 是一个基于 AngularJS 中最好的部分构思出来的版本。在这种意义上,它的目标和 AngularJS 风格指南是一样的:\n保留 AngularJS 中好的部分,去掉坏的部分。当然,Angular 还做了更多。\n说这些的意思是:*遵循这个风格指南可以让你写出更接近 Angular 程序的 AngularJS 程序*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEREAREAFEWRULESINPARTICULARTHATWILLMAKEITMUCHEASIERTODOANINCREMENTALUPGRADEUSINGTHEANGULARUPGRADESTATICMODULE:", "original": "There are a few rules in particular that will make it much easier to do\n*an incremental upgrade* using the Angular `upgrade/static` module:", "translation": "有一些特别的规则可以让使用 Angular 的 `upgrade/static` 模块进行*增量升级*变得更简单:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THERULEOF1HTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMD#SINGLERESPONSIBILITYSTATESTHATTHERESHOULDBEONECOMPONENTPERFILETHISNOTONLYMAKESCOMPONENTSEASYTONAVIGATEANDFINDBUTWILLALSOALLOWUSTOMIGRATETHEMBETWEENLANGUAGESANDFRAMEWORKSONEATATIMEINTHISEXAMPLEAPPLICATIONEACHCONTROLLERCOMPONENTSERVICEANDFILTERISINITSOWNSOURCEFILE", "original": "* The [Rule of 1](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#single-responsibility)\n states that there should be one component per file. This not only makes\n components easy to navigate and find, but will also allow us to migrate\n them between languages and frameworks one at a time. In this example application,\n each controller, component, service, and filter is in its own source file.", "translation": "[单一规则](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#single-responsibility)\n 规定每个文件应该只放一个组件。这不仅让组件更容易浏览和查找,而且还让你能逐个迁移它们的语言和框架。\n 在这个范例程序中,每个控制器、工厂和过滤器都位于各自的源文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEFOLDERSBYFEATURESTRUCTUREHTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMD#FOLDERSBYFEATURESTRUCTUREANDMODULARITYHTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMD#MODULARITYRULESDEFINESIMILARPRINCIPLESONAHIGHERLEVELOFABSTRACTION:DIFFERENTPARTSOFTHEAPPLICATIONSHOULDRESIDEINDIFFERENTDIRECTORIESANDNGMODULES", "original": "* The [Folders-by-Feature Structure](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#folders-by-feature-structure)\n and [Modularity](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#modularity)\n rules define similar principles on a higher level of abstraction: Different parts of the\n application should reside in different directories and NgModules.", "translation": "[按特性分目录的结构](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#folders-by-feature-structure)和[模块化](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#modularity)规则在较高的抽象层定义了一些相似的原则:应用程序中的不同部分应该被分到不同的目录和 Angular 模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENANAPPLICATIONISLAIDOUTFEATUREPERFEATUREINTHISWAYITCANALSOBEMIGRATEDONEFEATUREATATIMEFORAPPLICATIONSTHATDONTALREADYLOOKLIKETHISAPPLYINGTHERULESINTHEANGULARJSSTYLEGUIDEISAHIGHLYRECOMMENDEDPREPARATIONSTEPANDTHISISNOTJUSTFORTHESAKEOFTHEUPGRADEITISJUSTSOLIDADVICEINGENERAL", "original": "When an application is laid out feature per feature in this way, it can also be\nmigrated one feature at a time. For applications that don't already look like\nthis, applying the rules in the AngularJS style guide is a highly recommended\npreparation step. And this is not just for the sake of the upgrade - it is just\nsolid advice in general!", "translation": "如果应用程序能用这种方式把每个特性分到一个独立目录中,它也就能每次迁移一个特性。\n对于那些还没有这么做的程序,强烈建议把应用这条规则作为准备步骤。而且这也不仅仅对升级有价值,\n它还是一个通用的规则,可以让你的程序更“坚实”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###USINGAMODULELOADER", "original": "### Using a Module Loader", "translation": "### 使用模块加载器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENYOUBREAKAPPLICATIONCODEDOWNINTOONECOMPONENTPERFILEYOUOFTENENDUPWITHAPROJECTSTRUCTUREWITHALARGENUMBEROFRELATIVELYSMALLFILESTHISISAMUCHNEATERWAYTOORGANIZETHINGSTHANASMALLNUMBEROFLARGEFILESBUTITDOESNTWORKTHATWELLIFYOUHAVETOLOADALLTHOSEFILESTOTHEHTMLPAGEWITHLTSCRIPTGTTAGSESPECIALLYWHENYOUALSOHAVETOMAINTAINTHOSETAGSINTHECORRECTORDERTHATSWHYITSAGOODIDEATOSTARTUSINGAMODULELOADER", "original": "When you break application code down into one component per file, you often end\nup with a project structure with a large number of relatively small files. This is\na much neater way to organize things than a small number of large files, but it\ndoesn't work that well if you have to load all those files to the HTML page with\n<script> tags. Especially when you also have to maintain those tags in the correct\norder. That's why it's a good idea to start using a *module loader*.", "translation": "当你把应用代码分解到每个文件中只放一个组件的粒度后,通常会得到一个由大量相对较小的文件组成的项目结构。\n这比组织成少量大文件要整洁得多,但如果你不得不通过 `<script>` 标签在 HTML 页面中加载所有这些文件,那就不好玩了。\n尤其是当你不得不自己按正确的顺序维护这些标签时更是如此,就要开始使用*模块加载器*了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "USINGAMODULELOADERSUCHASSYSTEMJSHTTPS:GITHUBCOMSYSTEMJSSYSTEMJSWEBPACKHTTP:WEBPACKGITHUBIOORBROWSERIFYHTTP:BROWSERIFYORGALLOWSUSTOUSETHEBUILTINMODULESYSTEMSOFTYPESCRIPTORES2015YOUCANUSETHEIMPORTANDEXPORTFEATURESTHATEXPLICITLYSPECIFYWHATCODECANANDWILLBESHAREDBETWEENDIFFERENTPARTSOFTHEAPPLICATIONFORES5APPLICATIONSYOUCANUSECOMMONJSSTYLEREQUIREANDMODULEEXPORTSFEATURESINBOTHCASESTHEMODULELOADERWILLTHENTAKECAREOFLOADINGALLTHECODETHEAPPLICATIONNEEDSINTHECORRECTORDER", "original": "Using a module loader such as [SystemJS](https://github.com/systemjs/systemjs),\n[Webpack](http://webpack.github.io/), or [Browserify](http://browserify.org/)\nallows us to use the built-in module systems of TypeScript or ES2015.\nYou can use the `import` and `export` features that explicitly specify what code can\nand will be shared between different parts of the application. For ES5 applications\nyou can use CommonJS style `require` and `module.exports` features. In both cases,\nthe module loader will then take care of loading all the code the application needs\nin the correct order.", "translation": "使用模块加载器,比如[SystemJS](https://github.com/systemjs/systemjs)、\n[Webpack](http://webpack.github.io/)或[Browserify](http://browserify.org/),\n可以让你在程序中使用 TypeScript 或 ES2015 语言内置的模块系统。\n你可以使用 `import` 和 `export` 特性来明确指定哪些代码应该以及将会被在程序的不同部分之间共享。\n对于 ES5 程序来说,可以改用 CommonJS 风格的 `require` 和 `module.exports` 特性代替。\n无是论哪种情况,模块加载器都会按正确的顺序加载程序中用到的所有代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENMOVINGAPPLICATIONSINTOPRODUCTIONMODULELOADERSALSOMAKEITEASIERTOPACKAGETHEMALLUPINTOPRODUCTIONBUNDLESWITHBATTERIESINCLUDED", "original": "When moving applications into production, module loaders also make it easier\nto package them all up into production bundles with batteries included.", "translation": "当要把应用程序投入生产环境时,模块加载器也会让你把所有这些文件打成完整的产品包变得容易一些。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###MIGRATINGTOTYPESCRIPT", "original": "### Migrating to TypeScript", "translation": "### 迁移到 TypeScript", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "IFPARTOFTHEANGULARUPGRADEPLANISTOALSOTAKETYPESCRIPTINTOUSEITMAKESSENSETOBRINGINTHETYPESCRIPTCOMPILEREVENBEFORETHEUPGRADEITSELFBEGINSTHISMEANSTHERESONELESSTHINGTOLEARNANDTHINKABOUTDURINGTHEACTUALUPGRADEITALSOMEANSYOUCANSTARTUSINGTYPESCRIPTFEATURESINYOURANGULARJSCODE", "original": "If part of the Angular upgrade plan is to also take TypeScript into use, it makes\nsense to bring in the TypeScript compiler even before the upgrade itself begins.\nThis means there's one less thing to learn and think about during the actual upgrade.\nIt also means you can start using TypeScript features in your AngularJS code.", "translation": "Angular 升级计划的一部分是引入 TypeScript,即使在开始升级之前,引入 TypeScript 编译器也是有意义的。\n这意味着等真正升级的时候需要学习和思考的东西会更少,并且你可以在 AngularJS 代码中开始使用 TypeScript 的特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SINCETYPESCRIPTISASUPERSETOFECMASCRIPT2015WHICHINTURNISASUPERSETOFECMASCRIPT5SWITCHINGTOTYPESCRIPTDOESNTNECESSARILYREQUIREANYTHINGMORETHANINSTALLINGTHETYPESCRIPTCOMPILERANDRENAMINGFILESFROMJSTOTSBUTJUSTDOINGTHATISNOTHUGELYUSEFULOREXCITINGOFCOURSEADDITIONALSTEPSLIKETHEFOLLOWINGCANGIVEUSMUCHMOREBANGFORTHEBUCK:", "original": "Since TypeScript is a superset of ECMAScript 2015, which in turn is a superset\nof ECMAScript 5, \"switching\" to TypeScript doesn't necessarily require anything\nmore than installing the TypeScript compiler and renaming files from\n`*.js` to `*.ts`. But just doing that is not hugely useful or exciting, of course.\nAdditional steps like the following can give us much more bang for the buck:", "translation": "TypeScript 是 ECMAScript 2015 的超集,而 ES2015 又是 ECMAScript 5 的超集。\n这意味着除了安装一个 TypeScript 编译器,并把文件名都从 `*.js` 改成 `*.ts` 之外,其实什么都不用做。\n当然,如果仅仅这样做也没什么大用,也没什么有意思的地方。\n下面这些额外的步骤可以让你打起精神:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FORAPPLICATIONSTHATUSEAMODULELOADERTYPESCRIPTIMPORTSANDEXPORTSWHICHAREREALLYECMASCRIPT2015IMPORTSANDEXPORTSCANBEUSEDTOORGANIZECODEINTOMODULES", "original": "* For applications that use a module loader, TypeScript imports and exports\n (which are really ECMAScript 2015 imports and exports) can be used to organize\n code into modules.", "translation": "对那些使用了模块加载器的程序,TypeScript 的导入和导出语法(实际上是 ECMAScript 2015 的导入和导出)可以把代码组织成模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TYPEANNOTATIONSCANBEGRADUALLYADDEDTOEXISTINGFUNCTIONSANDVARIABLESTOPINDOWNTHEIRTYPESANDGETBENEFITSLIKEBUILDTIMEERRORCHECKINGGREATAUTOCOMPLETIONSUPPORTANDINLINEDOCUMENTATION", "original": "* Type annotations can be gradually added to existing functions and variables\n to pin down their types and get benefits like build-time error checking,\n great autocompletion support and inline documentation.", "translation": "可以逐步把类型注解添加到现有函数和变量上,以固定它们的类型,并获得其优点:比如编译期错误检查、更好的支持自动完成,以及内联式文档等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "JAVASCRIPTFEATURESNEWTOES2015LIKEARROWFUNCTIONSLETSANDCONSTSDEFAULTFUNCTIONPARAMETERSANDDESTRUCTURINGASSIGNMENTSCANALSOBEGRADUALLYADDEDTOMAKETHECODEMOREEXPRESSIVE", "original": "* JavaScript features new to ES2015, like arrow functions, `let`s and `const`s,\n default function parameters, and destructuring assignments can also be gradually\n added to make the code more expressive.", "translation": "那些 ES2015 中新增的特性,比如箭头函数、`let`、`const`、默认函数参数、解构赋值等也可以逐渐添加进来,让代码更有表现力。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SERVICESANDCONTROLLERSCANBETURNEDINTOCLASSESTHATWAYTHEYLLBEASTEPCLOSERTOBECOMINGANGULARSERVICEANDCOMPONENTCLASSESWHICHWILLMAKELIFEEASIERAFTERTHEUPGRADE", "original": "* Services and controllers can be turned into *classes*. That way they'll be a step\n closer to becoming Angular service and component classes, which will make\n life easier after the upgrade.", "translation": "服务和控制器可以转成*类*。这样它们就能一步步接近 Angular 的服务和组件类了,也会让升级变得简单一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###USINGCOMPONENTDIRECTIVES", "original": "### Using Component Directives", "translation": "### 使用组件型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INANGULARCOMPONENTSARETHEMAINPRIMITIVEFROMWHICHUSERINTERFACESAREBUILTYOUDEFINETHEDIFFERENTPORTIONSOFTHEUIASCOMPONENTSANDCOMPOSETHEMINTOAFULLUSEREXPERIENCE", "original": "In Angular, components are the main primitive from which user interfaces\nare built. You define the different portions of the UI as components and\ncompose them into a full user experience.", "translation": "在 Angular 中,组件是用来构建用户界面的主要元素。你把 UI 中的不同部分定义成组件,然后在模板中使用这些组件合成出最终的 UI。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANALSODOTHISINANGULARJSUSINGCOMPONENTDIRECTIVESTHESEAREDIRECTIVESTHATDEFINETHEIROWNTEMPLATESCONTROLLERSANDINPUTOUTPUTBINDINGSTHESAMETHINGSTHATANGULARCOMPONENTSDEFINEAPPLICATIONSBUILTWITHCOMPONENTDIRECTIVESAREMUCHEASIERTOMIGRATETOANGULARTHANAPPLICATIONSBUILTWITHLOWERLEVELFEATURESLIKENGCONTROLLERNGINCLUDEANDSCOPEINHERITANCE", "original": "You can also do this in AngularJS, using *component directives*. These are\ndirectives that define their own templates, controllers, and input/output bindings -\nthe same things that Angular components define. Applications built with\ncomponent directives are much easier to migrate to Angular than applications\nbuilt with lower-level features like `ng-controller`, `ng-include`, and scope\ninheritance.", "translation": "你在 AngularJS 中也能这么做。那就是一种定义了自己的模板、控制器和输入/输出绑定的指令 —— 跟 Angular 中对组件的定义是一样的。\n要迁移到 Angular,通过组件型指令构建的应用程序会比直接用 `ng-controller`、`ng-include` 和作用域继承等底层特性构建的要容易得多。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TOBEANGULARCOMPATIBLEANANGULARJSCOMPONENTDIRECTIVESHOULDCONFIGURETHESEATTRIBUTES:", "original": "To be Angular compatible, an AngularJS component directive should configure\nthese attributes:", "translation": "要与 Angular 兼容,AngularJS 的组件型指令应该配置下列属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "RESTRICT:ECOMPONENTSAREUSUALLYUSEDASELEMENTS", "original": "* `restrict: 'E'`. Components are usually used as elements.", "translation": "`restrict: 'E'`。组件通常会以元素的方式使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SCOPE:ANISOLATESCOPEINANGULARCOMPONENTSAREALWAYSISOLATEDFROMTHEIRSURROUNDINGSANDYOUSHOULDDOTHISINANGULARJSTOO", "original": "* `scope: {}` - an isolate scope. In Angular, components are always isolated\n from their surroundings, and you should do this in AngularJS too.", "translation": "`scope: {}` - 一个独立作用域。在 Angular 中,组件永远是从它们的环境中被隔离出来的,在 AngularJS 中也同样如此。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "BINDTOCONTROLLER:COMPONENTINPUTSANDOUTPUTSSHOULDBEBOUNDTOTHECONTROLLERINSTEADOFUSINGTHESCOPE", "original": "* `bindToController: {}`. Component inputs and outputs should be bound\n to the controller instead of using the `$scope`.", "translation": "`bindToController: {}`。组件的输入和输出应该绑定到控制器,而不是 `$scope`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "CONTROLLERANDCONTROLLERASCOMPONENTSHAVETHEIROWNCONTROLLERS", "original": "* `controller` and `controllerAs`. Components have their own controllers.", "translation": "`controller` 和 `controllerAs`。组件要有自己的控制器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TEMPLATEORTEMPLATEURLCOMPONENTSHAVETHEIROWNTEMPLATES", "original": "* `template` or `templateUrl`. Components have their own templates.", "translation": "`template` 或 `templateUrl`。组件要有自己的模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "COMPONENTDIRECTIVESMAYALSOUSETHEFOLLOWINGATTRIBUTES:", "original": "Component directives may also use the following attributes:", "translation": "组件型指令还可能使用下列属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TRANSCLUDE:TRUEIFTHECOMPONENTNEEDSTOTRANSCLUDECONTENTFROMELSEWHERE", "original": "* `transclude: true/{}`, if the component needs to transclude content from elsewhere.", "translation": "`transclude: true`:如果组件需要从其它地方透传内容,就设置它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "REQUIREIFTHECOMPONENTNEEDSTOCOMMUNICATEWITHSOMEPARENTCOMPONENTSCONTROLLER", "original": "* `require`, if the component needs to communicate with some parent component's\n controller.", "translation": "`require`:如果组件需要和父组件的控制器通讯,就设置它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "COMPONENTDIRECTIVESSHOULDNOTUSETHEFOLLOWINGATTRIBUTES:", "original": "Component directives **should not** use the following attributes:", "translation": "组件型指令**不能**使用下列属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "COMPILETHISWILLNOTBESUPPORTEDINANGULAR", "original": "* `compile`. This will not be supported in Angular.", "translation": "`compile`。Angular 不再支持它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "REPLACE:TRUEANGULARNEVERREPLACESACOMPONENTELEMENTWITHTHECOMPONENTTEMPLATETHISATTRIBUTEISALSODEPRECATEDINANGULARJS", "original": "* `replace: true`. Angular never replaces a component element with the\n component template. This attribute is also deprecated in AngularJS.", "translation": "`replace: true`。Angular 永远不会用组件模板替换一个组件元素。这个特性在 AngularJS 中也同样不建议使用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "PRIORITYANDTERMINALWHILEANGULARJSCOMPONENTSMAYUSETHESETHEYARENOTUSEDINANGULARANDITISBETTERNOTTOWRITECODETHATRELIESONTHEM", "original": "* `priority` and `terminal`. While AngularJS components may use these,\n they are not used in Angular and it is better not to write code\n that relies on them.", "translation": "`priority` 和 `terminal`。虽然 AngularJS 的组件可能使用这些,但它们在 Angular 中已经没用了,并且最好不要再写依赖它们的代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANANGULARJSCOMPONENTDIRECTIVETHATISFULLYALIGNEDWITHTHEANGULARARCHITECTUREMAYLOOKSOMETHINGLIKETHIS:", "original": "An AngularJS component directive that is fully aligned with the Angular\narchitecture may look something like this:", "translation": "AngularJS 中一个完全向 Angular 架构对齐过的组件型指令是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARJS15INTRODUCESTHECOMPONENTAPIHTTPS:DOCSANGULARJSORGAPINGTYPEANGULARMODULE#COMPONENTTHATMAKESITEASIERTODEFINECOMPONENTDIRECTIVESLIKETHESEITISAGOODIDEATOUSETHISAPIFORCOMPONENTDIRECTIVESFORSEVERALREASONS:", "original": "AngularJS 1.5 introduces the [component API](https://docs.angularjs.org/api/ng/type/angular.Module#component)\nthat makes it easier to define component directives like these. It is a good idea to use\nthis API for component directives for several reasons:", "translation": "AngularJS 1.5 引入了[组件 API](https://docs.angularjs.org/api/ng/type/angular.Module),它让定义指令变得更简单了。\n为组件型指令使用这个 API 是一个好主意,因为:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ITREQUIRESLESSBOILERPLATECODE", "original": "* It requires less boilerplate code.", "translation": "它需要更少的样板代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ITENFORCESTHEUSEOFCOMPONENTBESTPRACTICESLIKECONTROLLERAS", "original": "* It enforces the use of component best practices like `controllerAs`.", "translation": "它强制你遵循组件的最佳实践,比如 `controllerAs`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ITHASGOODDEFAULTVALUESFORDIRECTIVEATTRIBUTESLIKESCOPEANDRESTRICT", "original": "* It has good default values for directive attributes like `scope` and `restrict`.", "translation": "指令中像 `scope` 和 `restrict` 这样的属性应该有良好的默认值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THECOMPONENTDIRECTIVEEXAMPLEFROMABOVELOOKSLIKETHISWHENEXPRESSEDUSINGTHECOMPONENTAPI:", "original": "The component directive example from above looks like this when expressed\nusing the component API:", "translation": "如果使用这个组件 API 进行快捷定义,那么上面看到的组件型指令就变成了这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "CONTROLLERLIFECYCLEHOOKMETHODSONINITONDESTROYANDONCHANGESAREANOTHERCONVENIENTFEATURETHATANGULARJS15INTRODUCESTHEYALLHAVENEARLYEXACTEQUIVALENTSINANGULARGUIDELIFECYCLEHOOKSSOORGANIZINGCOMPONENTLIFECYCLELOGICAROUNDTHEMWILLEASETHEEVENTUALANGULARUPGRADEPROCESS", "original": "Controller lifecycle hook methods `$onInit()`, `$onDestroy()`, and `$onChanges()`\nare another convenient feature that AngularJS 1.5 introduces. They all have nearly\nexact [equivalents in Angular](guide/lifecycle-hooks), so organizing component lifecycle\nlogic around them will ease the eventual Angular upgrade process.", "translation": "控制器的生命周期钩子 `$onInit()`、`$onDestroy()` 和 `$onChanges()` 是 AngularJS 1.5 引入的另一些便利特性。\n它们都很像[Angular 中的等价物](guide/lifecycle-hooks),所以,围绕它们组织组件生命周期的逻辑会更容易升级。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "##UPGRADINGWITHNGUPGRADE", "original": "## Upgrading with ngUpgrade", "translation": "## 使用升级适配器进行升级", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THENGUPGRADELIBRARYINANGULARISAVERYUSEFULTOOLFORUPGRADINGANYTHINGBUTTHESMALLESTOFAPPLICATIONSWITHITYOUCANMIXANDMATCHANGULARJSANDANGULARCOMPONENTSINTHESAMEAPPLICATIONANDHAVETHEMINTEROPERATESEAMLESSLYTHATMEANSYOUDONTHAVETODOTHEUPGRADEWORKALLATONCESINCETHERESANATURALCOEXISTENCEBETWEENTHETWOFRAMEWORKSDURINGTHETRANSITIONPERIOD", "original": "The ngUpgrade library in Angular is a very useful tool for upgrading\nanything but the smallest of applications. With it you can mix and match\nAngularJS and Angular components in the same application and have them interoperate\nseamlessly. That means you don't have to do the upgrade work all at once,\nsince there's a natural coexistence between the two frameworks during the\ntransition period.", "translation": "不管要升级什么,Angular 中的 `ngUpgrade` 库都会是一个非常有用的工具 —— 除非是小到没功能的应用。\n借助它,你可以在同一个应用程序中混用并匹配 AngularJS 和 Angular 的组件,并让它们实现无缝的互操作。\n这意味着你不用被迫一次性做完所有的升级工作,因为在整个演进过程中,这两个框架可以很自然的和睦相处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###HOWNGUPGRADEWORKS", "original": "### How ngUpgrade Works", "translation": "### 升级模块工作原理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEPRIMARYTOOLPROVIDEDBYNGUPGRADEISCALLEDTHEUPGRADEMODULETHISISAMODULETHATCONTAINSUTILITIESFORBOOTSTRAPPINGANDMANAGINGHYBRIDAPPLICATIONSTHATSUPPORTBOTHANGULARANDANGULARJSCODE", "original": "The primary tool provided by ngUpgrade is called the `UpgradeModule`.\nThis is a module that contains utilities for bootstrapping and managing hybrid\napplications that support both Angular and AngularJS code.", "translation": "`upgrade` 模块提供的主要工具叫做 `UpgradeModule`。这是一个服务,它可以启动并管理一个能同时支持 Angular 和 AngularJS 的混合式应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENYOUUSENGUPGRADEWHATYOUREREALLYDOINGISRUNNINGBOTHANGULARJSANDANGULARATTHESAMETIMEALLANGULARCODEISRUNNINGINTHEANGULARFRAMEWORKANDANGULARJSCODEINTHEANGULARJSFRAMEWORKBOTHOFTHESEARETHEACTUALFULLYFEATUREDVERSIONSOFTHEFRAMEWORKSTHEREISNOEMULATIONGOINGONSOYOUCANEXPECTTOHAVEALLTHEFEATURESANDNATURALBEHAVIOROFBOTHFRAMEWORKS", "original": "When you use ngUpgrade, what you're really doing is *running both AngularJS and\nAngular at the same time*. All Angular code is running in the Angular\nframework, and AngularJS code in the AngularJS framework. Both of these are the\nactual, fully featured versions of the frameworks. There is no emulation going on,\nso you can expect to have all the features and natural behavior of both frameworks.", "translation": "当使用 `UpgradeModule` 时,你实际上在*同时运行两个版本的 Angular*。所有 Angular 的代码运行在 Angular 框架中,而 AngularJS 的代码运行在 AngularJS 框架中。所有这些都是真实的、全功能的框架版本。\n没有进行任何仿真,所以你可以认为同时存在着这两个框架的所有特性和自然行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHATHAPPENSONTOPOFTHISISTHATCOMPONENTSANDSERVICESMANAGEDBYONEFRAMEWORKCANINTEROPERATEWITHTHOSEFROMTHEOTHERFRAMEWORKTHISHAPPENSINTHREEMAINAREAS:DEPENDENCYINJECTIONTHEDOMANDCHANGEDETECTION", "original": "What happens on top of this is that components and services managed by one\nframework can interoperate with those from the other framework. This happens\nin three main areas: Dependency injection, the DOM, and change detection.", "translation": "所有这些事情的背后,本质上是一个框架中管理的组件和服务能和来自另一个框架的进行互操作。\n这些主要体现在三个方面:依赖注入、DOM 和变更检测。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####DEPENDENCYINJECTION", "original": "#### Dependency Injection", "translation": "#### 依赖注入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "DEPENDENCYINJECTIONISFRONTANDCENTERINBOTHANGULARJSANDANGULARBUTTHEREARESOMEKEYDIFFERENCESBETWEENTHETWOFRAMEWORKSINHOWITACTUALLYWORKS", "original": "Dependency injection is front and center in both AngularJS and\nAngular, but there are some key differences between the two\nframeworks in how it actually works.", "translation": "无论是在 AngularJS 中还是在 Angular 中,依赖注入都位于前沿和中心的位置,但在两个框架的工作原理上,却存在着一些关键的不同之处。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "DEPENDENCYINJECTIONTOKENSAREALWAYSSTRINGS", "original": "Dependency injection tokens are always strings", "translation": "依赖注入的令牌(Token)永远是字符串(译注:指服务名称)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TOKENSCANHAVEDIFFERENTTYPESGUIDEDEPENDENCYINJECTIONTHEYAREOFTENCLASSESTHEYMAYALSOBESTRINGS", "original": "Tokens [can have different types](guide/dependency-injection).\n They are often classes. They may also be strings.", "translation": "令牌[可能有不同的类型](guide/dependency-injection)。\n 通常是类,也可能是字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEREISEXACTLYONEINJECTOREVENINMULTIMODULEAPPLICATIONSEVERYTHINGISPOUREDINTOONEBIGNAMESPACE", "original": "There is exactly one injector. Even in multi-module applications,\n everything is poured into one big namespace.", "translation": "只有一个注入器。即使在多模块的应用程序中,每样东西也都会被装入一个巨大的命名空间中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEREISATREEHIERARCHYOFINJECTORSGUIDEHIERARCHICALDEPENDENCYINJECTIONWITHAROOTINJECTORANDANADDITIONALINJECTORFOREACHCOMPONENT", "original": "There is a [tree hierarchy of injectors](guide/hierarchical-dependency-injection),\n with a root injector and an additional injector for each component.", "translation": "这是一个[树状多层注入器](guide/hierarchical-dependency-injection):有一个根注入器,而且每个组件也有一个自己的注入器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "EVENACCOUNTINGFORTHESEDIFFERENCESYOUCANSTILLHAVEDEPENDENCYINJECTIONINTEROPERABILITYTHEUPGRADEMODULERESOLVESTHEDIFFERENCESANDMAKESEVERYTHINGWORKSEAMLESSLY:", "original": "Even accounting for these differences you can still have dependency injection\ninteroperability. The `UpgradeModule` resolves the differences and makes\neverything work seamlessly:", "translation": "就算有这么多不同点,也并不妨碍你在依赖注入时进行互操作。`UpgradeModule` 解决了这些差异,并让它们无缝的对接:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANMAKEANGULARJSSERVICESAVAILABLEFORINJECTIONTOANGULARCODEBYUPGRADINGTHEMTHESAMESINGLETONINSTANCEOFEACHSERVICEISSHAREDBETWEENTHEFRAMEWORKSINANGULARTHESESERVICESWILLALWAYSBEINTHEROOTINJECTORANDAVAILABLETOALLCOMPONENTS", "original": "* You can make AngularJS services available for injection to Angular code\n by *upgrading* them. The same singleton instance of each service is shared\n between the frameworks. In Angular these services will always be in the\n *root injector* and available to all components.", "translation": "通过升级它们,你就能让那些在 AngularJS 中能被注入的服务也可用于 Angular 的代码中。\n 在框架之间共享的是服务的同一个单例对象。在 Angular 中,这些外来服务总是被放在*根注入器*中,并可用于所有组件。\n 它们总是具有*字符串令牌* —— 跟它们在 AngularJS 中的令牌相同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANALSOMAKEANGULARSERVICESAVAILABLEFORINJECTIONTOANGULARJSCODEBYDOWNGRADINGTHEMONLYSERVICESFROMTHEANGULARROOTINJECTORCANBEDOWNGRADEDAGAINTHESAMESINGLETONINSTANCESARESHAREDBETWEENTHEFRAMEWORKSWHENYOUREGISTERADOWNGRADEDSERVICEYOUMUSTEXPLICITLYSPECIFYASTRINGTOKENTHATYOUWANTTOUSEINANGULARJS", "original": "* You can also make Angular services available for injection to AngularJS code\n by *downgrading* them. Only services from the Angular root injector can\n be downgraded. Again, the same singleton instances are shared between the frameworks.\n When you register a downgraded service, you must explicitly specify a *string token* that you want to\n use in AngularJS.", "translation": "通过降级它们,你也能让那些在 Angular 中能被注入的服务在 AngularJS 的代码中可用。\n 只有那些来自 Angular 根注入器的服务才能被降级。同样的,在框架之间共享的是同一个单例对象。\n 当你注册一个要降级的服务时,要明确指定一个打算在 AngularJS 中使用的*字符串令牌*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####COMPONENTSANDTHEDOM", "original": "#### Components and the DOM", "translation": "#### 组件与 DOM", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHEDOMOFAHYBRIDNGUPGRADEAPPLICATIONARECOMPONENTSANDDIRECTIVESFROMBOTHANGULARJSANDANGULARTHESECOMPONENTSCOMMUNICATEWITHEACHOTHERBYUSINGTHEINPUTANDOUTPUTBINDINGSOFTHEIRRESPECTIVEFRAMEWORKSWHICHNGUPGRADEBRIDGESTOGETHERTHEYMAYALSOCOMMUNICATETHROUGHSHAREDINJECTEDDEPENDENCIESASDESCRIBEDABOVE", "original": "In the DOM of a hybrid ngUpgrade application are components and\ndirectives from both AngularJS and Angular. These components\ncommunicate with each other by using the input and output bindings\nof their respective frameworks, which ngUpgrade bridges together. They may also\ncommunicate through shared injected dependencies, as described above.", "translation": "在混合式应用中,同时存在来自 AngularJS 和 Angular 中组件和指令的 DOM。\n这些组件通过它们各自框架中的输入和输出绑定来互相通讯,它们由 `UpgradeModule` 桥接在一起。\n它们也能通过共享被注入的依赖彼此通讯,就像前面所说的那样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEKEYTHINGTOUNDERSTANDABOUTAHYBRIDAPPLICATIONISTHATEVERYELEMENTINTHEDOMISOWNEDBYEXACTLYONEOFTHETWOFRAMEWORKSTHEOTHERFRAMEWORKIGNORESITIFANELEMENTISOWNEDBYANGULARJSANGULARTREATSITASIFITDIDNTEXISTANDVICEVERSA", "original": "The key thing to understand about a hybrid application is that every element in the DOM is owned by exactly one of the two frameworks.\nThe other framework ignores it. If an element is\nowned by AngularJS, Angular treats it as if it didn't exist,\nand vice versa.", "translation": "理解混合式应用的关键在于,DOM 中的每一个元素都只能属于这两个框架之一,而另一个框架则会忽略它。如果一个元素属于 AngularJS ,那么 Angular 就会当它不存在,反之亦然。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SONORMALLYAHYBRIDAPPLICATIONBEGINSLIFEASANANGULARJSAPPLICATIONANDITISANGULARJSTHATPROCESSESTHEROOTTEMPLATEEGTHEINDEXHTMLANGULARTHENSTEPSINTOTHEPICTUREWHENANANGULARCOMPONENTISUSEDSOMEWHEREINANANGULARJSTEMPLATETHATCOMPONENTSTEMPLATEWILLTHENBEMANAGEDBYANGULARANDITMAYCONTAINANYNUMBEROFANGULARCOMPONENTSANDDIRECTIVES", "original": "So normally a hybrid application begins life as an AngularJS application,\nand it is AngularJS that processes the root template, e.g. the index.html.\nAngular then steps into the picture when an Angular component is used somewhere\nin an AngularJS template. That component's template will then be managed\nby Angular, and it may contain any number of Angular components and\ndirectives.", "translation": "所以,混合式应用总是像 AngularJS 程序那样启动,处理根模板的也是 AngularJS.\n然后,当这个应用的模板中使用到了 Angular 的组件时,Angular 才开始参与。\n这个组件的视图由 Angular 进行管理,而且它还可以使用一系列的 Angular 组件和指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "BEYONDTHATYOUMAYINTERLEAVETHETWOFRAMEWORKSYOUALWAYSCROSSTHEBOUNDARYBETWEENTHETWOFRAMEWORKSBYONEOFTWOWAYS:", "original": "Beyond that, you may interleave the two frameworks.\nYou always cross the boundary between the two frameworks by one of two\nways:", "translation": "更进一步说,你可以按照需要,任意穿插使用这两个框架。\n使用下面的两种方式之一,你可以在这两个框架之间自由穿梭:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "1BYUSINGACOMPONENTFROMTHEOTHERFRAMEWORK:ANANGULARJSTEMPLATEUSINGANANGULARCOMPONENTORANANGULARTEMPLATEUSINGANANGULARJSCOMPONENT", "original": "1. By using a component from the other framework: An AngularJS template\n using an Angular component, or an Angular template using an\n AngularJS component.", "translation": "通过使用来自另一个框架的组件:AngularJS 的模板中用到了 Angular 的组件,或者 Angular 的模板中使用了 AngularJS 的组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "2BYTRANSCLUDINGORPROJECTINGCONTENTFROMTHEOTHERFRAMEWORKNGUPGRADEBRIDGESTHERELATEDCONCEPTSOFANGULARJSTRANSCLUSIONANDANGULARCONTENTPROJECTIONTOGETHER", "original": "2. By transcluding or projecting content from the other framework. ngUpgrade\n bridges the related concepts of AngularJS transclusion and Angular content\n projection together.", "translation": "通过透传(transclude)或投影(project)来自另一个框架的内容。`UpgradeModule` 牵线搭桥,把 AngularJS 的透传概念和 Angular 的内容投影概念关联起来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENEVERYOUUSEACOMPONENTTHATBELONGSTOTHEOTHERFRAMEWORKASWITCHBETWEENFRAMEWORKBOUNDARIESOCCURSHOWEVERTHATSWITCHONLYHAPPENSTOTHEELEMENTSINTHETEMPLATEOFTHATCOMPONENTCONSIDERASITUATIONWHEREYOUUSEANANGULARCOMPONENTFROMANGULARJSLIKETHIS:", "original": "Whenever you use a component that belongs to the other framework, a\nswitch between framework boundaries occurs. However, that switch only\nhappens to the elements in the template of that component. Consider a situation\nwhere you use an Angular component from AngularJS like this:", "translation": "当你使用一个属于另一个框架的组件时,就会发生一次跨框架边界的切换。不过,这种切换只发生在该组件元素的*子节点*上。\n考虑一个场景,你从 AngularJS 中使用一个 Angular 组件,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEDOMELEMENTACOMPONENTWILLREMAINTOBEANANGULARJSMANAGEDELEMENTBECAUSEITSDEFINEDINANANGULARJSTEMPLATETHATALSOMEANSYOUCANAPPLYADDITIONALANGULARJSDIRECTIVESTOITBUTNOTANGULARDIRECTIVESITISONLYINTHETEMPLATEOFTHEACOMPONENTWHEREANGULARSTEPSINTHISSAMERULEALSOAPPLIESWHENYOUUSEANGULARJSCOMPONENTDIRECTIVESFROMANGULAR", "original": "The DOM element `<a-component>` will remain to be an AngularJS managed\nelement, because it's defined in an AngularJS template. That also\nmeans you can apply additional AngularJS directives to it, but *not*\nAngular directives. It is only in the template of the `<a-component>`\nwhere Angular steps in. This same rule also applies when you\nuse AngularJS component directives from Angular.", "translation": "此时,`<a-component>` 这个 DOM 元素仍然由 AngularJS 管理,因为它是在 AngularJS 的模板中定义的。\n这也意味着你可以往它上面添加别的 AngularJS 指令,却*不能*添加 Angular 的指令。\n只有在 `<a-component>` 组件的模板中才是 Angular 的天下。同样的规则也适用于在 Angular 中使用 AngularJS 组件型指令的情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####CHANGEDETECTION", "original": "#### Change Detection", "translation": "#### 变更检测", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THESCOPEAPPLYISHOWANGULARJSDETECTSCHANGESANDUPDATESDATABINDINGSAFTEREVERYEVENTTHATOCCURSSCOPEAPPLYGETSCALLEDTHISISDONEEITHERAUTOMATICALLYBYTHEFRAMEWORKORMANUALLYBYYOU", "original": "The `scope.$apply()` is how AngularJS detects changes and updates data bindings.\nAfter every event that occurs, `scope.$apply()` gets called. This is done either\nautomatically by the framework, or manually by you.", "translation": "AngularJS 中的变更检测全是关于 `scope.$apply()` 的。在每个事件发生之后,`scope.$apply()` 就会被调用。\n这或者由框架自动调用,或者在某些情况下由你自己的代码手动调用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INANGULARTHINGSAREDIFFERENTWHILECHANGEDETECTIONSTILLOCCURSAFTEREVERYEVENTNOONENEEDSTOCALLSCOPEAPPLYFORTHATTOHAPPENTHISISBECAUSEALLANGULARCODERUNSINSIDESOMETHINGCALLEDTHEANGULARZONEAPICORENGZONEANGULARALWAYSKNOWSWHENTHECODEFINISHESSOITALSOKNOWSWHENITSHOULDKICKOFFCHANGEDETECTIONTHECODEITSELFDOESNTHAVETOCALLSCOPEAPPLYORANYTHINGLIKEIT", "original": "In Angular things are different. While change detection still\noccurs after every event, no one needs to call `scope.$apply()` for\nthat to happen. This is because all Angular code runs inside something\ncalled the [Angular zone](api/core/NgZone). Angular always\nknows when the code finishes, so it also knows when it should kick off\nchange detection. The code itself doesn't have to call `scope.$apply()`\nor anything like it.", "translation": "在 Angular 中,事情有点不一样。虽然变更检测仍然会在每一个事件之后发生,却不再需要每次调用 `scope.$apply()` 了。\n这是因为所有 Angular 代码都运行在一个叫做[Angular zone](api/core/NgZone)的地方。\nAngular 总是知道什么时候代码执行完了,也就知道了它什么时候应该触发变更检测。代码本身并不需要调用 `scope.$apply()` 或其它类似的东西。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHECASEOFHYBRIDAPPLICATIONSTHEUPGRADEMODULEBRIDGESTHEANGULARJSANDANGULARAPPROACHESHERESWHATHAPPENS:", "original": "In the case of hybrid applications, the `UpgradeModule` bridges the\nAngularJS and Angular approaches. Here's what happens:", "translation": "在这种混合式应用的案例中,`UpgradeModule` 在 AngularJS 的方法和 Angular 的方法之间建立了桥梁。发生了什么呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "EVERYTHINGTHATHAPPENSINTHEAPPLICATIONRUNSINSIDETHEANGULARZONETHISISTRUEWHETHERTHEEVENTORIGINATEDINANGULARJSORANGULARCODETHEZONETRIGGERSANGULARCHANGEDETECTIONAFTEREVERYEVENT", "original": "* Everything that happens in the application runs inside the Angular zone.\n This is true whether the event originated in AngularJS or Angular code.\n The zone triggers Angular change detection after every event.", "translation": "应用中发生的每件事都运行在 Angular 的 zone 里。\n 无论事件发生在 AngularJS 还是 Angular 的代码中,都是如此。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEUPGRADEMODULEWILLINVOKETHEANGULARJSROOTSCOPEAPPLYAFTEREVERYTURNOFTHEANGULARZONETHISALSOTRIGGERSANGULARJSCHANGEDETECTIONAFTEREVERYEVENT", "original": "* The `UpgradeModule` will invoke the AngularJS `$rootScope.$apply()` after\n every turn of the Angular zone. This also triggers AngularJS change\n detection after every event.", "translation": "`UpgradeModule` 将在每一次离开 Angular zone 时调用 AngularJS 的 `$rootScope.$apply()`。这样也就同样会在每个事件之后触发 AngularJS 的变更检测。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INPRACTICEYOUDONOTNEEDTOCALLAPPLYREGARDLESSOFWHETHERITISINANGULARJSONANGULARTHEUPGRADEMODULEDOESITFORUSYOUCANSTILLCALLAPPLYSOTHEREISNONEEDTOREMOVESUCHCALLSFROMEXISTINGCODETHOSECALLSJUSTTRIGGERADDITIONALANGULARJSCHANGEDETECTIONCHECKSINAHYBRIDAPPLICATION", "original": "In practice, you do not need to call `$apply()`,\nregardless of whether it is in AngularJS on Angular. The\n`UpgradeModule` does it for us. You *can* still call `$apply()` so there\nis no need to remove such calls from existing code. Those calls just trigger\nadditional AngularJS change detection checks in a hybrid application.", "translation": "在实践中,你不用在自己的代码中调用 `$apply()`,而不用管这段代码是在 AngularJS 还是 Angular 中。\n`UpgradeModule` 都替你做了。你仍然*可以*调用 `$apply()`,也就是说你不必从现有代码中移除此调用。\n在混合式应用中,这些调用只会触发一次额外的 AngularJS 变更检测。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENYOUDOWNGRADEANANGULARCOMPONENTANDTHENUSEITFROMANGULARJSTHECOMPONENTSINPUTSWILLBEWATCHEDUSINGANGULARJSCHANGEDETECTIONWHENTHOSEINPUTSCHANGETHECORRESPONDINGPROPERTIESINTHECOMPONENTARESETYOUCANALSOHOOKINTOTHECHANGESBYIMPLEMENTINGTHEONCHANGESAPICOREONCHANGESINTERFACEINTHECOMPONENTJUSTLIKEYOUCOULDIFITHADNTBEENDOWNGRADED", "original": "When you downgrade an Angular component and then use it from AngularJS,\nthe component's inputs will be watched using AngularJS change detection.\nWhen those inputs change, the corresponding properties in the component\nare set. You can also hook into the changes by implementing the\n[OnChanges](api/core/OnChanges) interface in the component,\njust like you could if it hadn't been downgraded.", "translation": "当你降级一个 Angular 组件,然后把它用于 AngularJS 中时,组件的输入属性就会被 AngularJS 的变更检测体系监视起来。\n当那些输入属性发生变化时,组件中相应的属性就会被设置。你也能通过实现[OnChanges](api/core/OnChanges)\n接口来挂钩到这些更改,就像它未被降级时一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "CORRESPONDINGLYWHENYOUUPGRADEANANGULARJSCOMPONENTANDUSEITFROMANGULARALLTHEBINDINGSDEFINEDFORTHECOMPONENTDIRECTIVESSCOPEORBINDTOCONTROLLERWILLBEHOOKEDINTOANGULARCHANGEDETECTIONTHEYWILLBETREATEDASREGULARANGULARINPUTSTHEIRVALUESWILLBEWRITTENTOTHEUPGRADEDCOMPONENTSSCOPEORCONTROLLERWHENTHEYCHANGE", "original": "Correspondingly, when you upgrade an AngularJS component and use it from Angular,\nall the bindings defined for the component directive's `scope` (or `bindToController`)\nwill be hooked into Angular change detection. They will be treated\nas regular Angular inputs. Their values will be written to the upgraded component's\nscope (or controller) when they change.", "translation": "相应的,当你把 AngularJS 的组件升级给 Angular 使用时,在这个组件型指令的 `scope`(或 `bindToController`)中定义的所有绑定,\n都将被挂钩到 Angular 的变更检测体系中。它们将和标准的 Angular 输入属性被同等对待,并当它们发生变化时设置回 scope(或控制器)上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###USINGUPGRADEMODULEWITHANGULARNGMODULES", "original": "### Using UpgradeModule with Angular _NgModules_", "translation": "### 通过 Angular 的 *NgModule* 来使用 UpgradeModule", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "BOTHANGULARJSANDANGULARHAVETHEIROWNCONCEPTOFMODULESTOHELPORGANIZEANAPPLICATIONINTOCOHESIVEBLOCKSOFFUNCTIONALITY", "original": "Both AngularJS and Angular have their own concept of modules\nto help organize an application into cohesive blocks of functionality.", "translation": "AngularJS 还是 Angular 都有自己的模块概念,来帮你把应用组织成一些内聚的功能块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEIRDETAILSAREQUITEDIFFERENTINARCHITECTUREANDIMPLEMENTATIONINANGULARJSYOUADDANGULARASSETSTOTHEANGULARMODULEPROPERTYINANGULARYOUCREATEONEORMORECLASSESADORNEDWITHANNGMODULEDECORATORTHATDESCRIBESANGULARASSETSINMETADATATHEDIFFERENCESBLOSSOMFROMTHERE", "original": "Their details are quite different in architecture and implementation.\nIn AngularJS, you add Angular assets to the `angular.module` property.\nIn Angular, you create one or more classes adorned with an `NgModule` decorator\nthat describes Angular assets in metadata. The differences blossom from there.", "translation": "它们在架构和实现的细节上有着显著的不同。\n在 AngularJS 中,你要把 AngularJS 的资源添加到 `angular.module` 属性上。\n在 Angular 中,你要创建一个或多个带有 `NgModule` 装饰器的类,这些装饰器用来在元数据中描述 Angular 资源。差异主要来自这里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INAHYBRIDAPPLICATIONYOURUNBOTHVERSIONSOFANGULARATTHESAMETIMETHATMEANSTHATYOUNEEDATLEASTONEMODULEEACHFROMBOTHANGULARJSANDANGULARYOUWILLIMPORTUPGRADEMODULEINSIDETHENGMODULEANDTHENUSEITFORBOOTSTRAPPINGTHEANGULARJSMODULE", "original": "In a hybrid application you run both versions of Angular at the same time.\nThat means that you need at least one module each from both AngularJS and Angular.\nYou will import `UpgradeModule` inside the NgModule, and then use it for\nbootstrapping the AngularJS module.", "translation": "在混合式应用中,你同时运行了两个版本的 Angular。\n这意味着你至少需要 AngularJS 和 Angular 各提供一个模块。\n当你使用 AngularJS 的模块进行引导时,就得把 Angular 的模块传给 `UpgradeModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FORMOREINFORMATIONSEENGMODULESGUIDENGMODULES", "original": "For more information, see [NgModules](guide/ngmodules).", "translation": "要了解更多,请参阅[NgModules](guide/ngmodules)页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###BOOTSTRAPPINGHYBRIDAPPLICATIONS", "original": "### Bootstrapping hybrid applications", "translation": "### 引导混合式应用程序", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TOBOOTSTRAPAHYBRIDAPPLICATIONYOUMUSTBOOTSTRAPEACHOFTHEANGULARANDANGULARJSPARTSOFTHEAPPLICATIONYOUMUSTBOOTSTRAPTHEANGULARBITSFIRSTANDTHENASKTHEUPGRADEMODULETOBOOTSTRAPTHEANGULARJSBITSNEXT", "original": "To bootstrap a hybrid application, you must bootstrap each of the Angular and\nAngularJS parts of the application. You must bootstrap the Angular bits first and\nthen ask the `UpgradeModule` to bootstrap the AngularJS bits next.", "translation": "要想引导混合式应用,就必须在应用中分别引导 Angular 和 AngularJS 应用的一部分。你必须先引导 Angular ,然后再调用 `UpgradeModule` 来引导 AngularJS。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INANANGULARJSAPPLICATIONYOUHAVEAROOTANGULARJSMODULEWHICHWILLALSOBEUSEDTOBOOTSTRAPTHEANGULARJSAPPLICATION", "original": "In an AngularJS application you have a root AngularJS module, which will also\nbe used to bootstrap the AngularJS application.", "translation": "在 AngularJS 应用中有一个 AngularJS 的根模块,它用于引导 AngularJS 应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "PUREANGULARJSAPPLICATIONSCANBEAUTOMATICALLYBOOTSTRAPPEDBYUSINGANNGAPPDIRECTIVESOMEWHEREONTHEHTMLPAGEBUTFORHYBRIDAPPLICATIONSYOUMANUALLYBOOTSTRAPVIATHEUPGRADEMODULETHEREFOREITISAGOODPRELIMINARYSTEPTOSWITCHANGULARJSAPPLICATIONSTOUSETHEMANUALJAVASCRIPTANGULARBOOTSTRAPHTTPS:DOCSANGULARJSORGAPINGFUNCTIONANGULARBOOTSTRAPMETHODEVENBEFORESWITCHINGTHEMTOHYBRIDMODE", "original": "Pure AngularJS applications can be automatically bootstrapped by using an `ng-app`\ndirective somewhere on the HTML page. But for hybrid applications, you manually bootstrap via the\n`UpgradeModule`. Therefore, it is a good preliminary step to switch AngularJS applications to use the\nmanual JavaScript [`angular.bootstrap`](https://docs.angularjs.org/api/ng/function/angular.bootstrap)\nmethod even before switching them to hybrid mode.", "translation": "单纯的 AngularJS 应用可以在 HTML 页面中使用 `ng-app` 指令进行引导,但对于混合式应用你要通过 `UpgradeModule` 模块进行手动引导。因此,在切换成混合式应用之前,最好先把 AngularJS 改写成使用 [`angular.bootstrap`](https://docs.angularjs.org/api/ng/function/angular.bootstrap) 进行手动引导的方式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SAYYOUHAVEANNGAPPDRIVENBOOTSTRAPSUCHASTHISONE:", "original": "Say you have an `ng-app` driven bootstrap such as this one:", "translation": "比如你现在有这样一个通过 `ng-app` 进行引导的应用:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANREMOVETHENGAPPANDNGSTRICTDIDIRECTIVESFROMTHEHTMLANDINSTEADSWITCHTOCALLINGANGULARBOOTSTRAPFROMJAVASCRIPTWHICHWILLRESULTINTHESAMETHING:", "original": "You can remove the `ng-app` and `ng-strict-di` directives from the HTML\nand instead switch to calling `angular.bootstrap` from JavaScript, which\nwill result in the same thing:", "translation": "你可以从 HTML 中移除 `ng-app` 和 `ng-strict-di` 指令,改为从 JavaScript 中调用 `angular.bootstrap`,它能达到同样效果:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TOBEGINCONVERTINGYOURANGULARJSAPPLICATIONTOAHYBRIDYOUNEEDTOLOADTHEANGULARFRAMEWORKYOUCANSEEHOWTHISCANBEDONEWITHSYSTEMJSBYFOLLOWINGTHEINSTRUCTIONSINSETUPGUIDESETUPSELECTIVELYCOPYINGCODEFROMTHEQUICKSTARTGITHUBREPOSITORYHTTPS:GITHUBCOMANGULARQUICKSTART", "original": "To begin converting your AngularJS application to a hybrid, you need to load the Angular framework.\nYou can see how this can be done with SystemJS by following the instructions in [Setup](guide/setup),\nselectively copying code from the [QuickStart github repository](https://github.com/angular/quickstart).", "translation": "要想把 AngularJS 应用变成 Hybrid 应用,就要先加载 Angular 框架。\n根据 [搭建本地开发环境](guide/setup)中给出的步骤,选择性的把<a href=\"https://github.com/angular/quickstart\" target=\"_blank\">“快速上手”的 Github 仓库</a>中的代码复制过来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUALSONEEDTOINSTALLTHEANGULARUPGRADEPACKAGEVIANPMINSTALLANGULARUPGRADESAVEANDADDAMAPPINGFORTHEANGULARUPGRADESTATICPACKAGE:", "original": "You also need to install the `@angular/upgrade` package via `npm install @angular/upgrade --save`\nand add a mapping for the `@angular/upgrade/static` package:", "translation": "也可以通过 `npm install @angular/upgrade --save` 命令来安装 `@angular/upgrade` 包,并给它添加一个到 `@angular/upgrade/static` 包的映射。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NEXTCREATEANAPPMODULETSFILEANDADDTHEFOLLOWINGNGMODULECLASS:", "original": "Next, create an `app.module.ts` file and add the following `NgModule` class:", "translation": "接下来,创建一个 `app.module.ts` 文件,并添加下列 `NgModule` 类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THISBAREMINIMUMNGMODULEIMPORTSBROWSERMODULETHEMODULEEVERYANGULARBROWSERBASEDAPPMUSTHAVEITALSOIMPORTSUPGRADEMODULEFROMANGULARUPGRADESTATICWHICHEXPORTSPROVIDERSTHATWILLBEUSEDFORUPGRADINGANDDOWNGRADINGSERVICESANDCOMPONENTS", "original": "This bare minimum `NgModule` imports `BrowserModule`, the module every Angular browser-based app must have.\nIt also imports `UpgradeModule` from `@angular/upgrade/static`, which exports providers that will be used\nfor upgrading and downgrading services and components.", "translation": "最小化的 `NgModule` 导入了 `BrowserModule`,它是每个基于浏览器的 Angular 应用必备的。\n它还从 `@angular/upgrade/static` 中导入了 `UpgradeModule`,它导出了一些服务提供商,这些提供商会用于升级、降级服务和组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHECONSTRUCTOROFTHEAPPMODULEUSEDEPENDENCYINJECTIONTOGETAHOLDOFTHEUPGRADEMODULEINSTANCEANDUSEITTOBOOTSTRAPTHEANGULARJSAPPINTHEAPPMODULENGDOBOOTSTRAPMETHODTHEUPGRADEBOOTSTRAPMETHODTAKESTHEEXACTSAMEARGUMENTSASANGULARBOOTSTRAPHTTPS:DOCSANGULARJSORGAPINGFUNCTIONANGULARBOOTSTRAP:", "original": "In the constructor of the `AppModule`, use dependency injection to get a hold of the `UpgradeModule` instance,\nand use it to bootstrap the AngularJS app in the `AppModule.ngDoBootstrap` method.\nThe `upgrade.bootstrap` method takes the exact same arguments as [angular.bootstrap](https://docs.angularjs.org/api/ng/function/angular.bootstrap):", "translation": "在 `AppModule` 的构造函数中,使用依赖注入技术获取了一个 `UpgradeModule` 实例,并用它在 `AppModule.ngDoBootstrap` 方法中启动 AngularJS 应用。\n`upgrade.bootstrap` 方法接受和 [angular.bootstrap](https://docs.angularjs.org/api/ng/function/angular.bootstrap) 完全相同的参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOTETHATYOUDONOTADDABOOTSTRAPDECLARATIONTOTHENGMODULEDECORATORSINCEANGULARJSWILLOWNTHEROOTTEMPLATEOFTHEAPPLICATION", "original": "Note that you do not add a `bootstrap` declaration to the `@NgModule` decorator, since\nAngularJS will own the root template of the application.", "translation": "注意,你不需要在 `@NgModule` 中加入 `bootstrap` 声明,因为 AngularJS 控制着该应用的根模板。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWYOUCANBOOTSTRAPAPPMODULEUSINGTHEPLATFORMBROWSERDYNAMICBOOTSTRAPMODULEMETHOD", "original": "Now you can bootstrap `AppModule` using the `platformBrowserDynamic.bootstrapModule` method.", "translation": "现在,你就可以使用 `platformBrowserDynamic.bootstrapModule` 方法来启动 `AppModule` 了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "CONGRATULATIONSYOURERUNNINGAHYBRIDAPPLICATIONTHEEXISTINGANGULARJSCODEWORKSASBEFOREANDYOUREREADYTOSTARTADDINGANGULARCODE", "original": "Congratulations! You're running a hybrid application! The\nexisting AngularJS code works as before _and_ you're ready to start adding Angular code.", "translation": "恭喜!你就要开始运行 AngularJS+2 的混合式应用程序了!所有现存的 AngularJS 代码会像以前一样正常工作,但是你现在也同样可以运行 Angular 代码了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###USINGANGULARCOMPONENTSFROMANGULARJSCODE", "original": "### Using Angular Components from AngularJS Code", "translation": "### 在 AngularJS 的代码中使用 Angular 的组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ONCEYOURERUNNINGAHYBRIDAPPYOUCANSTARTTHEGRADUALPROCESSOFUPGRADINGCODEONEOFTHEMORECOMMONPATTERNSFORDOINGTHATISTOUSEANANGULARCOMPONENTINANANGULARJSCONTEXTTHISCOULDBEACOMPLETELYNEWCOMPONENTORONETHATWASPREVIOUSLYANGULARJSBUTHASBEENREWRITTENFORANGULAR", "original": "Once you're running a hybrid app, you can start the gradual process of upgrading\ncode. One of the more common patterns for doing that is to use an Angular component\nin an AngularJS context. This could be a completely new component or one that was\npreviously AngularJS but has been rewritten for Angular.", "translation": "一旦你开始运行混合式应用,你就可以开始逐渐升级代码了。一种更常见的工作模式就是在 AngularJS 的上下文中使用 Angular 的组件。\n该组件可能是全新的,也可能是把原本 AngularJS 的组件用 Angular 重写而成的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SAYYOUHAVEASIMPLEANGULARCOMPONENTTHATSHOWSINFORMATIONABOUTAHERO:", "original": "Say you have a simple Angular component that shows information about a hero:", "translation": "假设你有一个简单的用来显示英雄信息的 Angular 组件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "IFYOUWANTTOUSETHISCOMPONENTFROMANGULARJSYOUNEEDTODOWNGRADEITUSINGTHEDOWNGRADECOMPONENTMETHODTHERESULTISANANGULARJSDIRECTIVEWHICHYOUCANTHENREGISTERINTHEANGULARJSMODULE:", "original": "If you want to use this component from AngularJS, you need to *downgrade* it\nusing the `downgradeComponent()` method. The result is an AngularJS\n*directive*, which you can then register in the AngularJS module:", "translation": "如果你想在 AngularJS 中使用这个组件,就得用 `downgradeComponent()` 方法把它*降级*。\n其结果是一个 AngularJS 的*指令*,你可以把它注册到 AngularJS 的模块中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "BECAUSEHERODETAILCOMPONENTISANANGULARCOMPONENTYOUMUSTALSOADDITTOTHEDECLARATIONSINTHEAPPMODULE", "original": "Because `HeroDetailComponent` is an Angular component, you must also add it to the\n`declarations` in the `AppModule`.", "translation": "由于 `HeroDetailComponent` 是一个 Angular 组件,所以你必须同时把它加入 `AppModule` 的 `declarations` 字段中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANDBECAUSETHISCOMPONENTISBEINGUSEDFROMTHEANGULARJSMODULEANDISANENTRYPOINTINTOTHEANGULARAPPLICATIONYOUMUSTADDITTOTHEENTRYCOMPONENTSFORTHENGMODULE", "original": "And because this component is being used from the AngularJS module, and is an entry point into\nthe Angular application, you must add it to the `entryComponents` for the\nNgModule.", "translation": "并且由于这个组件在 AngularJS 模块中使用,也是你 Angular 应用的一个入口点,你还需要\n将它加入到 Angular 模块的 `entryComponents` 列表中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ALLANGULARCOMPONENTSDIRECTIVESANDPIPESMUSTBEDECLAREDINANNGMODULE", "original": "All Angular components, directives and pipes must be declared in an NgModule.", "translation": "所有 Angular 组件、指令和管道都必须声明在 NgModule 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THENETRESULTISANANGULARJSDIRECTIVECALLEDHERODETAILTHATYOUCANUSELIKEANYOTHERDIRECTIVEINANGULARJSTEMPLATES", "original": "The net result is an AngularJS directive called `heroDetail`, that you can\nuse like any other directive in AngularJS templates.", "translation": "最终的结果是一个叫做 `heroDetail` 的 AngularJS 指令,你可以像用其它指令一样把它用在 AngularJS 模板中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOTETHATTHISANGULARJSISANELEMENTDIRECTIVERESTRICT:ECALLEDHERODETAILANANGULARJSELEMENTDIRECTIVEISMATCHEDBASEDONITSNAMETHESELECTORMETADATAOFTHEDOWNGRADEDANGULARCOMPONENTISIGNORED", "original": "Note that this AngularJS is an element directive (`restrict: 'E'`) called `heroDetail`.\nAn AngularJS element directive is matched based on its _name_.\n*The `selector` metadata of the downgraded Angular component is ignored.*", "translation": "注意,它在 AngularJS 中是一个名叫 `heroDetail` 的元素型指令(`restrict: 'E'`)。\nAngularJS 的元素型指令是基于它的*名字*匹配的。\n*Angular 组件中的 `selector` 元数据,在降级后的版本中会被忽略。*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "MOSTCOMPONENTSARENOTQUITETHISSIMPLEOFCOURSEMANYOFTHEMHAVEINPUTSANDOUTPUTSTHATCONNECTTHEMTOTHEOUTSIDEWORLDANANGULARHERODETAILCOMPONENTWITHINPUTSANDOUTPUTSMIGHTLOOKLIKETHIS:", "original": "Most components are not quite this simple, of course. Many of them\nhave *inputs and outputs* that connect them to the outside world. An\nAngular hero detail component with inputs and outputs might look\nlike this:", "translation": "当然,大多数组件都不像这个这么简单。它们中很多都有*输入属性和输出属性*,来把它们连接到外部世界。\nAngular 的英雄详情组件带有像这样的输入属性与输出属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THESEINPUTSANDOUTPUTSCANBESUPPLIEDFROMTHEANGULARJSTEMPLATEANDTHEDOWNGRADECOMPONENTMETHODTAKESCAREOFWIRINGTHEMUP:", "original": "These inputs and outputs can be supplied from the AngularJS template, and the\n`downgradeComponent()` method takes care of wiring them up:", "translation": "这些输入属性和输出属性的值来自于 AngularJS 的模板,而 `downgradeComponent()` 方法负责桥接它们:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOTETHATEVENTHOUGHYOUAREINANANGULARJSTEMPLATEYOUREUSINGANGULARATTRIBUTESYNTAXTOBINDTHEINPUTSANDOUTPUTSTHISISAREQUIREMENTFORDOWNGRADEDCOMPONENTSTHEEXPRESSIONSTHEMSELVESARESTILLREGULARANGULARJSEXPRESSIONS", "original": "Note that even though you are in an AngularJS template, **you're using Angular\nattribute syntax to bind the inputs and outputs**. This is a requirement for downgraded\ncomponents. The expressions themselves are still regular AngularJS expressions.", "translation": "注意,虽然你正在 AngularJS 的模板中,**但却在使用 Angular 的属性(Attribute)语法来绑定到输入属性与输出属性**。\n这是降级的组件本身要求的。而表达式本身仍然是标准的 AngularJS 表达式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "HEADERUSEKEBABCASEFORDOWNGRADEDCOMPONENTATTRIBUTESHEADER", "original": "<header>Use kebab-case for downgraded component attributes</header>", "translation": "<header>在降级过的组件属性中使用中线命名法</header>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THERESONENOTABLEEXCEPTIONTOTHERULEOFUSINGANGULARATTRIBUTESYNTAXFORDOWNGRADEDCOMPONENTSITHASTODOWITHINPUTOROUTPUTNAMESTHATCONSISTOFMULTIPLEWORDSINANGULARYOUWOULDBINDTHESEATTRIBUTESUSINGCAMELCASE:", "original": "There's one notable exception to the rule of using Angular attribute syntax\nfor downgraded components. It has to do with input or output names that consist\nof multiple words. In Angular, you would bind these attributes using camelCase:", "translation": "为降级过的组件使用 Angular 的属性(Attribute)语法规则时有一个值得注意的例外。\n它适用于由多个单词组成的输入或输出属性。在 Angular 中,你要使用小驼峰命名法绑定这些属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "BUTWHENUSINGTHEMFROMANGULARJSTEMPLATESYOUMUSTUSEKEBABCASE:", "original": "But when using them from AngularJS templates, you must use kebab-case:", "translation": "但是从 AngularJS 的模板中使用它们时,你得使用中线命名法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEEVENTVARIABLECANBEUSEDINOUTPUTSTOGAINACCESSTOTHEOBJECTTHATWASEMITTEDINTHISCASEITWILLBETHEHEROOBJECTBECAUSETHATISWHATWASPASSEDTOTHISDELETEDEMIT", "original": "The `$event` variable can be used in outputs to gain access to the\nobject that was emitted. In this case it will be the `Hero` object, because\nthat is what was passed to `this.deleted.emit()`.", "translation": "`$event` 变量能被用在输出属性里,以访问这个事件所发出的对象。这个案例中它是 `Hero` 对象,因为 `this.deleted.emit()` 函数曾把它传了出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SINCETHISISANANGULARJSTEMPLATEYOUCANSTILLUSEOTHERANGULARJSDIRECTIVESONTHEELEMENTEVENTHOUGHITHASANGULARBINDINGATTRIBUTESONITFOREXAMPLEYOUCANEASILYMAKEMULTIPLECOPIESOFTHECOMPONENTUSINGNGREPEAT:", "original": "Since this is an AngularJS template, you can still use other AngularJS\ndirectives on the element, even though it has Angular binding attributes on it.\nFor example, you can easily make multiple copies of the component using `ng-repeat`:", "translation": "由于这是一个 AngularJS 模板,虽然它已经有了 Angular 中绑定的属性(Attribute),你仍可以在这个元素上使用其它 AngularJS 指令。\n例如,你可以用 `ng-repeat` 简单的制作该组件的多份拷贝:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###USINGANGULARJSCOMPONENTDIRECTIVESFROMANGULARCODE", "original": "### Using AngularJS Component Directives from Angular Code", "translation": "### 从 Angular 代码中使用 AngularJS 组件型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SOYOUCANWRITEANANGULARCOMPONENTANDTHENUSEITFROMANGULARJSCODETHISISUSEFULWHENYOUSTARTTOMIGRATEFROMLOWERLEVELCOMPONENTSANDWORKYOURWAYUPBUTINSOMECASESITISMORECONVENIENTTODOTHINGSINTHEOPPOSITEORDER:TOSTARTWITHHIGHERLEVELCOMPONENTSANDWORKYOURWAYDOWNTHISTOOCANBEDONEUSINGTHEUPGRADEMODULEYOUCANUPGRADEANGULARJSCOMPONENTDIRECTIVESANDTHENUSETHEMFROMANGULAR", "original": "So, you can write an Angular component and then use it from AngularJS\ncode. This is useful when you start to migrate from lower-level\ncomponents and work your way up. But in some cases it is more convenient\nto do things in the opposite order: To start with higher-level components\nand work your way down. This too can be done using the `UpgradeModule`.\nYou can *upgrade* AngularJS component directives and then use them from\nAngular.", "translation": "现在,你已经能在 Angular 中写一个组件,并把它用于 AngularJS 代码中了。\n当你从低级组件开始移植,并往上走时,这非常有用。但在另外一些情况下,从相反的方向进行移植会更加方便:\n从高级组件开始,然后往下走。这也同样能用 `UpgradeModule` 完成。\n你可以*升级*AngularJS 组件型指令,然后从 Angular 中用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOTALLKINDSOFANGULARJSDIRECTIVESCANBEUPGRADEDTHEDIRECTIVEREALLYHASTOBEACOMPONENTDIRECTIVEWITHTHECHARACTERISTICSDESCRIBEDINTHEPREPARATIONGUIDEABOVEGUIDEUPGRADE#USINGCOMPONENTDIRECTIVESTHESAFESTBETFORENSURINGCOMPATIBILITYISUSINGTHECOMPONENTAPIHTTPS:DOCSANGULARJSORGAPINGTYPEANGULARMODULEINTRODUCEDINANGULARJS15", "original": "Not all kinds of AngularJS directives can be upgraded. The directive\nreally has to be a *component directive*, with the characteristics\n[described in the preparation guide above](guide/upgrade#using-component-directives).\nThe safest bet for ensuring compatibility is using the\n[component API](https://docs.angularjs.org/api/ng/type/angular.Module)\nintroduced in AngularJS 1.5.", "translation": "不是所有种类的 AngularJS 指令都能升级。该指令必须是一个严格的*组件型指令*,具有[上面的准备指南中描述的](guide/upgrade#using-component-directives)那些特征。\n确保兼容性的最安全的方式是 AngularJS 1.5 中引入的[组件 API](https://docs.angularjs.org/api/ng/type/angular.Module)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ASIMPLEEXAMPLEOFANUPGRADABLECOMPONENTISONETHATJUSTHASATEMPLATEANDACONTROLLER:", "original": "A simple example of an upgradable component is one that just has a template\nand a controller:", "translation": "可升级组件的简单例子是只有一个模板和一个控制器的指令:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANUPGRADETHISCOMPONENTTOANGULARUSINGTHEUPGRADECOMPONENTCLASSBYCREATINGANEWANGULARDIRECTIVETHATEXTENDSUPGRADECOMPONENTANDDOINGASUPERCALLINSIDEITSCONSTRUCTORYOUHAVEAFULLYUPGRADEDANGULARJSCOMPONENTTOBEUSEDINSIDEANGULARALLTHATISLEFTISTOADDITTOAPPMODULESDECLARATIONSARRAY", "original": "You can *upgrade* this component to Angular using the `UpgradeComponent` class.\nBy creating a new Angular **directive** that extends `UpgradeComponent` and doing a `super` call\ninside its constructor, you have a fully upgraded AngularJS component to be used inside Angular.\nAll that is left is to add it to `AppModule`'s `declarations` array.", "translation": "你可以使用 `UpgradeComponent` 方法来把这个组件*升级*到 Angular。\n具体方法是创建一个 Angular**指令**,继承 `UpgradeComponent`,在其构造函数中进行 `super` 调用,\n这样你就得到一个完全升级的 AngularJS 组件,并且可以 Angular 中使用。\n剩下是工作就是把它加入到 `AppModule` 的 `declarations` 数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "UPGRADEDCOMPONENTSAREANGULARDIRECTIVESINSTEADOFCOMPONENTSBECAUSEANGULARISUNAWARETHATANGULARJSWILLCREATEELEMENTSUNDERITASFARASANGULARKNOWSTHEUPGRADEDCOMPONENTISJUSTADIRECTIVEATAGANDANGULARDOESNTHAVETOCONCERNITSELFWITHITSCHILDREN", "original": "Upgraded components are Angular **directives**, instead of **components**, because Angular\nis unaware that AngularJS will create elements under it. As far as Angular knows, the upgraded\ncomponent is just a directive - a tag - and Angular doesn't have to concern itself with\nits children.", "translation": "升级后的组件是 Angular 的**指令**,而不是**组件**,因为 Angular 不知道 AngularJS 将在它下面创建元素。\nAngular 所知道的是升级后的组件只是一个指令(一个标签),Angular 不需要关心组件本身及其子元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANUPGRADEDCOMPONENTMAYALSOHAVEINPUTSANDOUTPUTSASDEFINEDBYTHESCOPECONTROLLERBINDINGSOFTHEORIGINALANGULARJSCOMPONENTDIRECTIVEWHENYOUUSETHECOMPONENTFROMANANGULARTEMPLATEPROVIDETHEINPUTSANDOUTPUTSUSINGANGULARTEMPLATESYNTAXOBSERVINGTHEFOLLOWINGRULES:", "original": "An upgraded component may also have inputs and outputs, as defined by\nthe scope/controller bindings of the original AngularJS component\ndirective. When you use the component from an Angular template,\nprovide the inputs and outputs using **Angular template syntax**,\nobserving the following rules:", "translation": "升级后的组件也可能有输入属性和输出属性,它们是在原 AngularJS 组件型指令的 scope/controller 绑定中定义的。\n当你从 Angular 模板中使用该组件时,就要使用**Angular 模板语法**来提供这些输入属性和输出属性,但要遵循下列规则:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "BINDINGDEFINITION", "original": "Binding definition", "translation": "绑定定义", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TEMPLATESYNTAX", "original": "Template syntax", "translation": "模板语法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ATTRIBUTEBINDING", "original": "Attribute binding", "translation": "属性(Attribute)绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "EXPRESSIONBINDING", "original": "Expression binding", "translation": "表达式绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ONEWAYBINDING", "original": "One-way binding", "translation": "单向绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TWOWAYBINDING", "original": "Two-way binding", "translation": "双向绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ASATWOWAYBINDING:MYCOMPONENTMYVALUEANEXPRESSIONSINCEMOSTANGULARJSTWOWAYBINDINGSACTUALLYONLYNEEDAONEWAYBINDINGINPRACTICEMYCOMPONENTMYVALUEANEXPRESSIONISOFTENENOUGH", "original": "As a two-way binding: `<my-component [(myValue)]=\"anExpression\">`.\n Since most AngularJS two-way bindings actually only need a one-way binding\n in practice, `<my-component [myValue]=\"anExpression\">` is often enough.", "translation": "用作输入:`<my-component [myValue]=\"anExpression\">` 或\n 用作双向绑定:`<my-component [(myValue)]=\"anExpression\"`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FOREXAMPLEIMAGINEAHERODETAILANGULARJSCOMPONENTDIRECTIVEWITHONEINPUTANDONEOUTPUT:", "original": "For example, imagine a hero detail AngularJS component directive\nwith one input and one output:", "translation": "举个例子,假设 AngularJS 中有一个表示“英雄详情”的组件型指令,它带有一个输入属性和一个输出属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANUPGRADETHISCOMPONENTTOANGULARANNOTATEINPUTSANDOUTPUTSINTHEUPGRADEDIRECTIVEANDTHENPROVIDETHEINPUTANDOUTPUTUSINGANGULARTEMPLATESYNTAX:", "original": "You can upgrade this component to Angular, annotate inputs and outputs in the upgrade directive,\nand then provide the input and output using Angular template syntax:", "translation": "你可以把这个组件升级到 Angular,然后使用 Angular 的模板语法提供这个输入属性和输出属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###PROJECTINGANGULARJSCONTENTINTOANGULARCOMPONENTS", "original": "### Projecting AngularJS Content into Angular Components", "translation": "### 把 AngularJS 的内容投影到 Angular 组件中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENYOUAREUSINGADOWNGRADEDANGULARCOMPONENTFROMANANGULARJSTEMPLATETHENEEDMAYARISETOTRANSCLUDESOMECONTENTINTOITTHISISALSOPOSSIBLEWHILETHEREISNOSUCHTHINGASTRANSCLUSIONINANGULARTHEREISAVERYSIMILARCONCEPTCALLEDCONTENTPROJECTIONTHEUPGRADEMODULEISABLETOMAKETHESETWOFEATURESINTEROPERATE", "original": "When you are using a downgraded Angular component from an AngularJS\ntemplate, the need may arise to *transclude* some content into it. This\nis also possible. While there is no such thing as transclusion in Angular,\nthere is a very similar concept called *content projection*. The `UpgradeModule`\nis able to make these two features interoperate.", "translation": "如果你在 AngularJS 模板中使用降级后的 Angular 组件时,可能会需要把模板中的一些内容投影进那个组件。\n这也是可能的,虽然在 Angular 中并没有透传(transclude)这样的东西,但它有一个非常相似的概念,叫做*内容投影*。\n`UpgradeModule` 也能让这两个特性实现互操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARCOMPONENTSTHATSUPPORTCONTENTPROJECTIONMAKEUSEOFANNGCONTENTTAGWITHINTHEMHERESANEXAMPLEOFSUCHACOMPONENT:", "original": "Angular components that support content projection make use of an `<ng-content>`\ntag within them. Here's an example of such a component:", "translation": "Angular 的组件通过使用 `<ng-content>` 标签来支持内容投影。下面是这类组件的一个例子:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENUSINGTHECOMPONENTFROMANGULARJSYOUCANSUPPLYCONTENTSFORITJUSTLIKETHEYWOULDBETRANSCLUDEDINANGULARJSTHEYGETPROJECTEDTOTHELOCATIONOFTHENGCONTENTTAGINANGULAR:", "original": "When using the component from AngularJS, you can supply contents for it. Just\nlike they would be transcluded in AngularJS, they get projected to the location\nof the `<ng-content>` tag in Angular:", "translation": "当从 AngularJS 中使用该组件时,你可以为它提供内容。正如它们将在 AngularJS 中被透传一样,\n它们也在 Angular 中被投影到了 `<ng-content>` 标签所在的位置:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENANGULARJSCONTENTGETSPROJECTEDINSIDEANANGULARCOMPONENTITSTILLREMAINSINANGULARJSLANDANDISMANAGEDBYTHEANGULARJSFRAMEWORK", "original": "When AngularJS content gets projected inside an Angular component, it still\nremains in \"AngularJS land\" and is managed by the AngularJS framework.", "translation": "当 AngularJS 的内容被投影到 Angular 组件中时,它仍然留在“AngularJS 王国”中,并被 AngularJS 框架管理着。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###TRANSCLUDINGANGULARCONTENTINTOANGULARJSCOMPONENTDIRECTIVES", "original": "### Transcluding Angular Content into AngularJS Component Directives", "translation": "### 把 Angular 的内容透传进 AngularJS 的组件型指令", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "JUSTASYOUCANPROJECTANGULARJSCONTENTINTOANGULARCOMPONENTSYOUCANTRANSCLUDEANGULARCONTENTINTOANGULARJSCOMPONENTSWHENEVERYOUAREUSINGUPGRADEDVERSIONSFROMTHEM", "original": "Just as you can project AngularJS content into Angular components,\nyou can *transclude* Angular content into AngularJS components, whenever\nyou are using upgraded versions from them.", "translation": "就像可以把 AngularJS 的内容投影进 Angular 组件一样,你也能把 Angular 的内容*透传*进 AngularJS 的组件,\n但不管怎样,你都要使用它们升级过的版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENANANGULARJSCOMPONENTDIRECTIVESUPPORTSTRANSCLUSIONITMAYUSETHENGTRANSCLUDEDIRECTIVEINITSTEMPLATETOMARKTHETRANSCLUSIONPOINT:", "original": "When an AngularJS component directive supports transclusion, it may use\nthe `ng-transclude` directive in its template to mark the transclusion\npoint:", "translation": "如果一个 AngularJS 组件型指令支持透传,它就会在自己的模板中使用 `ng-transclude` 指令标记出透传到的位置:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "IFYOUUPGRADETHISCOMPONENTANDUSEITFROMANGULARYOUCANPOPULATETHECOMPONENTTAGWITHCONTENTSTHATWILLTHENGETTRANSCLUDED:", "original": "If you upgrade this component and use it from Angular, you can populate\nthe component tag with contents that will then get transcluded:", "translation": "如果你升级这个组件,并把它用在 Angular 中,你就能把准备透传的内容放进这个组件的标签中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###MAKINGANGULARJSDEPENDENCIESINJECTABLETOANGULAR", "original": "### Making AngularJS Dependencies Injectable to Angular", "translation": "### 让 AngularJS 中的依赖可被注入到 Angular", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENRUNNINGAHYBRIDAPPYOUMAYENCOUNTERSITUATIONSWHEREYOUNEEDTOINJECTSOMEANGULARJSDEPENDENCIESINTOYOURANGULARCODEMAYBEYOUHAVESOMEBUSINESSLOGICSTILLINANGULARJSSERVICESMAYBEYOUWANTACCESSTOANGULARJSSBUILTINSERVICESLIKELOCATIONORTIMEOUT", "original": "When running a hybrid app, you may encounter situations where you need to inject\nsome AngularJS dependencies into your Angular code.\nMaybe you have some business logic still in AngularJS services.\nMaybe you want access to AngularJS's built-in services like `$location` or `$timeout`.", "translation": "当运行一个混合式应用时,可能会遇到这种情况:你需要把某些 AngularJS 的依赖注入到 Angular 代码中。\n这可能是因为某些业务逻辑仍然在 AngularJS 服务中,或者需要某些 AngularJS 的内置服务,比如 `$location` 或 `$timeout`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHESESITUATIONSITISPOSSIBLETOUPGRADEANANGULARJSPROVIDERTOANGULARTHISMAKESITPOSSIBLETOTHENINJECTITSOMEWHEREINANGULARCODEFOREXAMPLEYOUMIGHTHAVEASERVICECALLEDHEROESSERVICEINANGULARJS:", "original": "In these situations, it is possible to *upgrade* an AngularJS provider to\nAngular. This makes it possible to then inject it somewhere in Angular\ncode. For example, you might have a service called `HeroesService` in AngularJS:", "translation": "在这些情况下,把一个 AngularJS 提供商*升级到*Angular 也是有可能的。这就让它将来有可能被注入到 Angular 代码中的某些地方。\n比如,你可能在 AngularJS 中有一个名叫 `HeroesService` 的服务:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANUPGRADETHESERVICEUSINGAANGULARFACTORYPROVIDERGUIDEDEPENDENCYINJECTION#FACTORYPROVIDERSTHATREQUESTSTHESERVICEFROMTHEANGULARJSINJECTOR", "original": "You can upgrade the service using a Angular [factory provider](guide/dependency-injection#factory-providers)\nthat requests the service from the AngularJS `$injector`.", "translation": "你可以 Angular 的[工厂提供商(factory provider)](guide/dependency-injection#factory-providers)升级该服务,\n它从 AngularJS 的 `$injector` 请求服务。Angular 依赖的名称由你确定:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "MANYDEVELOPERSPREFERTODECLARETHEFACTORYPROVIDERINASEPARATEAJSUPGRADEDPROVIDERSTSFILESOTHATTHEYAREALLTOGETHERMAKINGITEASIERTOREFERENCETHEMCREATENEWONESANDDELETETHEMONCETHEUPGRADEISOVER", "original": "Many developers prefer to declare the factory provider in a separate `ajs-upgraded-providers.ts` file\nso that they are all together, making it easier to reference them, create new ones and\ndelete them once the upgrade is over.", "translation": "很多开发者都喜欢在一个独立的 `ajs-upgraded-providers.ts` 中声明这个工厂提供商,以便把它们都放在一起,这样便于引用、创建新的以及在升级完毕时删除它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ITSALSORECOMMENDEDTOEXPORTTHEHEROESSERVICEFACTORYFUNCTIONSOTHATAHEADOFTIMECOMPILATIONCANPICKITUP", "original": "It's also recommended to export the `heroesServiceFactory` function so that Ahead-of-Time\ncompilation can pick it up.", "translation": "同时,建议导出 `heroesServiceFactory` 函数,以便 AOT 编译器可以拿到它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANTHENINJECTITINANGULARUSINGITSCLASSASATYPEANNOTATION:", "original": "You can then inject it in Angular using its class as a type annotation:", "translation": "然后你就可以使用它的类作为类型注解将其在 Angular 中进行注入了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHISEXAMPLEYOUUPGRADEDASERVICECLASSYOUCANUSEATYPESCRIPTTYPEANNOTATIONWHENYOUINJECTITWHILEITDOESNTAFFECTHOWTHEDEPENDENCYISHANDLEDITENABLESTHEBENEFITSOFSTATICTYPECHECKINGTHISISNOTREQUIREDTHOUGHANDANYANGULARJSSERVICEFACTORYORPROVIDERCANBEUPGRADED", "original": "In this example you upgraded a service class.\nYou can use a TypeScript type annotation when you inject it. While it doesn't\naffect how the dependency is handled, it enables the benefits of static type\nchecking. This is not required though, and any AngularJS service, factory, or\nprovider can be upgraded.", "translation": "在这个例子中,你升级了服务类。当注入它时,你可以使用 TypeScript 类型注解来获得这些额外的好处。\n它没有影响该依赖的处理过程,同时还得到了启用静态类型检查的好处。\n任何 AngularJS 中的服务、工厂和提供商都能被升级 —— 尽管这不是必须的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###MAKINGANGULARDEPENDENCIESINJECTABLETOANGULARJS", "original": "### Making Angular Dependencies Injectable to AngularJS", "translation": "### 让 Angular 的依赖能被注入到 AngularJS 中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INADDITIONTOUPGRADINGANGULARJSDEPENDENCIESYOUCANALSODOWNGRADEANGULARDEPENDENCIESSOTHATYOUCANUSETHEMFROMANGULARJSTHISCANBEUSEFULWHENYOUSTARTMIGRATINGSERVICESTOANGULARORCREATINGNEWSERVICESINANGULARWHILERETAININGCOMPONENTSWRITTENINANGULARJS", "original": "In addition to upgrading AngularJS dependencies, you can also *downgrade*\nAngular dependencies, so that you can use them from AngularJS. This can be\nuseful when you start migrating services to Angular or creating new services\nin Angular while retaining components written in AngularJS.", "translation": "除了能升级 AngularJS 依赖之外,你还能*降级*Angular 的依赖,以便在 AngularJS 中使用它们。\n当你已经开始把服务移植到 Angular 或在 Angular 中创建新服务,但同时还有一些用 AngularJS 写成的组件时,这会非常有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FOREXAMPLEYOUMIGHTHAVEANANGULARSERVICECALLEDHEROES:", "original": "For example, you might have an Angular service called `Heroes`:", "translation": "例如,你可能有一个 Angular 的 `Heroes` 服务:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "AGAINASWITHANGULARCOMPONENTSREGISTERTHEPROVIDERWITHTHENGMODULEBYADDINGITTOTHEMODULESPROVIDERSLIST", "original": "Again, as with Angular components, register the provider with the `NgModule` by adding it to the module's `providers` list.", "translation": "仿照 Angular 组件,把该提供商加入 `NgModule` 的 `providers` 列表中,以注册它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWWRAPTHEANGULARHEROESINANANGULARJSFACTORYFUNCTIONUSINGDOWNGRADEINJECTABLEANDPLUGTHEFACTORYINTOANANGULARJSMODULETHENAMEOFTHEANGULARJSDEPENDENCYISUPTOYOU:", "original": "Now wrap the Angular `Heroes` in an *AngularJS factory function* using `downgradeInjectable()`\nand plug the factory into an AngularJS module.\nThe name of the AngularJS dependency is up to you:", "translation": "现在,用 `upgradeAdapter.downgradeNg2Provider()` 来把 Angular 的 `Heroes` 包装成*AngularJS 的工厂函数*,并把这个工厂注册进 AngularJS 的模块中。\n依赖在 AngularJS 中的名字你可以自己定:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "AFTERTHISTHESERVICEISINJECTABLEANYWHEREINANGULARJSCODE:", "original": "After this, the service is injectable anywhere in AngularJS code:", "translation": "此后,该服务就能被注入到 AngularJS 代码中的任何地方了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "##USINGAHEADOFTIMECOMPILATIONWITHHYBRIDAPPS", "original": "## Using Ahead-of-time compilation with hybrid apps", "translation": "## 在混合式应用中使用 AOT 编译", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANTAKEADVANTAGEOFAHEADOFTIMEAOTCOMPILATIONONHYBRIDAPPSJUSTLIKEONANYOTHERANGULARAPPLICATIONTHESETUPFORANHYBRIDAPPISMOSTLYTHESAMEASDESCRIBEDINTHEAHEADOFTIMECOMPILATIONCHAPTERGUIDEAOTCOMPILERSAVEFORDIFFERENCESININDEXHTMLANDMAINAOTTS", "original": "You can take advantage of Ahead-of-time (AOT) compilation on hybrid apps just like on any other\nAngular application.\nThe setup for an hybrid app is mostly the same as described in\n[the Ahead-of-time Compilation chapter](guide/aot-compiler)\nsave for differences in `index.html` and `main-aot.ts`", "translation": "你也可以其它 Angular 应用一样在混合式应用中发挥 AOT 编译的优势。\n对混合式应用的设置过程和[预编译](guide/aot-compiler)章节中所讲的几乎完全一样,不同点在于 `index.html` 和 `main-aot.ts` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEINDEXHTMLWILLLIKELYHAVESCRIPTTAGSLOADINGANGULARJSFILESSOTHEINDEXHTMLFORAOTMUSTALSOLOADTHOSEFILESANEASYWAYTOCOPYTHEMISBYADDINGEACHTOTHECOPYDISTFILESJSFILE", "original": "The `index.html` will likely have script tags loading AngularJS files, so the `index.html`\nfor AOT must also load those files.\nAn easy way to copy them is by adding each to the `copy-dist-files.js` file.", "translation": "`index.html` 仍然需要 script 标签来加载 AngularJS 的文件,因此供 AOT 编译的 `index.html` 也需要加载那些文件。\n复制它们的简单方案是把它们全都添加到 `copy-dist-files.js` 文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOULLNEEDTOUSETHEGENERATEDAPPMODULEFACTORYINSTEADOFTHEORIGINALAPPMODULETOBOOTSTRAPTHEHYBRIDAPP:", "original": "You'll need to use the generated `AppModuleFactory`, instead of the original `AppModule` to\nbootstrap the hybrid app:", "translation": "你还要使用所生成的 `AppModuleFactory` 而不是原来的 `AppModule` 来引导一个混合式应用:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANDTHATSALLYOUNEEDDOTOGETTHEFULLBENEFITOFAOTFORANGULARAPPS", "original": "And that's all you need do to get the full benefit of AOT for Angular apps!", "translation": "这就是你为获取 Angular 应用的 AOT 优势所要做的一切。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "##PHONECATUPGRADETUTORIAL", "original": "## PhoneCat Upgrade Tutorial", "translation": "## PhoneCat 升级教程", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHISSECTIONYOULLLEARNTOPREPAREANDUPGRADEANAPPLICATIONWITHNGUPGRADETHEEXAMPLEAPPISANGULARPHONECATHTTPS:GITHUBCOMANGULARANGULARPHONECATFROMTHEORIGINALANGULARJSTUTORIALHTTPS:DOCSANGULARJSORGTUTORIALWHICHISWHEREMANYOFUSBEGANOURANGULARADVENTURESNOWYOULLSEEHOWTOBRINGTHATAPPLICATIONTOTHEBRAVENEWWORLDOFANGULAR", "original": "In this section, you'll learn to prepare and upgrade an application with `ngUpgrade`.\nThe example app is [Angular PhoneCat](https://github.com/angular/angular-phonecat)\nfrom [the original AngularJS tutorial](https://docs.angularjs.org/tutorial),\nwhich is where many of us began our Angular adventures. Now you'll see how to\nbring that application to the brave new world of Angular.", "translation": "在本节和下节中,你将看一个完整的例子,它使用 `upgrade` 模块准备和升级了一个应用程序。\n该应用就是来自[原 AngularJS 教程](https://docs.angularjs.org/tutorial)中的[Angular PhoneCat](https://github.com/angular/angular-phonecat)。\n那是我们很多人当初开始 Angular 探险之旅的地方。\n现在,你会看到如何把该应用带入 Angular 的美丽新世界。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "DURINGTHEPROCESSYOULLLEARNHOWTOAPPLYTHESTEPSOUTLINEDINTHEPREPARATIONGUIDEGUIDEUPGRADE#PREPARATIONYOULLALIGNTHEAPPLICATIONWITHANGULARANDALSOSTARTWRITINGINTYPESCRIPT", "original": "During the process you'll learn how to apply the steps outlined in the\n[preparation guide](guide/upgrade#preparation). You'll align the application\nwith Angular and also start writing in TypeScript.", "translation": "这期间,你将学到如何在实践中应用[准备指南](guide/upgrade#preparation)中列出的那些重点步骤:\n你先让该应用向 Angular 看齐,然后为它引入 SystemJS 模块加载器和 TypeScript。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TOFOLLOWALONGWITHTHETUTORIALCLONETHEANGULARPHONECATHTTPS:GITHUBCOMANGULARANGULARPHONECATREPOSITORYANDAPPLYTHESTEPSASYOUGO", "original": "To follow along with the tutorial, clone the\n[angular-phonecat](https://github.com/angular/angular-phonecat) repository\nand apply the steps as you go.", "translation": "要跟随本教程,请先把[angular-phonecat](https://github.com/angular/angular-phonecat)仓库克隆到本地,并应用这些步骤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTERMSOFPROJECTSTRUCTURETHISISWHERETHEWORKBEGINS:", "original": "In terms of project structure, this is where the work begins:", "translation": "在项目结构方面,工作的起点是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THISISACTUALLYAPRETTYGOODSTARTINGPOINTTHECODEUSESTHEANGULARJS15COMPONENTAPIANDTHEORGANIZATIONFOLLOWSTHEANGULARJSSTYLEGUIDEHTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMDWHICHISANIMPORTANTPREPARATIONSTEPGUIDEUPGRADE#FOLLOWTHEANGULARSTYLEGUIDEBEFOREASUCCESSFULUPGRADE", "original": "This is actually a pretty good starting point. The code uses the AngularJS 1.5\ncomponent API and the organization follows the\n[AngularJS Style Guide](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md),\nwhich is an important [preparation step](guide/upgrade#follow-the-angular-styleguide) before\na successful upgrade.", "translation": "这确实是一个很好地起点。特别是,该结构遵循了[AngularJS 风格指南](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md),\n要想成功升级,这是一个很重要的[准备步骤](guide/upgrade#follow-the-angular-styleguide)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "EACHCOMPONENTSERVICEANDFILTERISINITSOWNSOURCEFILEASPERTHERULEOF1HTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMD#SINGLERESPONSIBILITY", "original": "* Each component, service, and filter is in its own source file, as per the\n [Rule of 1](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#single-responsibility).", "translation": "每个组件、服务和过滤器都在它自己的源文件中 —— 就像[单一规则](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#single-responsibility)所要求的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THECOREPHONEDETAILANDPHONELISTMODULESAREEACHINTHEIROWNSUBDIRECTORYTHOSESUBDIRECTORIESCONTAINTHEJAVASCRIPTCODEASWELLASTHEHTMLTEMPLATESTHATGOWITHEACHPARTICULARFEATURETHISISINLINEWITHTHEFOLDERSBYFEATURESTRUCTUREHTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMD#FOLDERSBYFEATURESTRUCTUREANDMODULARITYHTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMD#MODULARITYRULES", "original": "* The `core`, `phone-detail`, and `phone-list` modules are each in their\n own subdirectory. Those subdirectories contain the JavaScript code as well as\n the HTML templates that go with each particular feature. This is in line with the\n [Folders-by-Feature Structure](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#folders-by-feature-structure)\n and [Modularity](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#modularity)\n rules.", "translation": "`core`、`phone-detail` 和 `phone-list` 模块都在它们自己的子目录中。那些子目录除了包含 HTML 模板之外,还包含 JavaScript 代码,它们共同完成一个特性。\n 这是[按特性分目录的结构](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y152)\n 和[模块化](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#modularity)规则所要求的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "UNITTESTSARELOCATEDSIDEBYSIDEWITHAPPLICATIONCODEWHERETHEYAREEASILYFOUNDASDESCRIBEDINTHERULESFORORGANIZINGTESTSHTTPS:GITHUBCOMJOHNPAPAANGULARSTYLEGUIDEBLOBMASTERA1READMEMD#ORGANIZINGTESTS", "original": "* Unit tests are located side-by-side with application code where they are easily\n found, as described in the rules for\n [Organizing Tests](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#organizing-tests).", "translation": "单元测试都和应用代码在一起,它们很容易找到。就像规则\n [组织测试文件](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#organizing-tests)中要求的那样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###SWITCHINGTOTYPESCRIPT", "original": "### Switching to TypeScript", "translation": "### 切换到 TypeScript", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SINCEYOUREGOINGTOBEWRITINGANGULARCODEINTYPESCRIPTITMAKESSENSETOBRINGINTHETYPESCRIPTCOMPILEREVENBEFOREYOUBEGINUPGRADING", "original": "Since you're going to be writing Angular code in TypeScript, it makes sense to\nbring in the TypeScript compiler even before you begin upgrading.", "translation": "因为你将使用 TypeScript 编写 Angular 的代码,所以在开始升级之前,先要把 TypeScript 的编译器设置好。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOULLALSOSTARTTOGRADUALLYPHASEOUTTHEBOWERPACKAGEMANAGERINFAVOROFNPMINSTALLINGALLNEWDEPENDENCIESUSINGNPMANDEVENTUALLYREMOVINGBOWERFROMTHEPROJECT", "original": "You'll also start to gradually phase out the Bower package manager in favor\nof NPM, installing all new dependencies using NPM, and eventually removing Bower from the project.", "translation": "你还将开始逐步淘汰 Bower 包管理器,换成 NPM。后面你将使用 NPM 来安装新的依赖包,并最终从项目中移除 Bower。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "BEGINBYINSTALLINGTYPESCRIPTTOTHEPROJECT", "original": "Begin by installing TypeScript to the project.", "translation": "先把 TypeScript 包安装到项目中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INSTALLTYPEDEFINITIONSFORTHEEXISTINGLIBRARIESTHATYOUREUSINGBUTTHATDONTCOMEWITHPREPACKAGEDTYPES:ANGULARJSANDTHEJASMINEUNITTESTFRAMEWORK", "original": "Install type definitions for the existing libraries that\nyou're using but that don't come with prepackaged types: AngularJS and the\nJasmine unit test framework.", "translation": "还要为那些没有自带类型信息的库(比如 AngularJS 和 Jasmine)安装类型定义文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUSHOULDALSOCONFIGURETHETYPESCRIPTCOMPILERWITHATSCONFIGJSONINTHEPROJECTDIRECTORYASDESCRIBEDINTHETYPESCRIPTCONFIGURATIONGUIDETYPESCRIPTCONFIGURATIONGUIDETHETSCONFIGJSONFILETELLSTHETYPESCRIPTCOMPILERHOWTOTURNYOURTYPESCRIPTFILESINTOES5CODEBUNDLEDINTOCOMMONJSMODULES", "original": "You should also configure the TypeScript compiler with a `tsconfig.json` in the project directory\nas described in the [TypeScript Configuration](guide/typescript-configuration) guide.\nThe `tsconfig.json` file tells the TypeScript compiler how to turn your TypeScript files\ninto ES5 code bundled into CommonJS modules.", "translation": "你还应该要往项目目录下添加一个 `tsconfig.json` 文件,\n就像在 [TypeScript 配置](guide/typescript-configuration)中讲过的那样。\n`tsconfig.json` 文件会告诉 TypeScript 编译器如何把 TypeScript 文件转成 ES5 代码,并打包进 CommonJS 模块中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FINALLYYOUSHOULDADDSOMENPMSCRIPTSINPACKAGEJSONTOCOMPILETHETYPESCRIPTFILESTOJAVASCRIPTBASEDONTHETSCONFIGJSONCONFIGURATIONFILE:", "original": "Finally, you should add some npm scripts in `package.json` to compile the TypeScript files to\nJavaScript (based on the `tsconfig.json` configuration file):", "translation": "最后,你应该把下列 npm 脚本添加到 `package.json` 中,用于把 TypeScript 文件编译成 JavaScript (根据 `tsconfig.json` 的配置):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWLAUNCHTHETYPESCRIPTCOMPILERFROMTHECOMMANDLINEINWATCHMODE:", "original": "Now launch the TypeScript compiler from the command line in watch mode:", "translation": "现在,从命令行中用监视模式启动 TypeScript 编译器:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "KEEPTHISPROCESSRUNNINGINTHEBACKGROUNDWATCHINGANDRECOMPILINGASYOUMAKECHANGES", "original": "Keep this process running in the background, watching and recompiling as you make changes.", "translation": "让这个进程一直在后台运行,监听任何变化并自动重新编译。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NEXTCONVERTYOURCURRENTJAVASCRIPTFILESINTOTYPESCRIPTSINCETYPESCRIPTISASUPERSETOFECMASCRIPT2015WHICHINTURNISASUPERSETOFECMASCRIPT5YOUCANSIMPLYSWITCHTHEFILEEXTENSIONSFROMJSTOTSANDEVERYTHINGWILLWORKJUSTLIKEITDIDBEFOREASTHETYPESCRIPTCOMPILERRUNSITEMITSTHECORRESPONDINGJSFILEFOREVERYTSFILEANDTHECOMPILEDJAVASCRIPTISWHATACTUALLYGETSEXECUTEDIFYOUSTARTTHEPROJECTHTTPSERVERWITHNPMSTARTYOUSHOULDSEETHEFULLYFUNCTIONALAPPLICATIONINYOURBROWSER", "original": "Next, convert your current JavaScript files into TypeScript. Since\nTypeScript is a super-set of ECMAScript 2015, which in turn is a super-set\nof ECMAScript 5, you can simply switch the file extensions from `.js` to `.ts`\nand everything will work just like it did before. As the TypeScript compiler\nruns, it emits the corresponding `.js` file for every `.ts` file and the\ncompiled JavaScript is what actually gets executed. If you start\nthe project HTTP server with `npm start`, you should see the fully functional\napplication in your browser.", "translation": "接下来,把 JavaScript 文件转换成 TypeScript 文件。\n由于 TypeScript 是 ECMAScript 2015 的一个超集,而 ES2015 又是 ECMAScript 5 的超集,所以你可以简单的把文件的扩展名从 `.js` 换成 `.ts`,\n它们还是会像以前一样工作。由于 TypeScript 编译器仍在运行,它会为每一个 `.ts` 文件生成对应的 `.js` 文件,而真正运行的是编译后的 `.js` 文件。\n如果你用 `npm start` 开启了本项目的 HTTP 服务器,你会在浏览器中看到一个功能完好的应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWTHATYOUHAVETYPESCRIPTTHOUGHYOUCANSTARTBENEFITINGFROMSOMEOFITSFEATURESTHERESALOTOFVALUETHELANGUAGECANPROVIDETOANGULARJSAPPLICATIONS", "original": "Now that you have TypeScript though, you can start benefiting from some of its\nfeatures. There's a lot of value the language can provide to AngularJS applications.", "translation": "有了 TypeScript,你就可以从它的一些特性中获益了。此语言可以为 AngularJS 应用提供很多价值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FORONETHINGTYPESCRIPTISASUPERSETOFES2015ANYAPPTHATHASPREVIOUSLYBEENWRITTENINES5LIKETHEPHONECATEXAMPLEHASCANWITHTYPESCRIPTSTARTINCORPORATINGALLOFTHEJAVASCRIPTFEATURESTHATARENEWTOES2015THESEINCLUDETHINGSLIKELETSANDCONSTSARROWFUNCTIONSDEFAULTFUNCTIONPARAMETERSANDDESTRUCTURINGASSIGNMENTS", "original": "For one thing, TypeScript is a superset of ES2015. Any app that has previously\nbeen written in ES5 - like the PhoneCat example has - can with TypeScript\nstart incorporating all of the JavaScript features that are new to ES2015.\nThese include things like `let`s and `const`s, arrow functions, default function\nparameters, and destructuring assignments.", "translation": "首先,TypeScript 是一个 ES2015 的超集。任何以前用 ES5 写的程序(就像 PhoneCat 范例)都可以开始通过 TypeScript\n纳入那些添加到 ES2015 中的新特性。\n这包括 `let`、`const`、箭头函数、函数默认参数以及解构(destructure)赋值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANOTHERTHINGYOUCANDOISSTARTADDINGTYPESAFETYTOYOURCODETHISHASACTUALLYPARTIALLYALREADYHAPPENEDBECAUSEOFTHEANGULARJSTYPINGSYOUINSTALLEDTYPESCRIPTARECHECKINGTHATYOUARECALLINGANGULARJSAPISCORRECTLYWHENYOUDOTHINGSLIKEREGISTERCOMPONENTSTOANGULARMODULES", "original": "Another thing you can do is start adding *type safety* to your code. This has\nactually partially already happened because of the AngularJS typings you installed.\nTypeScript are checking that you are calling AngularJS APIs correctly when you do\nthings like register components to Angular modules.", "translation": "你能做的另一件事就是把*类型安全*添加到代码中。这实际上已经部分完成了,因为你已经安装了 AngularJS 的类型定义。\nTypeScript 会帮你检查是否正确调用了 AngularJS 的 API,—— 比如往 Angular 模块中注册组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "BUTYOUCANALSOSTARTADDINGTYPEANNOTATIONSTOGETEVENMOREOUTOFTYPESCRIPTSTYPESYSTEMFORINSTANCEYOUCANANNOTATETHECHECKMARKFILTERSOTHATITEXPLICITLYEXPECTSBOOLEANSASARGUMENTSTHISMAKESITCLEARERWHATTHEFILTERISSUPPOSEDTODO", "original": "But you can also start adding *type annotations* to get even more\nout of TypeScript's type system. For instance, you can annotate the checkmark\nfilter so that it explicitly expects booleans as arguments. This makes it clearer\nwhat the filter is supposed to do.", "translation": "你还能开始把*类型注解*添加到自己的代码中,来从 TypeScript 的类型系统中获得更多帮助。\n比如,你可以给 `checkmark` 过滤器加上注解,表明它期待一个 `boolean` 类型的参数。\n这可以更清楚的表明此过滤器打算做什么", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHEPHONESERVICEYOUCANEXPLICITLYANNOTATETHERESOURCESERVICEDEPENDENCYASANANGULARRESOURCEIRESOURCESERVICEATYPEDEFINEDBYTHEANGULARJSTYPINGS", "original": "In the `Phone` service, you can explicitly annotate the `$resource` service dependency\nas an `angular.resource.IResourceService` - a type defined by the AngularJS typings.", "translation": "在 `Phone` 服务中,你可以明确的把 `$resource` 服务声明为 `angular.resource.IResourceService`,一个 AngularJS 类型定义提供的类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANAPPLYTHESAMETRICKTOTHEAPPLICATIONSROUTECONFIGURATIONFILEINAPPCONFIGTSWHEREYOUAREUSINGTHELOCATIONANDROUTESERVICESBYANNOTATINGTHEMACCORDINGLYTYPESCRIPTCANVERIFYYOURECALLINGTHEIRAPISWITHTHECORRECTKINDSOFARGUMENTS", "original": "You can apply the same trick to the application's route configuration file in `app.config.ts`,\nwhere you are using the location and route services. By annotating them accordingly TypeScript\ncan verify you're calling their APIs with the correct kinds of arguments.", "translation": "你可以在应用的路由配置中使用同样的技巧,那里你用到了 location 和 route 服务。\n一旦为它们提供了类型信息,TypeScript 就能检查你是否在用类型的正确参数来调用它们了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEANGULARJS1XTYPEDEFINITIONSHTTPS:WWWNPMJSCOMPACKAGETYPESANGULARYOUINSTALLEDARENOTOFFICIALLYMAINTAINEDBYTHEANGULARTEAMBUTAREQUITECOMPREHENSIVEITISPOSSIBLETOMAKEANANGULARJS1XAPPLICATIONFULLYTYPEANNOTATEDWITHTHEHELPOFTHESEDEFINITIONS", "original": "The [AngularJS 1.x type definitions](https://www.npmjs.com/package/@types/angular)\nyou installed are not officially maintained by the Angular team,\nbut are quite comprehensive. It is possible to make an AngularJS 1.x application\nfully type-annotated with the help of these definitions.", "translation": "你用安装的这个[AngularJS.x 类型定义文件](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/angularjs)\n并不是由 Angular 开发组维护的,但它也已经足够全面了。借助这些类型定义的帮助,它可以为 AngularJS.x 程序加上全面的类型注解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "IFTHISISSOMETHINGYOUWANTEDTODOITWOULDBEAGOODIDEATOENABLETHENOIMPLICITANYCONFIGURATIONOPTIONINTSCONFIGJSONTHISWOULDCAUSETHETYPESCRIPTCOMPILERTODISPLAYAWARNINGWHENTHERESANYCODETHATDOESNOTYETHAVETYPEANNOTATIONSYOUCOULDUSEITASAGUIDETOINFORMUSABOUTHOWCLOSEYOUARETOHAVINGAFULLYANNOTATEDPROJECT", "original": "If this is something you wanted to do, it would be a good idea to enable\nthe `noImplicitAny` configuration option in `tsconfig.json`. This would\ncause the TypeScript compiler to display a warning when there's any code that\ndoes not yet have type annotations. You could use it as a guide to inform\nus about how close you are to having a fully annotated project.", "translation": "如果你想这么做,就在 `tsconfig.json` 中启用 `noImplicitAny` 配置项。\n这样,如果遇到什么还没有类型注解的代码,TypeScript 编译器就会显示一个警告。\n你可以用它作为指南,告诉你现在与一个完全类型化的项目距离还有多远。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANOTHERTYPESCRIPTFEATUREYOUCANMAKEUSEOFISCLASSESINPARTICULARYOUCANTURNCOMPONENTCONTROLLERSINTOCLASSESTHATWAYTHEYLLBEASTEPCLOSERTOBECOMINGANGULARCOMPONENTCLASSESWHICHWILLMAKELIFEEASIERONCEYOUUPGRADE", "original": "Another TypeScript feature you can make use of is *classes*. In particular, you\ncan turn component controllers into classes. That way they'll be a step\ncloser to becoming Angular component classes, which will make life\neasier once you upgrade.", "translation": "你能用的另一个 TypeScript 特性是*类*。具体来讲,你可以把控制器转换成类。\n这种方式下,你离成为 Angular 组件类就又近了一步,它会令你的升级之路变得更简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARJSEXPECTSCONTROLLERSTOBECONSTRUCTORFUNCTIONSTHATSEXACTLYWHATES2015TYPESCRIPTCLASSESAREUNDERTHEHOODSOTHATMEANSYOUCANJUSTPLUGINACLASSASACOMPONENTCONTROLLERANDANGULARJSWILLHAPPILYUSEIT", "original": "AngularJS expects controllers to be constructor functions. That's exactly what\nES2015/TypeScript classes are under the hood, so that means you can just plug in a\nclass as a component controller and AngularJS will happily use it.", "translation": "AngularJS 期望控制器是一个构造函数。这实际上就是 ES2015/TypeScript 中的类,\n这也就意味着只要你把一个类注册为组件控制器,AngularJS 就会愉快的使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "HERESWHATTHENEWCLASSFORTHEPHONELISTCOMPONENTCONTROLLERLOOKSLIKE:", "original": "Here's what the new class for the phone list component controller looks like:", "translation": "新的“电话列表(phone list)”组件控制器类是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHATWASPREVIOUSLYDONEINTHECONTROLLERFUNCTIONISNOWDONEINTHECLASSCONSTRUCTORFUNCTIONTHEDEPENDENCYINJECTIONANNOTATIONSAREATTACHEDTOTHECLASSUSINGASTATICPROPERTYINJECTATRUNTIMETHISBECOMESTHEPHONELISTCONTROLLERINJECTPROPERTY", "original": "What was previously done in the controller function is now done in the class\nconstructor function. The dependency injection annotations are attached\nto the class using a static property `$inject`. At runtime this becomes the\n`PhoneListController.$inject` property.", "translation": "以前在控制器函数中实现的一切,现在都改由类的构造函数来实现了。类型注入注解通过静态属性 `$inject`\n被附加到了类上。在运行时,它们变成了 `PhoneListController.$inject`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THECLASSADDITIONALLYDECLARESTHREEMEMBERS:THEARRAYOFPHONESTHENAMEOFTHECURRENTSORTKEYANDTHESEARCHQUERYTHESEAREALLTHINGSYOUHAVEALREADYBEENATTACHINGTOTHECONTROLLERBUTTHATWERENTEXPLICITLYDECLAREDANYWHERETHELASTONEOFTHESEISNTACTUALLYUSEDINTHETYPESCRIPTCODESINCEITSONLYREFERREDTOINTHETEMPLATEBUTFORTHESAKEOFCLARITYYOUSHOULDDEFINEALLOFTHECONTROLLERMEMBERS", "original": "The class additionally declares three members: The array of phones, the name of\nthe current sort key, and the search query. These are all things you have already\nbeen attaching to the controller but that weren't explicitly declared anywhere.\nThe last one of these isn't actually used in the TypeScript code since it's only\nreferred to in the template, but for the sake of clarity you should define all of the\ncontroller members.", "translation": "该类还声明了另外三个成员:电话列表、当前排序键的名字和搜索条件。\n这些东西你以前就加到了控制器上,只是从来没有在任何地方显式定义过它们。最后一个成员从未真正在 TypeScript 代码中用过,\n因为它只是在模板中被引用过。但为了清晰起见,你还是应该定义出此控制器应有的所有成员。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHEPHONEDETAILCONTROLLERYOULLHAVETWOMEMBERS:ONEFORTHEPHONETHATTHEUSERISLOOKINGATANDANOTHERFORTHEURLOFTHECURRENTLYDISPLAYEDIMAGE:", "original": "In the Phone detail controller, you'll have two members: One for the phone\nthat the user is looking at and another for the URL of the currently displayed image:", "translation": "在电话详情控制器中,你有两个成员:一个是用户正在查看的电话,另一个是正在显示的图像:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THISMAKESTHECONTROLLERCODELOOKALOTMORELIKEANGULARALREADYYOUREALLSETTOACTUALLYINTRODUCEANGULARINTOTHEPROJECT", "original": "This makes the controller code look a lot more like Angular already. You're\nall set to actually introduce Angular into the project.", "translation": "这已经让你的控制器代码看起来更像 Angular 了。你的准备工作做好了,可以引进 Angular 到项目中了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "IFYOUHADANYANGULARJSSERVICESINTHEPROJECTTHOSEWOULDALSOBEAGOODCANDIDATEFORCONVERTINGTOCLASSESSINCELIKECONTROLLERSTHEYREALSOCONSTRUCTORFUNCTIONSBUTYOUONLYHAVETHEPHONEFACTORYINTHISPROJECTANDTHATSABITSPECIALSINCEITSANNGRESOURCEFACTORYSOYOUWONTBEDOINGANYTHINGTOITINTHEPREPARATIONSTAGEYOULLINSTEADTURNITDIRECTLYINTOANANGULARSERVICE", "original": "If you had any AngularJS services in the project, those would also be\na good candidate for converting to classes, since like controllers,\nthey're also constructor functions. But you only have the `Phone` factory\nin this project, and that's a bit special since it's an `ngResource`\nfactory. So you won't be doing anything to it in the preparation stage.\nYou'll instead turn it directly into an Angular service.", "translation": "如果项目中有任何 AngularJS 的服务,它们也是转换成类的优秀候选人,像控制器一样,它们也是构造函数。\n但是在本项目中,你只有一个 `Phone` 工厂,这有点特别,因为它是一个 `ngResource` 工厂。\n所以你不会在准备阶段中处理它,而是在下一节中直接把它转换成 Angular 服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###INSTALLINGANGULAR", "original": "### Installing Angular", "translation": "### 安装 Angular", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "HAVINGCOMPLETEDTHEPREPARATIONWORKGETGOINGWITHTHEANGULARUPGRADEOFPHONECATYOULLDOTHISINCREMENTALLYWITHTHEHELPOFNGUPGRADE#UPGRADINGWITHNGUPGRADETHATCOMESWITHANGULARBYTHETIMEYOUREDONEYOULLBEABLETOREMOVEANGULARJSFROMTHEPROJECTCOMPLETELYBUTTHEKEYISTODOTHISPIECEBYPIECEWITHOUTBREAKINGTHEAPPLICATION", "original": "Having completed the preparation work, get going with the Angular\nupgrade of PhoneCat. You'll do this incrementally with the help of\n[ngUpgrade](#upgrading-with-ngupgrade) that comes with Angular.\nBy the time you're done, you'll be able to remove AngularJS from the project\ncompletely, but the key is to do this piece by piece without breaking the application.", "translation": "准备工作做完了,接下来就开始把 PhoneCat 升级到 Angular。\n你将在 Angular[升级模块](guide/upgrade#upgrading-with-ngupgrade)的帮助下增量式的完成此项工作。\n做完这些之后,就能把 AngularJS 从项目中完全移除了,但其中的关键是在不破坏此程序的前提下一小块一小块的完成它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEPROJECTALSOCONTAINSSOMEANIMATIONSYOUWONTUPGRADETHEMINTHISVERSIONOFTHEGUIDETURNTOTHEANGULARANIMATIONSGUIDEANIMATIONSGUIDETOLEARNABOUTTHAT", "original": "The project also contains some animations.\nYou won't upgrade them in this version of the guide.\nTurn to the [Angular animations](guide/animations) guide to learn about that.", "translation": "该项目还包含一些动画,在此指南的当前版本你先不升级它,请到 [Angular 动画](guide/animations)中进一步学习。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INSTALLANGULARINTOTHEPROJECTALONGWITHTHESYSTEMJSMODULELOADERTAKEALOOKATTHERESULTSOFTHESETUPGUIDESETUPINSTRUCTIONSANDGETTHEFOLLOWINGCONFIGURATIONSFROMTHERE:", "original": "Install Angular into the project, along with the SystemJS module loader.\nTake a look at the results of the [Setup](guide/setup) instructions\nand get the following configurations from there:", "translation": "用 SystemJS 模块加载器把 Angular 安装到项目中。\n看看[搭建本地开发环境](guide/setup)中的指南,并从那里获得如下配置:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ADDANGULARANDTHEOTHERNEWDEPENDENCIESTOPACKAGEJSON", "original": "* Add Angular and the other new dependencies to `package.json`", "translation": "把 Angular 和其它新依赖添加到 `package.json` 中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THESYSTEMJSCONFIGURATIONFILESYSTEMJSCONFIGJSTOTHEPROJECTROOTDIRECTORY", "original": "* The SystemJS configuration file `systemjs.config.js` to the project root directory.", "translation": "把 SystemJS 的配置文件 `systemjs.config.js` 添加到项目的根目录。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ONCETHESEAREDONERUN:", "original": "Once these are done, run:", "translation": "这些完成之后,就运行:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SOONYOUCANLOADANGULARDEPENDENCIESINTOTHEAPPLICATIONVIAINDEXHTMLBUTFIRSTYOUNEEDTODOSOMEDIRECTORYPATHADJUSTMENTSYOULLNEEDTOLOADFILESFROMNODEMODULESANDTHEPROJECTROOTINSTEADOFFROMTHEAPPDIRECTORYASYOUVEBEENDOINGTOTHISPOINT", "original": "Soon you can load Angular dependencies into the application via `index.html`,\nbut first you need to do some directory path adjustments.\nYou'll need to load files from `node_modules` and the project root instead of\nfrom the `/app` directory as you've been doing to this point.", "translation": "很快你就可以通过 `index.html` 来把 Angular 的依赖快速加载到应用中,\n但首先,你得做一些目录结构调整。这是因为你正准备从 `node_modules` 中加载文件,然而目前项目中的每一个文件都是从 `/app` 目录下加载的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "MOVETHEAPPINDEXHTMLFILETOTHEPROJECTROOTDIRECTORYTHENCHANGETHEDEVELOPMENTSERVERROOTPATHINPACKAGEJSONTOALSOPOINTTOTHEPROJECTROOTINSTEADOFAPP:", "original": "Move the `app/index.html` file to the project root directory. Then change the\ndevelopment server root path in `package.json` to also point to the project root\ninstead of `app`:", "translation": "把 `app/index.html` 移入项目的根目录,然后把 `package.json` 中的开发服务器根目录也指向项目的根目录,而不再是 `app` 目录:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWYOUREABLETOSERVEEVERYTHINGFROMTHEPROJECTROOTTOTHEWEBBROWSERBUTYOUDONOTWANTTOHAVETOCHANGEALLTHEIMAGEANDDATAPATHSUSEDINTHEAPPLICATIONCODETOMATCHTHEDEVELOPMENTSETUPFORTHATREASONYOULLADDABASETAGTOINDEXHTMLWHICHWILLCAUSERELATIVEURLSTOBERESOLVEDBACKTOTHEAPPDIRECTORY:", "original": "Now you're able to serve everything from the project root to the web browser. But you do *not*\nwant to have to change all the image and data paths used in the application code to match\nthe development setup. For that reason, you'll add a `<base>` tag to `index.html`, which will\ncause relative URLs to be resolved back to the `/app` directory:", "translation": "现在,你就能把项目根目录下的每一样东西发给浏览器了。但你*不想*为了适应开发环境中的设置,被迫修改应用代码中用到的所有图片和数据的路径。因此,你要往 `index.html` 中添加一个 `<base>` 标签,它将导致各种相对路径被解析回 `/app` 目录:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWYOUCANLOADANGULARVIASYSTEMJSYOULLADDTHEANGULARPOLYFILLSANDTHESYSTEMJSCONFIGTOTHEENDOFTHEHEADSECTIONANDTHENYOULLUSESYSTEMIMPORTTOLOADTHEACTUALAPPLICATION:", "original": "Now you can load Angular via SystemJS. You'll add the Angular polyfills and the\nSystemJS config to the end of the `<head>` section, and then you'll use `System.import`\nto load the actual application:", "translation": "现在你可以通过 SystemJS 加载 Angular 了。你还要把 Angular 的腻子脚本(polyfills)\n和 SystemJS 的配置加到 `<head>` 区的末尾,然后,你能就用 `System.import` 来加载实际的应用了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUALSONEEDTOMAKEACOUPLEOFADJUSTMENTSTOTHESYSTEMJSCONFIGJSFILEINSTALLEDDURINGSETUPGUIDESETUP", "original": "You also need to make a couple of adjustments\nto the `systemjs.config.js` file installed during [setup](guide/setup).", "translation": "你还需要对[环境设置](guide/setup)期间安装的 `systemjs.config.js` 文件做一些调整。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "POINTTHEBROWSERTOTHEPROJECTROOTWHENLOADINGTHINGSTHROUGHSYSTEMJSINSTEADOFUSINGTHEBASEURL", "original": "Point the browser to the project root when loading things through SystemJS,\ninstead of using the `<base>` URL.", "translation": "在 SystemJS 加载期间为浏览器指出项目的根在哪里,而不再使用 `<base>` URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INSTALLTHEUPGRADEPACKAGEVIANPMINSTALLANGULARUPGRADESAVEANDADDAMAPPINGFORTHEANGULARUPGRADESTATICPACKAGE", "original": "Install the `upgrade` package via `npm install @angular/upgrade --save`\nand add a mapping for the `@angular/upgrade/static` package.", "translation": "再通过 `npm install @angular/upgrade --save` 安装 `upgrade` 包,并为 `@angular/upgrade/static` 包添加一个映射。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###CREATINGTHEAPPMODULE", "original": "### Creating the _AppModule_", "translation": "### 创建 *AppModule*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWCREATETHEROOTNGMODULECLASSCALLEDAPPMODULETHEREISALREADYAFILENAMEDAPPMODULETSTHATHOLDSTHEANGULARJSMODULERENAMEITTOAPPMODULEAJSTSANDUPDATETHECORRESPONDINGSCRIPTNAMEINTHEINDEXHTMLASWELLTHEFILECONTENTSREMAIN:", "original": "Now create the root `NgModule` class called `AppModule`.\nThere is already a file named `app.module.ts` that holds the AngularJS module.\nRename it to `app.module.ajs.ts` and update the corresponding script name in the `index.html` as well.\nThe file contents remain:", "translation": "现在,创建一个名叫 `AppModule` 的根 `NgModule` 类。\n这里已经有了一个名叫 `app.module.ts` 的文件,其中存放着 AngularJS 的模块。\n把它改名为 `app.module.ng1.ts`,同时也要在 `index.html` 中修改对应的脚本名。\n文件的内容保留:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWCREATEANEWAPPMODULETSWITHTHEMINIMUMNGMODULECLASS:", "original": "Now create a new `app.module.ts` with the minimum `NgModule` class:", "translation": "然后创建一个新的 `app.module.ts` 文件,其中是一个最小化的 `NgModule` 类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###BOOTSTRAPPINGAHYBRIDPHONECAT", "original": "### Bootstrapping a hybrid PhoneCat", "translation": "### 引导 PhoneCat 的混合式应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NEXTYOULLBOOTSTRAPTHEAPPLICATIONASAHYBRIDAPPLICATIONTHATSUPPORTSBOTHANGULARJSANDANGULARCOMPONENTSAFTERTHATYOUCANSTARTCONVERTINGTHEINDIVIDUALPIECESTOANGULAR", "original": "Next, you'll bootstrap the application as a *hybrid application*\nthat supports both AngularJS and Angular components. After that,\nyou can start converting the individual pieces to Angular.", "translation": "接下来,你把该应用程序引导改装为一个同时支持 AngularJS 和 Angular 的*混合式应用*。\n然后,就能开始把这些不可分割的小块转换到 Angular 了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEAPPLICATIONISCURRENTLYBOOTSTRAPPEDUSINGTHEANGULARJSNGAPPDIRECTIVEATTACHEDTOTHEHTMLELEMENTOFTHEHOSTPAGETHISWILLNOLONGERWORKINTHEHYBRIDAPPSWITCHTOTHENGUPGRADEBOOTSTRAP#BOOTSTRAPPINGHYBRIDAPPLICATIONSMETHODINSTEAD", "original": "The application is currently bootstrapped using the AngularJS `ng-app` directive\nattached to the `<html>` element of the host page. This will no longer work in the hybrid\napp. Switch to the [ngUpgrade bootstrap](#bootstrapping-hybrid-applications) method\ninstead.", "translation": "本应用现在是使用宿主页面中附加到 `<html>` 元素上的 `ng-app` 指令引导的。\n但在混合式应用中,不能再这么用了。你得用[ngUpgrade bootstrap](#bootstrapping-hybrid-applications)方法代替。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FIRSTREMOVETHENGAPPATTRIBUTEFROMINDEXHTMLTHENIMPORTUPGRADEMODULEINTHEAPPMODULEANDOVERRIDEITSNGDOBOOTSTRAPMETHOD:", "original": "First, remove the `ng-app` attribute from `index.html`.\nThen import `UpgradeModule` in the `AppModule`, and override its `ngDoBootstrap` method:", "translation": "首先,从 `index.html` 中移除 `ng-app`。然后在 `AppModule` 中导入 `UpgradeModule`,并改写它的 `ngDoBootstrap` 方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOTETHATYOUAREBOOTSTRAPPINGTHEANGULARJSMODULEFROMINSIDENGDOBOOTSTRAPTHEARGUMENTSARETHESAMEASYOUWOULDPASSTOANGULARBOOTSTRAPIFYOUWEREMANUALLYBOOTSTRAPPINGANGULARJS:THEROOTELEMENTOFTHEAPPLICATIONANDANARRAYOFTHEANGULARJS1XMODULESTHATYOUWANTTOLOAD", "original": "Note that you are bootstrapping the AngularJS module from inside `ngDoBootstrap`.\nThe arguments are the same as you would pass to `angular.bootstrap` if you were manually\nbootstrapping AngularJS: the root element of the application; and an array of the\nAngularJS 1.x modules that you want to load.", "translation": "注意,你正在从内部的 `ngDoBootstrap` 中引导 AngularJS 模块。\n它的参数和你在手动引导 AngularJS 时传给 `angular.bootstrap` 的是一样的:应用的根元素,和所要加载的 AngularJS 1.x 模块的数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FINALLYBOOTSTRAPTHEAPPMODULEINSRCMAINTSTHISFILEHASBEENCONFIGUREDASTHEAPPLICATIONENTRYPOINTINSYSTEMJSCONFIGJSSOITISALREADYBEINGLOADEDBYTHEBROWSER", "original": "Finally, bootstrap the `AppModule` in `src/main.ts`.\nThis file has been configured as the application entrypoint in `systemjs.config.js`,\nso it is already being loaded by the browser.", "translation": "最后,在 `src/main.ts` 中引导这个 `AppModule`。该文件在 `systemjs.config.js` 中被配置为了应用的入口,所以它已经被加载进了浏览器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWYOURERUNNINGBOTHANGULARJSANDANGULARATTHESAMETIMETHATSPRETTYEXCITINGYOURENOTRUNNINGANYACTUALANGULARCOMPONENTSYETTHATSNEXT", "original": "Now you're running both AngularJS and Angular at the same time. That's pretty\nexciting! You're not running any actual Angular components yet. That's next.", "translation": "现在,你同时运行着 AngularJS 和 Angular。漂亮!不过你还没有运行什么实际的 Angular 组件,这就是接下来要做的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####WHYDECLAREANGULARASANGULARIANGULARSTATIC", "original": "#### Why declare _angular_ as _angular.IAngularStatic_?", "translation": "#### 为何要声明 *angular* 为*angular.IAngularStatic*?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TYPESANGULARISDECLAREDASAUMDMODULEANDDUETOTHEWAYAHREFHTTPS:GITHUBCOMMICROSOFTTYPESCRIPTWIKIWHATSNEWINTYPESCRIPT#SUPPORTFORUMDMODULEDEFINITIONSUMDTYPINGSAWORKONCEYOUHAVEANES6IMPORTSTATEMENTINAFILEALLUMDTYPEDMODULESMUSTALSOBEIMPORTEDVIAIMPORTSTATEMENTSINSTEADOFBEINGGLOBALLYAVAILABLE", "original": "`@types/angular` is declared as a UMD module, and due to the way\n<a href=\"https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#support-for-umd-module-definitions\">UMD typings</a>\nwork, once you have an ES6 `import` statement in a file all UMD typed modules must also be\nimported via `import` statements instead of being globally available.", "translation": "`@types/angular` 声明为 UMD 模块,根据<a href=\"https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#support-for-umd-module-definitions\" target=\"_blank\">UMD 类型</a>\n的工作方式,一旦你在文件中有一条 ES6 的 `import` 语句,所有的 UMD 类型化的模型必须都通过 `import` 语句导入,\n而是不是全局可用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARJSISCURRENTLYLOADEDBYASCRIPTTAGININDEXHTMLWHICHMEANSTHATTHEWHOLEAPPHASACCESSTOITASAGLOBALANDUSESTHESAMEINSTANCEOFTHEANGULARVARIABLEIFYOUUSEDIMPORTASANGULARFROMANGULARINSTEADYOUDALSOHAVETOLOADEVERYFILEINTHEANGULARJSAPPTOUSEES2015MODULESINORDERTOENSUREANGULARJSWASBEINGLOADEDCORRECTLY", "original": "AngularJS is currently loaded by a script tag in `index.html`, which means that the whole app\nhas access to it as a global and uses the same instance of the `angular` variable.\nIf you used `import * as angular from 'angular'` instead, you'd also have to\nload every file in the AngularJS app to use ES2015 modules in order to ensure AngularJS was being\nloaded correctly.", "translation": "AngularJS 是日前是通过 `index.html` 中的 script 标签加载,这意味着整个应用是作为一个全局变量进行访问的,\n使用同一个 `angular` 变量的实例。\n但如果你使用 `import * as angular from 'angular'`,我还需要彻底修改 AngularJS 应用中加载每个文件的方式,\n确保 AngularJS 应用被正确加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THISISACONSIDERABLEEFFORTANDITOFTENISNTWORTHITESPECIALLYSINCEYOUAREINTHEPROCESSOFMOVINGYOURCODETOANGULARINSTEADDECLAREANGULARASANGULARIANGULARSTATICTOINDICATEITISAGLOBALVARIABLEANDSTILLHAVEFULLTYPINGSUPPORT", "original": "This is a considerable effort and it often isn't worth it, especially since you are in the\nprocess of moving your code to Angular.\nInstead, declare `angular` as `angular.IAngularStatic` to indicate it is a global variable\nand still have full typing support.", "translation": "这需要相当多的努力,通常也不值得去做,特别是当你正在朝着 Angular 前进时。\n但如果你把 `angular` 声明为 `angular.IAngularStatic`,指明它是一个全局变量,\n仍然可以获得全面的类型支持。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###UPGRADINGTHEPHONESERVICE", "original": "### Upgrading the Phone service", "translation": "### 升级 `Phone` 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEFIRSTPIECEYOULLPORTOVERTOANGULARISTHEPHONESERVICEWHICHRESIDESINAPPCOREPHONEPHONESERVICETSANDMAKESITPOSSIBLEFORCOMPONENTSTOLOADPHONEINFORMATIONFROMTHESERVERRIGHTNOWITSIMPLEMENTEDWITHNGRESOURCEANDYOUREUSINGITFORTWOTHINGS:", "original": "The first piece you'll port over to Angular is the `Phone` service, which\nresides in `app/core/phone/phone.service.ts` and makes it possible for components\nto load phone information from the server. Right now it's implemented with\nngResource and you're using it for two things:", "translation": "你要移植到 Angular 的第一个片段是 `Phone` 工厂(位于 `app/js/core/phones.factory.ts`),\n并且让它能帮助控制器从服务器上加载电话信息。目前,它是用 `ngResource` 实现的,你用它做两件事:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FORLOADINGTHELISTOFALLPHONESINTOTHEPHONELISTCOMPONENT", "original": "* For loading the list of all phones into the phone list component.", "translation": "把所有电话的列表加载到电话列表组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FORLOADINGTHEDETAILSOFASINGLEPHONEINTOTHEPHONEDETAILCOMPONENT", "original": "* For loading the details of a single phone into the phone detail component.", "translation": "把一台电话的详情加载到电话详情组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCANREPLACETHISIMPLEMENTATIONWITHANANGULARSERVICECLASSWHILEKEEPINGTHECONTROLLERSINANGULARJSLAND", "original": "You can replace this implementation with an Angular service class, while\nkeeping the controllers in AngularJS land.", "translation": "你可以用 Angular 的服务类来替换这个实现,而把控制器继续留在 AngularJS 的地盘上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INTHENEWVERSIONYOUIMPORTTHEANGULARHTTPMODULEANDCALLITSHTTPSERVICEINSTEADOFNGRESOURCE", "original": "In the new version, you import the Angular HTTP module and call its `Http` service instead of `ngResource`.", "translation": "在这个新版本中,你导入了 Angular 的 HTTP 模块,并且用它的 `Http` 服务替换掉 `NgResource`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "REOPENTHEAPPMODULETSFILEIMPORTANDADDHTTPMODULETOTHEIMPORTSARRAYOFTHEAPPMODULE:", "original": "Re-open the `app.module.ts` file, import and add `HttpModule` to the `imports` array of the `AppModule`:", "translation": "再次打开 `app.module.ts` 文件,导入并把 `HttpModule` 添加到 `AppModule` 的 `imports` 数组中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWYOUREREADYTOUPGRADETHEPHONESERVICEITSELFREPLACETHENGRESOURCEBASEDSERVICEINPHONESERVICETSWITHATYPESCRIPTCLASSDECORATEDASINJECTABLE:", "original": "Now you're ready to upgrade the Phone service itself. Replace the ngResource-based\nservice in `phone.service.ts` with a TypeScript class decorated as `@Injectable`:", "translation": "现在,你已经准备好了升级 `Phones` 服务本身。你将为 `phone.service.ts` 文件中基于 ngResource 的服务加上 `@Injectable` 装饰器:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEINJECTABLEDECORATORWILLATTACHSOMEDEPENDENCYINJECTIONMETADATATOTHECLASSLETTINGANGULARKNOWABOUTITSDEPENDENCIESASDESCRIBEDBYTHEDEPENDENCYINJECTIONGUIDEGUIDEDEPENDENCYINJECTIONTHISISAMARKERDECORATORYOUNEEDTOUSEFORCLASSESTHATHAVENOOTHERANGULARDECORATORSBUTSTILLNEEDTOHAVETHEIRDEPENDENCIESINJECTED", "original": "The `@Injectable` decorator will attach some dependency injection metadata\nto the class, letting Angular know about its dependencies. As described\nby the [Dependency Injection Guide](guide/dependency-injection),\nthis is a marker decorator you need to use for classes that have no other\nAngular decorators but still need to have their dependencies injected.", "translation": "`@Injectable` 装饰器将把一些依赖注入相关的元数据附加到该类上,让 Angular 知道它的依赖信息。\n就像在[依赖注入指南](guide/dependency-injection)中描述过的那样,\n这是一个标记装饰器,你要把它用在那些没有其它 Angular 装饰器,并且自己有依赖注入的类上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INITSCONSTRUCTORTHECLASSEXPECTSTOGETTHEHTTPSERVICEITWILLBEINJECTEDTOITANDITISSTOREDASAPRIVATEFIELDTHESERVICEISTHENUSEDINTHETWOINSTANCEMETHODSONEOFWHICHLOADSTHELISTOFALLPHONESANDTHEOTHERLOADSTHEDETAILSOFASPECIFIEDPHONE:", "original": "In its constructor the class expects to get the `Http` service. It will\nbe injected to it and it is stored as a private field. The service is then\nused in the two instance methods, one of which loads the list of all phones,\nand the other loads the details of a specified phone:", "translation": "在它的构造函数中,该类期待一个 `Http` 服务。`Http` 服务将被注入进来并存入一个私有字段。\n然后该服务在两个实例方法中被使用到,一个加载所有电话的列表,另一个加载一台指定电话的详情:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEMETHODSNOWRETURNOBSERVABLESOFTYPEPHONEDATAANDPHONEDATATHISISATYPEYOUDONTHAVEYETADDASIMPLEINTERFACEFORIT:", "original": "The methods now return Observables of type `PhoneData` and `PhoneData[]`. This is\na type you don't have yet. Add a simple interface for it:", "translation": "该方法现在返回一个 `Phone` 类型或 `Phone[]` 类型的可观察对象(Observable)。\n这是一个你从未用过的类型,因此你得为它新增一个简单的接口:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARUPGRADESTATICHASADOWNGRADEINJECTABLEMETHODFORTHEPURPOSEOFMAKINGANGULARSERVICESAVAILABLETOANGULARJSCODEUSEITTOPLUGINTHEPHONESERVICE:", "original": "`@angular/upgrade/static` has a `downgradeInjectable` method for the purpose of making\nAngular services available to AngularJS code. Use it to plug in the `Phone` service:", "translation": "`@angular/upgrade/static` 有一个 `downgradeInjectable` 方法,可以使 Angular 服务在 AngularJS 的代码中可用。\n使用它来插入 `Phone` 服务:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "HERESTHEFULLFINALCODEFORTHESERVICE:", "original": "Here's the full, final code for the service:", "translation": "最终,该类的全部代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOTICETHATYOUREIMPORTINGTHEMAPOPERATOROFTHERXJSOBSERVABLESEPARATELYDOTHISFOREVERYRXJSOPERATOR", "original": "Notice that you're importing the `map` operator of the RxJS `Observable` separately.\nDo this for every RxJS operator.", "translation": "注意,你单独导入了 RxJS `Observable` 中的 `map` 操作符。\n你需要对想用的所有 RxJS 操作符这么做,因为 Angular 默认不会加载所有 RxJS 操作符。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THENEWPHONESERVICEHASTHESAMEFEATURESASTHEORIGINALNGRESOURCEBASEDSERVICEBECAUSEITSANANGULARSERVICEYOUREGISTERITWITHTHENGMODULEPROVIDERS:", "original": "The new `Phone` service has the same features as the original, `ngResource`-based service.\nBecause it's an Angular service, you register it with the `NgModule` providers:", "translation": "这个新的 `Phone` 服务具有和老的基于 `ngResource` 的服务相同的特性。\n因为它是 Angular 服务,你通过 `NgModule` 的 `providers` 数组来注册它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWTHATYOUARELOADINGPHONESERVICETSTHROUGHANIMPORTTHATISRESOLVEDBYSYSTEMJSYOUSHOULDREMOVETHELTSCRIPTGTTAGFORTHESERVICEFROMINDEXHTMLTHISISSOMETHINGYOULLDOTOALLCOMPONENTSASYOUUPGRADETHEMSIMULTANEOUSLYWITHTHEANGULARJSTOANGULARUPGRADEYOUREALSOMIGRATINGCODEFROMSCRIPTSTOMODULES", "original": "Now that you are loading `phone.service.ts` through an import that is resolved\nby SystemJS, you should **remove the <script> tag** for the service from `index.html`.\nThis is something you'll do to all components as you upgrade them. Simultaneously\nwith the AngularJS to Angular upgrade you're also migrating code from scripts to modules.", "translation": "现在,你正在用 SystemJS 加载 `phone.service.ts`,你应该从 `index.html` 中**移除该服务的 `<script>` 标签**。\n这也是你在升级所有组件时将会做的事。在从 AngularJS 向 Angular 升级的同时,你也把代码从脚本移植为模块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ATTHISPOINTYOUCANSWITCHTHETWOCOMPONENTSTOUSETHENEWSERVICEINSTEADOFTHEOLDONEWHILEYOUINJECTITASTHEDOWNGRADEDPHONEFACTORYITSREALLYANINSTANCEOFTHEPHONECLASSANDYOUANNOTATEITSTYPEACCORDINGLY:", "original": "At this point, you can switch the two components to use the new service\ninstead of the old one. While you `$inject` it as the downgraded `phone` factory,\nit's really an instance of the `Phone` class and you annotate its type accordingly:", "translation": "这时,你可以把两个控制器从使用老的服务切换成使用新的。你像降级过的 `phones` 工厂一样 `$inject` 它,\n但它实际上是一个 `Phones` 类的实例,并且你可以据此注解它的类型:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWTHEREARETWOANGULARJSCOMPONENTSUSINGANANGULARSERVICETHECOMPONENTSDONTNEEDTOBEAWAREOFTHISTHOUGHTHEFACTTHATTHESERVICERETURNSOBSERVABLESANDNOTPROMISESISABITOFAGIVEAWAYINANYCASEWHATYOUVEACHIEVEDISAMIGRATIONOFASERVICETOANGULARWITHOUTHAVINGTOYETMIGRATETHECOMPONENTSTHATUSEIT", "original": "Now there are two AngularJS components using an Angular service!\nThe components don't need to be aware of this, though the fact that the\nservice returns Observables and not Promises is a bit of a giveaway.\nIn any case, what you've achieved is a migration of a service to Angular\nwithout having to yet migrate the components that use it.", "translation": "这里的两个 AngularJS 控制器在使用 Angular 的服务!控制器不需要关心这一点,尽管实际上该服务返回的是可观察对象(Observable),而不是承诺(Promise)。\n无论如何,你达到的效果都是把服务移植到 Angular,而不用被迫移植组件来使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUCOULDUSETHETOPROMISEMETHODOFOBSERVABLETOTURNTHOSEOBSERVABLESINTOPROMISESINTHESERVICEINMANYCASESTHATREDUCETHENUMBEROFCHANGESTOTHECOMPONENTCONTROLLERS", "original": "You could use the `toPromise` method of `Observable` to turn those\nObservables into Promises in the service. In many cases that reduce\nthe number of changes to the component controllers.", "translation": "你也能使用 `Observable` 的 `toPromise` 方法来在服务中把这些可观察对象转变成承诺,以进一步减小组件控制器中需要修改的代码量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###UPGRADINGCOMPONENTS", "original": "### Upgrading Components", "translation": "### 升级组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "UPGRADETHEANGULARJSCOMPONENTSTOANGULARCOMPONENTSNEXTDOITONECOMPONENTATATIMEWHILESTILLKEEPINGTHEAPPLICATIONINHYBRIDMODEASYOUMAKETHESECONVERSIONSYOULLALSODEFINEYOURFIRSTANGULARPIPES", "original": "Upgrade the AngularJS components to Angular components next.\nDo it one component at a time while still keeping the application in hybrid mode.\nAs you make these conversions, you'll also define your first Angular *pipes*.", "translation": "接下来,把 AngularJS 的控制器升级成 Angular 的组件。每次升级一个,同时仍然保持应用运行在混合模式下。\n在做转换的同时,你还将自定义首个 Angular*管道*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "LOOKATTHEPHONELISTCOMPONENTFIRSTRIGHTNOWITCONTAINSATYPESCRIPTCONTROLLERCLASSANDACOMPONENTDEFINITIONOBJECTYOUCANMORPHTHISINTOANANGULARCOMPONENTBYJUSTRENAMINGTHECONTROLLERCLASSANDTURNINGTHEANGULARJSCOMPONENTDEFINITIONOBJECTINTOANANGULARCOMPONENTDECORATORYOUCANTHENALSOREMOVETHESTATICINJECTPROPERTYFROMTHECLASS:", "original": "Look at the phone list component first. Right now it contains a TypeScript\ncontroller class and a component definition object. You can morph this into\nan Angular component by just renaming the controller class and turning the\nAngularJS component definition object into an Angular `@Component` decorator.\nYou can then also remove the static `$inject` property from the class:", "translation": "先看看电话列表组件。它目前包含一个 TypeScript 控制器类和一个组件定义对象。重命名控制器类,\n并把 AngularJS 的组件定义对象更换为 Angular `@Component` 装饰器,这样你就把它变形为 Angular\n的组件了。然后,你还要从类中移除静态 `$inject` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THESELECTORATTRIBUTEISACSSSELECTORTHATDEFINESWHEREONTHEPAGETHECOMPONENTSHOULDGOINANGULARJSYOUDOMATCHINGBASEDONCOMPONENTNAMESBUTINANGULARYOUHAVETHESEEXPLICITSELECTORSTHISONEWILLMATCHELEMENTSWITHTHENAMEPHONELISTJUSTLIKETHEANGULARJSVERSIONDID", "original": "The `selector` attribute is a CSS selector that defines where on the page the component\nshould go. In AngularJS you do matching based on component names, but in Angular you\nhave these explicit selectors. This one will match elements with the name `phone-list`,\njust like the AngularJS version did.", "translation": "`selector` 属性是一个 CSS 选择器,用来定义组件应该被放在页面的哪。在 AngularJS 中,你会基于组件名字来匹配,\n但是在 Angular 中,你要显式指定这些选择器。本组件将会对应元素名字 `phone-list`,和 AngularJS 版本一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWCONVERTTHETEMPLATEOFTHISCOMPONENTINTOANGULARSYNTAXTHESEARCHCONTROLSREPLACETHEANGULARJSCTRLEXPRESSIONSWITHANGULARSTWOWAYNGMODELBINDINGSYNTAX:", "original": "Now convert the template of this component into Angular syntax.\nThe search controls replace the AngularJS `$ctrl` expressions\nwith Angular's two-way `[(ngModel)]` binding syntax:", "translation": "现在,将组件的模版也转换为 Angular 语法。在搜索控件中,把 AngularJS 的 `$ctrl` 表达式替换成 Angular 的双向绑定语法 `[(ngModel)]`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "REPLACETHELISTSNGREPEATWITHANNGFORASDESCRIBEDINTHETEMPLATESYNTAXPAGEGUIDETEMPLATESYNTAX#DIRECTIVESREPLACETHEIMAGETAGSNGSRCWITHABINDINGTOTHENATIVESRCPROPERTY", "original": "Replace the list's `ng-repeat` with an `*ngFor` as\n[described in the Template Syntax page](guide/template-syntax#directives).\nReplace the image tag's `ng-src` with a binding to the native `src` property.", "translation": "把列表中的 `ng-repeat` 替换为 `*ngFor` 以及它的 `let var of iterable` 语法,\n该语法在[模板语法指南中讲过](guide/template-syntax#directives)。\n再把 `img` 标签的 `ng-src` 替换为一个标准的 `src` 属性(property)绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####NOANGULARFILTERORORDERBYFILTERS", "original": "#### No Angular _filter_ or _orderBy_ filters", "translation": "#### Angular 中没有 `filter` 或 `orderBy` 过滤器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEBUILTINANGULARJSFILTERANDORDERBYFILTERSDONOTEXISTINANGULARSOYOUNEEDTODOTHEFILTERINGANDSORTINGYOURSELF", "original": "The built-in AngularJS `filter` and `orderBy` filters do not exist in Angular,\nso you need to do the filtering and sorting yourself.", "translation": "Angular 中并不存在 AngularJS 中内置的 `filter` 和 `orderBy` 过滤器。\n所以你得自己实现进行过滤和排序。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUREPLACEDTHEFILTERANDORDERBYFILTERSWITHBINDINGSTOTHEGETPHONESCONTROLLERMETHODWHICHIMPLEMENTSTHEFILTERINGANDORDERINGLOGICINSIDETHECOMPONENTITSELF", "original": "You replaced the `filter` and `orderBy` filters with bindings to the `getPhones()` controller method,\nwhich implements the filtering and ordering logic inside the component itself.", "translation": "你把 `filter` 和 `orderBy` 过滤器改成绑定到控制器中的 `getPhones()` 方法,通过该方法,组件本身实现了过滤和排序逻辑。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWYOUNEEDTODOWNGRADETHEANGULARCOMPONENTSOYOUCANUSEITINANGULARJSINSTEADOFREGISTERINGACOMPONENTYOUREGISTERAPHONELISTDIRECTIVEADOWNGRADEDVERSIONOFTHEANGULARCOMPONENT", "original": "Now you need to downgrade the Angular component so you can use it in AngularJS.\nInstead of registering a component, you register a `phoneList` *directive*,\na downgraded version of the Angular component.", "translation": "现在你需要降级你的 Angular 组件,这样你就可以在 AngularJS 中使用它了。\n你要注册一个 `phoneList`*指令*,而不是注册一个组件,它是一个降级版的 Angular 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEASANGULARIDIRECTIVEFACTORYCASTTELLSTHETYPESCRIPTCOMPILERTHATTHERETURNVALUEOFTHEDOWNGRADECOMPONENTMETHODISADIRECTIVEFACTORY", "original": "The `as angular.IDirectiveFactory` cast tells the TypeScript compiler\nthat the return value of the `downgradeComponent` method is a directive factory.", "translation": "强制类型转换 `as angular.IDirectiveFactory` 告诉 TypeScript 编译器 `downgradeComponent` 方法\n的返回值是一个指令工厂。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THENEWPHONELISTCOMPONENTUSESTHEANGULARNGMODELDIRECTIVELOCATEDINTHEFORMSMODULEADDTHEFORMSMODULETONGMODULEIMPORTSDECLARETHENEWPHONELISTCOMPONENTANDFINALLYADDITTOENTRYCOMPONENTSSINCEYOUDOWNGRADEDIT:", "original": "The new `PhoneListComponent` uses the Angular `ngModel` directive, located in the `FormsModule`.\nAdd the `FormsModule` to `NgModule` imports, declare the new `PhoneListComponent` and\nfinally add it to `entryComponents` since you downgraded it:", "translation": "新的 `PhoneListComponent` 使用 Angular 的 `ngModel` 指令,它位于 `FormsModule` 中。\n把 `FormsModule` 添加到 `NgModule` 的 `imports` 中,并声明新的 `PhoneListComponent` 组件,\n最后,把降级的结果添加到 `entryComponents`中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "REMOVETHELTSCRIPTGTTAGFORTHEPHONELISTCOMPONENTFROMINDEXHTML", "original": "Remove the <script> tag for the phone list component from `index.html`.", "translation": "从 `index.html` 中移除电话列表组件的<script>标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWSETTHEREMAININGPHONEDETAILCOMPONENTTSASFOLLOWS:", "original": "Now set the remaining `phone-detail.component.ts` as follows:", "translation": "现在,剩下的 `phone-detail.component.ts` 文件变成了这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THISISSIMILARTOTHEPHONELISTCOMPONENTTHENEWWRINKLEISTHEROUTEPARAMSTYPEANNOTATIONTHATIDENTIFIESTHEROUTEPARAMSDEPENDENCY", "original": "This is similar to the phone list component.\nThe new wrinkle is the `RouteParams` type annotation that identifies the `routeParams` dependency.", "translation": "这和电话列表组件很相似。\n这里的窍门在于 `@Inject` 装饰器,它标记出了 `$routeParams` 依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEANGULARJSINJECTORHASANANGULARJSROUTERDEPENDENCYCALLEDROUTEPARAMSWHICHWASINJECTEDINTOPHONEDETAILSWHENITWASSTILLANANGULARJSCONTROLLERYOUINTENDTOINJECTITINTOTHENEWPHONEDETAILSCOMPONENT", "original": "The AngularJS injector has an AngularJS router dependency called `$routeParams`,\nwhich was injected into `PhoneDetails` when it was still an AngularJS controller.\nYou intend to inject it into the new `PhoneDetailsComponent`.", "translation": "AngularJS 注入器具有 AngularJS 路由器的依赖,叫做 `$routeParams`。\n它被注入到了 `PhoneDetails` 中,但 `PhoneDetails` 现在还是一个 AngularJS 控制器。\n你要把它注入到新的 `PhoneDetailsComponent` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "UNFORTUNATELYANGULARJSDEPENDENCIESARENOTAUTOMATICALLYAVAILABLETOANGULARCOMPONENTSYOUMUSTUPGRADETHISSERVICEVIAAFACTORYPROVIDERGUIDEUPGRADE#MAKINGANGULARJSDEPENDENCIESINJECTABLETOANGULARTOMAKEROUTEPARAMSANANGULARINJECTABLEDOTHATINANEWFILECALLEDAJSUPGRADEDPROVIDERSTSANDIMPORTITINAPPMODULETS:", "original": "Unfortunately, AngularJS dependencies are not automatically available to Angular components.\nYou must upgrade this service via a [factory provider](guide/upgrade#making-angularjs-dependencies-injectable-to-angular)\nto make `$routeParams` an Angular injectable.\nDo that in a new file called `ajs-upgraded-providers.ts` and import it in `app.module.ts`:", "translation": "不幸的是,AngularJS 的依赖不会自动在 Angular 的组件中可用。\n你必须使用[工厂提供商(factory provider)](guide/upgrade#making-angularjs-dependencies-injectable-to-angular)\n来把 `$routeParams` 包装成 Angular 的服务提供商。\n新建一个名叫 `ajs-upgraded-providers.ts` 的文件,并且在 `app.module.ts` 中导入它:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "CONVERTTHEPHONEDETAILCOMPONENTTEMPLATEINTOANGULARSYNTAXASFOLLOWS:", "original": "Convert the phone detail component template into Angular syntax as follows:", "translation": "把该组件的模板转变成 Angular 的语法,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEREARESEVERALNOTABLECHANGESHERE:", "original": "There are several notable changes here:", "translation": "这里有几个值得注意的改动:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUVEREMOVEDTHECTRLPREFIXFROMALLEXPRESSIONS", "original": "* You've removed the `$ctrl.` prefix from all expressions.", "translation": "你从所有表达式中移除了 `$ctrl.` 前缀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUVEREPLACEDNGSRCWITHPROPERTYBINDINGSFORTHESTANDARDSRCPROPERTY", "original": "* You've replaced `ng-src` with property\n bindings for the standard `src` property.", "translation": "正如你在电话列表中做过的那样,你把 `ng-src` 替换成了标准的 `src` 属性绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUREUSINGTHEPROPERTYBINDINGSYNTAXAROUNDNGCLASSTHOUGHANGULARDOESHAVEAVERYSIMILARNGCLASSGUIDETEMPLATESYNTAX#DIRECTIVESASANGULARJSDOESITSVALUEISNOTMAGICALLYEVALUATEDASANEXPRESSIONINANGULARYOUALWAYSSPECIFYINTHETEMPLATEWHENANATTRIBUTESVALUEISAPROPERTYEXPRESSIONASOPPOSEDTOALITERALSTRING", "original": "* You're using the property binding syntax around `ng-class`. Though Angular\n does have [a very similar `ngClass`](guide/template-syntax#directives)\n as AngularJS does, its value is not magically evaluated as an expression.\n In Angular, you always specify in the template when an attribute's value is\n a property expression, as opposed to a literal string.", "translation": "你在 `ng-class` 周围使用了属性绑定语法。虽然 Angular 中有一个\n 和 AngularJS 中[非常相似的 `ngClass`](guide/template-syntax#directives)指令,\n 但是它的值不会神奇的作为表达式进行计算。在 Angular 中,模板中的属性(Attribute)值总是被作为\n 属性(Property)表达式计算,而不是作为字符串字面量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUVEREPLACEDNGREPEATSWITHNGFORS", "original": "* You've replaced `ng-repeat`s with `*ngFor`s.", "translation": "你把 `ng-repeat` 替换成了 `*ngFor`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUVEREPLACEDNGCLICKWITHANEVENTBINDINGFORTHESTANDARDCLICK", "original": "* You've replaced `ng-click` with an event binding for the standard `click`.", "translation": "你把 `ng-click` 替换成了一个到标准 `click` 事件的绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUVEWRAPPEDTHEWHOLETEMPLATEINANNGIFTHATCAUSESITONLYTOBERENDEREDWHENTHEREISAPHONEPRESENTYOUNEEDTHISBECAUSEWHENTHECOMPONENTFIRSTLOADSYOUDONTHAVEPHONEYETANDTHEEXPRESSIONSWILLREFERTOANONEXISTINGVALUEUNLIKEINANGULARJSANGULAREXPRESSIONSDONOTFAILSILENTLYWHENYOUTRYTOREFERTOPROPERTIESONUNDEFINEDOBJECTSYOUNEEDTOBEEXPLICITABOUTCASESWHERETHISISEXPECTED", "original": "* You've wrapped the whole template in an `ngIf` that causes it only to be\n rendered when there is a phone present. You need this because when the component\n first loads, you don't have `phone` yet and the expressions will refer to a\n non-existing value. Unlike in AngularJS, Angular expressions do not fail silently\n when you try to refer to properties on undefined objects. You need to be explicit\n about cases where this is expected.", "translation": "你把整个模板都包裹进了一个 `ngIf` 中,这导致只有当存在一个电话时它才会渲染。你必须这么做,\n 是因为组件首次加载时你还没有 `phone` 变量,这些表达式就会引用到一个不存在的值。\n 和 AngularJS 不同,当你尝试引用未定义对象上的属性时,Angular 中的表达式不会默默失败。\n 你必须明确指出这种情况是你所期望的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ADDPHONEDETAILCOMPONENTCOMPONENTTOTHENGMODULEDECLARATIONSANDENTRYCOMPONENTS:", "original": "Add `PhoneDetailComponent` component to the `NgModule` _declarations_ and _entryComponents_:", "translation": "把 `PhoneDetailComponent` 组件添加到 `NgModule` 的 *declarations* 和 *entryComponents* 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUSHOULDNOWALSOREMOVETHEPHONEDETAILCOMPONENTLTSCRIPTGTTAGFROMINDEXHTML", "original": "You should now also remove the phone detail component <script> tag from `index.html`.", "translation": "你现在应该从 `index.html` 中移除电话详情组件的<script>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####ADDTHECHECKMARKPIPE", "original": "#### Add the _CheckmarkPipe_", "translation": "#### 添加 *CheckmarkPipe*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEANGULARJSDIRECTIVEHADACHECKMARKFILTERTURNTHATINTOANANGULARPIPE", "original": "The AngularJS directive had a `checkmark` _filter_.\nTurn that into an Angular **pipe**.", "translation": "AngularJS 指令中有一个 `checkmark`*过滤器*,把它转换成 Angular 的**管道**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEREISNOUPGRADEMETHODTOCONVERTFILTERSINTOPIPESYOUWONTMISSITITSEASYTOTURNTHEFILTERFUNCTIONINTOANEQUIVALENTPIPECLASSTHEIMPLEMENTATIONISTHESAMEASBEFOREREPACKAGEDINTHETRANSFORMMETHODRENAMETHEFILETOCHECKMARKPIPETSTOCONFORMWITHANGULARCONVENTIONS:", "original": "There is no upgrade method to convert filters into pipes.\nYou won't miss it.\nIt's easy to turn the filter function into an equivalent Pipe class.\nThe implementation is the same as before, repackaged in the `transform` method.\nRename the file to `checkmark.pipe.ts` to conform with Angular conventions:", "translation": "没有什么升级方法能把过滤器转换成管道。\n但你也并不需要它。\n把过滤器函数转换成等价的 Pipe 类非常简单。\n实现方式和以前一样,但把它们包装进 `transform` 方法中就可以了。\n把该文件改名成 `checkmark.pipe.ts`,以符合 Angular 中的命名约定:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWIMPORTANDDECLARETHENEWLYCREATEDPIPEANDREMOVETHEFILTERLTSCRIPTGTTAGFROMINDEXHTML:", "original": "Now import and declare the newly created pipe and\nremove the filter <script> tag from `index.html`:", "translation": "现在,导入并声明这个新创建的管道,同时从 `index.html` 文件中移除该过滤器的`<script>` 标签:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###AOTCOMPILETHEHYBRIDAPP", "original": "### AOT compile the hybrid app", "translation": "### 对混合式应用做 AOT 编译", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TOUSEAOTWITHAHYBRIDAPPYOUHAVETOFIRSTSETITUPLIKEANYOTHERANGULARAPPLICATIONASSHOWNINTHEAHEADOFTIMECOMPILATIONCHAPTERGUIDEAOTCOMPILER", "original": "To use AOT with a hybrid app, you have to first set it up like any other Angular application,\nas shown in [the Ahead-of-time Compilation chapter](guide/aot-compiler).", "translation": "要在混合式应用中使用 AOT 编译,你首先要像其它 Angular 应用一样设置它,就像[AOT 编译一章](guide/aot-compiler)所讲的那样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THENCHANGEMAINAOTTSTOBOOTSTRAPTHEAPPCOMPONENTFACTORYTHATWASGENERATEDBYTHEAOTCOMPILER:", "original": "Then change `main-aot.ts` to bootstrap the `AppComponentFactory` that was generated\nby the AOT compiler:", "translation": "然后修改 `main-aot.ts` 的引导代码,通过所生成的 `AppComponentFactory` 来引导 AngularJS 应用:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUNEEDTOLOADALLTHEANGULARJSFILESYOUALREADYUSEININDEXHTMLINAOTINDEXHTMLASWELL:", "original": "You need to load all the AngularJS files you already use in `index.html` in `aot/index.html`\nas well:", "translation": "你还要把在 `index.html` 中已经用到的所有 AngularJS 文件加载到 `aot/index.html` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THESEFILESNEEDTOBECOPIEDTOGETHERWITHTHEPOLYFILLSTHEFILESTHEAPPLICATIONNEEDSATRUNTIMELIKETHEJSONPHONELISTSANDIMAGESALSONEEDTOBECOPIED", "original": "These files need to be copied together with the polyfills. The files the application\nneeds at runtime, like the `.json` phone lists and images, also need to be copied.", "translation": "这些文件要带着相应的腻子脚本复制到一起。应用运行时需要的文件,比如电话列表 `.json` 和图片,也需要复制过去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "INSTALLFSEXTRAVIANPMINSTALLFSEXTRASAVEDEVFORBETTERFILECOPYINGANDCHANGECOPYDISTFILESJSTOTHEFOLLOWING:", "original": "Install `fs-extra` via `npm install fs-extra --save-dev` for better file copying, and change\n`copy-dist-files.js` to the following:", "translation": "通过 `npm install fs-extra --save-dev` 安装 `fs-extra` 可以更好的复制文件,并且把 `copy-dist-files.js` 文件改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANDTHATSALLYOUNEEDTOUSEAOTWHILEUPGRADINGYOURAPP", "original": "And that's all you need to use AOT while upgrading your app!", "translation": "这就是想要在升级应用期间 AOT 编译所需的一切!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###ADDINGTHEANGULARROUTERANDBOOTSTRAP", "original": "### Adding The Angular Router And Bootstrap", "translation": "### 添加 Angular 路由器和引导程序", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ATTHISPOINTYOUVEREPLACEDALLANGULARJSAPPLICATIONCOMPONENTSWITHTHEIRANGULARCOUNTERPARTSEVENTHOUGHYOURESTILLSERVINGTHEMFROMTHEANGULARJSROUTER", "original": "At this point, you've replaced all AngularJS application components with\ntheir Angular counterparts, even though you're still serving them from the AngularJS router.", "translation": "此刻,你已经把所有 AngularJS 的组件替换成了它们在 Angular 中的等价物,不过你仍然在 AngularJS 路由器中使用它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####ADDTHEANGULARROUTER", "original": "#### Add the Angular router", "translation": "#### 添加 Angular 路由器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANGULARHASANALLNEWROUTERGUIDEROUTER", "original": "Angular has an [all-new router](guide/router).", "translation": "Angular 有一个[全新的路由器](guide/router)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "LIKEALLROUTERSITNEEDSAPLACEINTHEUITODISPLAYROUTEDVIEWSFORANGULARTHATSTHEROUTEROUTLETANDITBELONGSINAROOTCOMPONENTATTHETOPOFTHEAPPLICATIONSCOMPONENTTREE", "original": "Like all routers, it needs a place in the UI to display routed views.\nFor Angular that's the `<router-outlet>` and it belongs in a *root component*\nat the top of the applications component tree.", "translation": "像所有的路由器一样,它需要在 UI 中指定一个位置来显示路由的视图。\n在 Angular 中,它是 `<router-outlet>`,并位于应用组件树顶部的*根组件*中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUDONTYETHAVESUCHAROOTCOMPONENTBECAUSETHEAPPISSTILLMANAGEDASANANGULARJSAPPCREATEANEWAPPCOMPONENTTSFILEWITHTHEFOLLOWINGAPPCOMPONENTCLASS:", "original": "You don't yet have such a root component, because the app is still managed as an AngularJS app.\nCreate a new `app.component.ts` file with the following `AppComponent` class:", "translation": "你还没有这样一个根组件,因为该应用仍然是像一个 AngularJS 应用那样被管理的。\n创建新的 `app.component.ts` 文件,放入像这样的 `AppComponent` 类:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ITHASASIMPLETEMPLATETHATONLYINCLUDESTHEROUTEROUTLETTHISCOMPONENTJUSTRENDERSTHECONTENTSOFTHEACTIVEROUTEANDNOTHINGELSE", "original": "It has a simple template that only includes the `<router-outlet>.\nThis component just renders the contents of the active route and nothing else.", "translation": "它有一个很简单的模板,只包含 Angular 路由的 `<router-outlet>` 和 AngularJS 路由的 `ng-view` 指令。\n该组件只负责渲染活动路由的内容,此外啥也不干。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THESELECTORTELLSANGULARTOPLUGTHISROOTCOMPONENTINTOTHEPHONECATAPPELEMENTONTHEHOSTWEBPAGEWHENTHEAPPLICATIONLAUNCHES", "original": "The selector tells Angular to plug this root component into the `<phonecat-app>`\nelement on the host web page when the application launches.", "translation": "该选择器告诉 Angular:当应用启动时就把这个根组件插入到宿主页面的 `<phonecat-app>` 元素中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ADDTHISPHONECATAPPELEMENTTOTHEINDEXHTMLITREPLACESTHEOLDANGULARJSNGVIEWDIRECTIVE:", "original": "Add this `<phonecat-app>` element to the `index.html`.\nIt replaces the old AngularJS `ng-view` directive:", "translation": "把这个 `<phonecat-app>` 元素插入到 `index.html` 中。\n用它来代替 AngularJS 中的 `ng-view` 指令:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####CREATETHEROUTINGMODULE", "original": "#### Create the _Routing Module_", "translation": "#### 创建*路由模块*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "AROUTERNEEDSCONFIGURATIONWHETHERITSTHEANGULARJSORANGULARORANYOTHERROUTER", "original": "A router needs configuration whether it's the AngularJS or Angular or any other router.", "translation": "无论在 AngularJS 还是 Angular 或其它框架中,路由器都需要进行配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEDETAILSOFANGULARROUTERCONFIGURATIONAREBESTLEFTTOTHEROUTINGDOCUMENTATIONGUIDEROUTERWHICHRECOMMENDSTHATYOUCREATEANGMODULEDEDICATEDTOROUTERCONFIGURATIONCALLEDAROUTINGMODULE", "original": "The details of Angular router configuration are best left to the [Routing documentation](guide/router)\nwhich recommends that you create a `NgModule` dedicated to router configuration\n(called a _Routing Module_).", "translation": "Angular 路由器配置的详情最好去查阅下[路由与导航](guide/router)文档。\n它建议你创建一个专们用于路由器配置的 `NgModule`(名叫*路由模块*)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THISMODULEDEFINESAROUTESOBJECTWITHTWOROUTESTOTHETWOPHONECOMPONENTSANDADEFAULTROUTEFORTHEEMPTYPATHITPASSESTHEROUTESTOTHEROUTERMODULEFORROOTMETHODWHICHDOESTHEREST", "original": "This module defines a `routes` object with two routes to the two phone components\nand a default route for the empty path.\nIt passes the `routes` to the `RouterModule.forRoot` method which does the rest.", "translation": "该模块定义了一个 `routes` 对象,它带有两个路由,分别指向两个电话组件,以及为空路径指定的默认路由。\n它把 `routes` 传给 `RouterModule.forRoot` 方法,该方法会完成剩下的事。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ACOUPLEOFEXTRAPROVIDERSENABLEROUTINGWITHHASHURLSSUCHAS#PHONESINSTEADOFTHEDEFAULTPUSHSTATESTRATEGY", "original": "A couple of extra providers enable routing with \"hash\" URLs such as `#!/phones`\ninstead of the default \"push state\" strategy.", "translation": "一些额外的提供商让路由器使用“hash”策略解析 URL,比如 `#!/phones`,而不是默认的“Push State”策略。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOWUPDATETHEAPPMODULETOIMPORTTHISAPPROUTINGMODULEANDALSOTHEDECLARETHEROOTAPPCOMPONENTASTHEBOOTSTRAPCOMPONENTTHATTELLSANGULARTHATITSHOULDBOOTSTRAPTHEAPPWITHTHEROOTAPPCOMPONENTANDINSERTITSVIEWINTOTHEHOSTWEBPAGE", "original": "Now update the `AppModule` to import this `AppRoutingModule` and also the\ndeclare the root `AppComponent` as the bootstrap component.\nThat tells Angular that it should bootstrap the app with the _root_ `AppComponent` and\ninsert its view into the host web page.", "translation": "现在,修改 `AppModule`,让它导入这个 `AppRoutingModule`,并同时声明根组件 `AppComponent`。\n这会告诉 Angular,它应该使用根组件 `AppComponent` 引导应用,并把它的视图插入到宿主页面中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUMUSTALSOREMOVETHEBOOTSTRAPOFTHEANGULARJSMODULEFROMNGDOBOOTSTRAPINAPPMODULETSANDTHEUPGRADEMODULEIMPORT", "original": "You must also remove the bootstrap of the AngularJS module from `ngDoBootstrap()` in `app.module.ts`\nand the `UpgradeModule` import.", "translation": "你还要从 `app.module.ts` 中移除调用 `ngDoBootstrap()` 来引导 AngularJS 模块的代码,以及对 `UpgradeModule` 的导入代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANDSINCEYOUAREROUTINGTOPHONELISTCOMPONENTANDPHONEDETAILCOMPONENTDIRECTLYRATHERTHANUSINGAROUTETEMPLATEWITHAPHONELISTORPHONEDETAILTAGYOUCANDOAWAYWITHTHEIRANGULARSELECTORSASWELL", "original": "And since you are routing to `PhoneListComponent` and `PhoneDetailComponent` directly rather than\nusing a route template with a `<phone-list>` or `<phone-detail>` tag, you can do away with their\nAngular selectors as well.", "translation": "而且,由于你现在直接路由到 `PhoneListComponent` 和 `PhoneDetailComponent`,而不再使用带 `<phone-list>` 或 `<phone-detail>` 标签的路由模板,因此你同样不再需要它们的 Angular 选择器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####GENERATELINKSFOREACHPHONE", "original": "#### Generate links for each phone", "translation": "#### 为每个电话生成链接", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUNOLONGERHAVETOHARDCODETHELINKSTOPHONEDETAILSINTHEPHONELISTYOUCANGENERATEDATABINDINGSFOREACHPHONESIDTOTHEROUTERLINKDIRECTIVEANDLETTHATDIRECTIVECONSTRUCTTHEAPPROPRIATEURLTOTHEPHONEDETAILCOMPONENT:", "original": "You no longer have to hardcode the links to phone details in the phone list.\nYou can generate data bindings for each phone's `id` to the `routerLink` directive\nand let that directive construct the appropriate URL to the `PhoneDetailComponent`:", "translation": "在电话列表中,你不用再被迫硬编码电话详情的链接了。\n你可以通过把每个电话的 `id` 绑定到 `routerLink` 指令来生成它们了,该指令的构造函数会为 `PhoneDetailComponent` 生成正确的 URL:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SEETHEROUTINGGUIDEROUTERPAGEFORDETAILS", "original": "See the [Routing](guide/router) page for details.", "translation": "要了解详情,请查看[路由与导航](guide/router)页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "####USEROUTEPARAMETERS", "original": "#### Use route parameters", "translation": "#### 使用路由参数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEANGULARROUTERPASSESROUTEPARAMETERSDIFFERENTLYCORRECTTHEPHONEDETAILCOMPONENTCONSTRUCTORTOEXPECTANINJECTEDACTIVATEDROUTEOBJECTEXTRACTTHEPHONEIDFROMTHEACTIVATEDROUTESNAPSHOTPARAMSANDFETCHTHEPHONEDATAASBEFORE:", "original": "The Angular router passes route parameters differently.\nCorrect the `PhoneDetail` component constructor to expect an injected `ActivatedRoute` object.\nExtract the `phoneId` from the `ActivatedRoute.snapshot.params` and fetch the phone data as before:", "translation": "Angular 路由器会传入不同的路由参数。\n改正 `PhoneDetail` 组件的构造函数,让它改用注入进来的 `ActivatedRoute` 对象。\n从 `ActivatedRoute.snapshot.params` 中提取出 `phoneId`,并像以前一样获取手机的数据:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUARENOWRUNNINGAPUREANGULARAPPLICATION", "original": "You are now running a pure Angular application!", "translation": "你现在运行的就是纯正的 Angular 应用了!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###SAYGOODBYETOANGULARJS", "original": "### Say Goodbye to AngularJS", "translation": "### 再见,AngularJS!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ITISTIMETOTAKEOFFTHETRAININGWHEELSANDLETTHEAPPLICATIONBEGINITSNEWLIFEASAPURESHINYANGULARAPPTHEREMAININGTASKSALLHAVETODOWITHREMOVINGCODEWHICHOFCOURSEISEVERYPROGRAMMERSFAVORITETASK", "original": "It is time to take off the training wheels and let the application begin\nits new life as a pure, shiny Angular app. The remaining tasks all have to\ndo with removing code - which of course is every programmer's favorite task!", "translation": "终于可以把辅助训练的轮子摘下来了!让你的应用作为一个纯粹、闪亮的 Angular 程序开始它的新生命吧。\n 剩下的所有任务就是移除代码 —— 这当然是每个程序员最喜欢的任务!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEAPPLICATIONISSTILLBOOTSTRAPPEDASAHYBRIDAPPTHERESNONEEDFORTHATANYMORE", "original": "The application is still bootstrapped as a hybrid app.\nThere's no need for that anymore.", "translation": "应用仍然以混合式应用的方式启动,然而这再也没有必要了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SWITCHTHEBOOTSTRAPMETHODOFTHEAPPLICATIONFROMTHEUPGRADEMODULETOTHEANGULARWAY", "original": "Switch the bootstrap method of the application from the `UpgradeModule` to the Angular way.", "translation": "把应用的引导(`bootstrap`)方法从 `UpgradeAdapter` 的改为 Angular 的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "IFYOUHAVENTALREADYREMOVEALLREFERENCESTOTHEUPGRADEMODULEFROMAPPMODULETSASWELLASANYFACTORYPROVIDERGUIDEUPGRADE#MAKINGANGULARJSDEPENDENCIESINJECTABLETOANGULARFORANGULARJSSERVICESANDTHEAPPAJSUPGRADEDPROVIDERSTSFILE", "original": "If you haven't already, remove all references to the `UpgradeModule` from `app.module.ts`,\nas well as any [factory provider](guide/upgrade#making-angularjs-dependencies-injectable-to-angular)\nfor AngularJS services, and the `app/ajs-upgraded-providers.ts` file.", "translation": "如果你还没有这么做,请从 `app.module.ts 删除所有 `UpgradeModule 的引用,\n 以及所有用于 AngularJS 服务的[工厂供应商(factory provider)](guide/upgrade#making-angularjs-dependencies-injectable-to-angular)和 `app/ajs-upgraded-providers.ts` 文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ALSOREMOVEANYDOWNGRADEINJECTABLEORDOWNGRADECOMPONENTYOUFINDTOGETHERWITHTHEASSOCIATEDANGULARJSFACTORYORDIRECTIVEDECLARATIONSSINCEYOUNOLONGERHAVEDOWNGRADEDCOMPONENTSYOUNOLONGERLISTTHEMINENTRYCOMPONENTS", "original": "Also remove any `downgradeInjectable()` or `downgradeComponent()` you find,\ntogether with the associated AngularJS factory or directive declarations.\nSince you no longer have downgraded components, you no longer list them\nin `entryComponents`.", "translation": "还要删除所有的 `downgradeInjectable()` 或 `downgradeComponent()` 以及与 AngularJS 相关的工厂或指令声明。\n因为你不再需要降级任何组件了,也不再需要把它们列在 `entryComponents` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "YOUMAYALSOCOMPLETELYREMOVETHEFOLLOWINGFILESTHEYAREANGULARJSMODULECONFIGURATIONFILESANDNOTNEEDEDINANGULAR:", "original": "You may also completely remove the following files. They are AngularJS\nmodule configuration files and not needed in Angular:", "translation": "你还要完全移除了下列文件。它们是 AngularJS 的模块配置文件和类型定义文件,在 Angular 中不需要了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEEXTERNALTYPINGSFORANGULARJSMAYBEUNINSTALLEDASWELLTHEONLYONESYOUSTILLNEEDAREFORJASMINEANDANGULARPOLYFILLSTHEANGULARUPGRADEPACKAGEANDITSMAPPINGINSYSTEMJSCONFIGJSCANALSOGO", "original": "The external typings for AngularJS may be uninstalled as well. The only ones\nyou still need are for Jasmine and Angular polyfills.\nThe `@angular/upgrade` package and its mapping in `systemjs.config.js` can also go.", "translation": "还需要卸载 AngularJS 的外部类型定义文件。你现在只需要留下 Jasmine 和 Angular 所需的腻子脚本。\n`systemjs.config.js` 中的 `@angular/upgrade` 包及其映射也可以移除了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FINALLYFROMINDEXHTMLREMOVEALLREFERENCESTOANGULARJSSCRIPTSANDJQUERYWHENYOUREDONETHISISWHATITSHOULDLOOKLIKE:", "original": "Finally, from `index.html`, remove all references to AngularJS scripts and jQuery.\nWhen you're done, this is what it should look like:", "translation": "最后,从 `index.html` 和 `karma.conf.js` 中,移除所有对 AngularJS 和 jQuery 脚本的引用。\n当这些全部做完时,`index.html` 应该是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THATISTHELASTYOULLSEEOFANGULARJSITHASSERVEDUSWELLBUTNOWITSTIMETOSAYGOODBYE", "original": "That is the last you'll see of AngularJS! It has served us well but now\nit's time to say goodbye.", "translation": "这是你最后一次看到 AngularJS 了!它曾经带给你很多帮助,不过现在,该说再见了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "##APPENDIX:UPGRADINGPHONECATTESTS", "original": "## Appendix: Upgrading PhoneCat Tests", "translation": "## 附录:升级 PhoneCat 的测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "TESTSCANNOTONLYBERETAINEDTHROUGHANUPGRADEPROCESSBUTTHEYCANALSOBEUSEDASAVALUABLESAFETYMEASUREWHENENSURINGTHATTHEAPPLICATIONDOESNOTBREAKDURINGTHEUPGRADEE2ETESTSAREESPECIALLYUSEFULFORTHISPURPOSE", "original": "Tests can not only be retained through an upgrade process, but they can also be\nused as a valuable safety measure when ensuring that the application does not\nbreak during the upgrade. E2E tests are especially useful for this purpose.", "translation": "测试不仅要在升级过程中被保留,它还是确保应用在升级过程中不会被破坏的一个安全指示器。\n要达到这个目的,E2E 测试尤其有用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###E2ETESTS", "original": "### E2E Tests", "translation": "### E2E 测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEPHONECATPROJECTHASBOTHE2EPROTRACTORTESTSANDSOMEKARMAUNITTESTSINITOFTHESETWOE2ETESTSCANBEDEALTWITHMUCHMOREEASILY:BYDEFINITIONE2ETESTSACCESSTHEAPPLICATIONFROMTHEOUTSIDEBYINTERACTINGWITHTHEVARIOUSUIELEMENTSTHEAPPPUTSONTHESCREENE2ETESTSARENTREALLYTHATCONCERNEDWITHTHEINTERNALSTRUCTUREOFTHEAPPLICATIONCOMPONENTSTHATALSOMEANSTHATALTHOUGHYOUMODIFYTHEPROJECTQUITEABITDURINGTHEUPGRADETHEE2ETESTSUITESHOULDKEEPPASSINGWITHJUSTMINORMODIFICATIONSYOUDIDNTCHANGEHOWTHEAPPLICATIONBEHAVESFROMTHEUSERSPOINTOFVIEW", "original": "The PhoneCat project has both E2E Protractor tests and some Karma unit tests in it.\nOf these two, E2E tests can be dealt with much more easily: By definition,\nE2E tests access the application from the *outside* by interacting with\nthe various UI elements the app puts on the screen. E2E tests aren't really that\nconcerned with the internal structure of the application components. That\nalso means that, although you modify the project quite a bit during the upgrade, the E2E\ntest suite should keep passing with just minor modifications. You\ndidn't change how the application behaves from the user's point of view.", "translation": "PhoneCat 项目中同时有基于 Protractor 的 E2E 测试和一些基于 Karma 的单元测试。\n对这两者来说,E2E 测试的转换要容易得多:根据定义,E2E 测试通过与应用中显示的这些 UI 元素互动,从*外部*访问你的应用来进行测试。\nE2E 测试实际上并不关心这些应用中各部件的内部结构。这也意味着,虽然你已经修改了此应用程序,\n但是 E2E 测试套件仍然应该能像以前一样全部通过。因为从用户的角度来说,你并没有改变应用的行为。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "DURINGTYPESCRIPTCONVERSIONTHEREISNOTHINGTODOTOKEEPE2ETESTSWORKINGBUTWHENYOUCHANGETHEBOOTSTRAPTOTHATOFAHYBRIDAPPYOUMUSTMAKEAFEWCHANGES", "original": "During TypeScript conversion, there is nothing to do to keep E2E tests\nworking. But when you change the bootstrap to that of a Hybrid app,\nyou must make a few changes.", "translation": "在转成 TypeScript 期间,你不用做什么就能让 E2E 测试正常工作。\n只有当你想做些修改而把组件及其模板升级到 Angular 时才需要做些处理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "UPDATETHEPROTRACTORCONFJSTOSYNCWITHHYBRIDAPPS:", "original": "Update the `protractor-conf.js` to sync with hybrid apps:", "translation": "再对 `protractor-conf.js` 做下列修改,与混合应用同步:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENYOUSTARTTOUPGRADECOMPONENTSANDTHEIRTEMPLATESTOANGULARYOULLMAKEMORECHANGESBECAUSETHEE2ETESTSHAVEMATCHERSTHATARESPECIFICTOANGULARJSFORPHONECATYOUNEEDTOMAKETHEFOLLOWINGCHANGESINORDERTOMAKETHINGSWORKWITHANGULAR:", "original": "When you start to upgrade components and their templates to Angular, you'll make more changes\nbecause the E2E tests have matchers that are specific to AngularJS.\nFor PhoneCat you need to make the following changes in order to make things work with Angular:", "translation": "当你开始组件和模块升级到 Angular 时,还需要一系列后续的修改。\n这是因为 E2E 测试有一些匹配器是 AngularJS 中特有的。对于 PhoneCat 来说,为了让它能在 Angular 下工作,你得做下列修改:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "PREVIOUSCODE", "original": "Previous code", "translation": "老代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NEWCODE", "original": "New code", "translation": "新代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "NOTES", "original": "Notes", "translation": "说明", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEREPEATERMATCHERRELIESONANGULARJSNGREPEAT", "original": "The repeater matcher relies on AngularJS `ng-repeat`", "translation": "repeater 匹配器依赖于 AngularJS 中的 `ng-repeat`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEREPEATERMATCHERRELIESONANGULARJSNGREPEAT", "original": "The repeater matcher relies on AngularJS `ng-repeat`", "translation": "repeater 匹配器依赖于 AngularJS 中的 `ng-repeat`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEMODELMATCHERRELIESONANGULARJSNGMODEL", "original": "The model matcher relies on AngularJS `ng-model`", "translation": "model 匹配器依赖于 AngularJS 中的 `ng-model`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEMODELMATCHERRELIESONANGULARJSNGMODEL", "original": "The model matcher relies on AngularJS `ng-model`", "translation": "model 匹配器依赖于 AngularJS 中的 `ng-model`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEBINDINGMATCHERRELIESONANGULARJSDATABINDING", "original": "The binding matcher relies on AngularJS data binding", "translation": "binding 匹配器依赖于 AngularJS 的数据绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "WHENTHEBOOTSTRAPMETHODISSWITCHEDFROMTHATOFUPGRADEMODULETOPUREANGULARANGULARJSCEASESTOEXISTONTHEPAGECOMPLETELYATTHISPOINTYOUNEEDTOTELLPROTRACTORTHATITSHOULDNOTBELOOKINGFORANANGULARJSAPPANYMOREBUTINSTEADITSHOULDFINDANGULARAPPSFROMTHEPAGE", "original": "When the bootstrap method is switched from that of `UpgradeModule` to\npure Angular, AngularJS ceases to exist on the page completely.\nAt this point, you need to tell Protractor that it should not be looking for\nan AngularJS app anymore, but instead it should find *Angular apps* from\nthe page.", "translation": "当引导方式从 `UpgradeModule` 切换到纯 Angular 的时,AngularJS 就从页面中完全消失了。\n此时,你需要告诉 Protractor,它不用再找 AngularJS 应用了,而是从页面中查找 *Angular* 应用。\n于是在 `protractor-conf.js` 中做下列修改:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "REPLACETHENG12HYBRIDPREVIOUSLYADDEDWITHTHEFOLLOWINGINPROTRACTORCONFJS:", "original": "Replace the `ng12Hybrid` previously added with the following in `protractor-conf.js`:", "translation": "替换之前在 `protractor-conf.js` 中加入 `ng12Hybrid`,象这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ALSOTHEREAREACOUPLEOFPROTRACTORAPICALLSINTHEPHONECATTESTCODETHATAREUSINGTHEANGULARJSLOCATIONSERVICEUNDERTHEHOODASTHATSERVICEISNOLONGERPRESENTAFTERTHEUPGRADEREPLACETHOSECALLSWITHONESTHATUSEWEBDRIVERSGENERICURLAPISINSTEADTHEFIRSTOFTHESEISTHEREDIRECTIONSPEC:", "original": "Also, there are a couple of Protractor API calls in the PhoneCat test code that\nare using the AngularJS `$location` service under the hood. As that\nservice is no longer present after the upgrade, replace those calls with ones\nthat use WebDriver's generic URL APIs instead. The first of these is\nthe redirection spec:", "translation": "同样,`PhoneCat` 的测试代码中有两个 Protractor API 调用内部使用了 `$location`。该服务没有了,\n你就得把这些调用用一个 WebDriver 的通用 URL API 代替。第一个 API 是“重定向(redirect)”规约:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANDTHESECONDISTHEPHONELINKSSPEC:", "original": "And the second is the phone links spec:", "translation": "然后是“电话链接(phone links)”规约:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "###UNITTESTS", "original": "### Unit Tests", "translation": "### 单元测试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FORUNITTESTSONTHEOTHERHANDMORECONVERSIONWORKISNEEDEDEFFECTIVELYTHEYNEEDTOBEUPGRADEDALONGWITHTHEPRODUCTIONCODE", "original": "For unit tests, on the other hand, more conversion work is needed. Effectively\nthey need to be *upgraded* along with the production code.", "translation": "另一方面,对于单元测试来说,需要更多的转化工作。实际上,它们需要随着产品代码一起升级。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "DURINGTYPESCRIPTCONVERSIONNOCHANGESARESTRICTLYNECESSARYBUTITMAYBEAGOODIDEATOCONVERTTHEUNITTESTCODEINTOTYPESCRIPTASWELL", "original": "During TypeScript conversion no changes are strictly necessary. But it may be\na good idea to convert the unit test code into TypeScript as well.", "translation": "在转成 TypeScript 期间,严格来讲没有什么改动是必须的。但把单元测试代码转成 TypeScript 仍然是个好主意,\n产品代码从 TypeScript 中获得的那些增益也同样适用于测试代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FORINSTANCEINTHEPHONEDETAILCOMPONENTSPECYOUCANUSEES2015FEATURESLIKEARROWFUNCTIONSANDBLOCKSCOPEDVARIABLESANDBENEFITFROMTHETYPEDEFINITIONSOFTHEANGULARJSSERVICESYOURECONSUMING:", "original": "For instance, in the phone detail component spec, you can use ES2015\nfeatures like arrow functions and block-scoped variables and benefit from the type\ndefinitions of the AngularJS services you're consuming:", "translation": "比如,在这个电话详情组件的规约中,你不仅用到了 ES2015 中的箭头函数和块作用域变量这些特性,还为所用的一些\nAngularJS 服务提供了类型定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ONCEYOUSTARTTHEUPGRADEPROCESSANDBRINGINSYSTEMJSCONFIGURATIONCHANGESARENEEDEDFORKARMAYOUNEEDTOLETSYSTEMJSLOADALLTHENEWANGULARCODEWHICHCANBEDONEWITHTHEFOLLOWINGKINDOFSHIMFILE:", "original": "Once you start the upgrade process and bring in SystemJS, configuration changes\nare needed for Karma. You need to let SystemJS load all the new Angular code,\nwhich can be done with the following kind of shim file:", "translation": "一旦你开始了升级过程并引入了 SystemJS,还需要对 Karma 进行配置修改。\n你需要让 SystemJS 加载所有的 Angular 新代码,", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THESHIMFIRSTLOADSTHESYSTEMJSCONFIGURATIONTHENANGULARSTESTSUPPORTLIBRARIESANDTHENTHEAPPLICATIONSSPECFILESTHEMSELVES", "original": "The shim first loads the SystemJS configuration, then Angular's test support libraries,\nand then the application's spec files themselves.", "translation": "这个 shim 文件首先加载了 SystemJS 的配置,然后是 Angular 的测试支持库,然后是应用本身的规约文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "KARMACONFIGURATIONSHOULDTHENBECHANGEDSOTHATITUSESTHEAPPLICATIONROOTDIRASTHEBASEDIRECTORYINSTEADOFAPP", "original": "Karma configuration should then be changed so that it uses the application root dir\nas the base directory, instead of `app`.", "translation": "然后需要修改 Karma 配置,来让它使用本应用的根目录作为基础目录(base directory),而不是 `app`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ONCEDONEYOUCANLOADSYSTEMJSANDOTHERDEPENDENCIESANDALSOSWITCHTHECONFIGURATIONFORLOADINGAPPLICATIONFILESSOTHATTHEYARENOTINCLUDEDTOTHEPAGEBYKARMAYOULLLETTHESHIMANDSYSTEMJSLOADTHEM", "original": "Once done, you can load SystemJS and other dependencies, and also switch the configuration\nfor loading application files so that they are *not* included to the page by Karma. You'll let\nthe shim and SystemJS load them.", "translation": "一旦这些完成了,你就能加载 SystemJS 和其它依赖,并切换配置文件来加载那些应用文件,而*不用*在 Karma 页面中包含它们。\n你要让这个 shim 文件和 SystemJS 去加载它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "SINCETHEHTMLTEMPLATESOFANGULARCOMPONENTSWILLBELOADEDASWELLYOUMUSTHELPKARMAOUTABITSOTHATITCANROUTETHEMTOTHERIGHTPATHS:", "original": "Since the HTML templates of Angular components will be loaded as well, you must help\nKarma out a bit so that it can route them to the right paths:", "translation": "由于 Angular 组件中的 HTML 模板也同样要被加载,所以你得帮 Karma 一把,帮它在正确的路径下找到这些模板:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEUNITTESTFILESTHEMSELVESALSONEEDTOBESWITCHEDTOANGULARWHENTHEIRPRODUCTIONCOUNTERPARTSARESWITCHEDTHESPECSFORTHECHECKMARKPIPEAREPROBABLYTHEMOSTSTRAIGHTFORWARDASTHEPIPEHASNODEPENDENCIES:", "original": "The unit test files themselves also need to be switched to Angular when their production\ncounterparts are switched. The specs for the checkmark pipe are probably the most straightforward,\nas the pipe has no dependencies:", "translation": "如果产品代码被切换到了 Angular,单元测试文件本身也需要切换过来。对勾(checkmark)管道的规约可能是最简单的,因为它没有任何依赖:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "THEUNITTESTFORTHEPHONESERVICEISABITMOREINVOLVEDYOUNEEDTOSWITCHFROMTHEMOCKEDOUTANGULARJSHTTPBACKENDTOAMOCKEDOUTANGULARHTTPBACKEND", "original": "The unit test for the phone service is a bit more involved. You need to switch from the mocked-out\nAngularJS `$httpBackend` to a mocked-out Angular Http backend.", "translation": "`Phone` 服务的测试会牵扯到一点别的。你需要把模拟版的 AngularJS `$httpBackend` 服务切换到模拟板的 Angular Http 后端。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FORTHECOMPONENTSPECSYOUCANMOCKOUTTHEPHONESERVICEITSELFANDHAVEITPROVIDECANNEDPHONEDATAYOUUSEANGULARSCOMPONENTUNITTESTINGAPISFORBOTHCOMPONENTS", "original": "For the component specs, you can mock out the `Phone` service itself, and have it provide\ncanned phone data. You use Angular's component unit testing APIs for both components.", "translation": "对于组件的规约,你可以模拟出 `Phone` 服务本身,并且让它提供电话的数据。你可以对这些组件使用 Angular 的组件单元测试 API。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "FINALLYREVISITBOTHOFTHECOMPONENTTESTSWHENYOUSWITCHTOTHEANGULARROUTERFORTHEDETAILSCOMPONENTPROVIDEAMOCKOFANGULARACTIVATEDROUTEOBJECTINSTEADOFUSINGTHEANGULARJSROUTEPARAMS", "original": "Finally, revisit both of the component tests when you switch to the Angular\nrouter. For the details component, provide a mock of Angular `ActivatedRoute` object\ninstead of using the AngularJS `$routeParams`.", "translation": "最后,当你切换到 Angular 路由时,需要重新过一遍这些组件测试。对详情组件来说,你需要提供一个 Angular\n`RouteParams` 的 mock 对象,而不再用 AngularJS 中的 `$routeParams`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "ANDFORTHEPHONELISTCOMPONENTAFEWADJUSTMENTSTOTHEROUTERMAKETHEROUTELINKDIRECTIVESWORK", "original": "And for the phone list component, a few adjustments to the router make\nthe `RouteLink` directives work.", "translation": "对于电话列表组件,还要再做少量的调整,以便路由器能让 `RouteLink` 指令正常工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/upgrade.md" }, { + "key": "#USERINPUT", "original": "# User Input", "translation": "# 用户输入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "USERACTIONSSUCHASCLICKINGALINKPUSHINGABUTTONANDENTERINGTEXTRAISEDOMEVENTSTHISPAGEEXPLAINSHOWTOBINDTHOSEEVENTSTOCOMPONENTEVENTHANDLERSUSINGTHEANGULAREVENTBINDINGSYNTAX", "original": "User actions such as clicking a link, pushing a button, and entering\ntext raise DOM events.\nThis page explains how to bind those events to component event handlers using the Angular\nevent binding syntax.", "translation": "当用户点击链接、按下按钮或者输入文字时,这些用户动作都会产生 DOM 事件。\n本章解释如何使用 Angular 事件绑定语法把这些事件绑定到事件处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "RUNTHELIVEEXAMPLELIVEEXAMPLE", "original": "Run the <live-example></live-example>.", "translation": "运行<live-example></live-example>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "##BINDINGTOUSERINPUTEVENTS", "original": "## Binding to user input events", "translation": "## 绑定到用户输入事件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "YOUCANUSEANGULAREVENTBINDINGSGUIDETEMPLATESYNTAX#EVENTBINDINGTORESPONDTOANYDOMEVENTHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBEVENTSMANYDOMEVENTSARETRIGGEREDBYUSERINPUTBINDINGTOTHESEEVENTSPROVIDESAWAYTOGETINPUTFROMTHEUSER", "original": "You can use [Angular event bindings](guide/template-syntax#event-binding)\nto respond to any [DOM event](https://developer.mozilla.org/en-US/docs/Web/Events).\nMany DOM events are triggered by user input. Binding to these events provides a way to\nget input from the user.", "translation": "你可以使用 [Angular 事件绑定](guide/template-syntax#event-binding)机制来响应任何 [DOM 事件](https://developer.mozilla.org/en-US/docs/Web/Events)。\n许多 DOM 事件是由用户输入触发的。绑定这些事件可以获取用户输入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "TOBINDTOADOMEVENTSURROUNDTHEDOMEVENTNAMEINPARENTHESESANDASSIGNAQUOTEDTEMPLATESTATEMENTGUIDETEMPLATESYNTAX#TEMPLATESTATEMENTSTOIT", "original": "To bind to a DOM event, surround the DOM event name in parentheses and assign a quoted\n[template statement](guide/template-syntax#template-statements) to it.", "translation": "要绑定 DOM 事件,只要把 DOM 事件的名字包裹在圆括号中,然后用放在引号中的[模板语句](guide/template-syntax#template-statements)对它赋值就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEFOLLOWINGEXAMPLESHOWSANEVENTBINDINGTHATIMPLEMENTSACLICKHANDLER:", "original": "The following example shows an event binding that implements a click handler:", "translation": "下例展示了一个事件绑定,它实现了一个点击事件处理器:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THECLICKTOTHELEFTOFTHEEQUALSSIGNIDENTIFIESTHEBUTTONSCLICKEVENTASTHETARGETOFTHEBINDINGTHETEXTINQUOTESTOTHERIGHTOFTHEEQUALSSIGNISTHETEMPLATESTATEMENTWHICHRESPONDSTOTHECLICKEVENTBYCALLINGTHECOMPONENTSONCLICKMEMETHOD", "original": "The `(click)` to the left of the equals sign identifies the button's click event as the **target of the binding**.\nThe text in quotes to the right of the equals sign\nis the **template statement**, which responds\nto the click event by calling the component's `onClickMe` method.", "translation": "等号左边的 `(click)` 表示把按钮的点击事件作为**绑定目标**。\n等号右边引号中的文本是**模板语句**,通过调用组件的 `onClickMe` 方法来响应这个点击事件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "WHENWRITINGABINDINGBEAWAREOFATEMPLATESTATEMENTSEXECUTIONCONTEXTTHEIDENTIFIERSINATEMPLATESTATEMENTBELONGTOASPECIFICCONTEXTOBJECTUSUALLYTHEANGULARCOMPONENTCONTROLLINGTHETEMPLATETHEEXAMPLEABOVESHOWSASINGLELINEOFHTMLBUTTHATHTMLBELONGSTOALARGERCOMPONENT:", "original": "When writing a binding, be aware of a template statement's **execution context**.\nThe identifiers in a template statement belong to a specific context object,\nusually the Angular component controlling the template.\nThe example above shows a single line of HTML, but that HTML belongs to a larger component:", "translation": "写绑定时,需要知道模板语句的**执行上下文**。\n出现在模板语句中的每个标识符都属于特定的上下文对象。\n这个对象通常都是控制此模板的 Angular 组件。\n上例中只显示了一行 HTML,那段 HTML 片段属于下面这个组件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "WHENTHEUSERCLICKSTHEBUTTONANGULARCALLSTHEONCLICKMEMETHODFROMCLICKMECOMPONENT", "original": "When the user clicks the button, Angular calls the `onClickMe` method from `ClickMeComponent`.", "translation": "当用户点击按钮时,Angular 调用 `ClickMeComponent` 的 `onClickMe` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "##GETUSERINPUTFROMTHEEVENTOBJECT", "original": "## Get user input from the $event object", "translation": "## 通过 $event 对象取得用户输入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "DOMEVENTSCARRYAPAYLOADOFINFORMATIONTHATMAYBEUSEFULTOTHECOMPONENTTHISSECTIONSHOWSHOWTOBINDTOTHEKEYUPEVENTOFANINPUTBOXTOGETTHEUSERSINPUTAFTEREACHKEYSTROKE", "original": "DOM events carry a payload of information that may be useful to the component.\nThis section shows how to bind to the `keyup` event of an input box to get the user's input after each keystroke.", "translation": "DOM 事件可以携带可能对组件有用的信息。\n本节将展示如何绑定输入框的 `keyup` 事件,在每个敲击键盘时获取用户输入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEFOLLOWINGCODELISTENSTOTHEKEYUPEVENTANDPASSESTHEENTIREEVENTPAYLOADEVENTTOTHECOMPONENTEVENTHANDLER", "original": "The following code listens to the `keyup` event and passes the entire event payload (`$event`) to the component event handler.", "translation": "下面的代码监听 `keyup` 事件,并将整个事件载荷 (`$event`) 传递给组件的事件处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "WHENAUSERPRESSESANDRELEASESAKEYTHEKEYUPEVENTOCCURSANDANGULARPROVIDESACORRESPONDINGDOMEVENTOBJECTINTHEEVENTVARIABLEWHICHTHISCODEPASSESASAPARAMETERTOTHECOMPONENTSONKEYMETHOD", "original": "When a user presses and releases a key, the `keyup` event occurs, and Angular provides a corresponding\nDOM event object in the `$event` variable which this code passes as a parameter to the component's `onKey()` method.", "translation": "当用户按下并释放一个按键时,触发 `keyup` 事件,Angular 在 `$event` 变量提供一个相应的 DOM\n事件对象,上面的代码将它作为参数传递给 `onKey()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEPROPERTIESOFANEVENTOBJECTVARYDEPENDINGONTHETYPEOFDOMEVENTFOREXAMPLEAMOUSEEVENTINCLUDESDIFFERENTINFORMATIONTHANAINPUTBOXEDITINGEVENT", "original": "The properties of an `$event` object vary depending on the type of DOM event. For example,\na mouse event includes different information than a input box editing event.", "translation": "`$event` 对象的属性取决于 DOM 事件的类型。例如,鼠标事件与输入框编辑事件包含了不同的信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "ALLSTANDARDDOMEVENTOBJECTSHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIEVENTHAVEATARGETPROPERTYAREFERENCETOTHEELEMENTTHATRAISEDTHEEVENTINTHISCASETARGETREFERSTOTHEINPUTELEMENTHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBAPIHTMLINPUTELEMENTANDEVENTTARGETVALUERETURNSTHECURRENTCONTENTSOFTHATELEMENT", "original": "All [standard DOM event objects](https://developer.mozilla.org/en-US/docs/Web/API/Event)\nhave a `target` property, a reference to the element that raised the event.\nIn this case, `target` refers to the [`<input>` element](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement) and\n`event.target.value` returns the current contents of that element.", "translation": "所有[标准 DOM 事件对象](https://developer.mozilla.org/en-US/docs/Web/API/Event)都有一个 `target` 属性,\n引用触发该事件的元素。\n在本例中,`target` 是[`<input>` 元素](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement),\n`event.target.value` 返回该元素的当前内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "AFTEREACHCALLTHEONKEYMETHODAPPENDSTHECONTENTSOFTHEINPUTBOXVALUETOTHELISTINTHECOMPONENTSVALUESPROPERTYFOLLOWEDBYASEPARATORCHARACTERTHEINTERPOLATIONGUIDETEMPLATESYNTAX#INTERPOLATIONDISPLAYSTHEACCUMULATINGINPUTBOXCHANGESFROMTHEVALUESPROPERTY", "original": "After each call, the `onKey()` method appends the contents of the input box value to the list\nin the component's `values` property, followed by a separator character (|).\nThe [interpolation](guide/template-syntax#interpolation)\ndisplays the accumulating input box changes from the `values` property.", "translation": "在组件的 `onKey()` 方法中,把输入框的值和分隔符 (|) 追加组件的 `values` 属性。\n使用[插值表达式](guide/template-syntax#interpolation)来把存放累加结果的 `values` 属性回显到屏幕上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "SUPPOSETHEUSERENTERSTHELETTERSABCANDTHENBACKSPACESTOREMOVETHEMONEBYONEHERESWHATTHEUIDISPLAYS:", "original": "Suppose the user enters the letters \"abc\", and then backspaces to remove them one by one.\nHere's what the UI displays:", "translation": "假设用户输入字母“abc”,然后用退格键一个一个删除它们。\n用户界面将显示:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "ALTERNATIVELYYOUCOULDACCUMULATETHEINDIVIDUALKEYSTHEMSELVESBYSUBSTITUTINGEVENTKEYFOREVENTTARGETVALUEINWHICHCASETHESAMEUSERINPUTWOULDPRODUCE:", "original": "Alternatively, you could accumulate the individual keys themselves by substituting `event.key`\nfor `event.target.value` in which case the same user input would produce:", "translation": "或者,你可以用 `event.key` 替代 `event.target.value`,积累各个按键本身,这样同样的用户输入可以产生:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "###TYPETHEEVENT", "original": "### Type the _$event_", "translation": "### *$event*的类型", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEEXAMPLEABOVECASTSTHEEVENTASANANYTYPETHATSIMPLIFIESTHECODEATACOSTTHEREISNOTYPEINFORMATIONTHATCOULDREVEALPROPERTIESOFTHEEVENTOBJECTANDPREVENTSILLYMISTAKES", "original": "The example above casts the `$event` as an `any` type.\nThat simplifies the code at a cost.\nThere is no type information\nthat could reveal properties of the event object and prevent silly mistakes.", "translation": "上例将 `$event` 转换为 `any` 类型。\n这样简化了代码,但是有成本。\n没有任何类型信息能够揭示事件对象的属性,防止简单的错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEFOLLOWINGEXAMPLEREWRITESTHEMETHODWITHTYPES:", "original": "The following example rewrites the method with types:", "translation": "下面的例子,使用了带类型方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEEVENTISNOWASPECIFICKEYBOARDEVENTNOTALLELEMENTSHAVEAVALUEPROPERTYSOITCASTSTARGETTOANINPUTELEMENTTHEONKEYMETHODMORECLEARLYEXPRESSESWHATITEXPECTSFROMTHETEMPLATEANDHOWITINTERPRETSTHEEVENT", "original": "The `$event` is now a specific `KeyboardEvent`.\nNot all elements have a `value` property so it casts `target` to an input element.\nThe `OnKey` method more clearly expresses what it expects from the template and how it interprets the event.", "translation": "`$event` 的类型现在是 `KeyboardEvent`。\n不是所有的元素都有 `value` 属性,所以它将 `target` 转换为输入元素。\n`OnKey` 方法更加清晰的表达了它期望从模板得到什么,以及它是如何解析事件的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "###PASSINGEVENTISADUBIOUSPRACTICE", "original": "### Passing _$event_ is a dubious practice", "translation": "### 传入 *$event* 是靠不住的做法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "TYPINGTHEEVENTOBJECTREVEALSASIGNIFICANTOBJECTIONTOPASSINGTHEENTIREDOMEVENTINTOTHEMETHOD:THECOMPONENTHASTOOMUCHAWARENESSOFTHETEMPLATEDETAILSITCANTEXTRACTINFORMATIONWITHOUTKNOWINGMORETHANITSHOULDABOUTTHEHTMLIMPLEMENTATIONTHATBREAKSTHESEPARATIONOFCONCERNSBETWEENTHETEMPLATEWHATTHEUSERSEESANDTHECOMPONENTHOWTHEAPPLICATIONPROCESSESUSERDATA", "original": "Typing the event object reveals a significant objection to passing the entire DOM event into the method:\nthe component has too much awareness of the template details.\nIt can't extract information without knowing more than it should about the HTML implementation.\nThat breaks the separation of concerns between the template (_what the user sees_)\nand the component (_how the application processes user data_).", "translation": "类型化事件对象揭露了重要的一点,即反对把整个 DOM 事件传到方法中,因为这样组件会知道太多模板的信息。\n只有当它知道更多它本不应了解的 HTML 实现细节时,它才能提取信息。\n这就违反了模板(*用户看到的*)和组件(*应用如何处理用户数据*)之间的分离关注原则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THENEXTSECTIONSHOWSHOWTOUSETEMPLATEREFERENCEVARIABLESTOADDRESSTHISPROBLEM", "original": "The next section shows how to use template reference variables to address this problem.", "translation": "下面将介绍如何用模板引用变量来解决这个问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "##GETUSERINPUTFROMATEMPLATEREFERENCEVARIABLE", "original": "## Get user input from a template reference variable", "translation": "## 从一个模板引用变量中获得用户输入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THERESANOTHERWAYTOGETTHEUSERDATA:USEANGULARTEMPLATEREFERENCEVARIABLESGUIDETEMPLATESYNTAX#REFVARSTHESEVARIABLESPROVIDEDIRECTACCESSTOANELEMENTFROMWITHINTHETEMPLATETODECLAREATEMPLATEREFERENCEVARIABLEPRECEDEANIDENTIFIERWITHAHASHORPOUNDCHARACTER#", "original": "There's another way to get the user data: use Angular\n[**template reference variables**](guide/template-syntax#ref-vars).\nThese variables provide direct access to an element from within the template.\nTo declare a template reference variable, precede an identifier with a hash (or pound) character (#).", "translation": "还有另一种获取用户数据的方式:使用 Angular 的[**模板引用变量**](guide/template-syntax#ref-vars)。\n这些变量提供了从模块中直接访问元素的能力。\n在标识符前加上井号 (#) 就能声明一个模板引用变量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEFOLLOWINGEXAMPLEUSESATEMPLATEREFERENCEVARIABLETOIMPLEMENTAKEYSTROKELOOPBACKINASIMPLETEMPLATE", "original": "The following example uses a template reference variable\nto implement a keystroke loopback in a simple template.", "translation": "下面的例子使用了局部模板变量,在一个超简单的模板中实现按键反馈功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THETEMPLATEREFERENCEVARIABLENAMEDBOXDECLAREDONTHEINPUTELEMENTREFERSTOTHEINPUTELEMENTITSELFTHECODEUSESTHEBOXVARIABLETOGETTHEINPUTELEMENTSVALUEANDDISPLAYITWITHINTERPOLATIONBETWEENPTAGS", "original": "The template reference variable named `box`, declared on the `<input>` element,\nrefers to the `<input>` element itself.\nThe code uses the `box` variable to get the input element's `value` and display it\nwith interpolation between `<p>` tags.", "translation": "这个模板引用变量名叫 `box`,在 `<input>` 元素声明,它引用 `<input>` 元素本身。\n代码使用 `box` 获得输入元素的 `value` 值,并通过插值表达式把它显示在 `<p>` 标签中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THETEMPLATEISCOMPLETELYSELFCONTAINEDITDOESNTBINDTOTHECOMPONENTANDTHECOMPONENTDOESNOTHING", "original": "The template is completely self contained. It doesn't bind to the component,\nand the component does nothing.", "translation": "这个模板完全是完全自包含的。它没有绑定到组件,组件也没做任何事情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "TYPESOMETHINGINTHEINPUTBOXANDWATCHTHEDISPLAYUPDATEWITHEACHKEYSTROKE", "original": "Type something in the input box, and watch the display update with each keystroke.", "translation": "在输入框中输入,就会看到每次按键时,显示也随之更新了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THISWONTWORKATALLUNLESSYOUBINDTOANEVENT", "original": "**This won't work at all unless you bind to an event**.", "translation": "**除非你绑定一个事件,否则这将完全无法工作。**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "ANGULARUPDATESTHEBINDINGSANDTHEREFORETHESCREENONLYIFTHEAPPDOESSOMETHINGINRESPONSETOASYNCHRONOUSEVENTSSUCHASKEYSTROKESTHISEXAMPLECODEBINDSTHEKEYUPEVENTTOTHENUMBER0THESHORTESTTEMPLATESTATEMENTPOSSIBLEWHILETHESTATEMENTDOESNOTHINGUSEFULITSATISFIESANGULARSREQUIREMENTSOTHATANGULARWILLUPDATETHESCREEN", "original": "Angular updates the bindings (and therefore the screen)\nonly if the app does something in response to asynchronous events, such as keystrokes.\nThis example code binds the `keyup` event\nto the number 0, the shortest template statement possible.\nWhile the statement does nothing useful,\nit satisfies Angular's requirement so that Angular will update the screen.", "translation": "只有在应用做了些异步事件(如击键),Angular 才更新绑定(并最终影响到屏幕)。\n本例代码将 `keyup` 事件绑定到了数字 0,这可能是最短的模板语句了。\n虽然这个语句不做什么,但它满足 Angular 的要求,所以 Angular 将更新屏幕。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "ITSEASIERTOGETTOTHEINPUTBOXWITHTHETEMPLATEREFERENCEVARIABLETHANTOGOTHROUGHTHEEVENTOBJECTHERESAREWRITEOFTHEPREVIOUSKEYUPEXAMPLETHATUSESATEMPLATEREFERENCEVARIABLETOGETTHEUSERSINPUT", "original": "It's easier to get to the input box with the template reference\nvariable than to go through the `$event` object. Here's a rewrite of the previous\n`keyup` example that uses a template reference variable to get the user's input.", "translation": "从模板变量获得输入框比通过 `$event` 对象更加简单。\n下面的代码重写了之前 `keyup` 示例,它使用变量来获得用户输入。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "ANICEASPECTOFTHISAPPROACHISTHATTHECOMPONENTGETSCLEANDATAVALUESFROMTHEVIEWITNOLONGERREQUIRESKNOWLEDGEOFTHEEVENTANDITSSTRUCTURE", "original": "A nice aspect of this approach is that the component gets clean data values from the view.\nIt no longer requires knowledge of the `$event` and its structure.", "translation": "这个方法最漂亮的一点是:组件代码从视图中获得了干净的数据值。再也不用了解 `$event` 变量及其结构了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "##KEYEVENTFILTERINGWITHKEYENTER", "original": "## Key event filtering (with `key.enter`)", "translation": "## 按键事件过滤(通过 `key.enter`)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEKEYUPEVENTHANDLERHEARSEVERYKEYSTROKESOMETIMESONLYTHEENTERKEYMATTERSBECAUSEITSIGNALSTHATTHEUSERHASFINISHEDTYPINGONEWAYTOREDUCETHENOISEWOULDBETOEXAMINEEVERYEVENTKEYCODEANDTAKEACTIONONLYWHENTHEKEYISENTER", "original": "The `(keyup)` event handler hears *every keystroke*.\nSometimes only the _Enter_ key matters, because it signals that the user has finished typing.\nOne way to reduce the noise would be to examine every `$event.keyCode` and take action only when the key is _Enter_.", "translation": "`(keyup)` 事件处理器监听*每一次按键*。\n有时只在意*回车*键,因为它标志着用户结束输入。\n解决这个问题的一种方法是检查每个 `$event.keyCode`,只有键值是*回车*键时才采取行动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THERESANEASIERWAY:BINDTOANGULARSKEYUPENTERPSEUDOEVENTTHENANGULARCALLSTHEEVENTHANDLERONLYWHENTHEUSERPRESSESENTER", "original": "There's an easier way: bind to Angular's `keyup.enter` pseudo-event.\nThen Angular calls the event handler only when the user presses _Enter_.", "translation": "更简单的方法是:绑定到 Angular 的 `keyup.enter` 模拟事件。\n然后,只有当用户敲*回车*键时,Angular 才会调用事件处理器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "HERESHOWITWORKS", "original": "Here's how it works.", "translation": "下面展示了它是如何工作的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "##ONBLUR", "original": "## On blur", "translation": "## 失去焦点事件 (blur)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "INTHEPREVIOUSEXAMPLETHECURRENTSTATEOFTHEINPUTBOXISLOSTIFTHEUSERMOUSESAWAYANDCLICKSELSEWHEREONTHEPAGEWITHOUTFIRSTPRESSINGENTERTHECOMPONENTSVALUEPROPERTYISUPDATEDONLYWHENTHEUSERPRESSESENTER", "original": "In the previous example, the current state of the input box\nis lost if the user mouses away and clicks elsewhere on the page\nwithout first pressing _Enter_.\nThe component's `value` property is updated only when the user presses _Enter_.", "translation": "前上例中,如果用户没有先按回车键,而是移开了鼠标,点击了页面中其它地方,输入框的当前值就会丢失。\n只有当用户按下了回车键候,组件的 `values` 属性才能更新。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "TOFIXTHISISSUELISTENTOBOTHTHEENTERKEYANDTHEBLUREVENT", "original": "To fix this issue, listen to both the _Enter_ key and the _blur_ event.", "translation": "下面通过同时监听输入框的回车键和失去焦点事件来修正这个问题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "##PUTITALLTOGETHER", "original": "## Put it all together", "translation": "## 把它们放在一起", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THEPREVIOUSPAGESHOWEDHOWTODISPLAYDATAGUIDEDISPLAYINGDATATHISPAGEDEMONSTRATEDEVENTBINDINGTECHNIQUES", "original": "The previous page showed how to [display data](guide/displaying-data).\nThis page demonstrated event binding techniques.", "translation": "上一章介绍了如何[显示数据](guide/displaying-data)。\n本章展示了事件绑定技术。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "NOWPUTITALLTOGETHERINAMICROAPPTHATCANDISPLAYALISTOFHEROESANDADDNEWHEROESTOTHELISTTHEUSERCANADDAHEROBYTYPINGTHEHEROSNAMEINTHEINPUTBOXANDCLICKINGADD", "original": "Now, put it all together in a micro-app\nthat can display a list of heroes and add new heroes to the list.\nThe user can add a hero by typing the hero's name in the input box and\nclicking **Add**.", "translation": "现在,在一个微型应用中一起使用它们,应用能显示一个英雄列表,并把新的英雄加到列表中。\n用户可以通过输入英雄名和点击“添加”按钮来添加英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "BELOWISTHELITTLETOUROFHEROESCOMPONENT", "original": "Below is the \"Little Tour of Heroes\" component.", "translation": "下面就是“简版英雄指南”组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "###OBSERVATIONS", "original": "### Observations", "translation": "### 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "USETEMPLATEVARIABLESTOREFERTOELEMENTSMDASHTHENEWHEROTEMPLATEVARIABLEREFERSTOTHEINPUTELEMENTYOUCANREFERENCENEWHEROFROMANYSIBLINGORCHILDOFTHEINPUTELEMENT", "original": "* **Use template variables to refer to elements** —\nThe `newHero` template variable refers to the `<input>` element.\nYou can reference `newHero` from any sibling or child of the `<input>` element.", "translation": "**使用模板变量来引用元素** — `newHero` 模板变量引用了 `<input>` 元素。\n你可以在 `<input>` 的任何兄弟或子级元素中引用 `newHero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "PASSVALUESNOTELEMENTSMDASHINSTEADOFPASSINGTHENEWHEROINTOTHECOMPONENTSADDHEROMETHODGETTHEINPUTBOXVALUEANDPASSTHATTOADDHERO", "original": "* **Pass values, not elements** —\nInstead of passing the `newHero` into the component's `addHero` method,\nget the input box value and pass *that* to `addHero`.", "translation": "**传递数值,而非元素** —\n获取输入框的值并将*它*传递给组件的 `addHero`,而不要传递 `newHero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "KEEPTEMPLATESTATEMENTSSIMPLEMDASHTHEBLUREVENTISBOUNDTOTWOJAVASCRIPTSTATEMENTSTHEFIRSTSTATEMENTCALLSADDHEROTHESECONDSTATEMENTNEWHEROVALUECLEARSTHEINPUTBOXAFTERANEWHEROISADDEDTOTHELIST", "original": "* **Keep template statements simple** —\nThe `(blur)` event is bound to two JavaScript statements.\nThe first statement calls `addHero`. The second statement, `newHero.value=''`,\nclears the input box after a new hero is added to the list.", "translation": "**保持模板语句简单** —\n`(blur)` 事件被绑定到两个 JavaScript 语句。\n第一句调用 `addHero`。第二句 `newHero.value=''` 在添加新英雄到列表中后清除输入框。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "##SOURCECODE", "original": "## Source code", "translation": "## 源代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "FOLLOWINGISALLTHECODEDISCUSSEDINTHISPAGE", "original": "Following is all the code discussed in this page.", "translation": "下面是本章讨论过的所有源码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "YOUHAVEMASTEREDTHEBASICPRIMITIVESFORRESPONDINGTOUSERINPUTANDGESTURES", "original": "You have mastered the basic primitives for responding to user input and gestures.", "translation": "你已经掌握了响应用户输入和操作的基础技术。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "THESETECHNIQUESAREUSEFULFORSMALLSCALEDEMONSTRATIONSBUTTHEYQUICKLYBECOMEVERBOSEANDCLUMSYWHENHANDLINGLARGEAMOUNTSOFUSERINPUTTWOWAYDATABINDINGISAMOREELEGANTANDCOMPACTWAYTOMOVEVALUESBETWEENDATAENTRYFIELDSANDMODELPROPERTIESTHENEXTPAGEFORMSEXPLAINSHOWTOWRITETWOWAYBINDINGSWITHNGMODEL", "original": "These techniques are useful for small-scale demonstrations, but they\nquickly become verbose and clumsy when handling large amounts of user input.\nTwo-way data binding is a more elegant and compact way to move\nvalues between data entry fields and model properties.\nThe next page, `Forms`, explains how to write\ntwo-way bindings with `NgModel`.", "translation": "这些技术对小规模演示很实用,但是在处理大量用户输入时,很容易变得累赘和笨拙。\n要在数据录入字段和模型属性之间传递数据,双向数据绑定是更加优雅和简洁的方式。\n下一章 ` 表单 ` 解释了如何用 `NgModel` 来进行双向绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/user-input.md" }, { + "key": "#VISUALSTUDIO2015QUICKSTART", "original": "# Visual Studio 2015 QuickStart", "translation": "# Visual Studio 2015 快速上手", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "SOMEDEVELOPERSPREFERVISUALSTUDIOASTHEIRINTEGRATEDDEVELOPMENTENVIRONMENTIDE", "original": "Some developers prefer Visual Studio as their Integrated Development Environment (IDE).", "translation": "有些开发者喜欢用 Visual Studio。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "THISCOOKBOOKDESCRIBESTHESTEPSREQUIREDTOSETUPANDUSETHEANGULARQUICKSTARTFILESINVISUALSTUDIO2015WITHINANASPNET4XPROJECT", "original": "This cookbook describes the steps required to set up and use the\nAngular QuickStart files in **Visual Studio 2015 within an ASP.NET 4.x project**.", "translation": "本烹饪宝典介绍了在**Visual Studio 2015 的 ASP.NET 4.x 项目中**,用 Angular 实现“快速上手”所需的步骤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "THEREISNOLIVEEXAMPLEFORTHISCOOKBOOKBECAUSEITDESCRIBESVISUALSTUDIONOTTHEQUICKSTARTAPPLICATIONITSELF", "original": "There is no *live example* for this cookbook because it describes Visual Studio, not \nthe QuickStart application itself.", "translation": "本烹饪宝典中没有*在线例子*,因为它介绍的是 Visual Studio,而不是《快速上手》应用程序本身。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "##ASPNET4XPROJECT", "original": "## ASP.NET 4.x Project", "translation": "## ASP.NET 4.x 项目", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "TOSETUPTHEQUICKSTARTFILESWITHANASPNET4XPROJECTINVISUALSTUDIO2015FOLLOWTHESESTEPS:", "original": "To set up the QuickStart files with an **ASP.NET 4.x project** in\nVisual Studio 2015, follow these steps:", "translation": "要用 Visual Studio 2015 在**ASP.NET 4.x 项目**中设置**《快速上手》**文件,请遵循如下步骤:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "IFYOUPREFERAFILENEWPROJECTEXPERIENCEANDAREUSINGASPNETCORETHENCONSIDERTHEEXPERIMENTALAHREFHTTP:BLOGSTEVENSANDERSONCOM20161004ANGULAR2TEMPLATEFORVISUALSTUDIOASPNETCOREANGULARTEMPLATEFORVISUALSTUDIO2015ANOTETHATTHERESULTINGCODEDOESNOTMAPTOTHEDOCSADJUSTACCORDINGLY", "original": "If you prefer a `File | New Project` experience and are using **ASP.NET Core**, \nthen consider the _experimental_\n<a href=\"http://blog.stevensanderson.com/2016/10/04/angular2-template-for-visual-studio/\">ASP.NET Core + Angular template for Visual Studio 2015</a>. \nNote that the resulting code does not map to the docs. Adjust accordingly.", "translation": "如果你希望使用**ASP.NET Core**并体验全新项目,\n 参见*预览版*<a href=\"http://blog.stevensanderson.com/2016/10/04/angular2-template-for-visual-studio/\" target=\"_blank\">ASP.NET Core + Angular 的 Visual Studio 2015 模板</a>。 \n 注意,最终代码与本文不对应,请适当调节。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDPREREQ1PREREQUISITE:NODEJSH2", "original": "<h2 id='prereq1'>Prerequisite: Node.js</h2>", "translation": "<h2 id='prereq1'>前提条件: Node.js</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "INSTALLNODEJSANDNPMHTTPS:NODEJSORGENDOWNLOADIFTHEYARENOTALREADYONYOURMACHINE", "original": "Install **[Node.js® and npm](https://nodejs.org/en/download/)**\nif they are not already on your machine.", "translation": "如果你的电脑里没有 Node.js®和 npm,请安装**[它们](https://nodejs.org/en/download/)**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "VERIFYTHATYOUARERUNNINGNODEVERSION46XORGREATERANDNPM3XXORGREATERBYRUNNINGNODEVANDNPMVINATERMINALWINDOWOLDERVERSIONSPRODUCEERRORS", "original": "**Verify that you are running node version `4.6.x` or greater, and npm `3.x.x` or greater**\nby running `node -v` and `npm -v` in a terminal window.\nOlder versions produce errors.", "translation": "在终端或者控制台中运行 `node -v` 和 `npm -v`,**请确认你的 Node 版本为 `4.6.x` 或更高,npm 的版本为 `3.x.x` 或更高**。老版本会引起错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDPREREQ2PREREQUISITE:VISUALSTUDIO2015UPDATE3H2", "original": "<h2 id='prereq2'>Prerequisite: Visual Studio 2015 Update 3</h2>", "translation": "<h2 id='prereq2'>前提条件: Visual Studio 2015 Update 3</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "THEMINIMUMREQUIREMENTFORDEVELOPINGANGULARAPPLICATIONSWITHVISUALSTUDIOISUPDATE3EARLIERVERSIONSDONOTFOLLOWTHEBESTPRACTICESFORDEVELOPINGAPPLICATIONSWITHTYPESCRIPTTOVIEWYOURVERSIONOFVISUALSTUDIO2015GOTOHELPABOUTVISUALSTUDIO", "original": "The minimum requirement for developing Angular applications with Visual Studio is Update 3.\nEarlier versions do not follow the best practices for developing applications with TypeScript.\nTo view your version of Visual Studio 2015, go to `Help | About Visual Studio`.", "translation": "使用 Visual Studio 开发 Angular 应用程序的最低要求是 Update 3。\n早期版本没有遵循使用 TypeScript 开发应用程序的最佳实践。\n要查看你的 Visual Studio 2015 版本号,到 `Help | About Visual Studio`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "IFYOUDONTHAVEITINSTALLVISUALSTUDIO2015UPDATE3HTTPS:WWWVISUALSTUDIOCOMENUSNEWSRELEASENOTESVS2015UPDATE3VSORUSETOOLSEXTENSIONSANDUPDATESTOUPDATETOUPDATE3DIRECTLYFROMVISUALSTUDIO2015", "original": "If you don't have it, install **[Visual Studio 2015 Update 3](https://www.visualstudio.com/en-us/news/releasenotes/vs2015-update3-vs)**.\nOr use `Tools | Extensions and Updates` to update to Update 3 directly from Visual Studio 2015.", "translation": "如果还没有,安装**[Visual Studio 2015 Update 3](https://www.visualstudio.com/en-us/news/releasenotes/vs2015-update3-vs)**。或者使用 `Tools | Extensions and Updates` 来直接在 Visual Studio 2015 中更新到 Update 3。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDPREREQ3PREREQUISITE:CONFIGUREEXTERNALWEBTOOLSH2", "original": "<h2 id='prereq3'>Prerequisite: Configure External Web tools</h2>", "translation": "<h2 id='prereq3'>前提条件: 配置 External Web tools</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "CONFIGUREVISUALSTUDIOTOUSETHEGLOBALEXTERNALWEBTOOLSINSTEADOFTHETOOLSTHATSHIPWITHVISUALSTUDIO:", "original": "Configure Visual Studio to use the global external web tools instead of the tools that ship with Visual Studio:", "translation": "配置 Visual Studio 来使用全局 External Web Tools,而非 Visual Studio 默认的工具:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "OPENTHEOPTIONSDIALOGWITHTOOLSOPTIONS", "original": "* Open the **Options** dialog with `Tools` | `Options`.", "translation": "到 `Tools` | `Options` 打开 **Options** 对话框", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "INTHETREEONTHELEFTSELECTPROJECTSANDSOLUTIONSEXTERNALWEBTOOLS", "original": "* In the tree on the left, select `Projects and Solutions` | `External Web Tools`.", "translation": "在左边树型项目中,选择 `Projects and Solutions` | `External Web Tools`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "ONTHERIGHTMOVETHEPATHENTRYABOVETHEDEVENVDIRENTRIESTHISTELLSVISUALSTUDIOTOUSETHEEXTERNALTOOLSSUCHASNPMFOUNDINTHEGLOBALPATHBEFOREUSINGITSOWNVERSIONOFTHEEXTERNALTOOLS", "original": "* On the right, move the `$(PATH)` entry above the `$(DevEnvDir`) entries. This tells Visual Studio to\n use the external tools (such as npm) found in the global path before using its own version of the external tools.", "translation": "在右侧,将 `$(PATH)` 移动到 `$(DevEnvDir`)上面。这样,Visual Stuio 就会在使用自带的外部工具时,优先使用全局路径中的外部工具(比如 npm)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "CLICKOKTOCLOSETHEDIALOG", "original": "* Click OK to close the dialog.", "translation": "点击 OK 关闭对话框。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "RESTARTVISUALSTUDIOFORTHISCHANGETOTAKEEFFECT", "original": "* Restart Visual Studio for this change to take effect.", "translation": "重启 Visual Studio,以让设置变化生效。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "VISUALSTUDIONOWLOOKSFIRSTFOREXTERNALTOOLSINTHECURRENTWORKSPACEANDIFITDOESNTFINDTHEMITLOOKSINTHEGLOBALPATHIFVISUALSTUDIODOESNTFINDTHEMINEITHERLOCATIONITWILLUSEITSOWNVERSIONSOFTHETOOLS", "original": "Visual Studio now looks first for external tools in the current workspace and \nif it doesn't find them, it looks in the global path. If Visual Studio doesn't \nfind them in either location, it will use its own versions of the tools.", "translation": "Visual Studio 将优先在当前的工作区查找外部工具,如果没有找到,便查找全局路径,如果还没有找到,Visual Studio 就使用自带的工具版本。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDPREREQ4PREREQUISITE:INSTALLTYPESCRIPT22FORVISUALSTUDIO2015H2", "original": "<h2 id='prereq4'>Prerequisite: Install TypeScript 2.2 for Visual Studio 2015</h2>", "translation": "<h2 id='prereq4'>前提条件: 安装 TypeScript 2.2 for Visual Studio 2015</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "WHILEVISUALSTUDIOUPDATE3SHIPSWITHTYPESCRIPTSUPPORTOUTOFTHEBOXITCURRENTLYDOESNTSHIPWITHTYPESCRIPT22WHICHYOUNEEDTODEVELOPANGULARAPPLICATIONS", "original": "While Visual Studio Update 3 ships with TypeScript support out of the box, it currently doesn’t ship with TypeScript 2.2, \nwhich you need to develop Angular applications.", "translation": "Visual Studio Update 3 自带 TypeScript 支持,但是它的 TypeScript 版本开发 Angular 应用需要的不是 2.2。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "TOINSTALLTYPESCRIPT22:", "original": "To install TypeScript 2.2:", "translation": "要安装 TypeScript 2.2:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "DOWNLOADANDINSTALLTYPESCRIPT22FORVISUALSTUDIO2015HTTPS:WWWMICROSOFTCOMENUSDOWNLOADDETAILSASPXID48593", "original": "* Download and install **[TypeScript 2.2 for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48593)**", "translation": "下载并安装 **[TypeScript 2.2 for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48593)**", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "ORINSTALLITWITHNPM:NPMINSTALLGTYPESCRIPT22", "original": "* OR install it with npm: `npm install -g typescript@2.2`.", "translation": "或通过 npm 安装:`npm install -g typescript@2.2`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "YOUCANFINDOUTMOREABOUTTYPESCRIPT22SUPPORTINVISUALSTUDIOHEREHTTPS:BLOGSMSDNMICROSOFTCOMTYPESCRIPT20170222ANNOUNCINGTYPESCRIPT22", "original": "You can find out more about TypeScript 2.2 support in Visual studio **[here](https://blogs.msdn.microsoft.com/typescript/2017/02/22/announcing-typescript-2-2/)**.", "translation": "你可以在**[这儿](https://blogs.msdn.microsoft.com/typescript/2017/02/22/announcing-typescript-2-2/)**查看更多 Visual Studio 中 TypeScript 2.2 的支持。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "ATTHISPOINTVISUALSTUDIOISREADYITSAGOODIDEATOCLOSEVISUALSTUDIOANDRESTARTITTOMAKESUREEVERYTHINGISCLEAN", "original": "At this point, Visual Studio is ready. It’s a good idea to close Visual Studio and \nrestart it to make sure everything is clean.", "translation": "至此,Visual Studio 已经准备好了。重新启动 Visual Studio,这样就可以有一个崭新的开始了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDDOWNLOADSTEP1:DOWNLOADTHEQUICKSTARTFILESH2", "original": "<h2 id='download'>Step 1: Download the QuickStart files</h2>", "translation": "<h2 id='download'>第一步: 现在“快速上手”文件</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "DOWNLOADTHEQUICKSTARTSOURCEHTTPS:GITHUBCOMANGULARQUICKSTARTFROMGITHUBIFYOUDOWNLOADEDASAZIPFILEEXTRACTTHEFILES", "original": "[Download the QuickStart source](https://github.com/angular/quickstart)\nfrom GitHub. If you downloaded as a zip file, extract the files.", "translation": "从 GitHub[下载“快速上手”的源代码](https://github.com/angular/quickstart)。如果下载的是一个压缩的 zip 文件,解压它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDCREATEPROJECTSTEP2:CREATETHEVISUALSTUDIOASPNETPROJECTH2", "original": "<h2 id='create-project'>Step 2: Create the Visual Studio ASP.NET project</h2>", "translation": "<h2 id='create-project'>第二步:创建 Visual Studio ASP.net 项目</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "CREATETHEASPNET4XPROJECTINTHEUSUALWAYASFOLLOWS:", "original": "Create the ASP.NET 4.x project in the usual way as follows:", "translation": "按照下列步骤创建 ASP.NET 4.x 项目:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "INVISUALSTUDIOSELECTFILENEWPROJECTFROMTHEMENU", "original": "* In Visual Studio, select `File` | `New` | `Project` from the menu.", "translation": "在 Visual Studio 中,选择 `File` | `New` | `Project` 菜单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "INTHETEMPLATETREESELECTTEMPLATESVISUALC#ORVISUALBASICWEB", "original": "* In the template tree, select `Templates` | `Visual C#` (or `Visual Basic`) | `Web`.", "translation": "在模板树中,选择 `Templates` | `Visual C#`(或 `Visual Basic`) | `Web` 菜单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "SELECTTHEASPNETWEBAPPLICATIONTEMPLATEGIVETHEPROJECTANAMEANDCLICKOK", "original": "* Select the `ASP.NET Web Application` template, give the project a name, and click OK.", "translation": "选择 `ASP.NET Web Application` 模板,输入项目名,点击“OK”按钮。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "SELECTTHEDESIREDASPNET452TEMPLATEANDCLICKOK", "original": "* Select the desired ASP.NET 4.5.2 template and click OK.", "translation": "选择自己喜欢的 ASP.NET 4.5.2 模板,点击 OK。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "THISCOOKBOOKUSESTHEEMPTYTEMPLATEWITHNOADDEDFOLDERSNOAUTHENTICATIONANDNOHOSTINGPICKTHETEMPLATEANDOPTIONSAPPROPRIATEFORYOURPROJECT", "original": "This cookbook uses the `Empty` template with no added folders, \nno authentication, and no hosting. Pick the template and options appropriate for your project.", "translation": "本烹饪宝典选择了 `Empty` 模板,它没有添加过任何目录,没有身份验证,没有服务器托管。为你的项目选择合适的模板和选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDCOPYSTEP3:COPYTHEQUICKSTARTFILESINTOTHEASPNETPROJECTFOLDERH2", "original": "<h2 id='copy'>Step 3: Copy the QuickStart files into the ASP.NET project folder</h2>", "translation": "<h2 id='copy'>第三步: 把“快速上手”的文件复制到 ASP.NET 项目所在的目录</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "COPYTHEQUICKSTARTFILESYOUDOWNLOADEDFROMGITHUBINTOTHEFOLDERCONTAININGTHECSPROJFILEINCLUDETHEFILESINTHEVISUALSTUDIOPROJECTASFOLLOWS:", "original": "Copy the QuickStart files you downloaded from GitHub into the folder containing the `.csproj` file.\nInclude the files in the Visual Studio project as follows:", "translation": "拷贝从 GitHub 下载的“快速上手”文件到包含 `.csproj` 文件的目录中。按照下面的步骤把它们加到 Visual Studio 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "CLICKTHESHOWALLFILESBUTTONINSOLUTIONEXPLORERTOREVEALALLOFTHEHIDDENFILESINTHEPROJECT", "original": "* Click the `Show All Files` button in Solution Explorer to reveal all of the hidden files in the project.", "translation": "在 Solution Explorer 中点击 `Show All Files` 按钮,显示项目中所有隐藏文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "RIGHTCLICKONEACHFOLDERFILETOBEINCLUDEDINTHEPROJECTANDSELECTINCLUDEINPROJECTMINIMALLYINCLUDETHEFOLLOWINGFOLDERFILES:", "original": "* Right-click on each folder/file to be included in the project and select `Include in Project`.\n Minimally, include the following folder/files:", "translation": "右键点击每个目录和文件,选择 `Include in Project`。\n 最少要添加下列文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "SRCAPPFOLDERANSWERNOIFASKEDTOSEARCHFORTYPESCRIPTTYPINGS", "original": "* src/app folder (answer *No* if asked to search for TypeScript Typings)", "translation": "src/app 目录(如果询问是否要搜索 TypeScript 类型,回答 *No*)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDRESTORESTEP4:RESTORETHEREQUIREDPACKAGESH2", "original": "<h2 id='restore'>Step 4: Restore the required packages</h2>", - "translation": "<h2 id='restore'> 第四步: 恢复需要的包 </h2>", + "translation": "<h2 id='restore'>第四步: 恢复需要的包 </h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "RESTORETHEPACKAGESREQUIREDFORANANGULARAPPLICATIONASFOLLOWS:", "original": "Restore the packages required for an Angular application as follows:", "translation": "按下面的步骤恢复 Angular 应用程序需要的包:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "RIGHTCLICKONTHEPACKAGEJSONFILEINSOLUTIONEXPLORERANDSELECTRESTOREPACKAGESBRTHISUSESNPMTOINSTALLALLOFTHEPACKAGESDEFINEDINTHEPACKAGEJSONFILEITMAYTAKESOMETIME", "original": "* Right-click on the `package.json` file in Solution Explorer and select `Restore Packages`.\n <br>This uses `npm` to install all of the packages defined in the `package.json` file. \n It may take some time.", "translation": "在 Solution Explorer 中右键点击 `package.json`,选择 `Restore Packages`。\n <br>这样,Visual Studio 会使用 `npm` 来安装在 `package.json` 中定义的所有包. \n 这可能需要花一点时间。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "IFDESIREDOPENTHEOUTPUTWINDOWVIEWOUTPUTTOWATCHTHENPMCOMMANDSEXECUTE", "original": "* If desired, open the Output window (`View` | `Output`) to watch the npm commands execute.", "translation": "如果愿意,打开 Output 窗口(`View` | `Output`)来监控 npm 命令的执行情况。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "IGNORETHEWARNINGS", "original": "* Ignore the warnings.", "translation": "忽略所有警告。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "WHENTHERESTOREISFINISHEDAMESSAGEINTHEBOTTOMMESSAGEBAROFVISUALSTUDIOSHOULDSAY:INSTALLINGPACKAGESCOMPLETEBEPATIENTTHISCOULDTAKEAWHILE", "original": "* When the restore is finished, a message in the bottom message bar of Visual Studio \n should say: `Installing packages complete`. Be patient. This could take a while.", "translation": "当恢复完成后,将会出现一条消息:`Installing packages complete`。耐心点,这相当耗时间。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "CLICKTHEREFRESHICONINSOLUTIONEXPLORER", "original": "* Click the `Refresh` icon in Solution Explorer.", "translation": "在 Solution Explorer 里,点击 `Refresh` 图标。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "DONOTINCLUDETHENODEMODULESFOLDERINTHEPROJECTLETITBEAHIDDENPROJECTFOLDER", "original": "* **Do not** include the `node_modules` folder in the project. Let it be a hidden project folder.", "translation": "**不要**将 `node_modules` 目录添加到项目中,让它隐藏。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "H2IDBUILDANDRUNSTEP5:BUILDANDRUNTHEAPPH2", "original": "<h2 id='build-and-run'>Step 5: Build and run the app</h2>", "translation": "<h2 id='build-and-run'>第五步:构建和运行应用</h2>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "FIRSTENSURETHATSRCINDEXHTMLISSETASTHESTARTPAGERIGHTCLICKINDEXHTMLINSOLUTIONEXPLORERANDSELECTOPTIONSETASSTARTPAGE", "original": "First, ensure that `src/index.html` is set as the start page.\nRight-click `index.html` in Solution Explorer and select option `Set As Start Page`.", "translation": "首先,确认 `src/index.html` 已被设置为开始页面。\n 在 Solution Explorer 中,右键点击 `index.html`,选择选项 `Set As Start Page`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "###TORUNINVSWITHF5", "original": "### To run in VS with F5", "translation": "### 按 F5 以在 VS 中运行", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "MOSTVISUALSTUDIODEVELOPERSLIKETOPRESSTHEF5KEYANDSEETHEIISSERVERCOMEUPTOUSETHEIISSERVERWITHTHEQUICKSTARTAPPYOUMUSTMAKETHEFOLLOWINGTHREECHANGES", "original": "Most Visual Studio developers like to press the F5 key and see the IIS server come up. \nTo use the IIS server with the QuickStart app, you must make the following three changes.", "translation": "大多数 Visual Studio 开发者喜欢按 F5 键来启动 IIS 服务器。\n要在这个《快速上手》应用中使用 IIS 服务器,你要做下列修改:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "1ININDEXHTMLCHANGEBASEHREFFROMBASEHREFTOBASEHREFSRC", "original": "1. In `index.html`, change base href from `<base href=\"/\">` to `<base href=\"/src/\">`.", "translation": "在 `index.html` 中,把基地址从 `<base href=\"/\">` 改为 `<base href=\"/src/\">` 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "2ALSOININDEXHTMLCHANGETHESCRIPTSTOUSENODEMODULESWITHASLASHINSTEADOFNODEMODULESWITHOUTTHESLASH", "original": "2. Also in `index.html`, change the scripts to use `/node_modules` with a slash \ninstead of `node_modules` without the slash.", "translation": "同样在 `index.html` 中,修改脚本来用带有斜杠的 `/node_modules` 代替不带斜杠的 `node_modules`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "3INSRCSYSTEMJSCONFIGJSNEARTHETOPOFTHEFILECHANGETHENPMPATHTONODEMODULESWITHASLASH", "original": "3. In `src/systemjs.config.js`, near the top of the file, \nchange the npm `path` to `/node_modules/` with a slash.", "translation": "在 `src/systemjs.config.js` 的顶部,把 npm 的 `path` 设置为带斜杠的 `/node_modules/`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "AFTERTHESECHANGESNPMSTARTNOLONGERWORKSYOUMUSTCHOOSETOCONFIGUREEITHERFORF5WITHIISORFORNPMSTARTWITHTHELITESERVER", "original": "After these changes, `npm start` no longer works.\nYou must choose to configure _either_ for F5 with IIS _or_ for `npm start` with the lite-server.", "translation": "做完这些修改之后,`npm start` 不再工作了。你必须选择配置为 IIS + F5,还是 `npm start` + lite-server。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "###FORAPPSTHATUSEROUTING", "original": "### For apps that use routing", "translation": "### 为了使用路由的应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "IFYOURAPPUSESROUTINGYOUNEEDTOTEACHTHESERVERTOALWAYSRETURNINDEXHTMLWHENTHEUSERASKSFORANHTMLPAGEFORREASONSEXPLAINEDINTHEDEPLOYMENTGUIDEDEPLOYMENT#FALLBACKGUIDE", "original": "If your app uses routing, you need to teach the server to always return \n`index.html` when the user asks for an HTML page\nfor reasons explained in the [Deployment](guide/deployment#fallback) guide.", "translation": "如果应用要使用路由,就要让服务器在用户要求 HTML 页面时始终返回 `index.html`。\n此中原因,在[发布](guide/deployment#fallback)一章中有解释。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "EVERYTHINGSEEMSFINEWHILEYOUMOVEABOUTWITHINTHEAPPBUTYOULLSEETHEPROBLEMRIGHTAWAYIFYOUREFRESHTHEBROWSERORPASTEALINKTOANAPPPAGECALLEDADEEPLINKINTOTHEBROWSERADDRESSBAR", "original": "Everything seems fine while you move about _within_ the app. \nBut you'll see the problem right away if you refresh the browser\nor paste a link to an app page (called a \"deep link\") into the browser address bar.", "translation": "当你在应用*内部*移动时,看起来一切正常。但是如果刷新浏览器,或者在地址栏中输入一个到具体页面的地址(也就是\"深链接\")时,问题就来了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "YOULLMOSTLIKELYGETA404PAGENOTFOUNDRESPONSEFROMTHESERVERFORANYADDRESSOTHERTHANORINDEXHTML", "original": "You'll most likely get a *404 - Page Not Found* response from the server\nfor any address other than `/` or `/index.html`.", "translation": "你很可能从服务器得到得到*404 - 页面不存在* —— 只有 `/` 或 `/index.html` 例外。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "YOUHAVETOCONFIGURETHESERVERTORETURNINDEXHTMLFORREQUESTSTOTHESEUNKNOWNPAGESTHELITESERVERDEVELOPMENTSERVERDOESOUTOFTHEBOXIFYOUVESWITCHEDOVERTOF5ANDIISYOUHAVETOCONFIGUREIISTODOITTHISSECTIONWALKSTHROUGHTHESTEPSTOADAPTTHEQUICKSTARTAPPLICATION", "original": "You have to configure the server to return `index.html` for requests to these \"unknown\" pages.\nThe `lite-server` development server does out-of-the-box.\nIf you've switched over to F5 and IIS, you have to configure IIS to do it.\nThis section walks through the steps to adapt the QuickStart application.", "translation": "你就要配置服务器,为那些\"未知\"的页面返回 `index.html`。\n`lite-server` 开发服务器内置了这项功能。如果要切换到 F5 + IIS,你就要自己来配置 IIS 实现它了。\n接下来看看对快速起步应用做配置的步骤。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "####CONFIGUREIISREWRITERULES", "original": "#### Configure IIS rewrite rules", "translation": "#### 配置 IIS 重写规则", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "VISUALSTUDIOSHIPSWITHIISEXPRESSWHICHHASTHEREWRITEMODULEBAKEDINHOWEVERIFYOUREUSINGREGULARIISYOULLHAVETOINSTALLTHEREWRITEMODULE", "original": "Visual Studio ships with IIS Express, which has the rewrite module baked in. \nHowever, if you're using regular IIS you'll have to install the rewrite \nmodule.", "translation": "Visual Studio 自带了一个 IIS Express,其中有一个重写(rewrite)模块。\n不过,如果使用标准版的 IIS ,就要自己去安装这个重写模块了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "TELLVISUALSTUDIOHOWTOHANDLEREQUESTSFORROUTEAPPPAGESBYADDINGTHESEREWRITERULESNEARTHEBOTTOMOFTHEWEBCONFIG:", "original": "Tell Visual Studio how to handle requests for route app pages by adding these \nrewrite rules near the bottom of the `web.config`:", "translation": "通过把下列重写规则添加到 `web.config` 的底部,就可以告诉 Visual Studio 如何处理到应用页面的请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "THEMATCHURLMATCHURLWILLREWRITEEVERYREQUESTYOULLHAVETOADJUSTTHISIFYOUWANTSOMEREQUESTSTOGETTHROUGHSUCHASWEBAPIREQUESTS", "original": "The match url, `<match url=\".*\" />`, will rewrite every request. You'll have to adjust this if \nyou want some requests to get through, such as web API requests.", "translation": "匹配 url `<match url=\".*\" />` 语句将会重写每一个请求。如果需要直接放行某些请求,比如一些 Web API 请求,你就必须调整它才行。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "THEURLINACTIONTYPEREWRITEURLSRCSHOULDMATCHTHEBASEHREFININDEXHTML", "original": "The URL in `<action type=\"Rewrite\" url=\"/src/\"/>` should \nmatch the base href in `index.html`.", "translation": "`<action type=\"Rewrite\" url=\"/src/\"/>` 中的 url 将会匹配 `index.html` 中的基地址(base href)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "BUILDANDLAUNCHTHEAPPWITHDEBUGGERBYCLICKINGTHERUNBUTTONORBYPRESSINGF5", "original": "Build and launch the app with debugger by clicking the **Run** button or by pressing `F5`.", "translation": "点击 **Run** 按钮或者按 `F5` 键,用调试器构建和启动应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "ITSFASTERTORUNWITHOUTTHEDEBUGGERBYPRESSINGCTRLF5", "original": "It's faster to run without the debugger by pressing `Ctrl-F5`.", "translation": "按 `Ctrl-F5` 不带调试器的运行应用,速度会更快。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "THEDEFAULTBROWSEROPENSANDDISPLAYSTHEQUICKSTARTSAMPLEAPPLICATION", "original": "The default browser opens and displays the QuickStart sample application.", "translation": "默认浏览器打开并显示《快速上手》例子应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "TRYEDITINGANYOFTHEPROJECTFILESSAVEANDREFRESHTHEBROWSERTOSEETHECHANGES", "original": "Try editing any of the project files. Save and refresh the browser to\nsee the changes.", "translation": "尝试编辑任何项目文件,*保存*并刷新浏览器来查看效果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/visual-studio-2015.md" }, { + "key": "#WEBPACK:ANINTRODUCTION", "original": "# Webpack: An Introduction", "translation": "# Webpack 简介", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKHTTPS:WEBPACKGITHUBIOISAPOPULARMODULEBUNDLERATOOLFORBUNDLINGAPPLICATIONSOURCECODEINCONVENIENTCHUNKSANDFORLOADINGTHATCODEFROMASERVERINTOABROWSER", "original": "[**Webpack**](https://webpack.github.io/) is a popular module bundler,\na tool for bundling application source code in convenient _chunks_\nand for loading that code from a server into a browser.", "translation": "[**Webpack**](https://webpack.github.io/)是一个广受欢迎的模块打包器,\n这个工具用来把程序源码打包到一些方便易用的*块*中,以便把这些代码从服务器加载到浏览器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ITSANEXCELLENTALTERNATIVETOTHESYSTEMJSAPPROACHUSEDELSEWHEREINTHEDOCUMENTATIONTHISGUIDEOFFERSATASTEOFWEBPACKANDEXPLAINSHOWTOUSEITWITHANGULARAPPLICATIONS", "original": "It's an excellent alternative to the *SystemJS* approach used elsewhere in the documentation.\nThis guide offers a taste of Webpack and explains how to use it with Angular applications.", "translation": "它是这个文档中到处使用的 *SystemJS* 的一个优秀替代品。这篇指南会浅尝 Webpack,并解释如何在 Angular 程序中使用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "#CONTENTS", "original": "# Contents", "translation": "# 目录", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WHATISWEBPACKGUIDEWEBPACK#WHATISWEBPACK", "original": "* [What is Webpack?](guide/webpack#what-is-webpack)", "translation": "[什么是 Webpack?](guide/webpack#what-is-webpack)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ENTRIESANDOUTPUTSGUIDEWEBPACK#ENTRIESOUTPUTS", "original": "* [Entries and outputs](guide/webpack#entries-outputs)", "translation": "[入口与输出](guide/webpack#entries-outputs)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "MULTIPLEBUNDLESGUIDEWEBPACK#MULTIPLEBUNDLES", "original": "* [Multiple bundles](guide/webpack#multiple-bundles)", "translation": "[多重包](guide/webpack#multiple-bundles)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "LOADERSGUIDEWEBPACK#LOADERS", "original": "* [Loaders](guide/webpack#loaders)", "translation": "[加载器](guide/webpack#loaders)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "PLUGINSGUIDEWEBPACK#PLUGINS", "original": "* [Plugins](guide/webpack#plugins)", "translation": "[插件](guide/webpack#plugins)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "CONFIGURINGWEBPACKGUIDEWEBPACK#CONFIGUREWEBPACK", "original": "* [Configuring Webpack](guide/webpack#configure-webpack)", "translation": "[配置 Webpack](guide/webpack#configure-webpack)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "COMMONCONFIGURATIONGUIDEWEBPACK#COMMONCONFIGURATION", "original": "* [Common configuration](guide/webpack#common-configuration)", "translation": "[公共配置](guide/webpack#common-configuration)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "INSIDEWEBPACKCOMMONJSGUIDEWEBPACK#INSIDEWEBPACKCOMMONJS", "original": "* [Inside `webpack.common.js`](guide/webpack#inside-webpack-commonjs)", "translation": "[深入 `webpack.common.js`](guide/webpack#inside-webpack-commonjs)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ENTRYGUIDEWEBPACK#COMMONENTRIES", "original": "* [entry](guide/webpack#common-entries)", "translation": "[入口](guide/webpack#common-entries)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "RESOLVEEXTENSIONLESSIMPORTSGUIDEWEBPACK#COMMONRESOLVES", "original": "* [resolve extension-less imports](guide/webpack#common-resolves)", "translation": "[解析无扩展名的导入](guide/webpack#common-resolves)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "PLUGINSGUIDEWEBPACK#PLUGINS", "original": "* [Plugins](guide/webpack#plugins)", "translation": "[插件](guide/webpack#plugins)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ENVIRONMENTSPECIFICCONFIGURATIONGUIDEWEBPACK#ENVIRONMENTCONFIGURATION", "original": "* [Environment specific configuration](guide/webpack#environment-configuration)", "translation": "[针对特定环境进行配置](guide/webpack#environment-configuration)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "DEVELOPMENTCONFIGURATIONGUIDEWEBPACK#DEVELOPMENTCONFIGURATION", "original": "* [Development configuration](guide/webpack#development-configuration)", "translation": "[开发环境配置](guide/webpack#development-configuration)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "PRODUCTIONCONFIGURATIONGUIDEWEBPACK#PRODUCTIONCONFIGURATION", "original": "* [Production configuration](guide/webpack#production-configuration)", "translation": "[生产环境配置](guide/webpack#production-configuration)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "TESTCONFIGURATIONGUIDEWEBPACK#TESTCONFIGURATION", "original": "* [Test configuration](guide/webpack#test-configuration)", "translation": "[测试环境配置](guide/webpack#test-configuration)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "TRYINGITOUTGUIDEWEBPACK#TRY", "original": "* [Trying it out](guide/webpack#try)", "translation": "[试一下](guide/webpack#try)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "HIGHLIGHTSGUIDEWEBPACK#HIGHLIGHTS", "original": "* [Highlights](guide/webpack#highlights)", "translation": "[重点](guide/webpack#highlights)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "CONCLUSIONGUIDEWEBPACK#CONCLUSION", "original": "* [Conclusion](guide/webpack#conclusion)", "translation": "[总结](guide/webpack#conclusion)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUCANALSOAHREFGENERATEDZIPSWEBPACKWEBPACKZIPTARGETBLANKDOWNLOADTHEFINALRESULTA", "original": "You can also <a href=\"generated/zips/webpack/webpack.zip\" target=\"_blank\">download the final result.</a>", "translation": "你还可以<a href=\"generated/zips/webpack/webpack.zip\" target=\"_blank\">点这里下载最终结果</a>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "##WHATISWEBPACK", "original": "## What is Webpack?", "translation": "## 什么是 Webpack?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKISAPOWERFULMODULEBUNDLERABUNDLEISAJAVASCRIPTFILETHATINCORPORATESASSETSTHATBELONGTOGETHERANDSHOULDBESERVEDTOTHECLIENTINARESPONSETOASINGLEFILEREQUESTABUNDLECANINCLUDEJAVASCRIPTCSSSTYLESHTMLANDALMOSTANYOTHERKINDOFFILE", "original": "Webpack is a powerful module bundler.\nA _bundle_ is a JavaScript file that incorporates _assets_ that *belong* together and\nshould be served to the client in a response to a single file request.\nA bundle can include JavaScript, CSS styles, HTML, and almost any other kind of file.", "translation": "Webpack 是一个强力的模块打包器。\n所谓*包(bundle)*就是一个 JavaScript 文件,它把一堆*资源(assets)*合并在一起,以便它们可以在同一个文件请求中发回给客户端。\n包中可以包含 JavaScript、CSS 样式、HTML 以及很多其它类型的文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKROAMSOVERYOURAPPLICATIONSOURCECODELOOKINGFORIMPORTSTATEMENTSBUILDINGADEPENDENCYGRAPHANDEMITTINGONEORMOREBUNDLESWITHPLUGINSANDRULESWEBPACKCANPREPROCESSANDMINIFYDIFFERENTNONJAVASCRIPTFILESSUCHASTYPESCRIPTSASSANDLESSFILES", "original": "Webpack roams over your application source code,\nlooking for `import` statements, building a dependency graph, and emitting one or more _bundles_.\nWith plugins and rules, Webpack can preprocess and minify different non-JavaScript files such as TypeScript, SASS, and LESS files.", "translation": "Webpack 会遍历你应用中的所有源码,查找 `import` 语句,构建出依赖图谱,并产出一个(或多个)*包*。\n通过插件和规则,Webpack 可以对各种非 JavaScript 文件进行预处理和最小化(Minify),比如 TypeScript、SASS 和 LESS 文件等。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUDETERMINEWHATWEBPACKDOESANDHOWITDOESITWITHAJAVASCRIPTCONFIGURATIONFILEWEBPACKCONFIGJS", "original": "You determine what Webpack does and how it does it with a JavaScript configuration file, `webpack.config.js`.", "translation": "你通过一个 JavaScript 配置文件 `webpack.config.js` 来决定 Webpack 做什么以及如何做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###ENTRIESANDOUTPUTS", "original": "### Entries and outputs", "translation": "### 入口与输出", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUSUPPLYWEBPACKWITHONEORMOREENTRYFILESANDLETITFINDANDINCORPORATETHEDEPENDENCIESTHATRADIATEFROMTHOSEENTRIESTHEONEENTRYPOINTFILEINTHISEXAMPLEISTHEAPPLICATIONSROOTFILESRCMAINTS:", "original": "You supply Webpack with one or more *entry* files and let it find and incorporate the dependencies that radiate from those entries.\nThe one entry point file in this example is the application's root file, `src/main.ts`:", "translation": "你给 Webpack 提供一个或多个*入口*文件,来让它查找与合并那些从这些入口点发散出去的依赖。\n在下面这个例子中,唯一的入口点文件是该应用的根文件 `src/app.ts`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKINSPECTSTHATFILEANDTRAVERSESITSIMPORTDEPENDENCIESRECURSIVELY", "original": "Webpack inspects that file and traverses its `import` dependencies recursively.", "translation": "Webpack 探查那个文件,并且递归遍历它的 `import` 依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ITSEESTHATYOUREIMPORTINGANGULARCORESOITADDSTHATTOITSDEPENDENCYLISTFORPOTENTIALINCLUSIONINTHEBUNDLEITOPENSTHEANGULARCOREFILEANDFOLLOWSITSNETWORKOFIMPORTSTATEMENTSUNTILITHASBUILTTHECOMPLETEDEPENDENCYGRAPHFROMMAINTSDOWN", "original": "It sees that you're importing `@angular/core` so it adds that to its dependency list for potential inclusion in the bundle.\nIt opens the `@angular/core` file and follows _its_ network of `import` statements until it has built the complete dependency graph from `main.ts` down.", "translation": "这里,Webpack 看到你正在导入 `@angular/core`,于是就这个文件加入到它的依赖列表里,为(有可能)把该文件打进包中做准备。\n它打开 `@angular/core` 并追踪由*该文件的*`import` 语句构成的网络,直到构建出从 `main.ts` 往下的整个依赖图谱。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THENITOUTPUTSTHESEFILESTOTHEAPPJSBUNDLEFILEDESIGNATEDINCONFIGURATION:", "original": "Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:", "translation": "然后它把这些文件**输出**到当前配置所指定的*包文件*`app.js` 中:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THISAPPJSOUTPUTBUNDLEISASINGLEJAVASCRIPTFILETHATCONTAINSTHEAPPLICATIONSOURCEANDITSDEPENDENCIESYOULLLOADITLATERWITHASCRIPTTAGINTHEINDEXHTML", "original": "This `app.js` output bundle is a single JavaScript file that contains the application source and its dependencies.\nYou'll load it later with a `<script>` tag in the `index.html`.", "translation": "这个 `app.js` 输出包是个单一的 JavaScript 文件,它包含程序的源码及其所有依赖。\n 后面你将在 `index.html` 中用 `<script>` 标签来加载它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "####MULTIPLEBUNDLES", "original": "#### Multiple bundles", "translation": "#### 多重包", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUPROBABLYDONTWANTONEGIANTBUNDLEOFEVERYTHINGITSPREFERABLETOSEPARATETHEVOLATILEAPPLICATIONAPPCODEFROMCOMPARATIVELYSTABLEVENDORCODEMODULES", "original": "You probably don't want one giant bundle of everything.\nIt's preferable to separate the volatile application app code from comparatively stable vendor code modules.", "translation": "你可能不会希望把所有东西打进一个巨型包,而更喜欢把多变的应用代码从相对稳定的第三方提供商模块中分离出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "CHANGETHECONFIGURATIONSOTHATITHASTWOENTRYPOINTSMAINTSANDVENDORTS:", "original": "Change the configuration so that it has two entry points, `main.ts` and `vendor.ts`:", "translation": "所以要修改配置,以获得两个入口点:`main.ts` 和 `vendor.ts`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKCONSTRUCTSTWOSEPARATEDEPENDENCYGRAPHSANDEMITSTWOBUNDLEFILESONECALLEDAPPJSCONTAININGONLYTHEAPPLICATIONCODEANDANOTHERCALLEDVENDORJSWITHALLTHEVENDORDEPENDENCIES", "original": "Webpack constructs two separate dependency graphs\nand emits *two* bundle files, one called `app.js` containing only the application code and\nanother called `vendor.js` with all the vendor dependencies.", "translation": "Webpack 会构造出两个独立的依赖图谱,并产出*两个*包文件:一个叫做 `app.js`,它只包含应用的代码;另一个叫做 `vendor.js`,它包含所有的提供商依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THENAMEINTHEOUTPUTNAMEISAPLACEHOLDERTHATAWEBPACKPLUGINREPLACESWITHTHEENTRYNAMESAPPANDVENDORPLUGINSARECOVEREDLATERGUIDEWEBPACK#COMMONSCHUNKPLUGININTHEGUIDE", "original": "The `[name]` in the output name is a *placeholder* that a Webpack plugin replaces with the entry names,\n`app` and `vendor`. Plugins are [covered later](guide/webpack#commons-chunk-plugin) in the guide.", "translation": "在输出文件名中出现的 `[name]` 是一个 Webpack 的*占位符*,它将被一个 Webpack 插件替换为入口点的名字,分别是 `app` 和 `vendor`。插件在本章的[稍后部分](guide/webpack#commons-chunk-plugin)讲解。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "TOTELLWEBPACKWHATBELONGSINTHEVENDORBUNDLEADDAVENDORTSFILETHATONLYIMPORTSTHEAPPLICATIONSTHIRDPARTYMODULES:", "original": "To tell Webpack what belongs in the vendor bundle,\nadd a `vendor.ts` file that only imports the application's third-party modules:", "translation": "要想告诉 Webpack 哪些文件属于 vendor 包,可以添加一个 `vendor.ts` 文件,它只导入该应用的第三方模块:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###LOADERS", "original": "### Loaders", "translation": "### 加载器(Loader)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKCANBUNDLEANYKINDOFFILE:JAVASCRIPTTYPESCRIPTCSSSASSLESSIMAGESHTMLFONTSWHATEVERWEBPACKITSELFONLYUNDERSTANDSJAVASCRIPTFILESTEACHITTOTRANSFORMNONJAVASCRIPTFILEINTOTHEIRJAVASCRIPTEQUIVALENTSWITHLOADERSCONFIGURELOADERSFORTYPESCRIPTANDCSSASFOLLOWS", "original": "Webpack can bundle any kind of file: JavaScript, TypeScript, CSS, SASS, LESS, images, HTML, fonts, whatever.\nWebpack _itself_ only understands JavaScript files.\nTeach it to transform non-JavaScript file into their JavaScript equivalents with *loaders*.\nConfigure loaders for TypeScript and CSS as follows.", "translation": "Webpack 可以打包任何类型的文件:JavaScript、TypeScript、CSS、SASS、LESS、图片、HTML 以及字体文件等等。\n但 Webpack*本身*只认识 JavaScript 文件。\n要通过*加载器*来告诉它如何把这些文件处理成 JavaScript 文件。\n再为 TypeScript 和 CSS 文件配置如下加载器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WHENWEBPACKENCOUNTERSIMPORTSTATEMENTSLIKETHEFOLLOWINGITAPPLIESTHETESTREGEXPATTERNS", "original": "When Webpack encounters `import` statements like the following,\nit applies the `test` RegEx patterns.", "translation": "当 Webpack 遇到如下所示的 `import` 语句时,它就会调用正则表达式的 `test` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WHENAPATTERNMATCHESTHEFILENAMEWEBPACKPROCESSESTHEFILEWITHTHEASSOCIATEDLOADER", "original": "When a pattern matches the filename, Webpack processes the file with the associated loader.", "translation": "如果一个模式匹配上文件名,Webpack 就用它所关联的加载器处理这个文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEFIRSTIMPORTFILEMATCHESTHETSPATTERNSOWEBPACKPROCESSESITWITHTHEAWESOMETYPESCRIPTLOADERTHEIMPORTEDFILEDOESNTMATCHTHESECONDPATTERNSOITSLOADERISIGNORED", "original": "The first `import` file matches the `.ts` pattern so Webpack processes it with the `awesome-typescript-loader`.\nThe imported file doesn't match the second pattern so its loader is ignored.", "translation": "第一个 `import` 文件匹配上了 `.ts` 模式,于是 Webpack 就用 `awesome-typescript-loader` 加载器处理它。\n导入的文件没有匹配上第二个模式,于是它的加载器就被忽略了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THESECONDIMPORTMATCHESTHESECONDCSSPATTERNFORWHICHYOUHAVETWOLOADERSCHAINEDBYTHECHARACTERWEBPACKAPPLIESCHAINEDLOADERSRIGHTTOLEFTSOITAPPLIESTHECSSLOADERFIRSTTOFLATTENCSSIMPORTANDURLSTATEMENTSTHENITAPPLIESTHESTYLELOADERTOAPPENDTHECSSINSIDESTYLEELEMENTSONTHEPAGE", "original": "The second `import` matches the second `.css` pattern for which you have *two* loaders chained by the (!) character.\nWebpack applies chained loaders *right to left*. So it applies\nthe `css` loader first to flatten CSS `@import` and `url(...)` statements.\nThen it applies the `style` loader to append the css inside `<style>` elements on the page.", "translation": "第二个 `import` 匹配上了第二个 `.css` 模式,它有两个用叹号字符(`!`)串联起来的加载器。\nWebpack 会*从右到左*逐个应用串联的加载器,于是它先应用了 `css` 加载器(用来平面化 CSS 的 `@import` 和 `url(...)` 语句),\n然后应用了 `style` 加载器(用来把 css 追加到页面上的*<style>*元素中)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###PLUGINS", "original": "### Plugins", "translation": "### 插件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKHASABUILDPIPELINEWITHWELLDEFINEDPHASESTAPINTOTHATPIPELINEWITHPLUGINSSUCHASTHEUGLIFYMINIFICATIONPLUGIN:", "original": "Webpack has a build pipeline with well-defined phases.\nTap into that pipeline with plugins such as the `uglify` minification plugin:", "translation": "Webpack 有一条构建流水线,它被划分成多个经过精心定义的阶段(phase)。\n可以把插件(比如 `uglify` 代码最小化插件)挂到流水线上:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "##CONFIGURINGWEBPACK", "original": "## Configuring Webpack", "translation": "## 配置 Webpack", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "AFTERTHATBRIEFORIENTATIONYOUAREREADYTOBUILDYOUROWNWEBPACKCONFIGURATIONFORANGULARAPPS", "original": "After that brief orientation, you are ready to build your own Webpack configuration for Angular apps.", "translation": "经过简短的培训之后,你已经准备好为 Angular 应用构建一份自己的 Webpack 配置了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "BEGINBYSETTINGUPTHEDEVELOPMENTENVIRONMENT", "original": "Begin by setting up the development environment.", "translation": "从设置开发环境开始。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "CREATEANEWPROJECTFOLDER", "original": "Create a new project folder.", "translation": "创建一个新的项目文件夹。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ADDTHESEFILES:", "original": "Add these files:", "translation": "添加下列文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "MANYOFTHESEFILESSHOULDBEFAMILIARFROMOTHERANGULARDOCUMENTATIONGUIDESESPECIALLYTHETYPESCRIPTCONFIGURATIONGUIDETYPESCRIPTCONFIGURATIONANDNPMPACKAGESGUIDENPMPACKAGESGUIDES", "original": "Many of these files should be familiar from other Angular documentation guides,\nespecially the [Typescript configuration](guide/typescript-configuration) and\n[npm packages](guide/npm-packages) guides.", "translation": "这些文件很多都很眼熟,它们在其他文档里已经出现过,特别是[_TypeScript 配置_](guide/typescript-configuration)和[_npm 包_](guide/npm-packages)这两章里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKTHEPLUGINSANDTHELOADERSAREALSOINSTALLEDASPACKAGESTHEYARELISTEDINTHEUPDATEDPACKAGESJSON", "original": "Webpack, the plugins, and the loaders are also installed as packages.\nThey are listed in the updated `packages.json`.", "translation": "Webpack,包括它的插件以及加载器,也是以 npm 包的形式安装的,它们也列在了修改后的 package.json 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "OPENATERMINALWINDOWANDINSTALLTHENPMPACKAGES", "original": "Open a terminal window and install the npm packages.", "translation": "打开命令行窗口并安装这些 *npm* 包", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###POLYFILLS", "original": "### Polyfills", "translation": "### Polyfills 腻子脚本", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOULLNEEDPOLYFILLSTORUNANANGULARAPPLICATIONINMOSTBROWSERSASEXPLAINEDINTHEBROWSERSUPPORTGUIDEBROWSERSUPPORTGUIDE", "original": "You'll need polyfills to run an Angular application in most browsers as explained\nin the [Browser Support](guide/browser-support) guide.", "translation": "要让 Angular 应用能在大多数的浏览器里运行,它还需要一些腻子脚本,参见[浏览器支持](guide/browser-support)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "POLYFILLSSHOULDBEBUNDLEDSEPARATELYFROMTHEAPPLICATIONANDVENDORBUNDLESADDAPOLYFILLSTSLIKETHISONETOTHESRCFOLDER", "original": "Polyfills should be bundled separately from the application and vendor bundles.\nAdd a `polyfills.ts` like this one to the `src/` folder.", "translation": "Polyfills 最好跟应用代码和 vendor 代码区分开来单独打包。在 `src/` 文件夹里添加一个 `polyfills.ts` 文件,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "HEADERLOADINGPOLYFILLSHEADER", + "original": "<header>Loading polyfills</header>", + "translation": "<header>加载腻子脚本</header>", + "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" + }, + { + "key": "LOADZONEJSEARLYWITHINPOLYFILLSTSIMMEDIATELYAFTERTHEOTHERES6ANDMETADATASHIMS", "original": "Load `zone.js` early within `polyfills.ts`, immediately after the other ES6 and metadata shims.", "translation": "`polyfills.ts` 文件里,`zone.js` 库须尽早引入,紧跟在 ES6 shims 和 metadata shims 之后。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "BECAUSETHISBUNDLEFILEWILLLOADFIRSTPOLYFILLSTSISALSOAGOODPLACETOCONFIGURETHEBROWSERENVIRONMENTFORPRODUCTIONORDEVELOPMENT", "original": "Because this bundle file will load first, `polyfills.ts` is also a good place to configure the browser environment\nfor production or development.", "translation": "由于这个包最先加载,所以 `polyfills.ts` 非常适合用来配置浏览器环境,如生产环境配置或是开发环境。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###COMMONCONFIGURATION", "original": "### Common configuration", "translation": "### 通用配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "DEVELOPERSTYPICALLYHAVESEPARATECONFIGURATIONSFORDEVELOPMENTPRODUCTIONANDTESTENVIRONMENTSALLTHREEHAVEALOTOFCONFIGURATIONINCOMMON", "original": "Developers typically have separate configurations for development, production, and test environments.\nAll three have a lot of configuration in common.", "translation": "开发、生产、测试等不同的环境通常会分开配置,但实际上这些配置也有很多地方是通用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "GATHERTHECOMMONCONFIGURATIONINAFILECALLEDWEBPACKCOMMONJS", "original": "Gather the common configuration in a file called `webpack.common.js`.", "translation": "把这些通用的配置收归到一个文件,命名为 `webpack.common.js`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###INSIDEWEBPACKCOMMONJS", "original": "### Inside _webpack.common.js_", "translation": "### webpack.common.js 解读", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKISANODEJSBASEDTOOLTHATREADSCONFIGURATIONFROMAJAVASCRIPTCOMMONJSMODULEFILE", "original": "Webpack is a NodeJS-based tool that reads configuration from a JavaScript commonjs module file.", "translation": "Webpack 是基于 NodeJS 的一个工具,它能够从一个 *commonjs* 规范的 JavaScript 模块文件里读取配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THECONFIGURATIONIMPORTSDEPENDENCIESWITHREQUIRESTATEMENTSANDEXPORTSSEVERALOBJECTSASPROPERTIESOFAMODULEEXPORTSOBJECT", "original": "The configuration imports dependencies with `require` statements\nand exports several objects as properties of a `module.exports` object.", "translation": "这个配置文件是通过 `require` 语句导入依赖,然后将多个对象作为 `module.exports` 对象的属性导出。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ENTRYGUIDEWEBPACK#COMMONENTRIESMDASHTHEENTRYPOINTFILESTHATDEFINETHEBUNDLES", "original": "* [`entry`](guide/webpack#common-entries)—the entry-point files that define the bundles.", "translation": "[`entries`](guide/webpack#common-entries) - 包体的入口文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "RESOLVEGUIDEWEBPACK#COMMONRESOLVESMDASHHOWTORESOLVEFILENAMESWHENTHEYLACKEXTENSIONS", "original": "* [`resolve`](guide/webpack#common-resolves)—how to resolve file names when they lack extensions.", "translation": "[`resolve`](guide/webpack#common-resolves) - 省略扩展名时如何解释文件名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "MODULERULESGUIDEWEBPACK#COMMONRULESMDASHMODULEISANOBJECTWITHRULESFORDECIDINGHOWFILESARELOADED", "original": "* [`module.rules`](guide/webpack#common-rules)— `module` is an object with `rules` for deciding how files are loaded.", "translation": "[`module.rules`](guide/webpack#common-rules) - `module` 是一个对象,里面的 `rules` 属性用来决定文件如何加载。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "PLUGINSGUIDEWEBPACK#COMMONPLUGINSMDASHCREATESINSTANCESOFTHEPLUGINS", "original": "* [`plugins`](guide/webpack#common-plugins)—creates instances of the plugins.", "translation": "[`plugins`](guide/webpack#common-plugins) - 创建插件的实例。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "####ENTRY", "original": "#### _entry_", "translation": "#### _entry_ 入口", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEFIRSTEXPORTISTHEENTRYOBJECT:", "original": "The first export is the `entry` object:", "translation": "如上所述,第一个导出的对象是 *entries*:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THISENTRYOBJECTDEFINESTHETHREEBUNDLES:", "original": "This `entry` object defines the three bundles:", "translation": "`entry` 对象定义了三个包:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "POLYFILLSMDASHTHEPOLYFILLSNEEDEDTORUNANGULARAPPLICATIONSINMOSTMODERNBROWSERS", "original": "* `polyfills`—the polyfills needed to run Angular applications in most modern browsers.", "translation": "`polyfills` - 使得 Angular 应用能够运行在大多数的现代浏览器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "VENDORMDASHTHETHIRDPARTYDEPENDENCIESSUCHASANGULARLODASHANDBOOTSTRAPCSS", "original": "* `vendor`—the third-party dependencies such as Angular, lodash, and bootstrap.css.", "translation": "`vendor` - 第三方依赖,如 Angular、lodash 和 bootstrap.css。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "APPMDASHTHEAPPLICATIONCODE", "original": "* `app`—the application code.", "translation": "`app` - 应用代码。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "####RESOLVEEXTENSIONLESSIMPORTS", "original": "#### _resolve_ extension-less imports", "translation": "#### _resolve_ 无扩展名的文件导入", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEAPPWILLIMPORTDOZENSIFNOTHUNDREDSOFJAVASCRIPTANDTYPESCRIPTFILESYOUCOULDWRITEIMPORTSTATEMENTSWITHEXPLICITEXTENSIONSLIKETHISEXAMPLE:", "original": "The app will `import` dozens if not hundreds of JavaScript and TypeScript files.\nYou could write `import` statements with explicit extensions like this example:", "translation": "如果你的应用程序只须 `import` 几十个 JavaScript 或 TypeScript 文件,而不是几百个,你可以在 `import` 语句里完整写上扩展名,如:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "BUTMOSTIMPORTSTATEMENTSDONTMENTIONTHEEXTENSIONATALLTELLWEBPACKTORESOLVEEXTENSIONLESSFILEREQUESTSBYLOOKINGFORMATCHINGFILESWITHTSEXTENSIONORJSEXTENSIONFORREGULARJAVASCRIPTFILESANDPRECOMPILEDTYPESCRIPTFILES", "original": "But most `import` statements don't mention the extension at all.\nTell Webpack to resolve extension-less file requests by looking for matching files with\n`.ts` extension or `.js` extension (for regular JavaScript files and pre-compiled TypeScript files).", "translation": "但实际上大部分 `import` 语句都不带扩展名,可以告诉 Webpack,在查找这些没有扩展名的文件时,自动加上 `.ts` 或者 `.js` 扩展名来匹配。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "IFWEBPACKSHOULDRESOLVEEXTENSIONLESSFILESFORSTYLESANDHTMLADDCSSANDHTMLTOTHELIST", "original": "If Webpack should resolve extension-less files for styles and HTML,\nadd `.css` and `.html` to the list.", "translation": "如果要让 Webapck 也能解析那些不带扩展名的样式和 HTML 文件,在列表里追加 `.css` 和 `.html` 即可。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "####MODULERULES", "original": "#### _module.rules_", "translation": "#### _module.rules_ 规则", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "RULESTELLWEBPACKWHICHLOADERSTOUSEFOREACHFILEORMODULE:", "original": "Rules tell Webpack which loaders to use for each file, or module:", "translation": "Rules 用来告诉 Webpack 加载不同文件或模块时该用哪个加载器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "AWESOMETYPESCRIPTLOADERMDASHALOADERTOTRANSPILETHETYPESCRIPTCODETOES5GUIDEDBYTHETSCONFIGJSONFILE", "original": "* `awesome-typescript-loader`—a loader to transpile the Typescript code to ES5, guided by the `tsconfig.json` file.", "translation": "`awesome-typescript-loader` - 一个用于把 TypeScript 代码转译成 ES5 的加载器,它会由 `tsconfig.json` 文件提供指导", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ANGULAR2TEMPLATELOADERMDASHLOADSANGULARCOMPONENTSTEMPLATEANDSTYLES", "original": "* `angular2-template-loader`—loads angular components' template and styles.", "translation": "`angular2-template-loader` - 用于加载 Angular 组件的模板和样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "HTMLLOADERMDASHFORCOMPONENTTEMPLATES", "original": "* `html-loader`—for component templates.", "translation": "`html-loader` - 为组件模板准备的加载器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "IMAGESFONTSMDASHIMAGESANDFONTSAREBUNDLEDASWELL", "original": "* images/fonts—Images and fonts are bundled as well.", "translation": "`images/fonts` - 图片和字体文件也能被打包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "CSSMDASHTHEFIRSTPATTERNMATCHESAPPLICATIONWIDESTYLESTHESECONDHANDLESCOMPONENTSCOPEDSTYLESTHEONESSPECIFIEDINACOMPONENTSSTYLEURLSMETADATAPROPERTY", "original": "* CSS—the first pattern matches application-wide styles; the second handles\ncomponent-scoped styles (the ones specified in a component's `styleUrls` metadata property).", "translation": "CSS - 第一个模式匹配应用级样式,第二个模式匹配组件局部样式(就是在组件元数据的 `styleUrls` 属性中指定的那些)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEFIRSTPATTERNISFORTHEAPPLICATIONWIDESTYLESITEXCLUDESCSSFILESWITHINTHESRCAPPDIRECTORYWHERETHECOMPONENTSCOPEDSTYLESSITTHEEXTRACTTEXTPLUGINDESCRIBEDBELOWAPPLIESTHESTYLEANDCSSLOADERSTOTHESEFILES", "original": "The first pattern is for the application-wide styles. It excludes `.css` files within the `src/app` directory\nwhere the component-scoped styles sit. The `ExtractTextPlugin` (described below) applies the `style` and `css`\nloaders to these files.", "translation": "第一个模式是给全局样式使用的,它排除了 `/src/app` 目录下的 `.css` 文件,因为那里是组件的局部样式。\n它只包含了那些位于 `/src/app` 及其上级目录的 `.css` 文件,那里是应用级样式。\n`ExtractTextPlugin`(后面会讲到)使用 `style` 和 `css` 加载器来处理这些文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THESECONDPATTERNFILTERSFORCOMPONENTSCOPEDSTYLESANDLOADSTHEMASSTRINGSVIATHERAWLOADERWHICHISWHATANGULAREXPECTSTODOWITHSTYLESSPECIFIEDINASTYLEURLSMETADATAPROPERTY", "original": "The second pattern filters for component-scoped styles and loads them as strings via the `raw-loader`,\nwhich is what Angular expects to do with styles specified in a `styleUrls` metadata property.", "translation": "第二个模式过滤器是给组件局部样式的,并通过 `raw` 加载器把它们加载成字符串 —— 那是 Angular 期望通过元数据的 `styleUrls` 属性来指定样式的形式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "MULTIPLELOADERSCANBECHAINEDUSINGTHEARRAYNOTATION", "original": "Multiple loaders can be chained using the array notation.", "translation": "多重加载器也能使用数组形式串联起来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "####PLUGINS", "original": "#### _plugins_", "translation": "#### *插件*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "FINALLYCREATEINSTANCESOFTHREEPLUGINS:", "original": "Finally, create instances of three plugins:", "translation": "最后,创建三个插件实例:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "####COMMONSCHUNKPLUGIN", "original": "#### *CommonsChunkPlugin*", "translation": "#### *CommonsChunkPlugin* 插件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEAPPJSBUNDLESHOULDCONTAINONLYAPPLICATIONCODEALLVENDORCODEBELONGSINTHEVENDORJSBUNDLE", "original": "The `app.js` bundle should contain only application code. All vendor code belongs in the `vendor.js` bundle.", "translation": "`app.js` 包应该只包含应用代码。所有第三方代码都应该放进 `vendor.js` 包中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "OFCOURSETHEAPPLICATIONCODEIMPORTSVENDORCODEONITSOWNWEBPACKISNOTSMARTENOUGHTOKEEPTHEVENDORCODEOUTOFTHEAPPJSBUNDLETHECOMMONSCHUNKPLUGINDOESTHATJOB", "original": "Of course the application code imports vendor code.\nOn its own, Webpack is not smart enough to keep the vendor code out of the `app.js` bundle.\nThe `CommonsChunkPlugin` does that job.", "translation": "当然,应用代码中还是要 `imports` 第三方代码。\nWebpack 还没有智能到自动把提供商代码排除在 `app.js` 包之外的程度。\n`CommonsChunkPlugin` 插件能完成此工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THECOMMONSCHUNKPLUGINIDENTIFIESTHEHIERARCHYAMONGTHREECHUNKS:APPVENDORPOLYFILLSWHEREWEBPACKFINDSTHATAPPHASSHAREDDEPENDENCIESWITHVENDORITREMOVESTHEMFROMAPPITWOULDREMOVEPOLYFILLSFROMVENDORIFTHEYSHAREDDEPENDENCIESWHICHTHEYDONT", "original": "The `CommonsChunkPlugin` identifies the hierarchy among three _chunks_: `app` -> `vendor` -> `polyfills`.\nWhere Webpack finds that `app` has shared dependencies with `vendor`, it removes them from `app`.\nIt would remove `polyfills` from `vendor` if they shared dependencies, which they don't.", "translation": "`CommonsChunkPlugin` 标记出了三个*块*之间的等级体系:`app` -> `vendor` -> `polyfills`。\n当 Webpack 发现 `app` 与 `vendor` 有共享依赖时,就把它们从 `app` 中移除。\n在 `vendor` 和 `polyfills` 之间有共享依赖时也同样如此(虽然它们没啥可共享的)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "####HTMLWEBPACKPLUGIN", "original": "#### _HtmlWebpackPlugin_", "translation": "#### _HtmlWebpackPlugin_ 插件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKGENERATESANUMBEROFJSANDCSSFILESYOUCOULDINSERTTHEMINTOTHEINDEXHTMLMANUALLYTHATWOULDBETEDIOUSANDERRORPRONEWEBPACKCANINJECTTHOSESCRIPTSANDLINKSFORYOUWITHTHEHTMLWEBPACKPLUGIN", "original": "Webpack generates a number of js and CSS files.\nYou _could_ insert them into the `index.html` _manually_. That would be tedious and error-prone.\nWebpack can inject those scripts and links for you with the `HtmlWebpackPlugin`.", "translation": "Webpack 生成了一些 js 和 css 文件。\n虽然你*可以手动*把它们插入到 `index.html` 中,但那样既枯燥又容易出错。\nWebpack 可以通过 `HtmlWebpackPlugin` 自动为你注入那些 `script` 和 `link` 标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###ENVIRONMENTSPECIFICCONFIGURATION", "original": "### Environment-specific configuration", "translation": "### 环境相关的配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEWEBPACKCOMMONJSCONFIGURATIONFILEDOESMOSTOFTHEHEAVYLIFTINGCREATESEPARATEENVIRONMENTSPECIFICCONFIGURATIONFILESTHATBUILDONWEBPACKCOMMONBYMERGINGINTOITTHEPECULIARITIESPARTICULARTOTHETARGETENVIRONMENTS", "original": "The `webpack.common.js` configuration file does most of the heavy lifting.\nCreate separate, environment-specific configuration files that build on `webpack.common`\nby merging into it the peculiarities particular to the target environments.", "translation": "`webpack.common.js` 配置做了大部分繁重的工作。\n通过合并它们特有的配置,就可以基于 `webpack.common` 为目标环境创建独立的、环境相关的配置文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THESEFILESTENDTOBESHORTANDSIMPLE", "original": "These files tend to be short and simple.", "translation": "这些文件越小越简单越好。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###DEVELOPMENTCONFIGURATION", "original": "### Development configuration", "translation": "### 开发环境配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "HEREISTHEWEBPACKDEVJSDEVELOPMENTCONFIGURATIONFILE", "original": "Here is the `webpack.dev.js` development configuration file.", "translation": "下面是开发环境的而配置文件 `webpack.dev.js`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEDEVELOPMENTBUILDRELIESONTHEWEBPACKDEVELOPMENTSERVERCONFIGUREDNEARTHEBOTTOMOFTHEFILE", "original": "The development build relies on the Webpack development server, configured near the bottom of the file.", "translation": "开发环境下的构建依赖于 Webpack 的开发服务器,它是在靠近文件底部的地方配置的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "ALTHOUGHYOUTELLWEBPACKTOPUTOUTPUTBUNDLESINTHEDISTFOLDERTHEDEVSERVERKEEPSALLBUNDLESINMEMORYITDOESNTWRITETHEMTODISKYOUWONTFINDANYFILESINTHEDISTFOLDERATLEASTNOTANYGENERATEDFROMTHISDEVELOPMENTBUILD", "original": "Although you tell Webpack to put output bundles in the `dist` folder,\nthe dev server keeps all bundles in memory; it doesn't write them to disk.\nYou won't find any files in the `dist` folder, at least not any generated from *this development build*.", "translation": "虽然你告诉 Webpack 把输出包放到 `dist` 目录,但实际上开发服务器把这些包都放在了内存里,而不会把它们写到硬盘中。\n所以在 `dist` 目录下是找不到任何文件的(至少现在这个开发环境下构建时没有)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEHTMLWEBPACKPLUGINADDEDINWEBPACKCOMMONJSUSESTHEPUBLICPATHANDTHEFILENAMESETTINGSTOGENERATEAPPROPRIATESCRIPTANDLINKTAGSINTOTHEINDEXHTML", "original": "The `HtmlWebpackPlugin`, added in `webpack.common.js`, uses the `publicPath` and the `filename` settings to generate\nappropriate `<script>` and `<link>` tags into the `index.html`.", "translation": "`HtmlWebpackPlugin`(由 `webpack.common.js` 引入)插件使用了*`publicPath`*和*`filename`*设置,\n来向 `index.html` 中插入适当的<script>和<link>标签。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THECSSSTYLESAREBURIEDINSIDETHEJAVASCRIPTBUNDLESBYDEFAULTTHEEXTRACTTEXTPLUGINEXTRACTSTHEMINTOEXTERNALCSSFILESTHATTHEHTMLWEBPACKPLUGININSCRIBESASLINKTAGSINTOTHEINDEXHTML", "original": "The CSS styles are buried inside the Javascript bundles by default. The `ExtractTextPlugin` extracts them into\nexternal `.css` files that the `HtmlWebpackPlugin` inscribes as `<link>` tags into the `index.html`.", "translation": "默认情况下,这些 CSS 样式会被埋没在 JavaScript 包中。`ExtractTextPlugin` 会把它们提取成外部 `.css` 文件,\n这样 `HtmlWebpackPlugin` 插件就会转而把一个<link>标签写进 `index.html` 了。Refer to the [Webpack documentation](https://webpack.github.io/docs/) for details on these and \nother configuration options in this file.要了解本文件中这些以及其它配置项的详情,请参阅[Webpack 文档](https://webpack.github.io/docs/)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "REFERTOTHEWEBPACKDOCUMENTATIONHTTPS:WEBPACKGITHUBIODOCSFORDETAILSONTHESEANDOTHERCONFIGURATIONOPTIONSINTHISFILE", "original": "Refer to the [Webpack documentation](https://webpack.github.io/docs/) for details on these and\nother configuration options in this file.", "translation": "要想了解本文件中的这些配置项和其它配置项的详情,请参阅 [Webpack 官方文档](https://webpack.github.io/docs/)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "GRABTHEAPPCODEATTHEENDOFTHISGUIDEANDTRY:", "original": "Grab the app code at the end of this guide and try:", "translation": "抓取本指南底部的应用代码,并试一试:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###PRODUCTIONCONFIGURATION", "original": "### Production configuration", - "translation": "### 产品环境配置", + "translation": "### 生产环境配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "CONFIGURATIONOFAPRODUCTIONBUILDRESEMBLESDEVELOPMENTCONFIGURATIONWITHAFEWKEYCHANGES", "original": "Configuration of a *production* build resembles *development* configuration with a few key changes.", - "translation": "*产品环境*下的配置和*开发环境*下的配置很相似……除了一些关键的改动。", + "translation": "*生产环境*下的配置和*开发环境*下的配置很相似……除了一些关键的改动。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOULLDEPLOYTHEAPPLICATIONANDITSDEPENDENCIESTOAREALPRODUCTIONSERVERYOUWONTDEPLOYTHEARTIFACTSNEEDEDONLYINDEVELOPMENT", "original": "You'll deploy the application and its dependencies to a real production server.\nYou won't deploy the artifacts needed only in development.", "translation": "你希望把应用程序及其依赖都部署到一个真实的产品服务器中。\n而不希望部署那些只在开发环境下才用得到的依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "PUTTHEPRODUCTIONOUTPUTBUNDLEFILESINTHEDISTFOLDER", "original": "Put the production output bundle files in the `dist` folder.", - "translation": "把产品环境的输出包放在 `dist` 目录下。", + "translation": "把生产环境的输出包放在 `dist` 目录下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "WEBPACKGENERATESFILENAMESWITHCACHEBUSTINGHASHTHANKSTOTHEHTMLWEBPACKPLUGINYOUDONTHAVETOUPDATETHEINDEXHTMLFILEWHENTHEHASHCHANGES", "original": "Webpack generates file names with cache-busting hash.\nThanks to the `HtmlWebpackPlugin`, you don't have to update the `index.html` file when the hash changes.", "translation": "Webpack 生成的文件名中带有“缓存无效哈希(cache-busting hash)”。\n感谢 `HtmlWebpackPlugin` 插件,当这些哈希值变化时,你就不用去修改 `index.html` 了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEREAREADDITIONALPLUGINS:", "original": "There are additional plugins:", "translation": "还有一些别的插件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "NOEMITONERRORSPLUGINMDASHSTOPSTHEBUILDIFTHEREISANERROR", "original": "* *`NoEmitOnErrorsPlugin`—stops the build if there is an error.", "translation": "*`NoEmitOnErrorsPlugin`* - 如果出错就停止构建。*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "UGLIFYJSPLUGINMDASHMINIFIESTHEBUNDLES", "original": "* *`UglifyJsPlugin`—minifies the bundles.", "translation": "*`UglifyJsPlugin`* - 最小化(minify)生成的包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "EXTRACTTEXTPLUGINMDASHEXTRACTSEMBEDDEDCSSASEXTERNALFILESADDINGCACHEBUSTINGHASHTOTHEFILENAME", "original": "* *`ExtractTextPlugin`—extracts embedded css as external files, adding cache-busting hash to the filename.", "translation": "*`ExtractTextPlugin`* - 把内嵌的 css 抽取成外部文件,并为其文件名添加“缓存无效哈希”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "DEFINEPLUGINMDASHUSETODEFINEENVIRONMENTVARIABLESTHATYOUCANREFERENCEWITHINTHEAPPLICATION", "original": "* *`DefinePlugin`—use to define environment variables that you can reference within the application.", "translation": "*`DefinePlugin`* - 用来定义环境变量,以便你在自己的程序中引用它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "LOADEROPTIONSPLUGINSMDASHTOOVERRIDEOPTIONSOFCERTAINLOADERS", "original": "* *`LoaderOptionsPlugins`—to override options of certain loaders.", "translation": "*`LoaderOptionsPlugins`* - 为特定的加载器提供选项。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THANKSTOTHEDEFINEPLUGINANDTHEENVVARIABLEDEFINEDATTOPYOUCANENABLEANGULARPRODUCTIONMODELIKETHIS:", "original": "Thanks to the `DefinePlugin` and the `ENV` variable defined at top, you can enable Angular production mode like this:", "translation": "感谢 *DefinePlugin* 和顶部定义的 `ENV` 变量,你就可以像这样启用 Angular 的产品模式了:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "GRABTHEAPPCODEATTHEENDOFTHISGUIDEANDTRY:", "original": "Grab the app code at the end of this guide and try:", "translation": "抓取本指南底部的应用代码,并试一试:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "###TESTCONFIGURATION", "original": "### Test configuration", "translation": "### 测试环境配置", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUDONTNEEDMUCHCONFIGURATIONTORUNUNITTESTSYOUDONTNEEDTHELOADERSANDPLUGINSTHATYOUDECLAREDFORYOURDEVELOPMENTANDPRODUCTIONBUILDSYOUPROBABLYDONTNEEDTOLOADANDPROCESSTHEAPPLICATIONWIDESTYLESFILESFORUNITTESTSANDDOINGSOWOULDSLOWYOUDOWNYOULLUSETHENULLLOADERFORTHOSECSSFILES", "original": "You don't need much configuration to run unit tests.\nYou don't need the loaders and plugins that you declared for your development and production builds.\nYou probably don't need to load and process the application-wide styles files for unit tests and doing so would slow you down;\nyou'll use the `null` loader for those CSS files.", - "translation": "你并不需要使用很多配置项来运行单元测试。\n也不需要在开发环境和产品环境下引入的那些加载器和插件。\n如果有可能拖慢执行速度,甚至都不需要在单元测试中加载和处理应用全局样式文件,所以你用一个 `null` 加载器来处理所有 CSS。", + "translation": "你并不需要使用很多配置项来运行单元测试。\n也不需要在开发环境和生产环境下引入的那些加载器和插件。\n如果有可能拖慢执行速度,甚至都不需要在单元测试中加载和处理应用全局样式文件,所以你用一个 `null` 加载器来处理所有 CSS。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUCOULDMERGETHETESTCONFIGURATIONINTOTHEWEBPACKCOMMONCONFIGURATIONANDOVERRIDETHEPARTSYOUDONTWANTORNEEDBUTITMIGHTBESIMPLERTOSTARTOVERWITHACOMPLETELYFRESHCONFIGURATION", "original": "You could merge the test configuration into the `webpack.common` configuration and override the parts you don't want or need.\nBut it might be simpler to start over with a completely fresh configuration.", "translation": "你可以把测试环境的配置合并到 `webpack.common` 配置中,并且改写不想要或不需要的部分。\n但是从一个全新的配置开始可能更简单。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "RECONFIGUREKARMAHTTPS:KARMARUNNERGITHUBIO10INDEXHTMLTOUSEWEBPACKTORUNTHETESTS:", "original": "Reconfigure [Karma](https://karma-runner.github.io/1.0/index.html) to use Webpack to run the tests:", "translation": "重新配置[Karma](https://karma-runner.github.io/1.0/index.html),让它使用 webpack 来运行这些测试:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUDONTPRECOMPILETHETYPESCRIPTWEBPACKTRANSPILESTHETYPESCRIPTFILESONTHEFLYINMEMORYANDFEEDSTHEEMITTEDJSDIRECTLYTOKARMATHEREARENOTEMPORARYFILESONDISK", "original": "You don't precompile the TypeScript; Webpack transpiles the Typescript files on the fly, in memory, and feeds the emitted JS directly to Karma.\nThere are no temporary files on disk.", "translation": "你不用预编译 TypeScript,Webpack 会随时在内存中转译这些 TypeScript 文件,并且把产出的 JS 直接反馈给 Karma。\n硬盘上没有任何临时文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEKARMATESTSHIMTELLSKARMAWHATFILESTOPRELOADANDPRIMESTHEANGULARTESTFRAMEWORKWITHTESTVERSIONSOFTHEPROVIDERSTHATEVERYAPPEXPECTSTOBEPRELOADED", "original": "The `karma-test-shim` tells Karma what files to pre-load and\nprimes the Angular test framework with test versions of the providers that every app expects to be pre-loaded.", "translation": "`karma-test-shim` 告诉 Karma 哪些文件需要预加载,首要的是:带有“测试版提供商”的 Angular 测试框架是每个应用都希望预加载的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "NOTICETHATYOUDONOTLOADTHEAPPLICATIONCODEEXPLICITLYYOUTELLWEBPACKTOFINDANDLOADTHETESTFILESTHEFILESENDINGINSPECTSEACHSPECFILEIMPORTSALLMDASHANDONLYMDASHTHEAPPLICATIONSOURCECODETHATITTESTSWEBPACKLOADSJUSTTHOSESPECIFICAPPLICATIONFILESANDIGNORESTHEOTHERFILESTHATYOUARENTTESTING", "original": "Notice that you do _not_ load the application code explicitly.\nYou tell Webpack to find and load the test files (the files ending in `.spec.ts`).\nEach spec file imports all—and only—the application source code that it tests.\nWebpack loads just _those_ specific application files and ignores the other files that you aren't testing.", "translation": "注意,你*并没有*明确加载这些应用代码。\n只是告诉 Webpack 查找并加载这些测试文件(文件名以 `.spec.ts` 结尾)。\n每个规约(spec)文件都导入了所有(也只有)它测试所需的应用源码。\nWebpack 只加载*那些*特定的应用文件,而忽略所有其它你不会测试到的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "GRABTHEAPPCODEATTHEENDOFTHISGUIDEANDTRY:", "original": "Grab the app code at the end of this guide and try:", "translation": "抓取本指南底部的应用代码,并试一试:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "##TRYINGITOUT", "original": "## Trying it out", "translation": "## 试一试", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "HEREISTHESOURCECODEFORASMALLAPPLICATIONTHATBUNDLESWITHTHEWEBPACKTECHNIQUESCOVEREDINTHISGUIDE", "original": "Here is the source code for a small application that bundles with the\nWebpack techniques covered in this guide.", "translation": "这里是一个小型应用的全部源码,可以用本章中学到的 Webpack 技术打包它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THECODEAPPCOMPONENTHTMLCODEDISPLAYSTHISDOWNLOADABLEANGULARLOGOAHREFASSETSIMAGESLOGOSANGULARANGULARPNGIMGSRCASSETSIMAGESLOGOSANGULARANGULARPNGHEIGHT40PXTITLEDOWNLOADANGULARLOGOACREATEAFOLDERCALLEDIMAGESUNDERTHEPROJECTSASSETSFOLDERTHENRIGHTCLICKCMDCLICKONMACONTHEIMAGEANDDOWNLOADITTOTHATFOLDER", "original": "The <code>app.component.html</code> displays this downloadable Angular logo\n<a href=\"assets/images/logos/angular/angular.png\">\n<img src=\"assets/images/logos/angular/angular.png\" height=\"40px\" title=\"download Angular logo\"></a>.\nCreate a folder called `images` under the project's `assets` folder, then right-click (Cmd+click on Mac)\non the image and download it to that folder.", "translation": "<code>app.component.html</code>显示了这个可下载的 Angular Logo\n<a href=\"assets/images/logos/angular/angular.png\" target=\"_blank\">\n<img src=\"assets/images/logos/angular/angular.png\" height=\"40px\" title=\"download Angular logo\"></a>。\n在项目的 `assets` 目录下创建一个名叫 `images` 的文件夹,然后右键点击(Mac 上是 Cmd+点击)本图片,并把它下载到 `images` 文件夹中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "HEREAGAINARETHETYPESCRIPTENTRYPOINTFILESTHATDEFINETHEPOLYFILLSANDVENDORBUNDLES", "original": "Here again are the TypeScript entry-point files that define the `polyfills` and `vendor` bundles.", "translation": "这里又是 TypeScript 的入口点文件,它定义了 `polyfills` 和 `vendor` 这两个包。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "H3CLASSNOTOCHIGHLIGHTSH3", "original": "<h3 class=\"no-toc\">Highlights</h3>", "translation": "<h3 class=\"no-toc\">重点</h3>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEREARENOSCRIPTORLINKTAGSINTHEINDEXHTMLTHEHTMLWEBPACKPLUGININSERTSTHEMDYNAMICALLYATRUNTIME", "original": "* There are no `<script>` or `<link>` tags in the `index.html`.\nThe `HtmlWebpackPlugin` inserts them dynamically at runtime.", "translation": "在 `index.html` 中没有<script>或<link>标签。\n `HtmlWebpackPlugin` 会在运行时动态插入它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEAPPCOMPONENTINAPPCOMPONENTTSIMPORTSTHEAPPLICATIONWIDECSSWITHASIMPLEIMPORTSTATEMENT", "original": "* The `AppComponent` in `app.component.ts` imports the application-wide css with a simple `import` statement.", "translation": "`app.component.ts` 中的 `AppComponent` 类简单的用一个 `import` 语句导入了应用级 css。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEAPPCOMPONENTITSELFHASITSOWNHTMLTEMPLATEANDCSSFILEWEBPACKLOADSTHEMWITHCALLSTOREQUIREWEBPACKSTASHESTHOSECOMPONENTSCOPEDFILESINTHEAPPJSBUNDLETOOYOUDONTSEETHOSECALLSINTHESOURCECODETHEYREADDEDBEHINDTHESCENESBYTHEANGULAR2TEMPLATELOADERPLUGIN", "original": "* The `AppComponent` itself has its own html template and css file. WebPack loads them with calls to `require()`.\nWebpack stashes those component-scoped files in the `app.js` bundle too.\nYou don't see those calls in the source code;\nthey're added behind the scenes by the `angular2-template-loader` plug-in.", "translation": "`AppComponent` 组件本身有它自己的 HTML 模板和 CSS 文件。Webpack 通过调用 `require()` 方法加载它们。Webpack 还把那些组件内部的文件打包进了 `app.js` 中。\n你在自己的源码中看不到这些调用,这些工作是由幕后的 `angular2-template-loader` 插件完成的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "THEVENDORTSCONSISTSOFVENDORDEPENDENCYIMPORTSTATEMENTSTHATDRIVETHEVENDORJSBUNDLETHEAPPLICATIONIMPORTSTHESEMODULESTOOTHEYDBEDUPLICATEDINTHEAPPJSBUNDLEIFTHECOMMONSCHUNKPLUGINHADNTDETECTEDTHEOVERLAPANDREMOVEDTHEMFROMAPPJS", "original": "* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.\nThe application imports these modules too; they'd be duplicated in the `app.js` bundle\nif the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `app.js`.", "translation": "`vendor.ts` 由 `import` 提供商依赖的语句组成,它最终决定了 `vender.js` 的内容。\n 本应用也导入这些模块,如果没有 `CommonsChunkPlugin` 插件检测出这种重叠,并且把它们从 `app.js` 中移除,它们就会同时出现在 `app.js` 包中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "##CONCLUSION", "original": "## Conclusion", "translation": "## 总结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUVELEARNEDJUSTENOUGHWEBPACKTOCONFIGURATEDEVELOPMENTTESTANDPRODUCTIONBUILDSFORASMALLANGULARAPPLICATION", "original": "You've learned just enough Webpack to configurate development, test and production builds\nfor a small Angular application.", - "translation": "你学到了刚好够用来在开发、测试、产品环境下构建一个小型 Angular 应用的 Webpack 配置知识。", + "translation": "你学到了刚好够用来在开发、测试、生产环境下构建一个小型 Angular 应用的 Webpack 配置知识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "YOUCOULDALWAYSDOMORESEARCHTHEWEBFOREXPERTADVICEANDEXPANDYOURWEBPACKKNOWLEDGE", "original": "_You could always do more_. Search the web for expert advice and expand your Webpack knowledge.", "translation": "*但你还能做得更多*。搜索互联网来获得专家的建议,并扩展你对 Webpack 的认识。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "BACKTOTOPGUIDEWEBPACK#TOP", "original": "[Back to top](guide/webpack#top)", "translation": "[回到顶部](guide/webpack#top)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/guide/webpack.md" }, { + "key": "H1CLASSNOTOCWHATISANGULARH1", "original": "<h1 class=\"no-toc\">What is Angular?</h1>", "translation": "<h1 class=\"no-toc\">什么是 Angular?</h1>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "ANGULARISAPLATFORMTHATMAKESITEASYTOBUILDAPPLICATIONSWITHTHEWEBANGULARCOMBINESDECLARATIVETEMPLATESDEPENDENCYINJECTIONENDTOENDTOOLINGANDINTEGRATEDBESTPRACTICESTOSOLVEDEVELOPMENTCHALLENGESANGULAREMPOWERSDEVELOPERSTOBUILDAPPLICATIONSTHATLIVEONTHEWEBMOBILEORTHEDESKTOP", "original": "Angular is a platform that makes it easy to build applications with the web. Angular combines declarative templates, dependency injection, end to end tooling, and integrated best practices to solve development challenges. Angular empowers developers to build applications that live on the web, mobile, or the desktop", "translation": "Angular 是一个开发平台。它能帮你更轻松的构建 Web 应用。Angular 集声明式模板、依赖注入、端到端工具和一些最佳实践于一身,为你解决开发方面的各种挑战。Angular 为开发者提升构建 Web、手机或桌面应用的能力。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "SECTIONGETAGLIMPSEOFANGULARSECTION", "original": "<section>Get a Glimpse of Angular</section>", "translation": "<section>Angular 走马观花</section>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "PAQUICKLOOKATANANGULARHELLOWORLDAPPLICATIONP", "original": "<p>A quick look at an Angular \"hello world\" application.</p>", "translation": "<p>快速体验 Angular 的 \"hello world\" 应用。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "PCLASSCARDFOOTERANGULARINACTIONP", "original": "<p class=\"card-footer\">Angular in Action</p>", "translation": "<p class=\"card-footer\">体验 Angular</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "SECTIONGETGOINGWITHANGULARSECTION", "original": "<section>Get Going with Angular</section>", "translation": "<section>开始使用 Angular</section>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "PGETGOINGONYOUROWNENVIRONMENTWITHTHEQUICKSTARTP", "original": "<p>Get going on your own environment with the Quickstart.</p>", "translation": "<p>跟随\"快速上手\"构建你的开发环境</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "PCLASSCARDFOOTERQUICKSTARTP", "original": "<p class=\"card-footer\">Quickstart</p>", "translation": "<p class=\"card-footer\">快速上手</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "SECTIONFUNDAMENTALSSECTION", "original": "<section>Fundamentals</section>", "translation": "<section>基本原理</section>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "PLEARNANGULARAPPLICATIONFUNDAMENTALSSTARTINGWITHANARCHITECTUREOVERVIEWP", "original": "<p>Learn Angular application fundamentals, starting with an architecture overview.</p>", "translation": "<p>学习 Angular 应用的基本原理。<br/>从架构概览开始。</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "PCLASSCARDFOOTERARCHITECTUREP", "original": "<p class=\"card-footer\">Architecture</p>", "translation": "<p class=\"card-footer\">架构</p>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "##ASSUMPTIONS", "original": "## Assumptions", "translation": "## 基本假设", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "THISDOCUMENTATIONASSUMESTHATYOUAREALREADYFAMILIARWITHJAVASCRIPTHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTAREINTRODUCTIONTOJAVASCRIPTLEARNJAVASCRIPTANDSOMEOFTHETOOLSFROMTHELATESTSTANDARDSHTTPS:BABELJSIOLEARNES2015LATESTJAVASCRIPTSTANDARDSSUCHASCLASSESHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCECLASSESES2015CLASSESANDMODULESHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCESTATEMENTSIMPORTES2015MODULESTHECODESAMPLESAREWRITTENUSINGTYPESCRIPTHTTPS:WWWTYPESCRIPTLANGORGTYPESCRIPTMOSTANGULARCODECANBEWRITTENWITHJUSTTHELATESTJAVASCRIPTUSINGTYPESHTTPS:WWWTYPESCRIPTLANGORGDOCSHANDBOOKCLASSESHTMLTYPESCRIPTTYPESFORDEPENDENCYINJECTIONANDUSINGDECORATORSHTTPS:WWWTYPESCRIPTLANGORGDOCSHANDBOOKDECORATORSHTMLDECORATORSFORMETADATA", "original": "This documentation assumes that you are already familiar with\n[JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript \"Learn JavaScript\"),\nand some of the tools from the\n[latest standards](https://babeljs.io/learn-es2015/ \"Latest JavaScript standards\") such as\n[classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes \"ES2015 Classes\")\nand [modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import \"ES2015 Modules\").\nThe code samples are written using [TypeScript](https://www.typescriptlang.org/ \"TypeScript\").\nMost Angular code can be written with just the latest JavaScript,\nusing [types](https://www.typescriptlang.org/docs/handbook/classes.html \"TypeScript Types\") for dependency injection,\nand using [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html \"Decorators\") for metadata.", "translation": "本文档假设你已经熟悉了 [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript \"Learn JavaScript\") 和来自 [最新标准](https://babeljs.io/learn-es2015/ \"Latest JavaScript standards\") 的一些知识,比如 [类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes \"ES2015 Classes\") 和 [模块](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import \"ES2015 Modules\")。\n下列代码范例都是用最新版本的 JavaScript 写的,利用 [类型](https://www.typescriptlang.org/docs/handbook/classes.html \"TypeScript Types\") 实现依赖注入,并使用[装饰器](https://www.typescriptlang.org/docs/handbook/decorators.html \"Decorators\")来提供元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "##FEEDBACK", "original": "## Feedback", "translation": "## 反馈", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "YOUCANSITWITHUS", "original": "You can sit with us!", "translation": "你也可以和我们一起做贡献!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "YOUCANFILEDOCUMENTATIONISSUESHTTPS:GITHUBCOMANGULARANGULARISSUESANGULARGITHUBISSUESANDCREATEPULLREQUESTSHTTPS:GITHUBCOMANGULARANGULARPULLSANGULARGITHUBPULLREQUESTSONTHEANGULARGITHUBREPOSITORYTHECONTRIBUTINGGUIDEHTTPS:GITHUBCOMANGULARANGULARBLOBMASTERCONTRIBUTINGMDCONTRIBUTINGGUIDEWILLHELPYOUCONTRIBUTETOTHECOMMUNITYOURCOMMUNITYVALUESRESPECTFULSUPPORTIVECOMMUNICATIONPLEASECONSULTANDADHERETOTHECODEOFCONDUCTHTTPS:GITHUBCOMANGULARCODEOFCONDUCTBLOBMASTERCODEOFCONDUCTMDCONTRIBUTORCODEOFCONDUCT", "original": "You can file documentation\n[issues](https://github.com/angular/angular/issues \"Angular Github issues\") and create\n[pull requests](https://github.com/angular/angular/pulls \"Angular Github pull requests\")\non the Angular Github repository.\nThe [contributing guide](https://github.com/angular/angular/blob/master/CONTRIBUTING.md \"Contributing guide\")\nwill help you contribute to the community.\nOur community values respectful, supportive communication.\nPlease consult and adhere to the\n[code of conduct](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md \"contributor code of conduct\").", "translation": "你可以到 Angular 在 Github 上的仓库中提出文档方面的[问题](https://github.com/angular/angular/issues \"Angular Github issues\"),并创建[Pull Requests](https://github.com/angular/angular/pulls \"Angular Github pull requests\")。\n[贡献者指南](https://github.com/angular/angular/blob/master/CONTRIBUTING.md \"贡献者指南\")将会帮助你更好的为社区做贡献。\n我们社区的价值观是互相尊重、互相支持。参见[社区行为规范](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md \"contributor code of conduct\")。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/marketing/docs.md" }, { + "key": "WELCOMETOANGULARCN", "original": "Welcome to angular.cn!", "translation": "欢迎光临 angular.cn!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "THISOFFICIALSITEANDTHEDEVELOPERGUIDESYOUWILLFINDHEREARETHERESULTOFHARDWORKANDDEDICATIONBYMEMBERSOFANGULARSCHINESEDEVELOPERCOMMUNITYMORETHANJUSTALINGUISTICTRANSLATIONTHISSITEWASLOCALIZEDANDUPDATEDBYDEVELOPERSWHOUSEANDKNOWANGULARANDUNDERSTANDTHECONCEPTSASENGINEERSLEDBYFRIENDSZHICHENGWANGRALPHZHIMINYEREXLINYANGTODOUBABAUNITEDBYACOMMITMENTTOOPENSOURCESOFTWAREANDHELPINGDEVELOPERSTHEANGULARCNTRANSLATIONSCNABOUTTEAMISMOTIVATEDBYTHEDESIRETOMAKEANGULARMOREACCESSIBLETOTHEMILLIONSOFCHINESESPEAKINGDEVELOPERSWORLDWIDE", "original": "This official site and the developer guides you will find here are the result of hard work and dedication by members of Angular's Chinese developer community. More than just a linguistic translation, this site was localized and updated by developers who use and know Angular, and understand the concepts as engineers. Led by friends Zhicheng WANG (Ralph), Zhimin YE (Rex) Lin YANG (todoubaba), united by a commitment to open source software and helping developers, the [angular.cn](/translations/cn/about) team is motivated by the desire to make Angular more accessible to the millions of Chinese-speaking developers worldwide.", "translation": "这份官方网站和开发指南的中文版是中国的 Angular 开发者社区共同努力奉献的成果。他们来自深谙 Angular 设计理念的工程师,故此,这份中文版不仅是语言上的简单汉化。出于对“开源精神”和“共享精神”的执着与推崇,汪志成、叶志敏和杨林共同带领[angular.cn 团队](/translations/cn/about)奋力工作,力争让全世界的中文开发者与 Angular 实现零距离的亲密接触。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "THISCHINESEVERSIONOFANGULARIOISALSOTHEFIRSTOFFICIALRELEASEOFANGULARSDEVELOPERCONTENTINANYLANGUAGEOTHERTHANENGLISH", "original": "This Chinese version of angular.io is also the first official release of Angular's developer content in any language other than English!", "translation": "除英文版之外,该中文版是第一个由官方正式发布的开发文档!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "ASACHAMPIONOFOPENTECHNOLOGYGOOGLEHASINVESTEDALOTANDWILLCONTINUETOINVESTINTHEADVANCEMENTOFANGULARFORTHEBENEFITSOFOURUSERSINCHINAANDAROUNDTHEWORLD", "original": "As a champion of open technology, Google has invested a lot and will continue to invest in the advancement of Angular, for the benefits of our users in China and around the world.", "translation": "作为开源技术的倡导者,Google 已经并将继续投资于对 Angular 的完善和演进工作,造福并回馈中国区的用户以及全世界的用户。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "WEAREHAPPYTOSEETHATANGULARSCHINESEDEVELOPERCOMMUNITYHASGROWNTOITSCURRENTLARGESIZEFUELEDBYNOTONLYTHEPASSIONFORTECHNOLOGIESAMONGDEVELOPERSBUTALSOBYTHEDESIRETOMAKETHISTECHNOLOGYEFFECTIVEFORREALBUSINESSESMANYCOMPANIESINCHINAHAVEALREADYBUILTTHEIRBUSINESSESBASEDONANGULARTECHNOLOGYWEHOPETHATTHEUPDATEDMATERIALSONTHISOFFICIALSITEWILLCONTINUETOINSPIREANDHELPPUTTINGTHISTECHNOLOGYINTOMOREREALWORLDBUSINESSSERVICESANDAPPLICATIONSINCHINAIFYOURBUSINESSALREADYRUNSONANGULARWEINVITEYOUTOJOINOURDEVELOPERCOMMUNITYHEREANDBECOMEINVOLVEDINOUREFFORTINCONTINUINGIMPROVINGANDENHANCINGTHISTECHNOLOGYWEWELCOMEYOURCOMMENTSANDSUGGESTIONSATANYTIMEPLEASESENDYOURREMARKSTOGOOGLEDEVELOPERRELATIONSCHINATEAMSCONTACTEMAILAT:EMAILGENERATEDIMAGESTRANSLATIONSCNMAILDEVRELGIF", "original": "We are happy to see that Angular’s Chinese developer community has grown to its current large size, fueled by not only the passion for technologies among developers, but also by the desire to make this technology effective for real businesses. Many companies in China have already built their businesses based on Angular technology. We hope that the updated materials on this official site will continue to inspire and help putting this technology into more real world business services and applications in China. If your business already runs on Angular, we invite you to join our developer community here, and become involved in our effort in continuing improving and enhancing this technology. We welcome your comments and suggestions at any time. Please send your remarks to Google Developer Relations China team’s contact email at: ![email](generated/images/translations/cn/mail-dev-rel.gif).", "translation": "看到中国的 Angular 开发社区已经如此繁荣,我们非常高兴。这不仅仅是出于开发者对技术的固有热情,更是因为我们希望“用 Angular 高效实现商业需求”的宏伟愿景。事实上,许多中国公司的业务早已基于 Angular 技术。我们希望通过对官网内容的持续更新,鼓励并协助大家把 Angular 更多的应用于现实世界中的业务服务与应用程序。如果您的业务大厦已经构建在 Angular 的基础之上,我们欢迎您加入中文社区,参与到我们持续增强和优化此项技术的努力中来。我们随时欢迎您的意见和建议,请发邮件到 Google 的技术推广部联系我们,我们的邮箱是![email](generated/images/translations/cn/mail-dev-rel.gif)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "ANGULARSUCCEEDSBECAUSEITISBUILTBYANDFORDEVELOPERSWHOCOMEFROMMANYDIFFERENTBACKGROUNDSWEHOPETHATTHESEMATERIALSWILLHELPYOUTOLEARNANDUNDERSTANDANGULARANDTOCONTRIBUTEBACKTOTHEFRAMEWORKINFUTUREWEAREEXCITEDTOSEEWHATYOUWILLBUILDWITHANGULARHEREINCHINAANDHOWTHEFRAMEWORKITSELFWILLCHANGEASTHERESULTOFYOURENTHUSIASM", "original": "Angular succeeds because it is built by and for developers who come from many different backgrounds. We hope that these materials will help you to learn and understand Angular, and to contribute back to the framework in future. We are excited to see what you will build with Angular here in China, and how the framework itself will change as the result of your enthusiasm.", "translation": "Angular 的成功,是因为它由背景各异的开发者所创造,它为开发者而生。我们希望这些文档能帮助大家学习和理解 Angular,总有一天,大家还会为这个框架做出贡献。我们非常期待看到大家用各种方式应用 Angular 技术,更希望看到 Angular 在所有开发者的热情支持下继续演进。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "WEALSOHOPETHATTHROUGHANGULARCNYOUWILLDISCOVERMOREABOUTTHEWIDEVARIETYOFWEBANDMOBILETECHNOLOGIESFROMGOOGLEANDTHEOPENSOURCEWORLDANDHOWTOLEVERAGEMANYGOOGLEPLATFORMSFORYOURFUTUREBUSINESSSUCCESS", "original": "We also hope that through Angular.cn, you will discover more about the wide variety of web and mobile technologies from Google and the open source world, and how to leverage many Google platforms for your future business success.", "translation": "通过 angular.cn,我们希望广大的开发者们能继续发掘更多来自 Google 和开源世界的 Web 技术和移动技术,借助 Google 提供的平台登上业务成就的新高度。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "WEAREHAPPYTOHAVEYOUHEREWELCOME", "original": "We are happy to have you here. Welcome.", "translation": "非常高兴在这里遇见你们。Google 欢迎你!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "NAOMIBLACKANDBRADGREEN", "original": "Naomi Black and Brad Green", "translation": "Naomi Black 与 Brad Green", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "HELLOTODEVELOPERFRIENDSOFTHEANGULARCNCOMMUNITY", "original": "Hello to Developer Friends of the Angular.CN community!", "translation": "angular.cn 社区的开发者朋友们,大家好!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "ONBEHALFOFGOOGLEDEVELOPERRELATIONSCHINATEAMWEWARMLYWELCOMEYOUHEREWEAREVERYGLADTOSEETHEPARTNERSHIPANDCOLLABORATIONWITHTHEANGULARDEVELOPERCOMMUNITYINCHINAANDWEHOPETHATTHROUGHTHEPARTNERSHIPWITHTHEDEVELOPERFRIENDSATTHEANGULARCNCOMMUNITYOURCOLLABORATIONSWILLBEINCREASEDINTHEFUTURE", "original": "On behalf of Google Developer Relations China team, we warmly welcome you here! We are very glad to see the partnership and collaboration with the Angular developer community in China, and we hope that through the partnership with the developer friends at the Angular.CN community, our collaborations will be increased in the future.", "translation": "我谨代表谷歌公司开发技术推广部(Developer Relations)中国团队热烈欢迎你! 我们非常高兴和中国的 Angular 开发者社区在这里的合作,也希望通过这个合作和 Angular.CN 社区的开发者朋友们扩大未来更多的合作和分享。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "THISCHINESEANGULARWEBSITEREPRESENTSAGREATIDEAANDMODELFORCOLLABORATIONITNOTONLYHASTHEANGULARRESOURCESANDUPDATESTHATARETHERESULTSOFGOOGLEINVESTMENTBUTALSOTHERESULTSFROMMANYCHINESELOCALIZATIONSDONEBYTHEMANYVOLUNTEERSHEREFORTHELARGERDEVELOPERUSERSOUTTHERETHESELOCALIZEDRESOURCESFROMTHEEFFORTSFROMTHESEVOLUNTEERSWILLHELPMOREDEVELOPERSINCHINATOLEARNANDADOPTANGULARTECHNOLOGIESWEVERYMUCHAPPRECIATEDTHESECONTRIBUTIONSANDTHEEFFORTSINSHARINGITISTHISKINDOFSPIRITANDPRACTICESTHATRESULTEDINTHEVIBRANTINTERNETWEHAVETODAYWESALUTETOALLTHESEVOLUNTEERSANDATGOOGLEWEWILLCONTINUEOURSUPPORTTOOPENSOURCETECHNOLOGIESANDCOMMUNITIESASWEHAVEBEENDOING", "original": "This Chinese Angular website, represents a great idea and model for collaboration. It not only has the Angular resources and updates that are the results of Google investment, but also the results from many Chinese localizations done by the many volunteers here for the larger developer users out there. These localized resources from the efforts from these volunteers, will help more developers in China to learn and adopt Angular technologies. We very much appreciated these contributions and the efforts in sharing. It is this kind of spirit and practices that resulted in the vibrant Internet we have today. We salute to all these volunteers, and at Google we will continue our support to open source technologies and communities as we have been doing.", "translation": "这个 Angular 中文网站的大量资源,体现了一个很好的合作模式和精神。它不仅有谷歌公司投资所推动的 Angular 技术的资源和更新,更是有众多中国的技术爱好者和开发者们通过自己的无私义务劳动为广大开发者们所做的技术资料的中文本地化翻译工作的成果。这些志愿者们辛勤劳动所带来的中文资源,将帮助更多的中国开发者们能够方便地学习和采纳 Angular 技术。我们非常赞赏这样的奉献精神和分享实践,正是这样的精神和实践才造成了互联网今天的兴旺发展。我们向所有的志愿者们致敬,谷歌公司也将一如既往地继续支持开源代码技术和社区的发展。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "LETUSENJOYTHEPROCESSOFINNOVATINGTHROUGHTHISMODELOFSHARINGANDCOLLABORATION", "original": "Let us enjoy the process of innovating through this model of sharing and collaboration!", "translation": "让我们大家通过更多的分享和合作,一起快乐创新!", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "BILLLUANGREATERCHINAREGIONALLEADDEVELOPERRELATIONSGOOGLE", "original": "Bill Luan, Greater China Regional Lead, Developer Relations, Google", "translation": "谷歌开发技术推广部 大中华区主管 栾跃", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/home.md" }, { + "key": "#ANGULARNEWS", "original": "# Angular News", "translation": "# Angular 新闻中心", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/news.md" }, { + "key": "###THANKYOU", "original": "### THANK YOU", "translation": "VTHINKXIE, Wilson Zeng, chensimeng, zjgzx1988, SunMing, fbchen, Trotyl Yu, 雪狼, afc163, xufei, lightningtgc", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/translations/cn/news.md" }, { + "key": "H1CLASSNOTOCTUTORIAL:TOUROFHEROESH1", "original": "<h1 class=\"no-toc\">Tutorial: Tour of Heroes</h1>", "translation": "<h1 class=\"no-toc\">教程:英雄指南</h1>", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "THETOUROFHEROESTUTORIALCOVERSTHEFUNDAMENTALSOFANGULARINTHISTUTORIALYOUWILLBUILDANAPPTHATHELPSASTAFFINGAGENCYMANAGEITSSTABLEOFHEROES", "original": "The _Tour of Heroes_ tutorial covers the fundamentals of Angular. \nIn this tutorial you will build an app that helps a staffing agency manage its stable of heroes.", "translation": "**英雄指南**教程涵盖了 Angular 的核心原理。在本教程中,你将构建一个应用,来帮助招聘机构来管理一群英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "THISBASICAPPHASMANYOFTHEFEATURESYOUDEXPECTTOFINDINADATADRIVENAPPLICATIONITACQUIRESANDDISPLAYSALISTOFHEROESEDITSASELECTEDHEROSDETAILANDNAVIGATESAMONGDIFFERENTVIEWSOFHEROICDATA", "original": "This basic app has many of the features you'd expect to find in a data-driven application.\nIt acquires and displays a list of heroes, edits a selected hero's detail, and navigates among different views of heroic data.", "translation": "这个入门级 app 包含很多数据驱动的应用所需的特性。\n它需要获取并显示英雄的列表、编辑所选英雄的详情,并且在英雄数据的不同视图之间导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "BYTHEENDOFTHETUTORIALYOUWILLBEABLETODOTHEFOLLOWING:", "original": "By the end of the tutorial you will be able to do the following:", "translation": "在本教程的最后,你将完成下列工作:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "USEBUILTINANGULARDIRECTIVESTOSHOWANDHIDEELEMENTSANDDISPLAYLISTSOFHERODATA", "original": "* Use built-in Angular directives to show and hide elements and display lists of hero data.", "translation": "使用内置指令来显示 / 隐藏元素,并且显示英雄数据的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "CREATEANGULARCOMPONENTSTODISPLAYHERODETAILSANDSHOWANARRAYOFHEROES", "original": "* Create Angular components to display hero details and show an array of heroes.", "translation": "创建 Angular 组件以显示英雄的详情,并显示一个英雄数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "USEONEWAYDATABINDINGFORREADONLYDATA", "original": "* Use one-way data binding for read-only data.", "translation": "为只读数据使用单项数据绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "ADDEDITABLEFIELDSTOUPDATEAMODELWITHTWOWAYDATABINDING", "original": "* Add editable fields to update a model with two-way data binding.", "translation": "添加可编辑字段,使用双向数据绑定来更新模型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "BINDCOMPONENTMETHODSTOUSEREVENTSLIKEKEYSTROKESANDCLICKS", "original": "* Bind component methods to user events, like keystrokes and clicks.", "translation": "把组件中的方法绑定到用户事件上,比如按键和点击。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "ENABLEUSERSTOSELECTAHEROFROMAMASTERLISTANDEDITTHATHEROINTHEDETAILSVIEW", "original": "* Enable users to select a hero from a master list and edit that hero in the details view.", "translation": "让用户可以在主列表中选择一个英雄,然后在详情视图中编辑他。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "FORMATDATAWITHPIPES", "original": "* Format data with pipes.", "translation": "使用管道来格式化数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "CREATEASHAREDSERVICETOASSEMBLETHEHEROES", "original": "* Create a shared service to assemble the heroes.", "translation": "创建共享的服务来管理这些英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "USEROUTINGTONAVIGATEAMONGDIFFERENTVIEWSANDTHEIRCOMPONENTS", "original": "* Use routing to navigate among different views and their components.", "translation": "使用路由在不同的视图及其组件之间导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "YOULLLEARNENOUGHANGULARTOGETSTARTEDANDGAINCONFIDENCETHATANGULARCANDOWHATEVERYOUNEEDITTODO", "original": "You'll learn enough Angular to get started and gain confidence that\nAngular can do whatever you need it to do.", "translation": "你将学到足够的 Angular 知识,并确信 Angular 确实能提供你所需的支持。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "AFTERCOMPLETINGALLTUTORIALSTEPSTHEFINALAPPWILLLOOKLIKETHISLIVEEXAMPLENAMETOHPT6LIVEEXAMPLE", "original": "After completing all tutorial steps, the final app will look like this <live-example name=\"toh-pt6\"></live-example>.", "translation": "完成本教程的所有步骤之后,最终的应用会是这样的:<live-example name=\"toh-pt6\"></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "##WHATYOULLBUILD", "original": "## What you'll build", "translation": "## 你要构建出什么", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "HERESAVISUALIDEAOFWHERETHISTUTORIALLEADSBEGINNINGWITHTHEDASHBOARDVIEWANDTHEMOSTHEROICHEROES:", "original": "Here's a visual idea of where this tutorial leads, beginning with the \"Dashboard\"\nview and the most heroic heroes:", "translation": "下面是本教程关于界面的构想:开始是“Dashboard(仪表盘)”视图,来展示最勇敢的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "YOUCANCLICKTHETWOLINKSABOVETHEDASHBOARDDASHBOARDANDHEROESTONAVIGATEBETWEENTHISDASHBOARDVIEWANDAHEROESVIEW", "original": "You can click the two links above the dashboard (\"Dashboard\" and \"Heroes\")\nto navigate between this Dashboard view and a Heroes view.", "translation": "仪表盘顶部中有两个链接:“Dashboard(仪表盘)”和“Heroes(英雄列表)”。\n 你将点击它们在“仪表盘”和“英雄列表”视图之间导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "IFYOUCLICKTHEDASHBOARDHEROMAGNETATHEROUTEROPENSAHERODETAILSVIEWWHEREYOUCANCHANGETHEHEROSNAME", "original": "If you click the dashboard hero \"Magneta,\" the router opens a \"Hero Details\" view\nwhere you can change the hero's name.", "translation": "当你点击仪表盘上名叫“Magneta”的英雄时,路由会打开英雄详情页,在这里,你可以修改英雄的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "CLICKINGTHEBACKBUTTONRETURNSYOUTOTHEDASHBOARDLINKSATTHETOPTAKEYOUTOEITHEROFTHEMAINVIEWSIFYOUCLICKHEROESTHEAPPDISPLAYSTHEHEROESMASTERLISTVIEW", "original": "Clicking the \"Back\" button returns you to the Dashboard.\nLinks at the top take you to either of the main views.\nIf you click \"Heroes,\" the app displays the \"Heroes\" master list view.", "translation": "点击“Back(后退)”按钮将返回到“Dashboard(仪表盘)”。\n顶部的链接可以把你带到任何一个主视图。\n如果你点击“Heroes(英雄列表)”链接,应用将把你带到“英雄”主列表视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "WHENYOUCLICKADIFFERENTHERONAMETHEREADONLYMINIDETAILBENEATHTHELISTREFLECTSTHENEWCHOICE", "original": "When you click a different hero name, the read-only mini detail beneath the list reflects the new choice.", "translation": "当你点击另一位英雄时,一个只读的“微型详情视图”会显示在列表下方,以体现你的选择。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "YOUCANCLICKTHEVIEWDETAILSBUTTONTODRILLINTOTHEEDITABLEDETAILSOFTHESELECTEDHERO", "original": "You can click the \"View Details\" button to drill into the\neditable details of the selected hero.", "translation": "你可以点击“View Details(查看详情)”按钮进入所选英雄的编辑视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "THEFOLLOWINGDIAGRAMCAPTURESALLOFTHENAVIGATIONOPTIONS", "original": "The following diagram captures all of the navigation options.", "translation": "下面这张图汇总了所有可能的导航路径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "HERESTHEAPPINACTION:", "original": "Here's the app in action:", "translation": "下图演示了本应用中的动图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/index.md" }, { + "key": "#THEAPPLICATIONSHELL", "original": "# The Application Shell", "translation": "# 应用的“外壳”", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "##INSTALLTHEANGULARCLI", "original": "## Install the Angular CLI", "translation": "## 安装 Angular CLI 命令行工具", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "INSTALLTHEANGULARCLIHTTPS:GITHUBCOMANGULARANGULARCLIIFYOUHAVENTALREADYDONESO", "original": "Install the [Angular CLI](https://github.com/angular/angular-cli), if you haven't already done so.", "translation": "如果还没有安装 [Angular CLI](https://github.com/angular/angular-cli),请执行:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "##CREATEANEWAPPLICATION", "original": "## Create a new application", "translation": "## 创建新应用", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "CREATEANEWPROJECTNAMEDANGULARTOUROFHEROESWITHTHISCLICOMMAND", "original": "Create a new project named `angular-tour-of-heroes` with this CLI command.", "translation": "使用 CLI 命令创建一个名叫 `angular-tour-of-heroes` 的新项目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "THEANGULARCLIGENERATEDANEWPROJECTWITHADEFAULTAPPLICATIONANDSUPPORTINGFILES", "original": "The Angular CLI generated a new project with a default application and supporting files.", "translation": "这样 Angular CLI 就创建了一个带默认应用及其支持文件的新项目。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "##SERVETHEAPPLICATION", "original": "## Serve the application", "translation": "## 启动应用服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "GOTOTHEPROJECTDIRECTORYANDLAUNCHTHEAPPLICATION", "original": "Go to the project directory and launch the application.", "translation": "进入项目目录,并启动这个应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "THENGSERVECOMMANDBUILDSTHEAPPSTARTSTHEDEVELOPMENTSERVERWATCHESTHESOURCEFILESANDREBUILDSTHEAPPASYOUMAKECHANGESTOTHOSEFILES", "original": "The `ng serve` command builds the app, starts the development server,\nwatches the source files, and rebuilds the app as you make changes to those files.", "translation": "`ng serve` 命令会构建本应用、启动开发服务器、监听源文件,并且当那些文件发生变化时重新构建本应用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "THEOPENFLAGOPENSABROWSERTOHTTP:LOCALHOST:4200", "original": "The `--open` flag opens a browser to `http://localhost:4200/`.", "translation": "`--open` 标志会打开浏览器,并访问 `http://localhost:4200/`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "YOUSHOULDSEETHEAPPRUNNINGINYOURBROWSER", "original": "You should see the app running in your browser.", "translation": "你会发现本应用正运行在浏览器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "##ANGULARCOMPONENTS", "original": "## Angular components", "translation": "## Angular 组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "THEPAGEYOUSEEISTHEAPPLICATIONSHELLTHESHELLISCONTROLLEDBYANANGULARCOMPONENTNAMEDAPPCOMPONENT", "original": "The page you see is the _application shell_.\nThe shell is controlled by an Angular **component** named `AppComponent`.", "translation": "你所看到的这个页面就是*应用的外壳*。\n这个外壳是被一个名叫 `AppComponent` 的 Angular 组件控制的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "COMPONENTSARETHEFUNDAMENTALBUILDINGBLOCKSOFANGULARAPPLICATIONSTHEYDISPLAYDATAONTHESCREENLISTENFORUSERINPUTANDTAKEACTIONBASEDONTHATINPUT", "original": "_Components_ are the fundamental building blocks of Angular applications.\nThey display data on the screen, listen for user input, and take action based on that input.", "translation": "*组件*是 Angular 应用中的基本构造块。\n它们在屏幕上显示数据,监听用户输入,并且根据这些输入执行相应的动作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "##CHANGETHEAPPLICATIONTITLE", "original": "## Change the application title", "translation": "## 修改应用标题", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "OPENTHEPROJECTINYOURFAVORITEEDITORORIDEANDNAVIGATETOTHESRCAPPFOLDER", "original": "Open the project in your favorite editor or IDE and navigate to the `src/app` folder.", "translation": "用你最喜欢的编辑器或 IDE 打开这个项目,并访问 `src/app` 目录。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "YOULLFINDTHEIMPLEMENTATIONOFTHESHELLAPPCOMPONENTDISTRIBUTEDOVERTHREEFILES:", "original": "You'll find the implementation of the shell `AppComponent` distributed over three files:", "translation": "你会在这里看到 `AppComponent` 壳的三个实现文件:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "1APPCOMPONENTTSMDASHTHECOMPONENTCLASSCODEWRITTENINTYPESCRIPT", "original": "1. `app.component.ts`— the component class code, written in TypeScript.", "translation": "`app.component.ts`— 组件的类代码,这是用 TypeScript 写的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "1APPCOMPONENTHTMLMDASHTHECOMPONENTTEMPLATEWRITTENINHTML", "original": "1. `app.component.html`— the component template, written in HTML.", "translation": "`app.component.html`— 组件的模板,这是用 HTML 写的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "1APPCOMPONENTCSSMDASHTHECOMPONENTSPRIVATECSSSTYLES", "original": "1. `app.component.css`— the component's private CSS styles.", "translation": "`app.component.ts`— 组件的私有 CSS 样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "OPENTHECOMPONENTCLASSFILEAPPCOMPONENTTSANDCHANGETHEVALUEOFTHETITLEPROPERTYTOTOUROFHEROES", "original": "Open the component class file (`app.component.ts`) and change the value of the `title` property to 'Tour of Heroes'.", "translation": "打开组件的类文件 (`app.component.ts`),并把 `title` 属性的值修改为 'Tour of Heroes' (英雄指南)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "OPENTHECOMPONENTTEMPLATEFILEAPPCOMPONENTHTMLANDDELETETHEDEFAULTTEMPLATEGENERATEDBYTHEANGULARCLIREPLACEITWITHTHEFOLLOWINGLINEOFHTML", "original": "Open the component template file (`app.component.html`) and\ndelete the default template generated by the Angular CLI.\nReplace it with the following line of HTML.", "translation": "打开组件的模板文件 `app.component.html` 并清空 Angular CLI 自动生成的默认模板。改为下列 HTML 内容:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "THEDOUBLECURLYBRACESAREANGULARSINTERPOLATIONBINDINGSYNTAXTHISINTERPOLATIONBINDINGPRESENTSTHECOMPONENTSTITLEPROPERTYVALUEINSIDETHEHTMLHEADERTAG", "original": "The double curly braces are Angular's *interpolation binding* syntax. \nThis interpolation binding presents the component's `title` property value \ninside the HTML header tag.", "translation": "双花括号语法是 Angular 的*插值绑定*语法。\n这个插值绑定的意思是把组件的 `title` 属性的值绑定到 HTML 中的 `h1` 标记中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "THEBROWSERREFRESHESANDDISPLAYSTHENEWAPPLICATIONTITLE", "original": "The browser refreshes and displays the new application title.", "translation": "浏览器自动刷新,并且显示出了新的应用标题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "##ADDAPPLICATIONSTYLES", "original": "## Add application styles", "translation": "## 添加应用样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "MOSTAPPSSTRIVEFORACONSISTENTLOOKACROSSTHEAPPLICATIONTHECLIGENERATEDANEMPTYSTYLESCSSFORTHISPURPOSEPUTYOURAPPLICATIONWIDESTYLESTHERE", "original": "Most apps strive for a consistent look across the application.\nThe CLI generated an empty `styles.css` for this purpose.\nPut your application-wide styles there.", "translation": "大多数应用都会努力让整个应用保持一致的外观。\n因此,CLI 会生成一个空白的 `styles.css` 文件。\n你可以把全应用级别的样式放进去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "HERESANEXCERPTFROMTHESTYLESCSSFORTHETOUROFHEROESSAMPLEAPP", "original": "Here's an excerpt from the `styles.css` for the _Tour of Heroes_ sample app.", "translation": "下面是这个*英雄指南*范例应用中 `styles.css` 文件的片段。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "##FINALCODEREVIEW", "original": "## Final code review", "translation": "## 查看最终代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "THESOURCECODEFORTHISTUTORIALANDTHECOMPLETETOUROFHEROESGLOBALSTYLESAREAVAILABLEINTHELIVEEXAMPLELIVEEXAMPLE", "original": "The source code for this tutorial and the complete _Tour of Heroes_ global styles \nare available in the <live-example></live-example>.", "translation": "本教程的源文件以及*英雄指南*的完整全局样式可以在 <live-example></live-example> 中看到。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "HEREARETHECODEFILESDISCUSSEDONTHISPAGE", "original": "Here are the code files discussed on this page.", "translation": "下面是本页所提到的源代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "YOUCREATEDTHEINITIALAPPLICATIONSTRUCTUREUSINGTHEANGULARCLI", "original": "* You created the initial application structure using the Angular CLI.", "translation": "你使用 Angular CLI 创建了初始的应用结构。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "YOULEARNEDTHATANGULARCOMPONENTSDISPLAYDATA", "original": "* You learned that Angular components display data.", "translation": "你学会了使用 Angular 组件来显示数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "YOUUSEDTHEDOUBLECURLYBRACESOFINTERPOLATIONTODISPLAYTHEAPPTITLE", "original": "* You used the double curly braces of interpolation to display the app title.", "translation": "你使用双花括号插值表达式显示了应用标题。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt0.md" }, { + "key": "#THEHEROEDITOR", "original": "# The Hero Editor", "translation": "# 英雄编辑器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEAPPLICATIONNOWHASABASICTITLENEXTYOUWILLCREATEANEWCOMPONENTTODISPLAYHEROINFORMATIONANDPLACETHATCOMPONENTINTHEAPPLICATIONSHELL", "original": "The application now has a basic title.\nNext you will create a new component to display hero information\nand place that component in the application shell.", "translation": "应用程序现在有了基本的标题。\n接下来你要创建一个新的组件来显示英雄信息并且把这个组件放到应用程序的外壳里去。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "##CREATETHEHEROESCOMPONENT", "original": "## Create the heroes component", "translation": "## 创建英雄列表组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "USINGTHEANGULARCLIGENERATEANEWCOMPONENTNAMEDHEROES", "original": "Using the Angular CLI, generate a new component named `heroes`.", "translation": "使用 Angular CLI 创建一个名为 `heroes` 的新组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THECLICREATESANEWFOLDERSRCAPPHEROESANDGENERATESTHETHREEFILESOFTHEHEROESCOMPONENT", "original": "The CLI creates a new folder, `src/app/heroes/` and generates\nthe three files of the `HeroesComponent`.", "translation": "CLI 创建了一个新的文件夹 `src/app/heroes/`,并生成了 `HeroesComponent` 的三个文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEHEROESCOMPONENTCLASSFILEISASFOLLOWS:", "original": "The `HeroesComponent` class file is as follows:", "translation": "`HeroesComponent` 的类文件如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOUALWAYSIMPORTTHECOMPONENTSYMBOLFROMTHEANGULARCORELIBRARYANDANNOTATETHECOMPONENTCLASSWITHCOMPONENT", "original": "You always import the `Component` symbol from the Angular core library\nand annotate the component class with `@Component`.", "translation": "你要从 Angular 核心库中导入 `Component` 符号,并为组件类加上 `@Component` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "COMPONENTISADECORATORFUNCTIONTHATSPECIFIESTHEANGULARMETADATAFORTHECOMPONENT", "original": "`@Component` is a decorator function that specifies the Angular metadata for the component.", "translation": "`@Component` 是个装饰器函数,用于为该组件指定 Angular 所需的元数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THECLIGENERATEDTHREEMETADATAPROPERTIES:", "original": "The CLI generated three metadata properties:", "translation": "CLI 自动生成了三个元数据属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "1SELECTORMDASHTHECOMPONENTSCSSELEMENTSELECTOR", "original": "1. `selector`— the component's CSS element selector", "translation": "`selector`— 组件的选择器(CSS 元素选择器)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "1TEMPLATEURLMDASHTHELOCATIONOFTHECOMPONENTSTEMPLATEFILE", "original": "1. `templateUrl`— the location of the component's template file.", "translation": "`templateUrl`— 组件模板文件的位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "1STYLEURLSMDASHTHELOCATIONOFTHECOMPONENTSPRIVATECSSSTYLES", "original": "1. `styleUrls`— the location of the component's private CSS styles.", "translation": "`styleUrls`— 组件私有 CSS 样式表文件的位置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THECSSELEMENTSELECTORHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBCSSTYPESELECTORSAPPHEROESMATCHESTHENAMEOFTHEHTMLELEMENTTHATIDENTIFIESTHISCOMPONENTWITHINAPARENTCOMPONENTSTEMPLATE", "original": "The [CSS element selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors),\n`'app-heroes'`, matches the name of the HTML element that identifies this component within a parent component's template.", "translation": "[CSS 元素选择器](https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors) `app-heroes` 用来在父组件的模板中匹配 HTML 元素的名称,以识别出该组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THENGONINITISALIFECYCLEHOOKGUIDELIFECYCLEHOOKS#ONINITANGULARCALLSNGONINITSHORTLYAFTERCREATINGACOMPONENTITSAGOODPLACETOPUTINITIALIZATIONLOGIC", "original": "The `ngOnInit` is a [lifecycle hook](guide/lifecycle-hooks#oninit) \nAngular calls `ngOnInit` shortly after creating a component.\nIt's a good place to put initialization logic.", "translation": "`ngOnInit` 是一个[生命周期钩子](guide/lifecycle-hooks#oninit),Angular 在创建完组件后很快就会调用 `ngOnInit`。这里是放置初始化逻辑的好地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "ALWAYSEXPORTTHECOMPONENTCLASSSOYOUCANIMPORTITELSEWHERELIKEINTHEAPPMODULE", "original": "Always `export` the component class so you can `import` it elsewhere ... like in the `AppModule`.", "translation": "始终要 `export` 这个组件类,以便在其它地方(比如 `AppModule`)导入它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "###ADDAHEROPROPERTY", "original": "### Add a _hero_ property", "translation": "### 添加 `hero` 属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "ADDAHEROPROPERTYTOTHEHEROESCOMPONENTFORAHERONAMEDWINDSTORM", "original": "Add a `hero` property to the `HeroesComponent` for a hero named \"Windstorm.\"", "translation": "往 `HeroesComponent` 中添加一个 `hero` 属性,用来表示一个名叫 “Windstorm” 的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "###SHOWTHEHERO", "original": "### Show the hero", "translation": "### 显示英雄", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "OPENTHEHEROESCOMPONENTHTMLTEMPLATEFILEDELETETHEDEFAULTTEXTGENERATEDBYTHEANGULARCLIANDREPLACEITWITHADATABINDINGTOTHENEWHEROPROPERTY", "original": "Open the `heroes.component.html` template file.\nDelete the default text generated by the Angular CLI and \nreplace it with a data binding to the new `hero` property.", "translation": "打开模板文件 `heroes.component.html`。删除 Angular CLI 自动生成的默认内容,改为到 `hero` 属性的数据绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "##SHOWTHEHEROESCOMPONENTVIEW", "original": "## Show the _HeroesComponent_ view", "translation": "## 显示 `HeroesComponent` 视图", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "TODISPLAYTHEHEROESCOMPONENTYOUMUSTADDITTOTHETEMPLATEOFTHESHELLAPPCOMPONENT", "original": "To display the `HeroesComponent`, you must add it to the template of the shell `AppComponent`.", "translation": "要显示 `HeroesComponent` 你必须把它加到壳组件 `AppComponent` 的模板中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "REMEMBERTHATAPPHEROESISTHEELEMENTSELECTOR#SELECTORFORTHEHEROESCOMPONENTSOADDANAPPHEROESELEMENTTOTHEAPPCOMPONENTTEMPLATEFILEJUSTBELOWTHETITLE", "original": "Remember that `app-heroes` is the [element selector](#selector) for the `HeroesComponent`. \nSo add an `<app-heroes>` element to the `AppComponent` template file, just below the title.", "translation": "别忘了,`app-heroes` 就是 `HeroesComponent` 的 [元素选择器](#selector)。\n所以,只要把 `<app-heroes>` 元素添加到 `AppComponent` 的模板文件中就可以了,就放在标题下方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "ASSUMINGTHATTHECLINGSERVECOMMANDISSTILLRUNNINGTHEBROWSERSHOULDREFRESHANDDISPLAYBOTHTHEAPPLICATIONTITLEANDTHEHERONAME", "original": "Assuming that the CLI `ng serve` command is still running,\nthe browser should refresh and display both the application title and the hero name.", "translation": "如果 CLI 的 `ng serve` 命令仍在运行,浏览器就会自动刷新,并且同时显示出应用的标题和英雄的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "##CREATEAHEROCLASS", "original": "## Create a Hero class", "translation": "## 创建 `Hero` 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "AREALHEROISMORETHANANAME", "original": "A real hero is more than a name.", "translation": "真实的英雄当然不止一个名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "CREATEAHEROCLASSINITSOWNFILEINTHESRCAPPFOLDERGIVEITIDANDNAMEPROPERTIES", "original": "Create a `Hero` class in its own file in the `src/app` folder.\nGive it `id` and `name` properties.", "translation": "在 `src/app` 文件夹中为 `Hero` 类创建一个文件,并添加 `id` 和 `name` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "RETURNTOTHEHEROESCOMPONENTCLASSANDIMPORTTHEHEROCLASS", "original": "Return to the `HeroesComponent` class and import the `Hero` class.", "translation": "回到 `HeroesComponent` 类,并且导入这个 `Hero` 类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "REFACTORTHECOMPONENTSHEROPROPERTYTOBEOFTYPEHEROINITIALIZEITWITHANIDOF1ANDTHENAMEWINDSTORM", "original": "Refactor the component's `hero` property to be of type `Hero`.\nInitialize it with an `id` of `1` and the name `Windstorm`.", "translation": "把组件的 `hero` 属性的类型重构为 `Hero`。\n然后以 `1` 为 `id`、以 “Windstorm” 为名字初始化它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEREVISEDHEROESCOMPONENTCLASSFILESHOULDLOOKLIKETHIS:", "original": "The revised `HeroesComponent` class file should look like this:", "translation": "修改后的 `HeroesComponent` 类应该是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEPAGENOLONGERDISPLAYSPROPERLYBECAUSEYOUCHANGEDTHEHEROFROMASTRINGTOANOBJECT", "original": "The page no longer displays properly because you changed the hero from a string to an object.", "translation": "页面显示变得不正常了,因为你刚刚把 `hero` 从字符串改成了对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "##SHOWTHEHEROOBJECT", "original": "## Show the hero object", "translation": "## 显示 `hero` 对象", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "UPDATETHEBINDINGINTHETEMPLATETOANNOUNCETHEHEROSNAMEANDSHOWBOTHIDANDNAMEINADETAILSLAYOUTLIKETHIS:", "original": "Update the binding in the template to announce the hero's name\nand show both `id` and `name` in a details layout like this:", "translation": "修改模板中的绑定,以显示英雄的名字,并在详情中显示 `id` 和 `name`,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEBROWSERREFRESHESANDDISPLAYSTHEHEROSINFORMATION", "original": "The browser refreshes and display's the hero's information.", "translation": "浏览器自动刷新,并显示这位英雄的信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "##FORMATWITHTHEUPPERCASEPIPE", "original": "## Format with the _UppercasePipe_", "translation": "## 使用 `UppercasePipe` 进行格式化", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "MODIFYTHEHERONAMEBINDINGLIKETHIS", "original": "Modify the `hero.name` binding like this.", "translation": "把 `hero.name` 的绑定修改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEBROWSERREFRESHESANDNOWTHEHEROSNAMEISDISPLAYEDINCAPITALLETTERS", "original": "The browser refreshes and now the hero's name is displayed in capital letters.", "translation": "浏览器刷新了。现在,英雄的名字显示成了大写字母。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEWORDUPPERCASEINTHEINTERPOLATIONBINDINGRIGHTAFTERTHEPIPEOPERATORACTIVATESTHEBUILTINUPPERCASEPIPE", "original": "The word `uppercase` in the interpolation binding, \nright after the pipe operator ( | ),\nactivates the built-in `UppercasePipe`.", "translation": "绑定表达式中的 `uppercase` 位于管道操作符( | )的右边,用来调用内置管道 `UppercasePipe`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "PIPESGUIDEPIPESAREAGOODWAYTOFORMATSTRINGSCURRENCYAMOUNTSDATESANDOTHERDISPLAYDATAANGULARSHIPSWITHSEVERALBUILTINPIPESANDYOUCANCREATEYOUROWN", "original": "[Pipes](guide/pipes) are a good way to format strings, currency amounts, dates and other display data.\nAngular ships with several built-in pipes and you can create your own.", "translation": "[管道](guide/pipes) 是格式化字符串、金额、日期和其它显示数据的好办法。\nAngular 发布了一些内置管道,而且你还可以创建自己的管道。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "##EDITTHEHERO", "original": "## Edit the hero", "translation": "## 编辑英雄名字", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "USERSSHOULDBEABLETOEDITTHEHERONAMEINANINPUTTEXTBOX", "original": "Users should be able to edit the hero name in an `<input>` textbox.", "translation": "用户应该能在一个 `<input>` 输入框中编辑英雄的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THETEXTBOXSHOULDBOTHDISPLAYTHEHEROSNAMEPROPERTYANDUPDATETHATPROPERTYASTHEUSERTYPESTHATMEANSDATAFLOWFROMTHECOMPONENTCLASSOUTTOTHESCREENANDFROMTHESCREENBACKTOTHECLASS", "original": "The textbox should both _display_ the hero's `name` property\nand _update_ that property as the user types.\nThat means data flow from the component class _out to the screen_ and\nfrom the screen _back to the class_.", "translation": "当用户输入时,这个输入框应该能同时*显示*和*修改*英雄的 `name` 属性。\n也就是说,数据流从组件类**流出到屏幕**,并且从屏幕**流回到组件类**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "TOAUTOMATETHATDATAFLOWSETUPATWOWAYDATABINDINGBETWEENTHEINPUTFORMELEMENTANDTHEHERONAMEPROPERTY", "original": "To automate that data flow, setup a two-way data binding between the `<input>` form element and the `hero.name` property.", "translation": "要想让这种数据流动自动化,就要在表单元素 `<input>` 和组件的 `hero.name` 属性之间建立双向数据绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "###TWOWAYBINDING", "original": "### Two-way binding", "translation": "### 双向绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "REFACTORTHEDETAILSAREAINTHEHEROESCOMPONENTTEMPLATESOITLOOKSLIKETHIS:", "original": "Refactor the details area in the `HeroesComponent` template so it looks like this:", "translation": "把模板中的英雄名字重构成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "NGMODELISANGULARSTWOWAYDATABINDINGSYNTAX", "original": "**[(ngModel)]** is Angular's two-way data binding syntax.", "translation": "**[(ngModel)]** 是 Angular 的双向数据绑定语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "HEREITBINDSTHEHERONAMEPROPERTYTOTHEHTMLTEXTBOXSOTHATDATACANFLOWINBOTHDIRECTIONS:FROMTHEHERONAMEPROPERTYTOTHETEXTBOXANDFROMTHETEXTBOXBACKTOTHEHERONAME", "original": "Here it binds the `hero.name` property to the HTML textbox so that data can flow _in both directions:_ from the `hero.name` property to the textbox, and from the textbox back to the `hero.name`.", "translation": "这里把 `hero.name` 属性绑定到了 HTML 的 textbox 元素上,以便数据流可以**双向流动**:从 `hero.name` 属性流动到 textbox,并且从 textbox 流回到 `hero.name` 。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "###THEMISSINGFORMSMODULE", "original": "### The missing _FormsModule_", "translation": "### 缺少 `FormsModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "NOTICETHATTHEAPPSTOPPEDWORKINGWHENYOUADDEDNGMODEL", "original": "Notice that the app stopped working when you added `[(ngModel)]`.", "translation": "注意,当你加上 `[(ngModel)]` 之后这个应用无法工作了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "TOSEETHEERROROPENTHEBROWSERDEVELOPMENTTOOLSANDLOOKINTHECONSOLEFORAMESSAGELIKE", "original": "To see the error, open the browser development tools and look in the console\nfor a message like", "translation": "打开浏览器的开发工具,就会在控制台中看到如下信息:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "ALTHOUGHNGMODELISAVALIDANGULARDIRECTIVEITISNTAVAILABLEBYDEFAULT", "original": "Although `ngModel` is a valid Angular directive, it isn't available by default.", "translation": "虽然 `ngModel` 是一个有效的 Angular 指令,不过它在默认情况下是不可用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "ITBELONGSTOTHEOPTIONALFORMSMODULEANDYOUMUSTOPTINTOUSINGIT", "original": "It belongs to the optional `FormsModule` and you must _opt-in_ to using it.", "translation": "它属于一个可选模块 `FormsModule`,你必须自行添加此模块才能使用该指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "ANGULARNEEDSTOKNOWHOWTHEPIECESOFYOURAPPLICATIONFITTOGETHERANDWHATOTHERFILESANDLIBRARIESTHEAPPREQUIRESTHISINFORMATIONISCALLEDMETADATA", "original": "Angular needs to know how the pieces of your application fit together\nand what other files and libraries the app requires.\nThis information is called _metadata_", "translation": "Angular 需要知道如何把应用程序的各个部分组合到一起,以及该应用需要哪些其它文件和库。\n这些信息被称为*元数据(metadata)*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "SOMEOFTHEMETADATAISINTHECOMPONENTDECORATORSTHATYOUADDEDTOYOURCOMPONENTCLASSESOTHERCRITICALMETADATAISINNGMODULEGUIDENGMODULESDECORATORS", "original": "Some of the metadata is in the `@Component` decorators that you added to your component classes.\nOther critical metadata is in [`@NgModule`](guide/ngmodules) decorators.", "translation": "有些元数据位于 `@Component` 装饰器中,你会把它加到组件类上。\n另一些关键性的元数据位于 [`@NgModule`](guide/ngmodules) 装饰器中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEMOSTIMPORTANTNGMODULEDECORATORANNOTATESTHETOPLEVELAPPMODULECLASS", "original": "The most important `@NgModule`decorator annotates the top-level **AppModule** class.", "translation": "最重要的 `@NgModule` 装饰器位于顶级类 **AppModule** 上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEANGULARCLIGENERATEDANAPPMODULECLASSINSRCAPPAPPMODULETSWHENITCREATEDTHEPROJECTTHISISWHEREYOUOPTINTOTHEFORMSMODULE", "original": "The Angular CLI generated an `AppModule` class in `src/app/app.module.ts` when it created the project.\nThis is where you _opt-in_ to the `FormsModule`.", "translation": "Angular CLI 在创建项目的时候就在 `src/app/app.module.ts` 中生成了一个 `AppModule` 类。\n这里也就是你要添加 `FormsModule` 的地方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "###IMPORTFORMSMODULE", "original": "### Import _FormsModule_", "translation": "### 导入 `FormsModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "OPENAPPMODULEAPPMODULETSANDIMPORTTHEFORMSMODULESYMBOLFROMTHEANGULARFORMSLIBRARY", "original": "Open `AppModule` (`app.module.ts`) and import the `FormsModule` symbol from the `@angular/forms` library.", "translation": "打开 `AppModule` (`app.module.ts`) 并从 `@angular/forms` 库中导入 `FormsModule` 符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THENADDFORMSMODULETOTHENGMODULEMETADATASIMPORTSARRAYWHICHCONTAINSALISTOFEXTERNALMODULESTHATTHEAPPNEEDS", "original": "Then add `FormsModule` to the `@NgModule` metadata's `imports` array, which contains a list of external modules that the app needs.", "translation": "然后把 `FormsModule` 添加到 `@NgModule` 元数据的 `imports` 数组中,这里是该应用所需外部模块的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "WHENTHEBROWSERREFRESHESTHEAPPSHOULDWORKAGAINYOUCANEDITTHEHEROSNAMEANDSEETHECHANGESREFLECTEDIMMEDIATELYINTHEH2ABOVETHETEXTBOX", "original": "When the browser refreshes, the app should work again. You can edit the hero's name and see the changes reflected immediately in the `<h2>` above the textbox.", "translation": "刷新浏览器,应用又能正常工作了。你可以编辑英雄的名字,并且会看到这个改动立刻体现在这个输入框上方的 `<h2>` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "###DECLAREHEROESCOMPONENT", "original": "### Declare _HeroesComponent_", "translation": "### 声明 `HeroesComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "EVERYCOMPONENTMUSTBEDECLAREDINEXACTLYONENGMODULEGUIDENGMODULES", "original": "Every component must be declared in _exactly one_ [NgModule](guide/ngmodules).", "translation": "每个组件都必须声明在(且只能声明在)一个 [NgModule](guide/ngmodules) 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOUDIDNTDECLARETHEHEROESCOMPONENTSOWHYDIDTHEAPPLICATIONWORK", "original": "_You_ didn't declare the `HeroesComponent`.\nSo why did the application work?", "translation": "*你*没有声明过 `HeroesComponent`,可为什么本应用却正常呢?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "ITWORKEDBECAUSETHEANGULARCLIDECLAREDHEROESCOMPONENTINTHEAPPMODULEWHENITGENERATEDTHATCOMPONENT", "original": "It worked because the Angular CLI declared `HeroesComponent` in the `AppModule` when it generated that component.", "translation": "这是因为 Angular CLI 在生成 `HeroesComponent` 组件的时候就自动把它加到了 `AppModule` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "OPENSRCAPPAPPMODULETSANDFINDHEROESCOMPONENTIMPORTEDNEARTHETOP", "original": "Open `src/app/app.module.ts` and find `HeroesComponent` imported near the top.", "translation": "打开 `src/app/app.module.ts` 你就会发现 `HeroesComponent` 已经在顶部导入过了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "THEHEROESCOMPONENTISDECLAREDINTHENGMODULEDECLARATIONSARRAY", "original": "The `HeroesComponent` is declared in the `@NgModule.declarations` array.", "translation": "`HeroesComponent` 也已经声明在了 `@NgModule.declarations` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "NOTETHATAPPMODULEDECLARESBOTHAPPLICATIONCOMPONENTSAPPCOMPONENTANDHEROESCOMPONENT", "original": "Note that `AppModule` declares both application components, `AppComponent` and `HeroesComponent`.", "translation": "注意 `AppModule` 声明了应用中的所有组件,`AppComponent` 和 `HeroesComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "##FINALCODEREVIEW", "original": "## Final code review", "translation": "## 查看最终代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOURAPPSHOULDLOOKLIKETHISLIVEEXAMPLELIVEEXAMPLEHEREARETHECODEFILESDISCUSSEDONTHISPAGE", "original": "Your app should look like this <live-example></live-example>. Here are the code files discussed on this page.", "translation": "应用跑起来应该是这样的:<live-example></live-example>。本页中所提及的代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOUUSEDTHECLITOCREATEASECONDHEROESCOMPONENT", "original": "* You used the CLI to create a second `HeroesComponent`.", "translation": "你使用 CLI 创建了第二个组件 `HeroesComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOUDISPLAYEDTHEHEROESCOMPONENTBYADDINGITTOTHEAPPCOMPONENTSHELL", "original": "* You displayed the `HeroesComponent` by adding it to the `AppComponent` shell.", "translation": "你把 `HeroesComponent` 添加到了壳组件 `AppComponent` 中,以便显示它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOUAPPLIEDTHEUPPERCASEPIPETOFORMATTHENAME", "original": "* You applied the `UppercasePipe` to format the name.", "translation": "你使用 `UppercasePipe` 来格式化英雄的名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOUUSEDTWOWAYDATABINDINGWITHTHENGMODELDIRECTIVE", "original": "* You used two-way data binding with the `ngModel` directive.", "translation": "你用 `ngModel` 指令实现了双向数据绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOULEARNEDABOUTTHEAPPMODULE", "original": "* You learned about the `AppModule`.", "translation": "你知道了 `AppModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOUIMPORTEDTHEFORMSMODULEINTHEAPPMODULESOTHATANGULARWOULDRECOGNIZEANDAPPLYTHENGMODELDIRECTIVE", "original": "* You imported the `FormsModule` in the `AppModule` so that Angular would recognize and apply the `ngModel` directive.", "translation": "你把 `FormsModule` 导入了 `AppModule`,以便 Angular 能识别并应用 `ngModel` 指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "YOULEARNEDTHEIMPORTANCEOFDECLARINGCOMPONENTSINTHEAPPMODULEANDAPPRECIATEDTHATTHECLIDECLAREDITFORYOU", "original": "* You learned the importance of declaring components in the `AppModule`\nand appreciated that the CLI declared it for you.", "translation": "你知道了把组件声明到 `AppModule` 是很重要的,并认识到 CLI 会自动帮你声明它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt1.md" }, { + "key": "#DISPLAYAHEROESLIST", "original": "# Display a Heroes List", "translation": "# 显示英雄列表", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "INTHISPAGEYOULLEXPANDTHETOUROFHEROESAPPTODISPLAYALISTOFHEROESANDALLOWUSERSTOSELECTAHEROANDDISPLAYTHEHEROSDETAILS", "original": "In this page, you'll expand the Tour of Heroes app to display a list of heroes, and\nallow users to select a hero and display the hero's details.", "translation": "本页中,你将扩展《英雄指南》应用,让它显示一个英雄列表,\n并允许用户选择一个英雄,查看该英雄的详细信息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "##CREATEMOCKHEROES", "original": "## Create mock heroes", "translation": "## 创建模拟(mock)的英雄数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOULLNEEDSOMEHEROESTODISPLAY", "original": "You'll need some heroes to display.", "translation": "你需要一些英雄数据以供显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "EVENTUALLYYOULLGETTHEMFROMAREMOTEDATASERVERFORNOWYOULLCREATESOMEMOCKHEROESANDPRETENDTHEYCAMEFROMTHESERVER", "original": "Eventually you'll get them from a remote data server.\nFor now, you'll create some _mock heroes_ and pretend they came from the server.", "translation": "最终,你会从远端的数据服务器获取它。\n不过目前,你要先创建一些*模拟的英雄数据*,并假装它们是从服务器上取到的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "CREATEAFILECALLEDMOCKHEROESTSINTHESRCAPPFOLDERDEFINEAHEROESCONSTANTASANARRAYOFTENHEROESANDEXPORTITTHEFILESHOULDLOOKLIKETHIS", "original": "Create a file called `mock-heroes.ts` in the `src/app/` folder.\nDefine a `HEROES` constant as an array of ten heroes and export it.\nThe file should look like this.", "translation": "在 `src/app/` 文件夹中创建一个名叫 `mock-heroes.ts` 的文件。\n定义一个包含十个英雄的常量数组 `HEROES`,并导出它。\n该文件是这样的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "##DISPLAYINGHEROES", "original": "## Displaying heroes", "translation": "## 显示这些英雄", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOUREABOUTTODISPLAYTHELISTOFHEROESATTHETOPOFTHEHEROESCOMPONENT", "original": "You're about to display the list of heroes at the top of the `HeroesComponent`.", "translation": "你要在 `HeroesComponent` 的顶部显示这个英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "OPENTHEHEROESCOMPONENTCLASSFILEANDIMPORTTHEMOCKHEROES", "original": "Open the `HeroesComponent` class file and import the mock `HEROES`.", "translation": "打开 `HeroesComponent` 类文件,并导入模拟的 `HEROES`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "ADDAHEROESPROPERTYTOTHECLASSTHATEXPOSESTHESEHEROESFORBINDING", "original": "Add a `heroes` property to the class that exposes these heroes for binding.", "translation": "往类中添加一个 `heroes` 属性,这样可以暴露出这些英雄,以供绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "###LISTHEROESWITHNGFOR", "original": "### List heroes with _*ngFor_", "translation": "### 使用 `*ngFor` 列出这些英雄", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "OPENTHEHEROESCOMPONENTTEMPLATEFILEANDMAKETHEFOLLOWINGCHANGES:", "original": "Open the `HeroesComponent` template file and make the following changes:", "translation": "打开 `HeroesComponent` 的模板文件,并做如下修改:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "ADDANH2ATTHETOP", "original": "* Add an `<h2>` at the top,", "translation": "在顶部添加 `<h2>`,", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "BELOWITADDANHTMLUNORDEREDLISTUL", "original": "* Below it add an HTML unordered list (`<ul>`)", "translation": "然后添加表示无序列表的 HTML 元素(`<ul>`)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "INSERTANLIWITHINTHEULTHATDISPLAYSPROPERTIESOFAHERO", "original": "* Insert an `<li>` within the `<ul>` that displays properties of a `hero`.", "translation": "在 `<ul>` 中插入一个 `<li>` 元素,以显示单个 `hero` 的属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "SPRINKLESOMECSSCLASSESFORSTYLINGYOULLADDTHECSSSTYLESSHORTLY", "original": "* Sprinkle some CSS classes for styling (you'll add the CSS styles shortly).", "translation": "点缀上一些 CSS 类(稍后你还会添加更多 CSS 样式)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "MAKEITLOOKLIKETHIS:", "original": "Make it look like this:", "translation": "做完之后应该是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "NOWCHANGETHELITOTHIS:", "original": "Now change the `<li>` to this:", "translation": "现在,把 `<li>` 修改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THENGFORGUIDETEMPLATESYNTAX#NGFORISANGULARSREPEATERDIRECTIVEITREPEATSTHEHOSTELEMENTFOREACHELEMENTINALIST", "original": "The [`*ngFor`](guide/template-syntax#ngFor) is Angular's _repeater_ directive. \nIt repeats the host element for each element in a list.", "translation": "[`*ngFor`](guide/template-syntax#ngFor) 是一个 Angular 的复写器(repeater)指令。\n它会为列表中的每项数据复写它的宿主元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "INTHISEXAMPLE", "original": "In this example", "translation": "在这个例子中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "LIISTHEHOSTELEMENT", "original": "* `<li>` is the host element", "translation": "`<li>` 就是 `*ngFor` 的宿主元素", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "HEROESISTHELISTFROMTHEHEROESCOMPONENTCLASS", "original": "* `heroes` is the list from the `HeroesComponent` class.", "translation": "`heroes` 就是来自 `HeroesComponent` 类的列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "HEROHOLDSTHECURRENTHEROOBJECTFOREACHITERATIONTHROUGHTHELIST", "original": "* `hero` holds the current hero object for each iteration through the list.", "translation": "当依次遍历这个列表时,`hero` 会为每个迭代保存当前的英雄对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "DONTFORGETTHEASTERISKINFRONTOFNGFORITSACRITICALPARTOFTHESYNTAX", "original": "Don't forget the asterisk (*) in front of `ngFor`. It's a critical part of the syntax.", "translation": "不要忘了 `ngFor` 前面的星号(`*`),它是该语法中的关键部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "AFTERTHEBROWSERREFRESHESTHELISTOFHEROESAPPEARS", "original": "After the browser refreshes, the list of heroes appears.", "translation": "浏览器刷新之后,英雄列表出现了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "###STYLETHEHEROES", "original": "### Style the heroes", "translation": "### 给英雄们“美容”", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THEHEROESLISTSHOULDBEATTRACTIVEANDSHOULDRESPONDVISUALLYWHENUSERSHOVEROVERANDSELECTAHEROFROMTHELIST", "original": "The heroes list should be attractive and should respond visually when users \nhover over and select a hero from the list.", "translation": "英雄列表应该富有吸引力,并且当用户把鼠标移到某个英雄上和从列表中选中某个英雄时,应该给出视觉反馈。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "INTHEFIRSTTUTORIALTUTORIALTOHPT0#APPWIDESTYLESYOUSETTHEBASICSTYLESFORTHEENTIREAPPLICATIONINSTYLESCSSTHATSTYLESHEETDIDNTINCLUDESTYLESFORTHISLISTOFHEROES", "original": "In the [first tutorial](tutorial/toh-pt0#app-wide-styles), you set the basic styles for the entire application in `styles.css`.\nThat stylesheet didn't include styles for this list of heroes.", "translation": "在[教程的第一章](tutorial/toh-pt0#app-wide-styles),你曾在 `styles.css` 中为整个应用设置了一些基础的样式。\n但那个样式表并不包含英雄列表所需的样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOUCOULDADDMORESTYLESTOSTYLESCSSANDKEEPGROWINGTHATSTYLESHEETASYOUADDCOMPONENTS", "original": "You could add more styles to `styles.css` and keep growing that stylesheet as you add components.", "translation": "固然,你可以把更多样式加入到 `styles.css`,并且放任它随着你添加更多组件而不断膨胀。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOUMAYPREFERINSTEADTODEFINEPRIVATESTYLESFORASPECIFICCOMPONENTANDKEEPEVERYTHINGACOMPONENTNEEDSMDASHTHECODETHEHTMLANDTHECSSMDASHTOGETHERINONEPLACE", "original": "You may prefer instead to define private styles for a specific component and keep everything a component needs— the code, the HTML,\nand the CSS —together in one place.", "translation": "但还有更好的方式。你可以定义属于特定组件的私有样式,并且让组件所需的一切(代码、HTML 和 CSS)都放在一起。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THISAPPROACHMAKESITEASIERTOREUSETHECOMPONENTSOMEWHEREELSEANDDELIVERTHECOMPONENTSINTENDEDAPPEARANCEEVENIFTHEGLOBALSTYLESAREDIFFERENT", "original": "This approach makes it easier to re-use the component somewhere else\nand deliver the component's intended appearance even if the global styles are different.", "translation": "这种方式让你在其它地方复用该组件更加容易,并且即使全局样式和这里不一样,组件也仍然具有期望的外观。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOUDEFINEPRIVATESTYLESEITHERINLINEINTHECOMPONENTSTYLESARRAYORASSTYLESHEETFILESIDENTIFIEDINTHECOMPONENTSTYLEURLSARRAY", "original": "You define private styles either inline in the `@Component.styles` array or\nas stylesheet file(s) identified in the `@Component.styleUrls` array.", "translation": "你可以用多种方式定义私有样式,或者内联在 `@Component.styles` 数组中,或者在 `@Component.styleUrls` 所指出的样式表文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "WHENTHECLIGENERATEDTHEHEROESCOMPONENTITCREATEDANEMPTYHEROESCOMPONENTCSSSTYLESHEETFORTHEHEROESCOMPONENTANDPOINTEDTOITINCOMPONENTSTYLEURLSLIKETHIS", "original": "When the CLI generated the `HeroesComponent`, it created an empty `heroes.component.css` stylesheet for the `HeroesComponent`\nand pointed to it in `@Component.styleUrls` like this.", "translation": "当 CLI 生成 `HeroesComponent` 时,它也同时为 `HeroesComponent` 创建了空白的 `heroes.component.css` 样式表文件,并且让 `@Component.styleUrls` 指向它,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "OPENTHEHEROESCOMPONENTCSSFILEANDPASTEINTHEPRIVATECSSSTYLESFORTHEHEROESCOMPONENTYOULLFINDTHEMINTHEFINALCODEREVIEW#FINALCODEREVIEWATTHEBOTTOMOFTHISGUIDE", "original": "Open the `heroes.component.css` file and paste in the private CSS styles for the `HeroesComponent`.\nYou'll find them in the [final code review](#final-code-review) at the bottom of this guide.", "translation": "打开 `heroes.component.css` 文件,并且把 `HeroesComponent` 的私有 CSS 样式粘贴进去。\n你可以在本指南底部的[查看最终代码](#final-code-review)中找到它们。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "STYLESANDSTYLESHEETSIDENTIFIEDINCOMPONENTMETADATAARESCOPEDTOTHATSPECIFICCOMPONENTTHEHEROESCOMPONENTCSSSTYLESAPPLYONLYTOTHEHEROESCOMPONENTANDDONTAFFECTTHEOUTERHTMLORTHEHTMLINANYOTHERCOMPONENT", "original": "Styles and stylesheets identified in `@Component` metadata are scoped to that specific component.\nThe `heroes.component.css` styles apply only to the `HeroesComponent` and don't affect the outer HTML or the HTML in any other component.", "translation": "`@Component` 元数据中指定的样式和样式表都是局限于该组件的。\n`heroes.component.css` 中的样式只会作用于 `HeroesComponent`,既不会影响到组件外的 HTML,也不会影响到其它组件中的 HTML。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "##MASTERDETAIL", "original": "## Master/Detail", "translation": "## 主从结构", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "WHENTHEUSERCLICKSAHEROINTHEMASTERLISTTHECOMPONENTSHOULDDISPLAYTHESELECTEDHEROSDETAILSATTHEBOTTOMOFTHEPAGE", "original": "When the user clicks a hero in the **master** list, \nthe component should display the selected hero's **details** at the bottom of the page.", "translation": "当用户在**主**列表中点击一个英雄时,该组件应该在页面底部显示所选英雄的**详情**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "INTHISSECTIONYOULLLISTENFORTHEHEROITEMCLICKEVENTANDUPDATETHEHERODETAIL", "original": "In this section, you'll listen for the hero item click event\nand update the hero detail.", "translation": "在本节,你将监听英雄条目的点击事件,并更新英雄的详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "###ADDACLICKEVENTBINDING", "original": "### Add a click event binding", "translation": "### 添加 `click` 事件绑定", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "ADDACLICKEVENTBINDINGTOTHELILIKETHIS:", "original": "Add a click event binding to the `<li>` like this:", "translation": "再往 `<li>` 元素上插入一句点击事件的绑定代码:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THISISANEXAMPLEOFANGULARSEVENTBINDINGGUIDETEMPLATESYNTAX#EVENTBINDINGSYNTAX", "original": "This is an example of Angular's [event binding](guide/template-syntax#event-binding) syntax.", "translation": "这是 Angular [事件绑定](guide/template-syntax#event-binding) 语法的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THEPARENTHESESAROUNDCLICKTELLANGULARTOLISTENFORTHELIELEMENTSCLICKEVENTWHENTHEUSERCLICKSINTHELIANGULAREXECUTESTHEONSELECTHEROEXPRESSION", "original": "The parentheses around `click` tell Angular to listen for the `<li>` element's `click` event.\nWhen the user clicks in the `<li>`, Angular executes the `onSelect(hero)` expression.", "translation": "`click` 外面的圆括号会让 Angular 监听这个 `<li>` 元素的 `click` 事件。\n当用户点击 `<li>` 时,Angular 就会执行表达式 `onSelect(hero)`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "ONSELECTISAHEROESCOMPONENTMETHODTHATYOUREABOUTTOWRITEANGULARCALLSITWITHTHEHEROOBJECTDISPLAYEDINTHECLICKEDLITHESAMEHERODEFINEDPREVIOUSLYINTHENGFOREXPRESSION", "original": "`onSelect()` is a `HeroesComponent` method that you're about to write.\nAngular calls it with the `hero` object displayed in the clicked `<li>`,\nthe same `hero` defined previously in the `*ngFor` expression.", "translation": "`onSelect()` 是 `HeroesComponent` 上的一个方法,你很快就要写它。\nAngular 会把所点击的 `<li>` 上的 `hero` 对象传给它,这个 `hero` 也就是以前在 `*ngFor` 表达式中定义的那个。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "###ADDTHECLICKEVENTHANDLER", "original": "### Add the click event handler", "translation": "### 添加 `click` 事件处理器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "RENAMETHECOMPONENTSHEROPROPERTYTOSELECTEDHEROBUTDONTASSIGNITTHEREISNOSELECTEDHEROWHENTHEAPPLICATIONSTARTS", "original": "Rename the component's `hero` property to `selectedHero` but don't assign it.\nThere is no _selected hero_ when the application starts.", "translation": "把该组件的 `hero` 属性改名为 `selectedHero`,但不要为它赋值。\n因为应用刚刚启动时并没有*所选英雄*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "ADDTHEFOLLOWINGONSELECTMETHODWHICHASSIGNSTHECLICKEDHEROFROMTHETEMPLATETOTHECOMPONENTSSELECTEDHERO", "original": "Add the following `onSelect()` method, which assigns the clicked hero from the template\nto the component's `selectedHero`.", "translation": "添加如下 `onSelect()` 方法,它会把模板中被点击的英雄赋值给组件的 `selectedHero` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "###UPDATETHEDETAILSTEMPLATE", "original": "### Update the details template", "translation": "### 修改详情模板", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THETEMPLATESTILLREFERSTOTHECOMPONENTSOLDHEROPROPERTYWHICHNOLONGEREXISTSRENAMEHEROTOSELECTEDHERO", "original": "The template still refers to the component's old `hero` property which no longer exists. \nRename `hero` to `selectedHero`.", "translation": "该模板引用的仍然是老的 `hero` 属性,但它已经不存在了。\n把 `hero` 改名为 `selectedHero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "###HIDEEMPTYDETAILSWITHNGIF", "original": "### Hide empty details with _*ngIf_", "translation": "### 使用 `*ngIf` 隐藏空白的详情", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "AFTERTHEBROWSERREFRESHESTHEAPPLICATIONISBROKEN", "original": "After the browser refreshes, the application is broken.", "translation": "刷新浏览器,应用挂了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "OPENTHEBROWSERDEVELOPERTOOLSANDLOOKINTHECONSOLEFORANERRORMESSAGELIKETHIS:", "original": "Open the browser developer tools and look in the console for an error message like this:", "translation": "打开浏览器的开发者工具,它的控制台中显示出如下错误信息:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "NOWCLICKONEOFTHELISTITEMSTHEAPPSEEMSTOBEWORKINGAGAINTHEHEROESAPPEARINALISTANDDETAILSABOUTTHECLICKEDHEROAPPEARATTHEBOTTOMOFTHEPAGE", "original": "Now click one of the list items.\nThe app seems to be working again.\nThe heroes appear in a list and details about the clicked hero appear at the bottom of the page.", "translation": "现在,从列表中随便点击一个条目。\n应用又正常了。\n英雄们显示在列表中,并且所点英雄的详情也显示在了页面的下方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "####WHATHAPPENED", "original": "#### What happened?", "translation": "#### 怎么回事?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "WHENTHEAPPSTARTSTHESELECTEDHEROISUNDEFINEDBYDESIGN", "original": "When the app starts, the `selectedHero` is `undefined` _by design_.", "translation": "当应用启动时,`selectedHero` 是 `undefined`,*设计如此*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "BINDINGEXPRESSIONSINTHETEMPLATETHATREFERTOPROPERTIESOFSELECTEDHEROMDASHEXPRESSIONSLIKESELECTEDHERONAMEMDASHMUSTFAILBECAUSETHEREISNOSELECTEDHERO", "original": "Binding expressions in the template that refer to properties of `selectedHero` — expressions like `{{selectedHero.name}}` — _must fail_ because there is no selected hero.", "translation": "但模板中的绑定表达式引用了 `selectedHero` 的属性(表达式为 `{{selectedHero.name}}`),这必然会失败,因为你还没选过英雄呢。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "####THEFIX", "original": "#### The fix", "translation": "#### 修复", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THECOMPONENTSHOULDONLYDISPLAYTHESELECTEDHERODETAILSIFTHESELECTEDHEROEXISTS", "original": "The component should only display the selected hero details if the `selectedHero` exists.", "translation": "该组件应该只有当 `selectedHero` 存在时才显示所选英雄的详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "WRAPTHEHERODETAILHTMLINADIVADDANGULARSNGIFDIRECTIVETOTHEDIVANDSETITTOSELECTEDHERO", "original": "Wrap the hero detail HTML in a `<div>`.\nAdd Angular's `*ngIf` directive to the `<div>` and set it to `selectedHero`.", "translation": "把显示英雄详情的 HTML 包裹在一个 `<div>` 中。\n并且为这个 div 添加 Angular 的 `*ngIf` 指令,把它的值设置为 `selectedHero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "DONTFORGETTHEASTERISKINFRONTOFNGIFITSACRITICALPARTOFTHESYNTAX", "original": "Don't forget the asterisk (*) in front of `ngIf`. It's a critical part of the syntax.", "translation": "不要忘了 `ngIf` 前面的星号(`*`),它是该语法中的关键部分。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "AFTERTHEBROWSERREFRESHESTHELISTOFNAMESREAPPEARSTHEDETAILSAREAISBLANKCLICKAHEROANDITSDETAILSAPPEAR", "original": "After the browser refreshes, the list of names reappears.\nThe details area is blank.\nClick a hero and its details appear.", "translation": "浏览器刷新之后,英雄名字的列表又出现了。\n详情部分仍然是空。\n点击一个英雄,它的详情就出现了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "####WHYITWORKS", "original": "#### Why it works", "translation": "#### 为什么改好了?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "WHENSELECTEDHEROISUNDEFINEDTHENGIFREMOVESTHEHERODETAILFROMTHEDOMTHEREARENOSELECTEDHEROBINDINGSTOWORRYABOUT", "original": "When `selectedHero` is undefined, the `ngIf` removes the hero detail from the DOM. There are no `selectedHero` bindings to worry about.", "translation": "当 `selectedHero` 为 `undefined` 时,`ngIf` 从 DOM 中移除了英雄详情。因此也就不用担心 `selectedHero` 的绑定了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "WHENTHEUSERPICKSAHEROSELECTEDHEROHASAVALUEANDNGIFPUTSTHEHERODETAILINTOTHEDOM", "original": "When the user picks a hero, `selectedHero` has a value and\n`ngIf` puts the hero detail into the DOM.", "translation": "当用户选择一个英雄时,`selectedHero` 也就有了值,并且 `ngIf` 把英雄的详情放回到 DOM 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "###STYLETHESELECTEDHERO", "original": "### Style the selected hero", "translation": "### 给所选英雄添加样式", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "ITSDIFFICULTTOIDENTIFYTHESELECTEDHEROINTHELISTWHENALLLIELEMENTSLOOKALIKE", "original": "It's difficult to identify the _selected hero_ in the list when all `<li>` elements look alike.", "translation": "所有的 `<li>` 元素看起来都是一样的,因此很难从列表中识别出*所选英雄*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "IFTHEUSERCLICKSMAGNETATHATHEROSHOULDRENDERWITHADISTINCTIVEBUTSUBTLEBACKGROUNDCOLORLIKETHIS:", "original": "If the user clicks \"Magneta\", that hero should render with a distinctive but subtle background color like this:", "translation": "如果用户点击了“Magneta”,这个英雄应该用一个略有不同的背景色显示出来,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THATSELECTEDHEROCOLORINGISTHEWORKOFTHESELECTEDCSSCLASSINTHESTYLESYOUADDEDEARLIER#STYLESYOUJUSTHAVETOAPPLYTHESELECTEDCLASSTOTHELIWHENTHEUSERCLICKSIT", "original": "That _selected hero_ coloring is the work of the `.selected` CSS class in the [styles you added earlier](#styles).\nYou just have to apply the `.selected` class to the `<li>` when the user clicks it.", "translation": "*所选英雄*的颜色来自于[你前面添加的样式](#styles)中的 CSS 类 `.selected`。\n所以你只要在用户点击一个 `<li>` 时把 `.selected` 类应用到该元素上就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THEANGULARCLASSBINDINGGUIDETEMPLATESYNTAX#CLASSBINDINGMAKESITEASYTOADDANDREMOVEACSSCLASSCONDITIONALLYJUSTADDCLASSSOMECSSCLASSSOMECONDITIONTOTHEELEMENTYOUWANTTOSTYLE", "original": "The Angular [class binding](guide/template-syntax#class-binding) makes it easy to add and remove a CSS class conditionally. \nJust add `[class.some-css-class]=\"some-condition\"` to the element you want to style.", "translation": "Angular 的 [CSS 类绑定](guide/template-syntax#class-binding)机制让根据条件添加或移除一个 CSS 类变得很容易。\n只要把 `[class.some-css-class]=\"some-condition\"` 添加到你要施加样式的元素上就可以了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "ADDTHEFOLLOWINGCLASSSELECTEDBINDINGTOTHELIINTHEHEROESCOMPONENTTEMPLATE:", "original": "Add the following `[class.selected]` binding to the `<li>` in the `HeroesComponent` template:", "translation": "在 `HeroesComponent` 模板中的 `<li>` 元素上添加 `[class.selected]` 绑定,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "WHENTHECURRENTROWHEROISTHESAMEASTHESELECTEDHEROANGULARADDSTHESELECTEDCSSCLASSWHENTHETWOHEROESAREDIFFERENTANGULARREMOVESTHECLASS", "original": "When the current row hero is the same as the `selectedHero`, Angular adds the `selected` CSS class. When the two heroes are different, Angular removes the class.", "translation": "如果当前行的英雄和 `selectedHero` 相同,Angular 就会添加 CSS 类 `selected`,否则就会移除它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THEFINISHEDLILOOKSLIKETHIS:", "original": "The finished `<li>` looks like this:", "translation": "最终的 `<li>` 是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "##FINALCODEREVIEW", "original": "## Final code review", "translation": "## 查看最终代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOURAPPSHOULDLOOKLIKETHISLIVEEXAMPLELIVEEXAMPLE", "original": "Your app should look like this <live-example></live-example>.", - "translation": "本应用现在变成了这样:<live-example></live-example>。", + "translation": "你的应用现在变成了这样:<live-example></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "HEREARETHECODEFILESDISCUSSEDONTHISPAGEINCLUDINGTHEHEROESCOMPONENTSTYLES", "original": "Here are the code files discussed on this page, including the `HeroesComponent` styles.", "translation": "下面是本页面中所提及的代码文件,包括 `HeroesComponent` 的样式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THETOUROFHEROESAPPDISPLAYSALISTOFHEROESINAMASTERDETAILVIEW", "original": "* The Tour of Heroes app displays a list of heroes in a Master/Detail view.", "translation": "英雄指南应用在一个主从视图中显示了英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "THEUSERCANSELECTAHEROANDSEETHATHEROSDETAILS", "original": "* The user can select a hero and see that hero's details.", "translation": "用户可以选择一个英雄,并查看该英雄的详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOUUSEDNGFORTODISPLAYALIST", "original": "* You used `*ngFor` to display a list.", "translation": "你使用 `*ngFor` 显示了一个列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOUUSEDNGIFTOCONDITIONALLYINCLUDEOREXCLUDEABLOCKOFHTML", "original": "* You used `*ngIf` to conditionally include or exclude a block of HTML.", "translation": "你使用 `*ngIf` 来根据条件包含或排除了一段 HTML。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "YOUCANTOGGLEACSSSTYLECLASSWITHACLASSBINDING", "original": "* You can toggle a CSS style class with a `class` binding.", "translation": "你可以用 `class` 绑定来切换 CSS 的样式类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt2.md" }, { + "key": "#MASTERDETAILCOMPONENTS", "original": "# Master/Detail Components", "translation": "# 主从组件", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "ATTHEMOMENTTHEHEROESCOMPONENTDISPLAYSBOTHTHELISTOFHEROESANDTHESELECTEDHEROSDETAILS", "original": "At the moment, the `HeroesComponent` displays both the list of heroes and the selected hero's details.", "translation": "此刻,`HeroesComponent` 同时显示了英雄列表和所选英雄的详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "KEEPINGALLFEATURESINONECOMPONENTASTHEAPPLICATIONGROWSWILLNOTBEMAINTAINABLEYOULLWANTTOSPLITUPLARGECOMPONENTSINTOSMALLERSUBCOMPONENTSEACHFOCUSEDONASPECIFICTASKORWORKFLOW", "original": "Keeping all features in one component as the application grows will not be maintainable.\nYou'll want to split up large components into smaller sub-components, each focused on a specific task or workflow.", "translation": "把所有特性都放在同一个组件中,将会使应用“长大”后变得不可维护。\n你要把大型组件拆分成小一点的子组件,每个子组件都要集中精力处理某个特定的任务或工作流。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { - "original": "In this page, you'll take the first step in that direction by moving the hero details into a separate, reusable `HeroDetailComponent`.", + "key": "INTHISPAGEYOULLTAKETHEFIRSTSTEPINTHATDIRECTIONBYMOVINGTHEHERODETAILSINTOASEPARATEREUSABLEHERODETAILSCOMPONENT", + "original": "In this page, you'll take the first step in that direction by moving the hero details into a separate, reusable `HeroDetailsComponent`.", "translation": "本页面中,你将迈出第一步 —— 把英雄详情移入一个独立的、可复用的 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { - "original": "The `HeroesComponent` will only present the list of heroes.\nThe `HeroDetailComponent` will present details of a selected hero.", + "key": "THEHEROESCOMPONENTWILLONLYPRESENTTHELISTOFHEROESTHEHERODETAILSCOMPONENTWILLPRESENTDETAILSOFASELECTEDHERO", + "original": "The `HeroesComponent` will only present the list of heroes.\nThe `HeroDetailsComponent` will present details of a selected hero.", "translation": "`HeroesComponent` 将仅仅用来表示英雄列表。\n`HeroDetailComponent` 将用来表示所选英雄的详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "##MAKETHEHERODETAILCOMPONENT", "original": "## Make the `HeroDetailComponent`", "translation": "## 制作 `HeroDetailComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "USETHEANGULARCLITOGENERATEANEWCOMPONENTNAMEDHERODETAIL", "original": "Use the Angular CLI to generate a new component named `hero-detail`.", "translation": "使用 Angular CLI 生成一个名叫 `hero-detail` 的新组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THECOMMANDSCAFFOLDSTHEHERODETAILCOMPONENTFILESANDDECLARESTHECOMPONENTINAPPMODULE", "original": "The command scaffolds the `HeroDetailComponent` files and declares the component in `AppModule`.", "translation": "该命令会生成 `HeroDetailComponent` 文件的脚手架,并把它声明在 `AppModule` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "###WRITETHETEMPLATE", "original": "### Write the template", "translation": "### 编写模板", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "CUTTHEHTMLFORTHEHERODETAILFROMTHEBOTTOMOFTHEHEROESCOMPONENTTEMPLATEANDPASTEITOVERTHEGENERATEDBOILERPLATEINTHEHERODETAILCOMPONENTTEMPLATE", "original": "Cut the HTML for the hero detail from the bottom of the `HeroesComponent` template and paste it over the generated boilerplate in the `HeroDetailComponent` template.", "translation": "从 `HeroesComponent` 模板的底部把表示英雄详情的 HTML 代码剪切粘贴到所生成的 `HeroDetailComponent` 模板中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THEPASTEDHTMLREFERSTOASELECTEDHEROTHENEWHERODETAILCOMPONENTCANPRESENTANYHERONOTJUSTASELECTEDHEROSOREPLACESELECTEDHEROWITHHEROEVERYWHEREINTHETEMPLATE", "original": "The pasted HTML refers to a `selectedHero`.\nThe new `HeroDetailComponent` can present _any_ hero, not just a selected hero.\nSo replace \"selectedHero\" with \"hero\" everywhere in the template.", "translation": "所粘贴的 HTML 引用了 `selectedHero`。\n新的 `HeroDetailComponent` 可以展示*任意*英雄,而不仅仅所选的。因此还要把模板中的所有 `selectedHero` 替换为 `hero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "WHENYOUREDONETHEHERODETAILCOMPONENTTEMPLATESHOULDLOOKLIKETHIS:", "original": "When you're done, the `HeroDetailComponent` template should look like this:", "translation": "完工之后,`HeroDetailComponent` 的模板应该是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "###ADDTHEINPUTHEROPROPERTY", "original": "### Add the `@Input()` hero property", "translation": "### 添加 `@Input() hero` 属性", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THEHERODETAILCOMPONENTTEMPLATEBINDSTOTHECOMPONENTSHEROPROPERTYWHICHISOFTYPEHERO", "original": "The `HeroDetailComponent` template binds to the component's `hero` property\nwhich is of type `Hero`.", "translation": "`HeroDetailComponent` 模板中绑定了组件中的 `hero` 属性,它的类型是 `Hero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "OPENTHEHERODETAILCOMPONENTCLASSFILEANDIMPORTTHEHEROSYMBOL", "original": "Open the `HeroDetailComponent` class file and import the `Hero` symbol.", "translation": "打开 `HeroDetailComponent` 类文件,并导入 `Hero` 符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THEHEROPROPERTYMUSTBEANINPUTPROPERTYGUIDETEMPLATESYNTAX#INPUTSOUTPUTSINPUTANDOUTPUTPROPERTIESANNOTATEDWITHTHEINPUTDECORATORBECAUSETHEEXTERNALHEROESCOMPONENTWILLBINDTOIT#HEROESCOMPONENTTEMPLATELIKETHIS", "original": "The `hero` property \n[must be an _Input_ property](guide/template-syntax#inputs-outputs \"Input and Output properties\"),\nannotated with the `@Input()` decorator,\nbecause the _external_ `HeroesComponent` [will bind to it](#heroes-component-template) like this.", "translation": "`hero` 属性[必须是一个带有 `@Input()` 装饰器的输入属性](guide/template-syntax#inputs-outputs \"Input and Output properties\"),因为*外部的* `HeroesComponent` 组件[将会绑定到它](#heroes-component-template)。就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "AMENDTHEANGULARCOREIMPORTSTATEMENTTOINCLUDETHEINPUTSYMBOL", "original": "Amend the `@angular/core` import statement to include the `Input` symbol.", "translation": "修改 `@angular/core` 的导入语句,导入 `Input` 符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "ADDAHEROPROPERTYPRECEDEDBYTHEINPUTDECORATOR", "original": "Add a `hero` property, preceded by the `@Input()` decorator.", "translation": "添加一个带有 `@Input()` 装饰器的 `hero` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THATSTHEONLYCHANGEYOUSHOULDMAKETOTHEHERODETAILCOMPONENTCLASSTHEREARENOMOREPROPERTIESTHERESNOPRESENTATIONLOGICTHISCOMPONENTSIMPLYRECEIVESAHEROOBJECTTHROUGHITSHEROPROPERTYANDDISPLAYSIT", "original": "That's the only change you should make to the `HeroDetailComponent` class.\nThere are no more properties. There's no presentation logic. \nThis component simply receives a hero object through its `hero` property and displays it.", "translation": "这就是你要对 `HeroDetailComponent` 类做的唯一一项修改。\n没有其它属性,也没有展示逻辑。这个组件所做的只是通过 `hero` 属性接收一个英雄对象,并显示它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "##SHOWTHEHERODETAILCOMPONENT", "original": "## Show the `HeroDetailComponent`", "translation": "## 显示 `HeroDetailComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THEHEROESCOMPONENTISSTILLAMASTERDETAILVIEW", "original": "The `HeroesComponent` is still a master/detail view.", "translation": "`HeroesComponent` 仍然是主从视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "ITUSEDTODISPLAYTHEHERODETAILSONITSOWNBEFOREYOUCUTTHATPORTIONOFTHETEMPLATENOWITWILLDELEGATETOTHEHERODETAILCOMPONENT", "original": "It used to display the hero details on its own, before you cut that portion of the template. Now it will delegate to the `HeroDetailComponent`.", "translation": "在你从模板中剪切走代码之前,它自己负责显示英雄的详情。现在它要把这个职责委托给 `HeroDetailComponent` 了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THETWOCOMPONENTSWILLHAVEAPARENTCHILDRELATIONSHIPTHEPARENTHEROESCOMPONENTWILLCONTROLTHECHILDHERODETAILCOMPONENTBYSENDINGITANEWHEROTODISPLAYWHENEVERTHEUSERSELECTSAHEROFROMTHELIST", "original": "The two components will have a parent/child relationship.\nThe parent `HeroesComponent` will control the child `HeroDetailComponent` \nby sending it a new hero to display whenever\nthe user selects a hero from the list.", "translation": "这两个组件将会具有父子关系。\n当用户从列表中选择了某个英雄时,父组件 `HeroesComponent` 将通过把要显示的新英雄发送给子组件 `HeroDetailComponent`,来控制子组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "YOUWONTCHANGETHEHEROESCOMPONENTCLASSBUTYOUWILLCHANGEITSTEMPLATE", "original": "You won't change the `HeroesComponent` _class_ but you will change its _template_.", "translation": "你不用修改 `HeroesComponent` *类*,但是要修改它的*模板*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "###UPDATETHEHEROESCOMPONENTTEMPLATE", "original": "### Update the `HeroesComponent` template", "translation": "### 修改 `HeroesComponent` 的模板", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THEHERODETAILCOMPONENTSELECTORISAPPHERODETAILADDANAPPHERODETAILELEMENTNEARTHEBOTTOMOFTHEHEROESCOMPONENTTEMPLATEWHERETHEHERODETAILVIEWUSEDTOBE", "original": "The `HeroDetailComponent` selector is `'app-hero-detail'`.\nAdd an `<app-hero-detail>` element near the bottom of the `HeroesComponent` template, where the hero detail view used to be.", "translation": "`HeroDetailComponent` 的选择器是 `'app-hero-detail'`。\n把 `<app-hero-detail>` 添加到 `HeroesComponent` 模板的底部,以便把英雄详情的视图显示到那里。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "BINDTHEHEROESCOMPONENTSELECTEDHEROTOTHEELEMENTSHEROPROPERTYLIKETHIS", "original": "Bind the `HeroesComponent.selectedHero` to the element's `hero` property like this.", "translation": "把 `HeroesComponent.selectedHero` 绑定到钙元素的 `hero` 属性,就像这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "HEROSELECTEDHEROISANANGULARPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDING", "original": "`[hero]=\"selectedHero\"` is an Angular [property binding](guide/template-syntax#property-binding).", "translation": "`[hero]=\"selectedHero\"` 是 Angular 的[属性绑定](guide/template-syntax#property-binding)语法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "ITSAONEWAYDATABINDINGFROMTHESELECTEDHEROPROPERTYOFTHEHEROESCOMPONENTTOTHEHEROPROPERTYOFTHETARGETELEMENTWHICHMAPSTOTHEHEROPROPERTYOFTHEHERODETAILCOMPONENT", "original": "It's a _one way_ data binding from\nthe `selectedHero` property of the `HeroesComponent` to the `hero` property of the target element, which maps to the `hero` property of the `HeroDetailComponent`.", "translation": "这是一种*单向*数据绑定。从 `HeroesComponent` 的 `selectedHero` 属性绑定到目标元素的 `hero` 属性,并映射到了 `HeroDetailComponent` 的 `hero` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "NOWWHENTHEUSERCLICKSAHEROINTHELISTTHESELECTEDHEROCHANGESWHENTHESELECTEDHEROCHANGESTHEPROPERTYBINDINGUPDATESHEROANDTHEHERODETAILCOMPONENTDISPLAYSTHENEWHERO", "original": "Now when the user clicks a hero in the list, the `selectedHero` changes.\nWhen the `selectedHero` changes, the _property binding_ updates `hero`\nand the `HeroDetailComponent` displays the new hero.", "translation": "现在,当用户在列表中点击某个英雄时,`selectedHero` 就改变了。\n当 `selectedHero` 改变时,*属性绑定*会修改 `HeroDetailComponent` 的 `hero` 属性,`HeroDetailComponent` 就会显示这个新的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THEREVISEDHEROESCOMPONENTTEMPLATESHOULDLOOKLIKETHIS:", "original": "The revised `HeroesComponent` template should look like this:", "translation": "修改后的 `HeroesComponent` 的模板是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "THEBROWSERREFRESHESANDTHEAPPSTARTSWORKINGAGAINASITDIDBEFORE", "original": "The browser refreshes and the app starts working again as it did before.", "translation": "浏览器刷新,应用又像以前一样开始工作了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "##WHATCHANGED", "original": "## What changed?", "translation": "## 有哪些变化?", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "ASBEFORETUTORIALTOHPT2WHENEVERAUSERCLICKSONAHERONAMETHEHERODETAILAPPEARSBELOWTHEHEROLISTNOWTHEHERODETAILCOMPONENTISPRESENTINGTHOSEDETAILSINSTEADOFTHEHEROESCOMPONENT", "original": "As [before](tutorial/toh-pt2), whenever a user clicks on a hero name,\nthe hero detail appears below the hero list.\nNow the `HeroDetailComponent` is presenting those details instead of the `HeroesComponent`.", "translation": "像[以前](tutorial/toh-pt2)一样,一旦用户点击了一个英雄的名字,该英雄的详情就显示在了英雄列表下方。\n现在,`HeroDetailComponent` 负责显示那些详情,而不再是 `HeroesComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "REFACTORINGTHEORIGINALHEROESCOMPONENTINTOTWOCOMPONENTSYIELDSBENEFITSBOTHNOWANDINTHEFUTURE:", "original": "Refactoring the original `HeroesComponent` into two components yields benefits, both now and in the future:", "translation": "把原来的 `HeroesComponent` 重构成两个组件带来了一些优点,无论是现在还是未来:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "1YOUSIMPLIFIEDTHEHEROESCOMPONENTBYREDUCINGITSRESPONSIBILITIES", "original": "1. You simplified the `HeroesComponent` by reducing its responsibilities.", "translation": "你通过缩减 `HeroesComponent` 的职责简化了该组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "1YOUCANEVOLVETHEHERODETAILCOMPONENTINTOARICHHEROEDITORWITHOUTTOUCHINGTHEPARENTHEROESCOMPONENT", "original": "1. You can evolve the `HeroDetailComponent` into a rich hero editor\nwithout touching the parent `HeroesComponent`.", "translation": "你可以把 `HeroDetailComponent` 改进成一个功能丰富的英雄编辑器,而不用改动父组件 `HeroesComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "1YOUCANEVOLVETHEHEROESCOMPONENTWITHOUTTOUCHINGTHEHERODETAILVIEW", "original": "1. You can evolve the `HeroesComponent` without touching the hero detail view.", "translation": "你可以改进 `HeroesComponent`,而不用改动英雄详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "1YOUCANREUSETHEHERODETAILCOMPONENTINTHETEMPLATEOFSOMEFUTURECOMPONENT", "original": "1. You can re-use the `HeroDetailComponent` in the template of some future component.", "translation": "将来你可以在其它组件的模板中重复使用 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "##FINALCODEREVIEW", "original": "## Final code review", "translation": "## 查看最终代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "HEREARETHECODEFILESDISCUSSEDONTHISPAGEANDYOURAPPSHOULDLOOKLIKETHISLIVEEXAMPLELIVEEXAMPLE", "original": "Here are the code files discussed on this page and your app should look like this <live-example></live-example>.", "translation": "你的应用应该变成了这样 <live-example></live-example>。本页所提及的代码文件如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "YOUCREATEDASEPARATEREUSABLEHERODETAILCOMPONENT", "original": "* You created a separate, reusable `HeroDetailComponent`.", "translation": "你创建了一个独立的、可复用的 `HeroDetailComponent` 组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "YOUUSEDAPROPERTYBINDINGGUIDETEMPLATESYNTAX#PROPERTYBINDINGTOGIVETHEPARENTHEROESCOMPONENTCONTROLOVERTHECHILDHERODETAILCOMPONENT", "original": "* You used a [property binding](guide/template-syntax#property-binding) to give the parent `HeroesComponent` control over the child `HeroDetailComponent`.", "translation": "你用[属性绑定](guide/template-syntax#property-binding)语法来让父组件 `HeroesComponent` 可以控制子组件 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "YOUUSEDTHEINPUTDECORATORGUIDETEMPLATESYNTAX#INPUTSOUTPUTSTOMAKETHEHEROPROPERTYAVAILABLEFORBINDINGBYTHEEXTERNALHEROESCOMPONENT", "original": "* You used the [`@Input` decorator](guide/template-syntax#inputs-outputs) \nto make the `hero` property available for binding\nby the external `HeroesComponent`.", "translation": "你用 [`@Input` 装饰器](guide/template-syntax#inputs-outputs)来让 `hero` 属性可以在外部的 `HeroesComponent` 中绑定。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt3.md" }, { + "key": "#SERVICES", "original": "# Services", "translation": "# 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THETOUROFHEROESHEROESCOMPONENTISCURRENTLYGETTINGANDDISPLAYINGFAKEDATA", "original": "The Tour of Heroes `HeroesComponent` is currently getting and displaying fake data.", "translation": "英雄指南的 `HeroesComponent` 目前获取和显示的都是模拟数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "AFTERTHEREFACTORINGINTHISTUTORIALHEROESCOMPONENTWILLBELEANANDFOCUSEDONSUPPORTINGTHEVIEWITWILLALSOBEEASIERTOUNITTESTWITHAMOCKSERVICE", "original": "After the refactoring in this tutorial, `HeroesComponent` will be lean and focused on supporting the view.\nIt will also be easier to unit-test with a mock service.", "translation": "本节课的重构完成之后,`HeroesComponent` 变得更精简,并且聚焦于为它的视图提供支持。这也让它更容易使用模拟服务进行单元测试。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "##WHYSERVICES", "original": "## Why services", "translation": "## 为什么需要服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "COMPONENTSSHOULDNTFETCHORSAVEDATADIRECTLYANDTHEYCERTAINLYSHOULDNTKNOWINGLYPRESENTFAKEDATATHEYSHOULDFOCUSONPRESENTINGDATAANDDELEGATEDATAACCESSTOASERVICE", "original": "Components shouldn't fetch or save data directly and they certainly shouldn't knowingly present fake data.\nThey should focus on presenting data and delegate data access to a service.", "translation": "组件不应该直接获取或保存数据,它们不应该了解是否在展示假数据。\n它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "INTHISTUTORIALYOULLCREATEAHEROSERVICETHATALLAPPLICATIONCLASSESCANUSETOGETHEROESINSTEADOFCREATINGTHATSERVICEWITHNEWYOULLRELYONANGULARDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONTOINJECTITINTOTHEHEROESCOMPONENTCONSTRUCTOR", "original": "In this tutorial, you'll create a `HeroService` that all application classes can use to get heroes.\nInstead of creating that service with `new`, \nyou'll rely on Angular [*dependency injection*](guide/dependency-injection) \nto inject it into the `HeroesComponent` constructor.", "translation": "本节课,你将创建一个 `HeroService`,应用中的所有类都可以使用它来获取英雄列表。\n不要使用 `new` 来创建此服务,而要依靠 Angular 的[*依赖注入*](guide/dependency-injection)机制把它注入到 `HeroesComponent` 的构造函数中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "SERVICESAREAGREATWAYTOSHAREINFORMATIONAMONGCLASSESTHATDONTKNOWEACHOTHERYOULLCREATEAMESSAGESERVICEANDINJECTITINTWOPLACES:", "original": "Services are a great way to share information among classes that _don't know each other_.\nYou'll create a `MessageService` and inject it in two places:", "translation": "服务是在多个“互相不知道”的类之间共享信息的好办法。\n你将创建一个 `MessageService`,并且把它注入到两个地方:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "1INHEROSERVICEWHICHUSESTHESERVICETOSENDAMESSAGE", "original": "1. in `HeroService` which uses the service to send a message.", "translation": "`HeroService` 中,它会使用该服务发送消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "2INMESSAGESCOMPONENTWHICHDISPLAYSTHATMESSAGE", "original": "2. in `MessagesComponent` which displays that message.", "translation": "`MessagesComponent` 中,它会显示其中的消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "##CREATETHEHEROSERVICE", "original": "## Create the _HeroService_", "translation": "## 创建 `HeroService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "USINGTHEANGULARCLICREATEASERVICECALLEDHERO", "original": "Using the Angular CLI, create a service called `hero`.", "translation": "使用 Angular CLI 创建一个名叫 `hero` 的服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THECOMMANDGENERATESSKELETONHEROSERVICECLASSINSRCAPPHEROSERVICETSTHEHEROSERVICECLASSSHOULDLOOKLIKETHEBELOW", "original": "The command generates skeleton `HeroService` class in `src/app/hero.service.ts`\nThe `HeroService` class should look like the below.", "translation": "该命令会在 `src/app/hero.service.ts` 中生成 `HeroService` 类的骨架。\n`HeroService` 类的代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###INJECTABLESERVICES", "original": "### _@Injectable()_ services", "translation": "### _@Injectable()_ 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "NOTICETHATTHENEWSERVICEIMPORTSTHEANGULARINJECTABLESYMBOLANDANNOTATESTHECLASSWITHTHEINJECTABLEDECORATOR", "original": "Notice that the new service imports the Angular `Injectable` symbol and annotates\nthe class with the `@Injectable()` decorator.", "translation": "注意,这个新的服务导入了 Angular 的 `Injectable` 符号,并且给这个服务类添加了 `@Injectable()` 装饰器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEINJECTABLEDECORATORTELLSANGULARTHATTHISSERVICEMIGHTITSELFHAVEINJECTEDDEPENDENCIESITDOESNTHAVEDEPENDENCIESNOWBUTITWILLSOON#INJECTMESSAGESERVICEWHETHERITDOESORITDOESNTITSGOODPRACTICETOKEEPTHEDECORATOR", "original": "The `@Injectable()` decorator tells Angular that this service _might_ itself\nhave injected dependencies.\nIt doesn't have dependencies now but [it will soon](#inject-message-service).\nWhether it does or it doesn't, it's good practice to keep the decorator.", "translation": "`@Injectable()` 装饰器告诉 Angular 这个服务本身*可能*拥有被注入的依赖。\n目前它还没有依赖,但是[很快就会有了](#inject-message-service)。\n无论它会不会有,总是给服务加上这个装饰器都是一种好的做法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEANGULARSTYLEGUIDELINESGUIDESTYLEGUIDE#STYLE0704STRONGLYRECOMMENDKEEPINGITANDTHELINTERENFORCESTHISRULE", "original": "The Angular [style guidelines](guide/styleguide#style-07-04) strongly recommend keeping it\nand the linter enforces this rule.", "translation": "Angular 的[风格指南](guide/styleguide#style-07-04)强烈建议加上,而且 linter(代码检查器) 也会确保这条规则。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###GETHERODATA", "original": "### Get hero data", "translation": "### 获取英雄数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEHEROSERVICECOULDGETHERODATAFROMANYWHEREMDASHAWEBSERVICELOCALSTORAGEORAMOCKDATASOURCE", "original": "The `HeroService` could get hero data from anywhere—a web service, local storage, or a mock data source.", "translation": "`HeroService` 可以从任何地方获取数据:Web 服务、本地存储(LocalStorage)或一个模拟的数据源。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "REMOVINGDATAACCESSFROMCOMPONENTSMEANSYOUCANCHANGEYOURMINDABOUTTHEIMPLEMENTATIONANYTIMEWITHOUTTOUCHINGANYCOMPONENTSTHEYDONTKNOWHOWTHESERVICEWORKS", "original": "Removing data access from components means you can change your mind about the implementation anytime, without touching any components.\nThey don't know how the service works.", "translation": "从组件中移除数据访问逻辑,意味着将来任何时候你都可以改变目前的实现方式,而不用改动任何组件。\n这些组件不需要了解该服务的内部实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEIMPLEMENTATIONINTHISTUTORIALWILLCONTINUETODELIVERMOCKHEROES", "original": "The implementation in _this_ tutorial will continue to deliver _mock heroes_.", "translation": "这节课中的实现仍然会提供*模拟的英雄列表*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "IMPORTTHEHEROANDHEROES", "original": "Import the `Hero` and `HEROES`.", "translation": "导入 `Hero` 和 `HEROES`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "ADDAGETHEROESMETHODTORETURNTHEMOCKHEROES", "original": "Add a `getHeroes` method to return the _mock heroes_.", "translation": "添加一个 `getHeroes` 方法,让它返回*模拟的英雄列表*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "##PROVIDETHEHEROSERVICE", "original": "## Provide the `HeroService`", "translation": "## 提供(provide) `HeroService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUMUSTPROVIDETHEHEROSERVICEINTHEDEPENDENCYINJECTIONSYSTEMBEFOREANGULARCANINJECTITINTOTHEHEROESCOMPONENTASYOUWILLDOBELOW#INJECT", "original": "You must _provide_ the `HeroService` in the _dependency injection system_\nbefore Angular can _inject_ it into the `HeroesComponent`, \nas you will do [below](#inject).", "translation": "在要求 Angular 把 `HeroService` 注入到 `HeroesComponent` 之前,你必须先把这个服务*提供给依赖注入系统*。[稍后](#inject)你就要这么做。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEREARESEVERALWAYSTOPROVIDETHEHEROSERVICE:INTHEHEROESCOMPONENTINTHEAPPCOMPONENTINTHEAPPMODULEEACHOPTIONHASPROSANDCONS", "original": "There are several ways to provide the `HeroService`: \nin the `HeroesComponent`, in the `AppComponent`, in the `AppModule`.\nEach option has pros and cons.", "translation": "有很多途径可以提供 `HeroService`:在 `HeroesComponent` 中、在 `AppComponent` 中,或在 `AppModule` 中。\n每个选项都各有优缺点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THISTUTORIALCHOOSESTOPROVIDEITINTHEAPPMODULE", "original": "This tutorial chooses to provide it in the `AppModule`.", "translation": "这节课选择在 `AppModule` 中提供它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THATSSUCHAPOPULARCHOICETHATYOUCOULDHAVETOLDTHECLITOPROVIDEITTHEREAUTOMATICALLYBYAPPENDINGMODULEAPP", "original": "That's such a popular choice that you could have told the CLI to provide it there automatically\nby appending `--module=app`.", "translation": "这是一个常用的选择,因此你可以通过 `--module=app` 选项让 CLI 自动把它提供给 `AppModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "SINCEYOUDIDNOTYOULLHAVETOPROVIDEITYOURSELF", "original": "Since you did not, you'll have to provide it yourself.", "translation": "如果不这样做,你就要自行提供它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "OPENTHEAPPMODULECLASSIMPORTTHEHEROSERVICEANDADDITTOTHENGMODULEPROVIDERSARRAY", "original": "Open the `AppModule` class, import the `HeroService`, and add it to the `@NgModule.providers` array.", "translation": "打开 `AppModule` 类,导入 `HeroService`,并把它加入 `@NgModule.providers` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEPROVIDERSARRAYTELLSANGULARTOCREATEASINGLESHAREDINSTANCEOFHEROSERVICEANDINJECTINTOANYCLASSTHATASKSFORIT", "original": "The `providers` array tells Angular to create a single, shared instance of `HeroService`\nand inject into any class that asks for it.", "translation": "`providers` 数组会告诉 Angular 创建 `HeroService` 的单一、共享的实例,并且把它注入到如何请求注入它的类中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEHEROSERVICEISNOWREADYTOPLUGINTOTHEHEROESCOMPONENT", "original": "The `HeroService` is now ready to plug into the `HeroesComponent`.", "translation": "现在 `HeroService` 已经准备好插入到 `HeroesComponent` 中了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THISISAINTERIMCODESAMPLETHATWILLALLOWYOUTOPROVIDEANDUSETHEHEROSERVICEATTHISPOINTTHECODEWILLDIFFERFROMTHEHEROSERVICEINTHEFINALCODEREVIEW#FINALCODEREVIEW", "original": "This is a interim code sample that will allow you to provide and use the `HeroService`. At this point, the code will differ from the `HeroService` in the [\"final code review\"](#final-code-review).", "translation": "这是一个过渡性的代码范例,它将会允许你提供并使用 `HeroService`。此刻的代码和[最终代码](#final-code-review)相差很大。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "LEARNMOREABOUTPROVIDERSINTHEPROVIDERSGUIDEPROVIDERSGUIDE", "original": "Learn more about _providers_ in the [Providers](guide/providers) guide.", "translation": "要进一步了解*提供商*,参见[服务提供商](guide/providers)一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "##UPDATEHEROESCOMPONENT", "original": "## Update `HeroesComponent`", "translation": "## 修改 `HeroesComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "OPENTHEHEROESCOMPONENTCLASSFILE", "original": "Open the `HeroesComponent` class file.", "translation": "打开 `HeroesComponent` 类文件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "DELETETHEHEROESIMPORTASYOUWONTNEEDTHATANYMOREIMPORTTHEHEROSERVICEINSTEAD", "original": "Delete the `HEROES` import as you won't need that anymore.\nImport the `HeroService` instead.", "translation": "删除 `HEROES` 导入,你以后不会再用它了。\n转而导入 `HeroService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "REPLACETHEDEFINITIONOFTHEHEROESPROPERTYWITHASIMPLEDECLARATION", "original": "Replace the definition of the `heroes` property with a simple declaration.", "translation": "把 `heroes` 属性的定义改为一句简单的声明。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###INJECTTHEHEROSERVICE", "original": "### Inject the `HeroService`", "translation": "### 注入 `HeroService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "ADDAPRIVATEHEROSERVICEPARAMETEROFTYPEHEROSERVICETOTHECONSTRUCTOR", "original": "Add a private `heroService` parameter of type `HeroService` to the constructor.", "translation": "往构造函数中添加一个私有的 `heroService`,其类型为 `HeroService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEPARAMETERSIMULTANEOUSLYDEFINESAPRIVATEHEROSERVICEPROPERTYANDIDENTIFIESITASAHEROSERVICEINJECTIONSITE", "original": "The parameter simultaneously defines a private `heroService` property and identifies it as a `HeroService` injection site.", "translation": "这个参数同时做了两件事:1. 声明了一个私有 `heroService` 属性,2. 把它标记为一个 `HeroService` 的注入点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "WHENANGULARCREATESAHEROESCOMPONENTTHEDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONSYSTEMSETSTHEHEROSERVICEPARAMETERTOTHESINGLETONINSTANCEOFHEROSERVICE", "original": "When Angular creates a `HeroesComponent`, the [Dependency Injection](guide/dependency-injection) system\nsets the `heroService` parameter to the singleton instance of `HeroService`.", "translation": "当 Angular 创建 `HeroesComponent` 时,[依赖注入](guide/dependency-injection)系统就会把这个 `heroService` 参数设置为 `HeroService` 的单例对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###ADDGETHEROES", "original": "### Add _getHeroes()_", "translation": "### 添加 _getHeroes()_", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "CREATEAFUNCTIONTORETRIEVETHEHEROESFROMTHESERVICE", "original": "Create a function to retrieve the heroes from the service.", "translation": "创建一个函数,以从服务中获取这些英雄数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###CALLITINNGONINIT", "original": "### Call it in `ngOnInit`", "translation": "### 在 `ngOnInit` 中调用它", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "WHILEYOUCOULDCALLGETHEROESINTHECONSTRUCTORTHATSNOTTHEBESTPRACTICE", "original": "While you could call `getHeroes()` in the constructor, that's not the best practice.", "translation": "你固然可以在构造函数中调用 `getHeroes()`,但那不是最佳实践。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "RESERVETHECONSTRUCTORFORSIMPLEINITIALIZATIONSUCHASWIRINGCONSTRUCTORPARAMETERSTOPROPERTIESTHECONSTRUCTORSHOULDNTDOANYTHINGITCERTAINLYSHOULDNTCALLAFUNCTIONTHATMAKESHTTPREQUESTSTOAREMOTESERVERASAREALDATASERVICEWOULD", "original": "Reserve the constructor for simple initialization such as wiring constructor parameters to properties.\nThe constructor shouldn't _do anything_.\nIt certainly shouldn't call a function that makes HTTP requests to a remote server as a _real_ data service would.", "translation": "让构造函数保持简单,只做初始化操作,比如把构造函数的参数赋值给属性。\n构造函数不应该*做任何事*。\n它肯定不能调用某个函数来向远端服务(比如真实的数据服务)发起 HTTP 请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "INSTEADCALLGETHEROESINSIDETHENGONINITLIFECYCLEHOOKGUIDELIFECYCLEHOOKSANDLETANGULARCALLNGONINITATANAPPROPRIATETIMEAFTERCONSTRUCTINGAHEROESCOMPONENTINSTANCE", "original": "Instead, call `getHeroes()` inside the [*ngOnInit lifecycle hook*](guide/lifecycle-hooks) and\nlet Angular call `ngOnInit` at an appropriate time _after_ constructing a `HeroesComponent` instance.", "translation": "你应该改为在 [*ngOnInit 生命周期钩子*](guide/lifecycle-hooks)中调用 `getHeroes()`,并且等 Angular 构造出 `HeroesComponent` 的实例之后,找个恰当的时机调用 `ngOnInit`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###SEEITRUN", "original": "### See it run", "translation": "### 查看运行效果", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "AFTERTHEBROWSERREFRESHESTHEAPPSHOULDRUNASBEFORESHOWINGALISTOFHEROESANDAHERODETAILVIEWWHENYOUCLICKONAHERONAME", "original": "After the browser refreshes, the app should run as before, \nshowing a list of heroes and a hero detail view when you click on a hero name.", "translation": "刷新浏览器,该应用仍运行的一如既往。\n显示英雄列表,并且当你点击某个英雄的名字时显示出英雄详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "##OBSERVABLEDATA", "original": "## Observable data", "translation": "## 可观察(Observable)的数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEHEROSERVICEGETHEROESMETHODHASASYNCHRONOUSSIGNATUREWHICHIMPLIESTHATTHEHEROSERVICECANFETCHHEROESSYNCHRONOUSLYTHEHEROESCOMPONENTCONSUMESTHEGETHEROESRESULTASIFHEROESCOULDBEFETCHEDSYNCHRONOUSLY", "original": "The `HeroService.getHeroes()` method has a _synchronous signature_,\nwhich implies that the `HeroService` can fetch heroes synchronously.\nThe `HeroesComponent` consumes the `getHeroes()` result \nas if heroes could be fetched synchronously.", "translation": "`HeroService.getHeroes()` 的函数签名是*同步的*,它所隐含的假设是 `HeroService` 总是能同步获取英雄列表数据。\n而 `HeroesComponent` 也同样假设能同步取到 `getHeroes()` 的结果。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THISWILLNOTWORKINAREALAPPYOUREGETTINGAWAYWITHITNOWBECAUSETHESERVICECURRENTLYRETURNSMOCKHEROESBUTSOONTHEAPPWILLFETCHHEROESFROMAREMOTESERVERWHICHISANINHERENTLYASYNCHRONOUSOPERATION", "original": "This will not work in a real app.\nYou're getting away with it now because the service currently returns _mock heroes_.\nBut soon the app will fetch heroes from a remote server, \nwhich is an inherently _asynchronous_ operation.", "translation": "这在真实的应用中几乎是不可能的。\n现在能这么做,只是因为目前该服务返回的是*模拟数据*。\n不过很快,该应用就要从远端服务器获取英雄数据了,而那天生就是*异步*操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEHEROSERVICEMUSTWAITFORTHESERVERTORESPONDGETHEROESCANNOTRETURNIMMEDIATELYWITHHERODATAANDTHEBROWSERWILLNOTBLOCKWHILETHESERVICEWAITS", "original": "The `HeroService` must wait for the server to respond,\n`getHeroes()` cannot return immediately with hero data,\nand the browser will not block while the service waits.", "translation": "`HeroService` 必须等服务器给出相应,\n而 `getHeroes()` 不能立即返回英雄数据,\n浏览器也不会在该服务等待期间停止响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "HEROSERVICEGETHEROESMUSTHAVEANASYNCHRONOUSSIGNATUREOFSOMEKIND", "original": "`HeroService.getHeroes()` must have an _asynchronous signature_ of some kind.", "translation": "`HeroService.getHeroes()` 必须具有某种形式的*异步函数签名*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "ITCANTAKEACALLBACKITCOULDRETURNAPROMISEITCOULDRETURNANOBSERVABLE", "original": "It can take a callback. It could return a `Promise`. It could return an `Observable`.", "translation": "它可以使用回调函数,可以返回 `Promise`(承诺),也可以返回 `Observable`(可观察对象)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "INTHISTUTORIALHEROSERVICEGETHEROESWILLRETURNANOBSERVABLEINPARTBECAUSEITWILLEVENTUALLYUSETHEANGULARHTTPCLIENTGETMETHODTOFETCHTHEHEROESANDHTTPCLIENTGETRETURNSANOBSERVABLEGUIDEHTTP", "original": "In this tutorial, `HeroService.getHeroes()` will return an `Observable`\nin part because it will eventually use the Angular `HttpClient.get` method to fetch the heroes\nand [`HttpClient.get()` returns an `Observable`](guide/http).", "translation": "这节课,`HeroService.getHeroes()` 将会返回 `Observable`,因为它最终会使用 Angular 的 `HttpClient.get` 方法来获取英雄数据,而 [`HttpClient.get()` 会返回 `Observable`](guide/http)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###OBSERVABLEHEROSERVICE", "original": "### Observable _HeroService_", "translation": "### 可观察对象版本的 `HeroService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "OBSERVABLEISONEOFTHEKEYCLASSESINTHERXJSLIBRARYHTTP:REACTIVEXIORXJS", "original": "`Observable` is one of the key classes in the [RxJS library](http://reactivex.io/rxjs/).", "translation": "`Observable` 是 [RxJS 库](http://reactivex.io/rxjs/)中的一个关键类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "INALATERTUTORIALONHTTPTUTORIALTOHPT6YOULLLEARNTHATANGULARSHTTPCLIENTMETHODSRETURNRXJSOBSERVABLESINTHISTUTORIALYOULLSIMULATEGETTINGDATAFROMTHESERVERWITHTHERXJSOFFUNCTION", "original": "In a [later tutorial on HTTP](tutorial/toh-pt6), you'll learn that Angular's `HttpClient` methods return RxJS `Observable`s.\nIn this tutorial, you'll simulate getting data from the server with the RxJS `of()` function.", "translation": "在[稍后的 HTTP 教程](tutorial/toh-pt6)中,你就会知道 Angular `HttpClient` 的方法会返回 RxJS 的 `Observable`。\n这节课,你将使用 RxJS 的 `of()` 函数来模拟从服务器返回数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "OPENTHEHEROSERVICEFILEANDIMPORTTHEOBSERVABLEANDOFSYMBOLSFROMRXJS", "original": "Open the `HeroService` file and import the `Observable` and `of` symbols from RxJS.", "translation": "打开 `HeroService` 文件,并从 RxJS 中导入 `Observable` 和 `of` 符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "REPLACETHEGETHEROESMETHODWITHTHISONE", "original": "Replace the `getHeroes` method with this one.", "translation": "把 `getHeroes` 方法改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "OFHEROESRETURNSANOBSERVABLEHEROTHATEMITSASINGLEVALUETHEARRAYOFMOCKHEROES", "original": "`of(HEROES)` returns an `Observable<Hero[]>` that emits _a single value_, the array of mock heroes.", "translation": "`of(HEROES)` 会返回一个 `Observable<Hero[]>`,它会发出单个值,这个值就是这些模拟英雄的数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "INTHEHTTPTUTORIALTUTORIALTOHPT6YOULLCALLHTTPCLIENTGETHEROWHICHALSORETURNSANOBSERVABLEHEROTHATEMITSASINGLEVALUEANARRAYOFHEROESFROMTHEBODYOFTHEHTTPRESPONSE", "original": "In the [HTTP tutorial](tutorial/toh-pt6), you'll call `HttpClient.get<Hero[]>()` which also returns an `Observable<Hero[]>` that emits _a single value_, an array of heroes from the body of the HTTP response.", "translation": "在 [HTTP 教程](tutorial/toh-pt6)中,你将会调用 `HttpClient.get<Hero[]>()` 它也同样返回一个 `Observable<Hero[]>`,它也会发出单个值,这个值就是来自 HTTP 响应体中的英雄数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###SUBSCRIBEINHEROESCOMPONENT", "original": "### Subscribe in _HeroesComponent_", "translation": "### 在 `HeroesComponent` 中订阅", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEHEROSERVICEGETHEROESMETHODUSEDTORETURNAHERONOWITRETURNSANOBSERVABLEHERO", "original": "The `HeroService.getHeroes` method used to return a `Hero[]`.\nNow it returns an `Observable<Hero[]>`.", "translation": "`HeroService.getHeroes` 方法用于返回一个 `Hero[]`,\n目前它返回的是 `Observable<Hero[]>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOULLHAVETOADJUSTTOTHATDIFFERENCEINHEROESCOMPONENT", "original": "You'll have to adjust to that difference in `HeroesComponent`.", "translation": "你必须在 `HeroesComponent` 中也向本服务中的这种形式看齐。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "FINDTHEGETHEROESMETHODANDREPLACEITWITHTHEFOLLOWINGCODESHOWNSIDEBYSIDEWITHTHEPREVIOUSVERSIONFORCOMPARISON", "original": "Find the `getHeroes` method and replace it with the following code\n(shown side-by-side with the previous version for comparison)", "translation": "找到 `getHeroes` 方法,并且把它替换为如下代码(和前一个版本对比显示):", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "OBSERVABLESUBSCRIBEISTHECRITICALDIFFERENCE", "original": "`Observable.subscribe()` is the critical difference.", "translation": "`Observable.subscribe()` 是关键的差异点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEPREVIOUSVERSIONASSIGNSANARRAYOFHEROESTOTHECOMPONENTSHEROESPROPERTYTHEASSIGNMENTOCCURSSYNCHRONOUSLYASIFTHESERVERCOULDRETURNHEROESINSTANTLYORTHEBROWSERCOULDFREEZETHEUIWHILEITWAITEDFORTHESERVERSRESPONSE", "original": "The previous version assigns an array of heroes to the component's `heroes` property.\nThe assignment occurs _synchronously_, as if the server could return heroes instantly\nor the browser could freeze the UI while it waited for the server's response.", "translation": "上一个版本把英雄的数组赋值给了该组件的 `heroes` 属性。\n这种赋值是*同步*的,这里包含的假设是服务器能立即返回英雄数组或者浏览器能在等待服务器响应时冻结界面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THATWONTWORKWHENTHEHEROSERVICEISACTUALLYMAKINGREQUESTSOFAREMOTESERVER", "original": "That _won't work_ when the `HeroService` is actually making requests of a remote server.", "translation": "当 `HeroService` 真的向远端服务器发起请求时,这种方式就行不通了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THENEWVERSIONWAITSFORTHEOBSERVABLETOEMITTHEARRAYOFHEROESMDASHWHICHCOULDHAPPENNOWORSEVERALMINUTESFROMNOWTHENSUBSCRIBEPASSESTHEEMITTEDARRAYTOTHECALLBACKWHICHSETSTHECOMPONENTSHEROESPROPERTY", "original": "The new version waits for the `Observable` to emit the array of heroes— \nwhich could happen now or several minutes from now.\nThen `subscribe` passes the emitted array to the callback,\nwhich sets the component's `heroes` property.", "translation": "新的版本等待 `Observable` 发出这个英雄数组,这可能立即发生,也可能会在几分钟之后。\n然后,`subscribe` 函数把这个英雄数组传给这个回调函数,该函数把英雄数组赋值给组件的 `heroes` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THISASYNCHRONOUSAPPROACHWILLWORKWHENTHEHEROSERVICEREQUESTSHEROESFROMTHESERVER", "original": "This asynchronous approach _will work_ when\nthe `HeroService` requests heroes from the server.", "translation": "使用这种异步方式,当 `HeroService` 从远端服务器获取英雄数据时,就*可以工作了*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "##SHOWMESSAGES", "original": "## Show messages", "translation": "## 显示消息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "INTHISSECTIONYOUWILL", "original": "In this section you will", "translation": "在这一节,你将", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "ADDAMESSAGESCOMPONENTTHATDISPLAYSAPPMESSAGESATTHEBOTTOMOFTHESCREEN", "original": "* add a `MessagesComponent` that displays app messages at the bottom of the screen.", "translation": "添加一个 `MessagesComponent`,它在屏幕的底部显示应用中的消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "CREATEANINJECTABLEAPPWIDEMESSAGESERVICEFORSENDINGMESSAGESTOBEDISPLAYED", "original": "* create an injectable, app-wide `MessageService` for sending messages to be displayed", "translation": "创建一个可注入的、全应用级别的 `MessageService`,用于发送要显示的消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "INJECTMESSAGESERVICEINTOTHEHEROSERVICE", "original": "* inject `MessageService` into the `HeroService`", "translation": "把 `MessageService` 注入到 `HeroService` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "DISPLAYAMESSAGEWHENHEROSERVICEFETCHESHEROESSUCCESSFULLY", "original": "* display a message when `HeroService` fetches heroes successfully.", "translation": "当 `HeroService` 成功获取了英雄数据时显示一条消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###CREATEMESSAGESCOMPONENT", "original": "### Create _MessagesComponent_", "translation": "### 创建 `MessagesComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "USETHECLITOCREATETHEMESSAGESCOMPONENT", "original": "Use the CLI to create the `MessagesComponent`.", "translation": "使用 CLI 创建 `MessagesComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THECLICREATESTHECOMPONENTFILESINTHESRCAPPMESSAGESFOLDERANDDECLAREMESSAGESCOMPONENTINAPPMODULE", "original": "The CLI creates the component files in the `src/app/messages` folder and declare `MessagesComponent` in `AppModule`.", "translation": "CLI 在 `src/app/messages` 中创建了组件文件,并且把 `MessagesComponent` 声明在了 `AppModule` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "MODIFYTHEAPPCOMPONENTTEMPLATETODISPLAYTHEGENERATEDMESSAGESCOMPONENT", "original": "Modify the `AppComponent` template to display the generated `MessagesComponent`", "translation": "修改 `AppComponent` 的模板来显示所生成的 `MessagesComponent`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUSHOULDSEETHEDEFAULTPARAGRAPHFROMMESSAGESCOMPONENTATTHEBOTTOMOFTHEPAGE", "original": "You should see the default paragraph from `MessagesComponent` at the bottom of the page.", "translation": "你可以在页面的底部看到来自的 `MessagesComponent` 的默认内容。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###CREATETHEMESSAGESERVICE", "original": "### Create the _MessageService_", "translation": "### 创建 `MessageService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "USETHECLITOCREATETHEMESSAGESERVICEINSRCAPPTHEMODULEAPPOPTIONTELLSTHECLITOPROVIDETHISSERVICE#PROVIDEINTHEAPPMODULE", "original": "Use the CLI to create the `MessageService` in `src/app`. \nThe `--module=app` option tells the CLI to [_provide_ this service](#provide) in the `AppModule`,", "translation": "使用 CLI 在 `src/app` 中创建 `MessageService`。\n`--module=app` 选项告诉 CLI 在 `AppModule` 中[提供这个服务](#provide)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "OPENMESSAGESERVICEANDREPLACEITSCONTENTSWITHTHEFOLLOWING", "original": "Open `MessageService` and replace its contents with the following.", "translation": "打开 `MessageService`,并把它的内容改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THESERVICEEXPOSESITSCACHEOFMESSAGESANDTWOMETHODS:ONETOADDAMESSAGETOTHECACHEANDANOTHERTOCLEARTHECACHE", "original": "The service exposes its cache of `messages` and two methods: one to `add()` a message to the cache and another to `clear()` the cache.", "translation": "该服务对外暴露了它的 `messages` 缓存,以及两个方法:`add()` 方法往缓存中添加一条消息,`clear()` 方法用于清空缓存。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###INJECTITINTOTHEHEROSERVICE", "original": "### Inject it into the `HeroService`", "translation": "### 把它注入到 `HeroService` 中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "REOPENTHEHEROSERVICEANDIMPORTTHEMESSAGESERVICE", "original": "Re-open the `HeroService` and import the `MessageService`.", "translation": "重新打开 `HeroService`,并且导入 `MessageService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "MODIFYTHECONSTRUCTORWITHAPARAMETERTHATDECLARESAPRIVATEMESSAGESERVICEPROPERTYANGULARWILLINJECTTHESINGLETONMESSAGESERVICEINTOTHATPROPERTYWHENITCREATESTHEHEROSERVICE", "original": "Modify the constructor with a parameter that declares a private `messageService` property.\nAngular will inject the singleton `MessageService` into that property \nwhen it creates the `HeroService`.", "translation": "修改这个构造函数,添加一个私有的 `messageService` 属性参数。\nAngular 将会在创建 `HeroService` 时把 `MessageService` 的单例注入到这个属性中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THISISATYPICALSERVICEINSERVICESCENARIO:YOUINJECTTHEMESSAGESERVICEINTOTHEHEROSERVICEWHICHISINJECTEDINTOTHEHEROESCOMPONENT", "original": "This is a typical \"*service-in-service*\" scenario:\nyou inject the `MessageService` into the `HeroService` which is injected into the `HeroesComponent`.", "translation": "这是一个典型的“服务中的服务”场景:\n你把 `MessageService` 注入到了 `HeroService` 中,而 `HeroService` 又被注入到了 `HeroesComponent` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###SENDAMESSAGEFROMHEROSERVICE", "original": "### Send a message from `HeroService`", "translation": "### 从 `HeroService` 中发送一条消息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "MODIFYTHEGETHEROESMETHODTOSENDAMESSAGEWHENTHEHEROESAREFETCHED", "original": "Modify the `getHeroes` method to send a message when the heroes are fetched.", "translation": "修改 `getHeroes` 方法,在获取到英雄数组时发送一条消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###DISPLAYTHEMESSAGEFROMHEROSERVICE", "original": "### Display the message from `HeroService`", "translation": "### 从 `HeroService` 中显示消息", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEMESSAGESCOMPONENTSHOULDDISPLAYALLMESSAGESINCLUDINGTHEMESSAGESENTBYTHEHEROSERVICEWHENITFETCHESHEROES", "original": "The `MessagesComponent` should display all messages, \nincluding the message sent by the `HeroService` when it fetches heroes.", "translation": "`MessagesComponent` 可以显示所有消息,\n包括当 `HeroService` 获取到英雄数据时发送的那条。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "OPENMESSAGESCOMPONENTANDIMPORTTHEMESSAGESERVICE", "original": "Open `MessagesComponent` and import the `MessageService`.", "translation": "打开 `MessagesComponent`,并且导入 `MessageService`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { - "original": "Modify the constructor with a parameter that declares a **public** `messageService` property.\nAngular will inject the singleton `MessageService` into that property \nwhen it creates the `MessagesComponent`.", + "key": "MODIFYTHECONSTRUCTORWITHAPARAMETERTHATDECLARESAPUBLICMESSAGESERVICEPROPERTYANGULARWILLINJECTTHESINGLETONMESSAGESERVICEINTOTHATPROPERTYWHENITCREATESTHEHEROSERVICE", + "original": "Modify the constructor with a parameter that declares a **public** `messageService` property.\nAngular will inject the singleton `MessageService` into that property \nwhen it creates the `HeroService`.", "translation": "修改构造函数,添加一个 **public** 的 `messageService` 属性。\nAngular 将会在创建 `MessagesComponent` 的实例时 把 `MessageService` 的实例注入到这个属性中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEMESSAGESERVICEPROPERTYMUSTBEPUBLICBECAUSEYOUREABOUTTOBINDTOITINTHETEMPLATE", "original": "The `messageService` property **must be public** because you're about to bind to it in the template.", "translation": "这个 `messageService` 属性必须是公共属性,因为你将会在模板中绑定到它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "ANGULARONLYBINDSTOPUBLICCOMPONENTPROPERTIES", "original": "Angular only binds to _public_ component properties.", "translation": "Angular 只会绑定到组件的*公共*属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "###BINDTOTHEMESSAGESERVICE", "original": "### Bind to the _MessageService_", "translation": "### 绑定到 `MessageService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "REPLACETHECLIGENERATEDMESSAGESCOMPONENTTEMPLATEWITHTHEFOLLOWING", "original": "Replace the CLI-generated `MessagesComponent` template with the following.", "translation": "把 CLI 生成的 `MessagesComponent` 的模板改成这样:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THISTEMPLATEBINDSDIRECTLYTOTHECOMPONENTSMESSAGESERVICE", "original": "This template binds directly to the component's `messageService`.", "translation": "这个模板直接绑定到了组件的 `messageService` 属性上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THENGIFONLYDISPLAYSTHEMESSAGESAREAIFTHEREAREMESSAGESTOSHOW", "original": "* The `*ngIf` only displays the messages area if there are messages to show.", "translation": "`*ngIf` 只有当在有消息时才会显示消息区。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "ANNGFORPRESENTSTHELISTOFMESSAGESINREPEATEDDIVELEMENTS", "original": "* An `*ngFor` presents the list of messages in repeated `<div>` elements.", "translation": "`*ngFor` 用来在一系列 `<div>` 元素中展示消息列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "ANANGULAREVENTBINDINGGUIDETEMPLATESYNTAX#EVENTBINDINGBINDSTHEBUTTONSCLICKEVENTTOMESSAGESERVICECLEAR", "original": "* An Angular [event binding](guide/template-syntax#event-binding) binds the button's click event\nto `MessageService.clear()`.", "translation": "Angular 的[事件绑定](guide/template-syntax#event-binding)把按钮的 `click` 事件绑定到了 `MessageService.clear()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEMESSAGESWILLLOOKBETTERWHENYOUADDTHEPRIVATECSSSTYLESTOMESSAGESCOMPONENTCSSASLISTEDINONEOFTHEFINALCODEREVIEW#FINALCODEREVIEWTABSBELOW", "original": "The messages will look better when you add the private CSS styles to `messages.component.css`\nas listed in one of the [\"final code review\"](#final-code-review) tabs below.", "translation": "当你把 [最终代码](#final-code-review) 某一页的内容添加到 `messages.component.css` 中时,这些消息会变得好看一些。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEBROWSERREFRESHESANDTHEPAGEDISPLAYSTHELISTOFHEROESSCROLLTOTHEBOTTOMTOSEETHEMESSAGEFROMTHEHEROSERVICEINTHEMESSAGEAREACLICKTHECLEARBUTTONANDTHEMESSAGEAREADISAPPEARS", "original": "The browser refreshes and the page displays the list of heroes.\nScroll to the bottom to see the message from the `HeroService` in the message area.\nClick the \"clear\" button and the message area disappears.", "translation": "刷新浏览器,页面显示出了英雄列表。\n滚动到底部,就会在消息区看到来自 `HeroService` 的消息。\n点击“清空”按钮,消息区不见了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "##FINALCODEREVIEW", "original": "## Final code review", "translation": "## 查看最终代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "HEREARETHECODEFILESDISCUSSEDONTHISPAGEANDYOURAPPSHOULDLOOKLIKETHISLIVEEXAMPLELIVEEXAMPLE", "original": "Here are the code files discussed on this page and your app should look like this <live-example></live-example>.", "translation": "你的应用应该变成了这样 <live-example></live-example>。本页所提及的代码文件如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUREFACTOREDDATAACCESSTOTHEHEROSERVICECLASS", "original": "* You refactored data access to the `HeroService` class.", "translation": "你把数据访问逻辑重构到了 `HeroService` 类中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUPROVIDEDTHEHEROSERVICEINTHEROOTAPPMODULESOTHATITCANBEINJECTEDANYWHERE", "original": "* You _provided_ the `HeroService` in the root `AppModule` so that it can be injected anywhere.", "translation": "你在根模块 `AppModule` 中提供了 `HeroService` 服务,以便在别处可以注入它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUUSEDANGULARDEPENDENCYINJECTIONGUIDEDEPENDENCYINJECTIONTOINJECTITINTOACOMPONENT", "original": "* You used [Angular Dependency Injection](guide/dependency-injection) to inject it into a component.", "translation": "你使用 [Angular 依赖注入](guide/dependency-injection)机制把它注入到了组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUGAVETHEHEROSERVICEGETDATAMETHODANASYNCHRONOUSSIGNATURE", "original": "* You gave the `HeroService` _get data_ method an asynchronous signature.", "translation": "你给 `HeroService` 中获取数据的方法提供了一个异步的函数签名。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUDISCOVEREDOBSERVABLEANDTHERXJSOBSERVABLELIBRARY", "original": "* You discovered `Observable` and the RxJS _Observable_ library.", "translation": "你发现了 `Observable` 以及 RxJS 库。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUUSEDRXJSOFTORETURNANOBSERVABLEOFMOCKHEROESOBSERVABLEHERO", "original": "* You used RxJS `of()` to return an _Observable_ of mock heroes (`Observable<Hero[]>`).", "translation": "你使用 RxJS 的 `of()` 方法返回了一个模拟英雄数据的*可观察对象* (`Observable<Hero[]>`)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THECOMPONENTSNGONINITLIFECYCLEHOOKCALLSTHEHEROSERVICEMETHODNOTTHECONSTRUCTOR", "original": "* The component's `ngOnInit` lifecycle hook calls the `HeroService` method, not the constructor.", "translation": "在组件的 `ngOnInit` 生命周期钩子中调用 `HeroService` 方法,而不是构造函数中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "YOUCREATEDAMESSAGESERVICEFORLOOSELYCOUPLEDCOMMUNICATIONBETWEENCLASSES", "original": "* You created a `MessageService` for loosely-coupled communication between classes.", "translation": "你创建了一个 `MessageService`,以便在类之间实现松耦合通讯。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "THEHEROSERVICEINJECTEDINTOACOMPONENTISCREATEDWITHANOTHERINJECTEDSERVICEMESSAGESERVICE", "original": "* The `HeroService` injected into a component is created with another injected service,\n `MessageService`.", "translation": "`HeroService` 连同注入到它的服务 `MessageService` 一起,注入到了组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt4.md" }, { + "key": "#ROUTING", "original": "# Routing", "translation": "# 路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEREARENEWREQUIREMENTSFORTHETOUROFHEROESAPP:", "original": "There are new requirements for the Tour of Heroes app:", "translation": "有一些《英雄指南》的新需求:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDADASHBOARDVIEW", "original": "* Add a *Dashboard* view.", "translation": "添加一个*仪表盘*视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDTHEABILITYTONAVIGATEBETWEENTHEHEROESANDDASHBOARDVIEWS", "original": "* Add the ability to navigate between the *Heroes* and *Dashboard* views.", "translation": "在*英雄列表*和*仪表盘*视图之间导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "WHENUSERSCLICKAHERONAMEINEITHERVIEWNAVIGATETOADETAILVIEWOFTHESELECTEDHERO", "original": "* When users click a hero name in either view, navigate to a detail view of the selected hero.", "translation": "无论在哪个视图中点击一个英雄,都会导航到该英雄的详情页。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "WHENUSERSCLICKADEEPLINKINANEMAILOPENTHEDETAILVIEWFORAPARTICULARHERO", "original": "* When users click a *deep link* in an email, open the detail view for a particular hero.", "translation": "在邮件中点击一个*深链接*,会直接打开一个特定英雄的详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "WHENYOUREDONEUSERSWILLBEABLETONAVIGATETHEAPPLIKETHIS:", "original": "When you’re done, users will be able to navigate the app like this:", "translation": "完成时,用户就能像这样在应用中导航:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { - "original": "## Add the _AppRoutingModule_", - "translation": "## 添加 _AppRoutingModule_", + "key": "##ADDTHEAPPROUTINGMODULE", + "original": "## Add the `AppRoutingModule`", + "translation": "## 添加 `AppRoutingModule`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ANANGULARBESTPRACTICEISTOLOADANDCONFIGURETHEROUTERINASEPARATETOPLEVELMODULETHATISDEDICATEDTOROUTINGANDIMPORTEDBYTHEROOTAPPMODULE", "original": "An Angular best practice is to load and configure the router in a separate, top-level module\nthat is dedicated to routing and imported by the root `AppModule`.", "translation": "Angular 的最佳实践之一就是在一个独立的顶级模块中加载和配置路由器,它专注于路由功能,然后由根模块 `AppModule` 导入它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "BYCONVENTIONTHEMODULECLASSNAMEISAPPROUTINGMODULEANDITBELONGSINTHEAPPROUTINGMODULETSINTHESRCAPPFOLDER", "original": "By convention, the module class name is `AppRoutingModule` and it belongs in the `app-routing.module.ts` in the `src/app` folder.", "translation": "按照惯例,这个模块类的名字叫做 `APPRoutingModule`,并且位于 `src/app` 下的 `app-routing.module.ts` 文件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "USETHECLITOGENERATEIT", "original": "Use the CLI to generate it.", "translation": "使用 CLI 生成它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "FLATPUTSTHEFILEINSRCAPPINSTEADOFITSOWNFOLDERBRMODULEAPPTELLSTHECLITOREGISTERITINTHEIMPORTSARRAYOFTHEAPPMODULE", "original": "`--flat` puts the file in `src/app` instead of its own folder.<br>\n`--module=app` tells the CLI to register it in the `imports` array of the `AppModule`.", "translation": "`--flat` 把这个文件放进了 `src/app` 中,而不是单独的目录中。<br>\n`--module=app` 告诉 CLI 把它注册到 `AppModule` 的 `imports` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEGENERATEDFILELOOKSLIKETHIS:", "original": "The generated file looks like this:", "translation": "生成的文件是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUGENERALLYDONTDECLARECOMPONENTSINAROUTINGMODULESOYOUCANDELETETHENGMODULEDECLARATIONSARRAYANDDELETECOMMONMODULEREFERENCESTOO", "original": "You generally don't declare components in a routing module so you can delete the\n`@NgModule.declarations` array and delete `CommonModule` references too.", "translation": "你通常不会在路由模块中声明组件,所以可以删除 `@NgModule.declarations` 并删除对 `CommonModule` 的引用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOULLCONFIGURETHEROUTERWITHROUTESINTHEROUTERMODULESOIMPORTTHOSETWOSYMBOLSFROMTHEANGULARROUTERLIBRARY", "original": "You'll configure the router with `Routes` in the `RouterModule`\nso import those two symbols from the `@angular/router` library.", "translation": "你将会使用 `RouterModule` 中的 `Routes` 类来配置路由器,所以还要从 `@angular/router` 库中导入这两个符号。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDANNGMODULEEXPORTSARRAYWITHROUTERMODULEINITEXPORTINGROUTERMODULEMAKESROUTERDIRECTIVESAVAILABLEFORUSEINTHEAPPMODULECOMPONENTSTHATWILLNEEDTHEM", "original": "Add an `@NgModule.exports` array with `RouterModule` in it.\nExporting `RouterModule` makes router directives available for use\nin the `AppModule` components that will need them.", "translation": "添加一个 `@NgModule.exports` 数组,其中放上 `RouterModule` 。\n导出 `RouterModule` 让路由器的相关指令可以在 `AppModule` 中的组件中使用。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "APPROUTINGMODULELOOKSLIKETHISNOW:", "original": "`AppRoutingModule` looks like this now:", "translation": "此刻的 `AppRoutingModule` 是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "###ADDROUTES", "original": "### Add routes", "translation": "### 添加路由定义", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ROUTESTELLTHEROUTERWHICHVIEWTODISPLAYWHENAUSERCLICKSALINKORPASTESAURLINTOTHEBROWSERADDRESSBAR", "original": "*Routes* tell the router which view to display when a user clicks a link or\npastes a URL into the browser address bar.", "translation": "*路由定义* 会告诉路由器,当用户点击某个链接或者在浏览器地址栏中输入某个 URL 时,要显示哪个视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ATYPICALANGULARROUTEHASTWOPROPERTIES:", "original": "A typical Angular `Route` has two properties:", "translation": "典型的 Angular 路由(`Route`)有两个属性:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "1PATH:ASTRINGTHATMATCHESTHEURLINTHEBROWSERADDRESSBAR", "original": "1. `path`: a string that matches the URL in the browser address bar.", "translation": "`path`:一个用于匹配浏览器地址栏中 URL 的字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "1COMPONENT:THECOMPONENTTHATTHEROUTERSHOULDCREATEWHENNAVIGATINGTOTHISROUTE", "original": "1. `component`: the component that the router should create when navigating to this route.", "translation": "`component`:当导航到此路由时,路由器应该创建哪个组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUINTENDTONAVIGATETOTHEHEROESCOMPONENTWHENTHEURLISSOMETHINGLIKELOCALHOST:4200HEROES", "original": "You intend to navigate to the `HeroesComponent` when the URL is something like `localhost:4200/heroes`.", "translation": "如果你希望当 URL 为 `localhost:4200/heroes` 时,就导航到 `HeroesComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "IMPORTTHEHEROESCOMPONENTSOYOUCANREFERENCEITINAROUTETHENDEFINEANARRAYOFROUTESWITHASINGLEROUTETOTHATCOMPONENT", "original": "Import the `HeroesComponent` so you can reference it in a `Route`.\nThen define an array of routes with a single `route` to that component.", "translation": "首先要导入 `HeroesComponent`,以便能在 `Route` 中引用它。\n然后定义一个路由数组,其中的某个路由是指向这个组件的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ONCEYOUVEFINISHEDSETTINGUPTHEROUTERWILLMATCHTHATURLTOPATH:HEROESANDDISPLAYTHEHEROESCOMPONENT", "original": "Once you've finished setting up, the router will match that URL to `path: 'heroes'` \nand display the `HeroesComponent`.", "translation": "完成这些设置之后,路由器将会把 URL 匹配到 `path: 'heroes'`,并显示 `HeroesComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUFIRSTMUSTINITIALIZETHEROUTERANDSTARTITLISTENINGFORBROWSERLOCATIONCHANGES", "original": "You first must initialize the router and start it listening for browser location changes.", "translation": "你必须首先初始化路由器,并让它开始监听浏览器中的地址变化。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDROUTERMODULETOTHENGMODULEIMPORTSARRAYANDCONFIGUREITWITHTHEROUTESINONESTEPBYCALLINGROUTERMODULEFORROOTWITHINTHEIMPORTSARRAYLIKETHIS:", "original": "Add `RouterModule` to the `@NgModule.imports` array and \nconfigure it with the `routes` in one step by calling \n`RouterModule.forRoot()` _within_ the `imports` array, like this:", "translation": "把 `RouterModule` 添加到 `@NgModule.imports` 数组中,并用 `routes` 来配置它。你只要调用 `imports` 数组中的\n`RouterModule.forRoot()` 函数就行了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEMETHODISCALLEDFORROOTBECAUSEYOUCONFIGURETHEROUTERATTHEAPPLICATIONSROOTLEVELTHEFORROOTMETHODSUPPLIESTHESERVICEPROVIDERSANDDIRECTIVESNEEDEDFORROUTINGANDPERFORMSTHEINITIALNAVIGATIONBASEDONTHECURRENTBROWSERURL", "original": "The method is called `forRoot()` because you configure the router at the application's root level.\n The `forRoot()` method supplies the service providers and directives needed for routing, \n and performs the initial navigation based on the current browser URL.", "translation": "这个方法之所以叫 `forRoot()`,是因为你要在应用的顶级配置这个路由器。\n `forRoot()` 方法会提供路由所需的服务提供商和指令,还会基于浏览器的当前 URL 执行首次导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "##ADDROUTEROUTLET", "original": "## Add _RouterOutlet_", "translation": "## 添加路由出口 (_RouterOutlet_)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "OPENTHEAPPCOMPONENTTEMPLATEREPLACETHEAPPHEROESELEMENTWITHAROUTEROUTLETELEMENT", "original": "Open the `AppComponent` template replace the `<app-heroes>` element with a `<router-outlet>` element.", "translation": "打开 `AppComponent` 的模板,把 `<app-heroes>` 元素替换为 `<router-outlet>` 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUREMOVEDAPPHEROESBECAUSEYOUWILLONLYDISPLAYTHEHEROESCOMPONENTWHENTHEUSERNAVIGATESTOIT", "original": "You removed `<app-heroes>` because you will only display the `HeroesComponent` when the user navigates to it.", "translation": "之所以移除 `<app-heroes>` 是因为当用户进行导航时,你不再仅仅显示 `HeroesComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEROUTEROUTLETTELLSTHEROUTERWHERETODISPLAYROUTEDVIEWS", "original": "The `<router-outlet>` tells the router where to display routed views.", "translation": "`<router-outlet>` 会告诉路由器要在哪里显示路由到的视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEROUTEROUTLETISONEOFTHEROUTERDIRECTIVESTHATBECAMEAVAILABLETOTHEAPPCOMPONENTBECAUSEAPPMODULEIMPORTSAPPROUTINGMODULEWHICHEXPORTEDROUTERMODULE", "original": "The `RouterOutlet` is one of the router directives that became available to the `AppComponent`\nbecause `AppModule` imports `AppRoutingModule` which exported `RouterModule`.", "translation": "能在 `AppComponent` 中使用 `RouterOutlet`,是因为 `AppModule` 导入了 `AppRoutingModule`,而 `AppRoutingModule` 中导出了 `RouterModule`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "####TRYIT", "original": "#### Try it", "translation": "#### 试试看", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUSHOULDSTILLBERUNNINGWITHTHISCLICOMMAND", "original": "You should still be running with this CLI command.", "translation": "你的 CLI 命令应该仍在运行吧。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEBROWSERSHOULDREFRESHANDDISPLAYTHEAPPTITLEBUTNOTTHELISTOFHEROES", "original": "The browser should refresh and display the app title but not the list of heroes.", "translation": "浏览器应该刷新,并显示着应用的标题,但是没有显示英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "LOOKATTHEBROWSERSADDRESSBARTHEURLENDSINTHEROUTEPATHTOHEROESCOMPONENTISHEROES", "original": "Look at the browser's address bar. \nThe URL ends in `/`.\nThe route path to `HeroesComponent` is `/heroes`.", "translation": "看看浏览器的地址栏。\nURL 是以 `/` 结尾的。\n而到 `HeroesComponent` 的路由路径是 `/heroes`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "APPENDHEROESTOTHEURLINTHEBROWSERADDRESSBARYOUSHOULDSEETHEFAMILIARHEROESMASTERDETAILVIEW", "original": "Append `/heroes` to the URL in the browser address bar.\nYou should see the familiar heroes master/detail view.", "translation": "在地址栏中把 `/heroes` 追加到 URL 后面。你应该能看到熟悉的主从结构的英雄显示界面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { - "original": "## Add a navigation link (_routerLink_)", - "translation": "## 添加路由链接 (*routerLink*)", + "key": "##ADDANAVIGATIONLINKROUTERLINK", + "original": "## Add a navigation link (`routerLink`)", + "translation": "## 添加路由链接 (`routerLink`)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "USERSSHOULDNTHAVETOPASTEAROUTEURLINTOTHEADDRESSBARTHEYSHOULDBEABLETOCLICKALINKTONAVIGATE", "original": "Users shouldn't have to paste a route URL into the address bar. \nThey should be able to click a link to navigate.", "translation": "不应该让用户只能把路由的 URL 粘贴到地址栏中。他们还应该能通过点击链接进行导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDANAVELEMENTANDWITHINTHATANANCHORELEMENTTHATWHENCLICKEDTRIGGERSNAVIGATIONTOTHEHEROESCOMPONENTTHEREVISEDAPPCOMPONENTTEMPLATELOOKSLIKETHIS:", "original": "Add a `<nav>` element and, within that, an anchor element that, when clicked, \ntriggers navigation to the `HeroesComponent`.\nThe revised `AppComponent` template looks like this:", "translation": "添加一个 `<nav>` 元素,并在其中放一个链接 `<a>` 元素,当点击它时,就会触发一个到 `HeroesComponent` 的导航。\n修改过的 `AppComponent` 模板如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "AROUTERLINKATTRIBUTE#ROUTERLINKISSETTOHEROESTHESTRINGTHATTHEROUTERMATCHESTOTHEROUTETOHEROESCOMPONENTTHEROUTERLINKISTHESELECTORFORTHEROUTERLINKDIRECTIVE#ROUTERLINKTHATTURNSUSERCLICKSINTOROUTERNAVIGATIONSITSANOTHEROFTHEPUBLICDIRECTIVESINTHEROUTERMODULE", "original": "A [`routerLink` attribute](#routerlink) is set to `\"/heroes\"`,\nthe string that the router matches to the route to `HeroesComponent`.\nThe `routerLink` is the selector for the [`RouterLink` directive](#routerlink)\nthat turns user clicks into router navigations.\nIt's another of the public directives in the `RouterModule`.", "translation": "[`routerLink` 属性](#routerlink)的值为 `\"/heroes\"`,路由器会用它来匹配出指向 `HeroesComponent` 的路由。\n`routerLink` 是 [`RouterLink` 指令](#routerlink)的选择器,它会把用户的点击转换为路由器的导航操作。\n它是 `RouterModule` 中公开的另一个指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEBROWSERREFRESHESANDDISPLAYSTHEAPPTITLEANDHEROESLINKBUTNOTTHEHEROESLIST", "original": "The browser refreshes and displays the app title and heroes link, \nbut not the heroes list.", "translation": "刷新浏览器,显示出了应用的标题和指向英雄列表的链接,但并没有显示英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "CLICKTHELINKTHEADDRESSBARUPDATESTOHEROESANDTHELISTOFHEROESAPPEARS", "original": "Click the link. \nThe address bar updates to `/heroes` and the list of heroes appears.", "translation": "点击这个链接。地址栏变成了 `/heroes`,并且显示出了英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "MAKETHISANDFUTURENAVIGATIONLINKSLOOKBETTERBYADDINGPRIVATECSSSTYLESTOAPPCOMPONENTCSSASLISTEDINTHEFINALCODEREVIEW#APPCOMPONENTBELOW", "original": "Make this and future navigation links look better by adding private CSS styles to `app.component.css`\nas listed in the [final code review](#appcomponent) below.", "translation": "从下面的 [最终代码](#appcomponent)中把私有 CSS 样式添加到 `app.component.css` 中,可以让导航链接变得更好看一点。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "##ADDADASHBOARDVIEW", "original": "## Add a dashboard view", "translation": "## 添加仪表盘视图", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ROUTINGMAKESMORESENSEWHENTHEREAREMULTIPLEVIEWSSOFARTHERESONLYTHEHEROESVIEW", "original": "Routing makes more sense when there are multiple views.\nSo far there's only the heroes view.", "translation": "当有多个视图时,路由会更有价值。不过目前还只有一个英雄列表视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDADASHBOARDCOMPONENTUSINGTHECLI:", "original": "Add a `DashboardComponent` using the CLI:", "translation": "使用 CLI 添加一个 `DashboardComponent`:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THECLIGENERATESTHEFILESFORTHEDASHBOARDCOMPONENTANDDECLARESITINAPPMODULE", "original": "The CLI generates the files for the `DashboardComponent` and declares it in `AppModule`.", "translation": "CLI 生成了 `DashboardComponent` 的相关文件,并把它声明到 `AppModule` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "REPLACETHEDEFAULTFILECONTENTINTHESETHREEFILESASFOLLOWSANDTHENRETURNFORALITTLEDISCUSSION:", "original": "Replace the default file content in these three files as follows and then return for a little discussion:", "translation": "把这三个文件中的内容改成这样,并回来做一个随堂讨论:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THETEMPLATEPRESENTSAGRIDOFHERONAMELINKS", "original": "The _template_ presents a grid of hero name links.", "translation": "这个*模板*用来表示由英雄名字链接组成的一个阵列。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THENGFORREPEATERCREATESASMANYLINKSASAREINTHECOMPONENTSHEROESARRAY", "original": "* The `*ngFor` repeater creates as many links as are in the component's `heroes` array.", "translation": "`*ngFor` 复写器为组件的 `heroes` 数组中的每个条目创建了一个链接。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THELINKSARESTYLEDASCOLOREDBLOCKSBYTHEDASHBOARDCOMPONENTCSS", "original": "* The links are styled as colored blocks by the `dashboard.component.css`.", "translation": "这些链接被 `dashboard.component.css` 中的样式格式化成了一些色块。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THELINKSDONTGOANYWHEREYETBUTTHEYWILLSHORTLY#HERODETAILS", "original": "* The links don't go anywhere yet but [they will shortly](#hero-details).", "translation": "这些链接还没有指向任何地方,但[很快就会了](#hero-details)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THECLASSISSIMILARTOTHEHEROESCOMPONENTCLASS", "original": "The _class_ is similar to the `HeroesComponent` class.", "translation": "这个*类*和 `HeroesComponent` 类很像。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ITDEFINESAHEROESARRAYPROPERTY", "original": "* It defines a `heroes` array property.", "translation": "它定义了一个 `heroes` 数组属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THECONSTRUCTOREXPECTSANGULARTOINJECTTHEHEROSERVICEINTOAPRIVATEHEROSERVICEPROPERTY", "original": "* The constructor expects Angular to inject the `HeroService` into a private `heroService` property.", "translation": "它的构造函数希望 Angular 把 `HeroService` 注入到私有的 `heroService` 属性中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THENGONINITLIFECYCLEHOOKCALLSGETHEROES", "original": "* The `ngOnInit()` lifecycle hook calls `getHeroes`.", "translation": "在 `ngOnInit()` 生命周期钩子中调用 `getHeroes`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THISGETHEROESREDUCESTHENUMBEROFHEROESDISPLAYEDTOFOUR2ND3RD4THAND5TH", "original": "This `getHeroes` reduces the number of heroes displayed to four\n(2nd, 3rd, 4th, and 5th).", "translation": "这个 `getHeroes` 函数把要显示的英雄的数量缩减为四个(第二、第三、第四、第五)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "###ADDTHEDASHBOARDROUTE", "original": "### Add the dashboard route", "translation": "### 添加仪表盘路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "TONAVIGATETOTHEDASHBOARDTHEROUTERNEEDSANAPPROPRIATEROUTE", "original": "To navigate to the dashboard, the router needs an appropriate route.", "translation": "要导航到仪表盘,路由器中就需要一个相应的路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "IMPORTTHEDASHBOARDCOMPONENTINTHEAPPROUTINGMODULE", "original": "Import the `DashboardComponent` in the `AppRoutingModule`.", "translation": "把 `DashboardComponent` 导入到 `AppRoutingModule` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDAROUTETOTHEAPPROUTINGMODULEROUTESARRAYTHATMATCHESAPATHTOTHEDASHBOARDCOMPONENT", "original": "Add a route to the `AppRoutingModule.routes` array that matches a path to the `DashboardComponent`.", "translation": "把一个指向 `DashboardComponent` 的路由添加到 `AppRoutingModule.routes` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "###ADDADEFAULTROUTE", "original": "### Add a default route", "translation": "### 添加默认路由", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "WHENTHEAPPSTARTSTHEBROWSERSADDRESSBARPOINTSTOTHEWEBSITESROOTTHATDOESNTMATCHANYEXISTINGROUTESOTHEROUTERDOESNTNAVIGATEANYWHERETHESPACEBELOWTHEROUTEROUTLETISBLANK", "original": "When the app starts, the browsers address bar points to the web site's root.\nThat doesn't match any existing route so the router doesn't navigate anywhere.\nThe space below the `<router-outlet>` is blank.", "translation": "当应用启动时,浏览器的地址栏指向了网站的根路径。\n它没有匹配到任何现存路由,因此路由器也不会导航到任何地方。\n`<router-outlet>` 下方是空白的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "TOMAKETHEAPPNAVIGATETOTHEDASHBOARDAUTOMATICALLYADDTHEFOLLOWINGROUTETOTHEAPPROUTINGMODULEROUTESARRAY", "original": "To make the app navigate to the dashboard automatically, add the following\nroute to the `AppRoutingModule.Routes` array.", "translation": "要让应用自动导航到这个仪表盘,请把下列路由添加到 `AppRoutingModule.Routes` 数组中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THISROUTEREDIRECTSAURLTHATFULLYMATCHESTHEEMPTYPATHTOTHEROUTEWHOSEPATHISDASHBOARD", "original": "This route redirects a URL that fully matches the empty path to the route whose path is `'/dashboard'`.", "translation": "这个路由会把一个与空路径“完全匹配”的 URL 重定向到路径为 `'/dashboard'` 的路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "AFTERTHEBROWSERREFRESHESTHEROUTERLOADSTHEDASHBOARDCOMPONENTANDTHEBROWSERADDRESSBARSHOWSTHEDASHBOARDURL", "original": "After the browser refreshes, the router loads the `DashboardComponent`\nand the browser address bar shows the `/dashboard` URL.", "translation": "浏览器刷新之后,路由器加载了 `DashboardComponent`,并且浏览器的地址栏会显示出 `/dashboard` 这个 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "###ADDDASHBOARDLINKTOTHESHELL", "original": "### Add dashboard link to the shell", "translation": "### 把仪表盘链接添加到壳组件中", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEUSERSHOULDBEABLETONAVIGATEBACKANDFORTHBETWEENTHEDASHBOARDCOMPONENTANDTHEHEROESCOMPONENTBYCLICKINGLINKSINTHENAVIGATIONAREANEARTHETOPOFTHEPAGE", "original": "The user should be able to navigate back and forth between the\n`DashboardComponent` and the `HeroesComponent` by clicking links in the\nnavigation area near the top of the page.", "translation": "应该允许用户通过点击页面顶部导航区的各个链接在 `DashboardComponent` 和 `HeroesComponent` 之间来回导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDADASHBOARDNAVIGATIONLINKTOTHEAPPCOMPONENTSHELLTEMPLATEJUSTABOVETHEHEROESLINK", "original": "Add a dashboard navigation link to the `AppComponent` shell template, just above the *Heroes* link.", "translation": "把仪表盘的导航链接添加到壳组件 `AppComponent` 的模板中,就放在 *Heroes* 链接的前面。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "AFTERTHEBROWSERREFRESHESYOUCANNAVIGATEFREELYBETWEENTHETWOVIEWSBYCLICKINGTHELINKS", "original": "After the browser refreshes you can navigate freely between the two views by clicking the links.", "translation": "刷新浏览器,你就能通过点击这些链接在这两个视图之间自由导航了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "##NAVIGATINGTOHERODETAILS", "original": "## Navigating to hero details", "translation": "## 导航到英雄详情", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEHERODETAILSCOMPONENTDISPLAYSDETAILSOFASELECTEDHEROATTHEMOMENTTHEHERODETAILSCOMPONENTISONLYVISIBLEATTHEBOTTOMOFTHEHEROESCOMPONENT", "original": "The `HeroDetailsComponent` displays details of a selected hero.\nAt the moment the `HeroDetailsComponent` is only visible at the bottom of the `HeroesComponent`", "translation": "`HeroDetailComponent` 可以显示所选英雄的详情。\n此刻,`HeroDetailsComponent` 只能在 `HeroesComponent` 的底部看到。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEUSERSHOULDBEABLETOGETTOTHESEDETAILSINTHREEWAYS", "original": "The user should be able to get to these details in three ways.", "translation": "用户应该能通过三种途径看到这些详情。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "1BYCLICKINGAHEROINTHEDASHBOARD", "original": "1. By clicking a hero in the dashboard.", "translation": "通过在仪表盘中点击某个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "1BYCLICKINGAHEROINTHEHEROESLIST", "original": "1. By clicking a hero in the heroes list.", "translation": "通过在英雄列表中点击某个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "1BYPASTINGADEEPLINKURLINTOTHEBROWSERADDRESSBARTHATIDENTIFIESTHEHEROTODISPLAY", "original": "1. By pasting a \"deep link\" URL into the browser address bar that identifies the hero to display.", "translation": "通过把一个“深链接” URL 粘贴到浏览器的地址栏中来指定要显示的英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "INTHISSECTIONYOULLENABLENAVIGATIONTOTHEHERODETAILSCOMPONENTANDLIBERATEITFROMTHEHEROESCOMPONENT", "original": "In this section, you'll enable navigation to the `HeroDetailsComponent`\nand liberate it from the `HeroesComponent`.", "translation": "在这一节,你将能导航到 `HeroDetailComponent`,并把它从 `HeroesComponent` 中解放出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { - "original": "### Delete _hero details_ from _HeroesComponent_", + "key": "###DELETEHERODETAILSFROMHEROESCOMPONENT", + "original": "### Delete _hero details_ from `HeroesComponent`", "translation": "### 从 `HeroesComponent` 中删除*英雄详情*", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "WHENTHEUSERCLICKSAHEROITEMINTHEHEROESCOMPONENTTHEAPPSHOULDNAVIGATETOTHEHERODETAILCOMPONENTREPLACINGTHEHEROESLISTVIEWWITHTHEHERODETAILVIEWTHEHEROESLISTVIEWSHOULDNOLONGERSHOWHERODETAILSASITDOESNOW", "original": "When the user clicks a hero item in the `HeroesComponent`,\nthe app should navigate to the `HeroDetailComponent`,\nreplacing the heroes list view with the hero detail view.\nThe heroes list view should no longer show hero details as it does now.", "translation": "当用户在 `HeroesComponent` 中点击某个英雄条目时,应用应该能导航到 `HeroDetailComponent`,从英雄列表视图切换到英雄详情视图。\n英雄列表视图将不再显示,而英雄详情视图要显示出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "OPENTHEHEROESCOMPONENTTEMPLATEHEROESHEROESCOMPONENTHTMLANDDELETETHEAPPHERODETAILELEMENTFROMTHEBOTTOM", "original": "Open the `HeroesComponent` template (`heroes/heroes.component.html`) and\ndelete the `<app-hero-detail>` element from the bottom.", "translation": "打开 `HeroesComponent` 的模板文件(`heroes/heroes.component.html`),并从底部删除 `<app-hero-detail>` 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "CLICKINGAHEROITEMNOWDOESNOTHINGYOULLFIXTHATSHORTLY#HEROESCOMPONENTLINKSAFTERYOUENABLEROUTINGTOTHEHERODETAILCOMPONENT", "original": "Clicking a hero item now does nothing. \nYou'll [fix that shortly](#heroes-component-links) after you enable routing to the `HeroDetailComponent`.", "translation": "目前,点击某个英雄条目还没有反应。不过当你启用了到 `HeroDetailComponent` 的路由之后,[很快就能修复它](#heroes-component-links)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "###ADDAHERODETAILROUTE", "original": "### Add a _hero detail_ route", "translation": "### 添加*英雄详情*视图", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "AURLLIKEDETAIL11WOULDBEAGOODURLFORNAVIGATINGTOTHEHERODETAILVIEWOFTHEHEROWHOSEIDIS11", "original": "A URL like `~/detail/11` would be a good URL for navigating to the *Hero Detail* view of the hero whose `id` is `11`.", "translation": "要导航到 `id` 为 `11` 的英雄的*详情*视图,类似于 `~/detail/11` 的 URL 将是一个不错的 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "OPENAPPROUTINGMODULEANDIMPORTHERODETAILCOMPONENT", "original": "Open `AppRoutingModule` and import `HeroDetailComponent`.", "translation": "打开 `AppRoutingModule` 并导入 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THENADDAPARAMETERIZEDROUTETOTHEAPPROUTINGMODULEROUTESARRAYTHATMATCHESTHEPATHPATTERNTOTHEHERODETAILVIEW", "original": "Then add a _parameterized_ route to the `AppRoutingModule.routes` array that matches the path pattern to the _hero detail_ view.", "translation": "然后把一个*参数化*路由添加到 `AppRoutingModule.routes` 数组中,它要匹配指向*英雄详情*视图的路径。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THECOLON:INTHEPATHINDICATESTHAT:IDISAPLACEHOLDERFORASPECIFICHEROID", "original": "The colon (:) in the `path` indicates that `:id` is a placeholder for a specific hero `id`.", "translation": "`path` 中的冒号(`:`)表示 `:id` 是一个占位符,它表示某个特定英雄的 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ATTHISPOINTALLAPPLICATIONROUTESAREINPLACE", "original": "At this point, all application routes are in place.", "translation": "此刻,应用中的所有路由都就绪了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { - "original": "### _DashboardComponent_ hero links", + "key": "###DASHBOARDCOMPONENTHEROLINKS", + "original": "### `DashboardComponent` hero links", "translation": "### `DashboardComponent` 中的英雄链接", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEDASHBOARDCOMPONENTHEROLINKSDONOTHINGATTHEMOMENT", "original": "The `DashboardComponent` hero links do nothing at the moment.", "translation": "此刻,`DashboardComponent` 中的英雄连接还没有反应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "NOWTHATTHEROUTERHASAROUTETOHERODETAILCOMPONENTFIXTHEDASHBOARDHEROLINKSTONAVIGATEVIATHEPARAMETERIZEDDASHBOARDROUTE", "original": "Now that the router has a route to `HeroDetailComponent`,\nfix the dashboard hero links to navigate via the _parameterized_ dashboard route.", "translation": "路由器已经有一个指向 `HeroDetailComponent` 的路由了,\n修改仪表盘中的英雄连接,让它们通过参数化的英雄详情路由进行导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUREUSINGANGULARINTERPOLATIONBINDINGGUIDETEMPLATESYNTAX#INTERPOLATIONWITHINTHENGFORREPEATERTOINSERTTHECURRENTINTERATIONSHEROIDINTOEACHROUTERLINK#ROUTERLINK", "original": "You're using Angular [interpolation binding](guide/template-syntax#interpolation) within the `*ngFor` repeater \nto insert the current interation's `hero.id` into each \n[`routerLink`](#routerlink).", "translation": "你正在 `*ngFor` 复写器中使用 Angular 的[插值表达式](guide/template-syntax#interpolation)来把当前迭代的 `hero.id` 插入到每个 [`routerLink`](#routerlink) 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { - "original": "### _HeroesComponent_ hero links", + "key": "###HEROESCOMPONENTHEROLINKS", + "original": "### `HeroesComponent` hero links", "translation": "### `HeroesComponent` 中的英雄链接", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEHEROITEMSINTHEHEROESCOMPONENTARELIELEMENTSWHOSECLICKEVENTSAREBOUNDTOTHECOMPONENTSONSELECTMETHOD", "original": "The hero items in the `HeroesComponent` are `<li>` elements whose click events\nare bound to the component's `onSelect()` method.", "translation": "`HeroesComponent` 中的这些英雄条目都是 `<li>` 元素,它们的点击事件都绑定到了组件的 `onSelect()` 方法中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "STRIPTHELIBACKTOJUSTITSNGFORWRAPTHEBADGEANDNAMEINANANCHORELEMENTAANDADDAROUTERLINKATTRIBUTETOTHEANCHORTHATISTHESAMEASINTHEDASHBOARDTEMPLATE", "original": "Strip the `<li>` back to just its `*ngFor`,\nwrap the badge and name in an anchor element (`<a>`),\nand add a `routerLink` attribute to the anchor that \nis the same as in the dashboard template", "translation": "清理 `<li>`,只保留它的 `*ngFor`,把徽章(`<badge>`)和名字包裹进一个 `<a>` 元素中,\n并且像仪表盘的模板中那样为这个 `<a>` 元素添加一个 `routerLink` 属性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOULLHAVETOFIXTHEPRIVATESTYLESHEETHEROESCOMPONENTCSSTOMAKETHELISTLOOKASITDIDBEFOREREVISEDSTYLESAREINTHEFINALCODEREVIEW#HEROESCOMPONENTATTHEBOTTOMOFTHISGUIDE", "original": "You'll have to fix the private stylesheet (`heroes.component.css`) to make\nthe list look as it did before.\nRevised styles are in the [final code review](#heroescomponent) at the bottom of this guide.", "translation": "你还要修改私有样式表(`heroes.component.css`),让列表恢复到以前的外观。\n修改后的样式表参见本指南底部的[最终代码](#heroescomponent)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "####REMOVEDEADCODEOPTIONAL", "original": "#### Remove dead code (optional)", "translation": "#### 移除死代码(可选)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "WHILETHEHEROESCOMPONENTCLASSSTILLWORKSTHEONSELECTMETHODANDSELECTEDHEROPROPERTYARENOLONGERUSED", "original": "While the `HeroesComponent` class still works, \nthe `onSelect()` method and `selectedHero` property are no longer used.", "translation": "虽然 `HeroesComponent` 类仍然能正常工作,但 `onSelect()` 方法和 `selectedHero` 属性已经没用了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ITSNICETOTIDYUPANDYOULLBEGRATEFULTOYOURSELFLATERHERESTHECLASSAFTERPRUNINGAWAYTHEDEADCODE", "original": "It's nice to tidy up and you'll be grateful to yourself later.\nHere's the class after pruning away the dead code.", "translation": "最好清理掉它们,将来你会体会到这么做的好处。\n下面是删除了死代码之后的类。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "##ROUTABLEHERODETAILCOMPONENT", "original": "## Routable *HeroDetailComponent*", "translation": "## 支持路由的 `HeroDetailComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "PREVIOUSLYTHEPARENTHEROESCOMPONENTSETTHEHERODETAILCOMPONENTHEROPROPERTYANDTHEHERODETAILCOMPONENTDISPLAYEDTHEHERO", "original": "Previously, the parent `HeroesComponent` set the `HeroDetailComponent.hero`\nproperty and the `HeroDetailComponent` displayed the hero.", "translation": "以前,父组件 `HeroesComponent` 会设置 `HeroDetailComponent.hero` 属性,然后 `HeroDetailComponent` 就会显示这个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "HEROESCOMPONENTDOESNTDOTHATANYMORENOWTHEROUTERCREATESTHEHERODETAILCOMPONENTINRESPONSETOAURLSUCHASDETAIL11", "original": "`HeroesComponent` doesn't do that anymore.\nNow the router creates the `HeroDetailComponent` in response to a URL such as `~/detail/11`.", "translation": "`HeroesComponent` 已经不会再那么做了。\n现在,当路由器会在响应形如 `~/detail/11` 的 URL 时创建 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEHERODETAILCOMPONENTNEEDSANEWWAYTOOBTAINTHEHEROTODISPLAY", "original": "The `HeroDetailComponent` needs a new way to obtain the _hero-to-display_.", "translation": "`HeroDetailComponent` 需要从一种新的途径获取*要显示的英雄*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "GETTHEROUTETHATCREATEDIT", "original": "* Get the route that created it,", "translation": "获取创建本组件的路由,", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "EXTRACTTHEIDFROMTHEROUTE", "original": "* Extract the `id` from the route", "translation": "从这个路由中提取出 `id`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ACQUIRETHEHEROWITHTHATIDFROMTHESERVERVIATHEHEROSERVICE", "original": "* Acquire the hero with that `id` from the server via the `HeroService`", "translation": "通过 `HeroService` 从服务器上获取具有这个 `id` 的英雄数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDTHEFOLLOWINGIMPORTS:", "original": "Add the following imports:", "translation": "先添加下列导入语句:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "INJECTTHEACTIVATEDROUTEHEROSERVICEANDLOCATIONSERVICESINTOTHECONSTRUCTORSAVINGTHEIRVALUESINPRIVATEFIELDS:", "original": "Inject the `ActivatedRoute`, `HeroService`, and `Location` services\ninto the constructor, saving their values in private fields:", "translation": "然后把 `ActivatedRoute`、`HeroService` 和 `Location` 服务注入到构造函数中,将它们的值保存到私有变量里:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEACTIVATEDROUTEAPIROUTERACTIVATEDROUTEHOLDSINFORMATIONABOUTTHEROUTETOTHISINSTANCEOFTHEHERODETAILCOMPONENTTHISCOMPONENTISINTERESTEDINTHEROUTESBAGOFPARAMETERSEXTRACTEDFROMTHEURLTHEIDPARAMETERISTHEIDOFTHEHEROTODISPLAY", "original": "The [`ActivatedRoute`](api/router/ActivatedRoute) holds information about the route to this instance of the `HeroDetailComponent`.\nThis component is interested in the route's bag of parameters extracted from the URL.\nThe _\"id\"_ parameter is the `id` of the hero to display.", "translation": "[`ActivatedRoute`](api/router/ActivatedRoute) 保存着到这个 `HeroDetailComponent` 实例的路由信息。\n这个组件对从 URL 中提取的路由参数感兴趣。\n其中的 *`id`* 参数就是要现实的英雄的 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEHEROSERVICETUTORIALTOHPT4GETSHERODATAFROMTHEREMOTESERVERANDTHISCOMPONENTWILLUSEITTOGETTHEHEROTODISPLAY", "original": "The [`HeroService`](tutorial/toh-pt4) gets hero data from the remote server\nand this component will use it to get the _hero-to-display_.", "translation": "[`HeroService`](tutorial/toh-pt4) 从远端服务器获取英雄数据,本组件将使用它来获取*要显示的英雄*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THELOCATIONAPICOMMONLOCATIONISANANGULARSERVICEFORINTERACTINGWITHTHEBROWSERYOULLUSEITLATER#GOBACKTONAVIGATEBACKTOTHEVIEWTHATNAVIGATEDHERE", "original": "The [`location`](api/common/Location) is an Angular service for interacting with the browser.\nYou'll use it [later](#goback) to navigate back to the view that navigated here.", "translation": "[`location`](api/common/Location) 是一个 Angular 的服务,用来与浏览器打交道。\n[稍后](#goback),你就会使用它来导航回上一个视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "###EXTRACTTHEIDROUTEPARAMETER", "original": "### Extract the _id_ route parameter", "translation": "### 从路由参数中提取 `id`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "INTHENGONINITLIFECYCLEHOOKGUIDELIFECYCLEHOOKS#ONINITCALLGETHEROANDDEFINEITASFOLLOWS", "original": "In the `ngOnInit()` [lifecycle hook](guide/lifecycle-hooks#oninit)\ncall `getHero()` and define it as follows.", "translation": "在 `ngOnInit()` [生命周期钩子](guide/lifecycle-hooks#oninit)\n中调用 `getHero()`,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEROUTESNAPSHOTISASTATICIMAGEOFTHEROUTEINFORMATIONSHORTLYAFTERTHECOMPONENTWASCREATED", "original": "The `route.snapshot` is a static image of the route information shortly after the component was created.", "translation": "`route.snapshot` 是一个路由信息的静态快照,抓取自组件刚刚创建完毕之后。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEPARAMMAPISADICTIONARYOFROUTEPARAMETERVALUESEXTRACTEDFROMTHEURLTHEIDKEYRETURNSTHEIDOFTHEHEROTOFETCH", "original": "The `paramMap` is a dictionary of route parameter values extracted from the URL.\nThe `\"id\"` key returns the `id` of the hero to fetch.", "translation": "`paramMap` 是一个从 URL 中提取的路由参数值的字典。\n`\"id\"` 对应的值就是要获取的英雄的 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ROUTEPARAMETERSAREALWAYSSTRINGSTHEJAVASCRIPTOPERATORCONVERTSTHESTRINGTOANUMBERWHICHISWHATAHEROIDSHOULDBE", "original": "Route parameters are always strings.\nThe JavaScript (+) operator converts the string to a number,\nwhich is what a hero `id` should be.", "translation": "路由参数总会是字符串。\nJavaScript 的 (+) 操作符会把字符串转换成数字,英雄的 `id` 就是数字类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEBROWSERREFRESHESANDTHEAPPCRASHESWITHACOMPILERERRORHEROSERVICEDOESNTHAVEAGETHEROMETHODADDITNOW", "original": "The browser refreshes and the app crashes with a compiler error.\n`HeroService` doesn't have a `getHero()` method.\nAdd it now.", "translation": "刷新浏览器,应用挂了。出现一个编译错误,因为 `HeroService` 没有一个名叫 `getHero()` 的方法。\n这就添加它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { - "original": "### Add *HeroService.getHero()*", - "translation": "### 添加 *HeroService.getHero()*", + "key": "###ADDHEROSERVICEGETHERO", + "original": "### Add `HeroService.getHero()`", + "translation": "### 添加 `HeroService.getHero()`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "OPENHEROSERVICEANDADDTHISGETHEROMETHOD", "original": "Open `HeroService` and add this `getHero()` method", "translation": "添加 `HeroService`,并添加如下的 `getHero()` 方法", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "NOTETHEBACKTICKS#96THATDEFINEAJAVASCRIPTTEMPLATELITERALHTTPS:DEVELOPERMOZILLAORGENUSDOCSWEBJAVASCRIPTREFERENCETEMPLATELITERALSFOREMBEDDINGTHEID", "original": "Note the backticks ( ` ) that \ndefine a JavaScript \n[_template literal_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) for embedding the `id`.", "translation": "注意,反引号 ( ` ) 用于定义 JavaScript 的 [模板字符串字面量](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals),以便嵌入 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "LIKEGETHEROESTUTORIALTOHPT4#OBSERVABLEHEROSERVICEGETHEROHASANASYNCHRONOUSSIGNATUREITRETURNSAMOCKHEROASANOBSERVABLEUSINGTHERXJSOFFUNCTION", "original": "Like [`getHeroes()`](tutorial/toh-pt4#observable-heroservice),\n`getHero()` has an asynchronous signature.\nIt returns a _mock hero_ as an `Observable`, using the RxJS `of()` function.", "translation": "像 [`getHeroes()`](tutorial/toh-pt4#observable-heroservice) 一样,`getHero()` 也有一个异步函数签名。\n它用 RxJS 的 `of()` 函数返回一个 `Observable` 形式的*模拟英雄数据*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOULLBEABLETOREIMPLEMENTGETHEROASAREALHTTPREQUESTWITHOUTHAVINGTOCHANGETHEHERODETAILCOMPONENTTHATCALLSIT", "original": "You'll be able to re-implement `getHero()` as a real `Http` request\nwithout having to change the `HeroDetailComponent` that calls it.", "translation": "你将来可以用一个真实的 `Http` 请求来重现实现 `getHero()`,而不用修改调用了它的 `HeroDetailComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "####TRYIT", "original": "#### Try it", "translation": "#### 试试看", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "THEBROWSERREFRESHESANDTHEAPPISWORKINGAGAINYOUCANCLICKAHEROINTHEDASHBOARDORINTHEHEROESLISTANDNAVIGATETOTHATHEROSDETAILVIEW", "original": "The browser refreshes and the app is working again.\nYou can click a hero in the dashboard or in the heroes list and navigate to that hero's detail view.", "translation": "刷新浏览器,应用又恢复正常了。\n你可以在仪表盘或英雄列表中点击一个英雄来导航到该英雄的详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "IFYOUPASTELOCALHOST:4200DETAIL11INTHEBROWSERADDRESSBARTHEROUTERNAVIGATESTOTHEDETAILVIEWFORTHEHEROWITHID:11MRNICE", "original": "If you paste `localhost:4200/detail/11` in the browser address bar,\nthe router navigates to the detail view for the hero with `id: 11`, \"Mr. Nice\".", "translation": "如果你在浏览器的地址栏中粘贴了 `localhost:4200/detail/11`,路由器也会导航到 `id: 11` 的英雄(\"Mr. Nice\")的详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "###FINDTHEWAYBACK", "original": "### Find the way back", "translation": "### 回到原路", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "BYCLICKINGTHEBROWSERSBACKBUTTONYOUCANGOBACKTOTHEHEROLISTORDASHBOARDVIEWDEPENDINGUPONWHICHSENTYOUTOTHEDETAILVIEW", "original": "By clicking the browser's back button, \nyou can go back to the hero list or dashboard view,\ndepending upon which sent you to the detail view.", "translation": "通过点击浏览器的后退按钮,你可以回到英雄列表或仪表盘视图,这取决于你从哪里进入的详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ITWOULDBENICETOHAVEABUTTONONTHEHERODETAILVIEWTHATCANDOTHAT", "original": "It would be nice to have a button on the `HeroDetail` view that can do that.", "translation": "如果能在 `HeroDetail` 视图中也有这么一个按钮就更好了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDAGOBACKBUTTONTOTHEBOTTOMOFTHECOMPONENTTEMPLATEANDBINDITTOTHECOMPONENTSGOBACKMETHOD", "original": "Add a *go back* button to the bottom of the component template and bind it\nto the component's `goBack()` method.", "translation": "把一个*后退*按钮添加到组件模板的底部,并且把它绑定到组件的 `goBack()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "ADDAGOBACKMETHODTOTHECOMPONENTCLASSTHATNAVIGATESBACKWARDONESTEPINTHEBROWSERSHISTORYSTACKUSINGTHELOCATIONSERVICETHATYOUINJECTEDPREVIOUSLY#HERODETAILCTOR", "original": "Add a `goBack()` _method_ to the component class that navigates backward one step \nin the browser's history stack\nusing the `Location` service that you [injected previously](#hero-detail-ctor).", "translation": "在组件类中添加一个 `goBack()` 方法,利用[你以前注入的](#hero-detail-ctor) `Location` 服务在浏览器的历史栈中后退一步。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "REFRESHTHEBROWSERANDSTARTCLICKINGUSERSCANNAVIGATEAROUNDTHEAPPFROMTHEDASHBOARDTOHERODETAILSANDBACKFROMHEROESLISTTOTHEMINIDETAILTOTHEHERODETAILSANDBACKTOTHEHEROESAGAIN", "original": "Refresh the browser and start clicking.\nUsers can navigate around the app, from the dashboard to hero details and back,\nfrom heroes list to the mini detail to the hero details and back to the heroes again.", "translation": "刷新浏览器,并开始点击。\n用户能在应用中导航:从仪表盘到英雄详情再回来,从英雄列表到 mini 版英雄详情到英雄详情,再回到英雄列表。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUVEMETALLOFTHENAVIGATIONALREQUIREMENTSTHATPROPELLEDTHISPAGE", "original": "You've met all of the navigational requirements that propelled this page.", "translation": "你已经满足了在本章开头设定的所有导航需求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "##FINALCODEREVIEW", "original": "## Final code review", "translation": "## 查看最终代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "HEREARETHECODEFILESDISCUSSEDONTHISPAGEANDYOURAPPSHOULDLOOKLIKETHISLIVEEXAMPLELIVEEXAMPLE", "original": "Here are the code files discussed on this page and your app should look like this <live-example></live-example>.", "translation": "你的应用应该变成了这样 <live-example></live-example>。本页所提及的代码文件如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { - "original": "#### _AppRoutingModule_ and _AppModule_", - "translation": "#### _AppRoutingModule_ 与 _AppModule_", + "key": "####APPROUTINGMODULEAPPMODULEANDHEROSERVICE", + "original": "#### _AppRoutingModule_, _AppModule_, and _HeroService_", + "translation": "#### `AppRoutingModule`、`AppModule` 和 `HeroService`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUADDEDTHEANGULARROUTERTONAVIGATEAMONGDIFFERENTCOMPONENTS", "original": "* You added the Angular router to navigate among different components.", "translation": "添加了 Angular *路由器*在各个不同组件之间导航。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUTURNEDTHEAPPCOMPONENTINTOANAVIGATIONSHELLWITHALINKSANDAROUTEROUTLET", "original": "* You turned the `AppComponent` into a navigation shell with `<a>` links and a `<router-outlet>`.", "translation": "你使用一些 `<a>` 链接和一个 `<router-outlet>` 把 `AppComponent` 转换成了一个导航用的壳组件。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUCONFIGUREDTHEROUTERINANAPPROUTINGMODULE", "original": "* You configured the router in an `AppRoutingModule`", "translation": "你在 `AppRoutingModule` 中配置了路由器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUDEFINEDSIMPLEROUTESAREDIRECTROUTEANDAPARAMETERIZEDROUTE", "original": "* You defined simple routes, a redirect route, and a parameterized route.", "translation": "你定义了一些简单路由、一个重定向路由和一个参数化路由。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUUSEDTHEROUTERLINKDIRECTIVEINANCHORELEMENTS", "original": "* You used the `routerLink` directive in anchor elements.", "translation": "你在 `<a>` 元素中使用了 `routerLink` 指令。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUREFACTOREDATIGHTLYCOUPLEDMASTERDETAILVIEWINTOAROUTEDDETAILVIEW", "original": "* You refactored a tightly-coupled master/detail view into a routed detail view.", "translation": "你把一个紧耦合的主从视图重构成了带路由的详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUUSEDROUTERLINKPARAMETERSTONAVIGATETOTHEDETAILVIEWOFAUSERSELECTEDHERO", "original": "* You used router link parameters to navigate to the detail view of a user-selected hero.", "translation": "你使用路由链接参数来导航到所选英雄的详情视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "YOUSHAREDTHEHEROSERVICEAMONGMULTIPLECOMPONENTS", "original": "* You shared the `HeroService` among multiple components.", "translation": "在多个组件之间共享了 `HeroService` 服务。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt5.md" }, { + "key": "INTHISTUTORIALYOULLADDTHEFOLLOWINGDATAPERSISTENCEFEATURESWITHHELPFROMANGULARSHTTPCLIENT", "original": "In this tutorial, you'll add the following data persistence features with help from\nAngular's `HttpClient`.", "translation": "在这节课中,你将借助 Angular 的 `HttpClient` 来添加一些数据持久化特性。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEHEROSERVICEGETSHERODATAWITHHTTPREQUESTS", "original": "* The `HeroService` gets hero data with HTTP requests.", "translation": "`HeroService` 通过 HTTP 请求获取英雄数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "USERSCANADDEDITANDDELETEHEROESANDSAVETHESECHANGESOVERHTTP", "original": "* Users can add, edit, and delete heroes and save these changes over HTTP.", "translation": "用户可以添加、编辑和删除英雄,并通过 HTTP 来保存这些更改。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "USERSCANSEARCHFORHEROESBYNAME", "original": "* Users can search for heroes by name.", "translation": "用户可以根据名字搜索英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "WHENYOUREDONEWITHTHISPAGETHEAPPSHOULDLOOKLIKETHISLIVEEXAMPLELIVEEXAMPLE", "original": "When you're done with this page, the app should look like this <live-example></live-example>.", "translation": "当你完成这一章时,应用会变成这样:<live-example></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##ENABLEHTTPSERVICES", "original": "## Enable HTTP services", "translation": "## 启用 HTTP 服务", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "HTTPCLIENTISANGULARSMECHANISMFORCOMMUNICATINGWITHAREMOTESERVEROVERHTTP", "original": "`HttpClient` is Angular's mechanism for communicating with a remote server over HTTP.", "translation": "`HttpClient` 是 Angular 通过 HTTP 与远程服务器通讯的机制。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "TOMAKEHTTPCLIENTAVAILABLEEVERYWHEREINTHEAPP", "original": "To make `HttpClient` available everywhere in the app,", "translation": "要让 `HttpClient` 在应用中随处可用,请", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "OPENTHEROOTAPPMODULE", "original": "* open the root `AppModule`,", "translation": "打开根模块 `AppModule`,", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "IMPORTTHEHTTPCLIENTMODULESYMBOLFROMANGULARCOMMONHTTP", "original": "* import the `HttpClientModule` symbol from `@angular/common/http`,", "translation": "从 `@angular/common/http` 中导入 `HttpClientModule` 符号,", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ADDITTOTHENGMODULEIMPORTSARRAY", "original": "* add it to the `@NgModule.imports` array.", "translation": "把它加入 `@NgModule.imports` 数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##SIMULATEADATASERVER", "original": "## Simulate a data server", "translation": "## 模拟数据服务器", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THISTUTORIALSAMPLEMIMICSCOMMUNICATIONWITHAREMOTEDATASERVERBYUSINGTHEINMEMORYWEBAPIHTTPS:GITHUBCOMANGULARINMEMORYWEBAPIINMEMORYWEBAPIMODULE", "original": "This tutorial sample _mimics_ communication with a remote data server by using the\n[_In-memory Web API_](https://github.com/angular/in-memory-web-api \"In-memory Web API\") module.", "translation": "这个教学例子会与一个使用 [内存 Web API(_In-memory Web API_)](https://github.com/angular/in-memory-web-api \"In-memory Web API\") 模拟出的远程数据服务器通讯。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "AFTERINSTALLINGTHEMODULETHEAPPWILLMAKEREQUESTSTOANDRECEIVERESPONSESFROMTHEHTTPCLIENTWITHOUTKNOWINGTHATTHEINMEMORYWEBAPIISINTERCEPTINGTHOSEREQUESTSAPPLYINGTHEMTOANINMEMORYDATASTOREANDRETURNINGSIMULATEDRESPONSES", "original": "After installing the module, the app will make requests to and receive responses from the `HttpClient`\nwithout knowing that the *In-memory Web API* is intercepting those requests,\napplying them to an in-memory data store, and returning simulated responses.", "translation": "安装完这个模块之后,应用将会通过 `HttpClient` 来发起请求和接收响应,而不用在乎实际上是这个内存 Web API 在拦截这些请求、操作一个内存数据库,并且给出仿真的响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THISFACILITYISAGREATCONVENIENCEFORTHETUTORIALYOUWONTHAVETOSETUPASERVERTOLEARNABOUTHTTPCLIENT", "original": "This facility is a great convenience for the tutorial.\nYou won't have to set up a server to learn about `HttpClient`.", "translation": "这给本教程带来了极大的便利。你不用被迫先架设一个服务器再来学习 `HttpClient`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ITMAYALSOBECONVENIENTINTHEEARLYSTAGESOFYOUROWNAPPDEVELOPMENTWHENTHESERVERSWEBAPIISILLDEFINEDORNOTYETIMPLEMENTED", "original": "It may also be convenient in the early stages of your own app development when\nthe server's web api is ill-defined or not yet implemented.", "translation": "在你自己的应用开发的早期阶段这也同样很方便,那时候服务器的 Web API 可能定义上存在错误或者尚未实现。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "IMPORTANT:THEINMEMORYWEBAPIMODULEHASNOTHINGTODOWITHHTTPINANGULAR", "original": "**Important:** the *In-memory Web API* module has nothing to do with HTTP in Angular.", "translation": "**重要:** 这个*内存 Web API* 模块与 Angular 中的 HTTP 模块无关。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "IFYOUREJUSTREADINGTHISTUTORIALTOLEARNABOUTHTTPCLIENTYOUCANSKIPOVER#IMPORTHEROESTHISSTEPIFYOURECODINGALONGWITHTHISTUTORIALSTAYHEREANDADDTHEINMEMORYWEBAPINOW", "original": "If you're just _reading_ this tutorial to learn about `HttpClient`, you can [skip over](#import-heroes) this step.\nIf you're _coding along_ with this tutorial, stay here and add the *In-memory Web API* now.", "translation": "如果你只是在*阅读*本教程来学习 `HttpClient`,那么可以[跳过](#import-heroes)这一步。\n如果你正在随着本教程*敲代码*,那就留下来,并加上这个*内存 Web API*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "INSTALLTHEINMEMORYWEBAPIPACKAGEFROMNPM", "original": "Install the *In-memory Web API* package from _npm_", "translation": "从 `npm` 中安装这个*内存 Web API* 包(译注:请使用 0.5+ 的版本,不要使用 0.4-)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "IMPORTTHEINMEMORYWEBAPIMODULEANDTHEINMEMORYDATASERVICECLASSWHICHYOUWILLCREATEINAMOMENT", "original": "Import the `InMemoryWebApiModule` and the `InMemoryDataService` class, \nwhich you will create in a moment.", "translation": "导入 `InMemoryWebApiModule` 和 `InMemoryDataService` 类(你很快就要创建它)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ADDTHEINMEMORYWEBAPIMODULETOTHENGMODULEIMPORTSARRAYMDASHAFTERIMPORTINGTHEHTTPCLIENTMDASHWHILECONFIGURINGITWITHTHEINMEMORYDATASERVICE", "original": "Add the `InMemoryWebApiModule` to the `@NgModule.imports` array—\n_after importing the `HttpClient`_,\n—while configuring it with the `InMemoryDataService`.", "translation": "把 `InMemoryWebApiModule` 添加到 `@NgModule.imports` 数组中(放在 `HttpClient` 之后),\n然后使用 `InMemoryDataService` 来配置它。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEFORROOTCONFIGURATIONMETHODTAKESANINMEMORYDATASERVICECLASSTHATPRIMESTHEINMEMORYDATABASE", "original": "The `forRoot()` configuration method takes an `InMemoryDataService` class\nthat primes the in-memory database.", "translation": "`forRoot()` 配置方法接受一个 `InMemoryDataService` 类(初期的内存数据库)作为参数。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THETOUROFHEROESSAMPLECREATESSUCHACLASSSRCAPPINMEMORYDATASERVICETSWHICHHASTHEFOLLOWINGCONTENT:", "original": "The _Tour of Heroes_ sample creates such a class \n`src/app/in-memory-data.service.ts` which has the following content:", "translation": "在*英雄指南*范例中创建一个类 `src/app/in-memory-data.service.ts`,内容如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THISFILEREPLACESMOCKHEROESTSWHICHISNOWSAFETODELETE", "original": "This file replaces `mock-heroes.ts`, which is now safe to delete.", "translation": "这个文件替代了 `mock-heroes.ts`(你可以安全删除它了)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "WHENYOURSERVERISREADYDETACHTHEINMEMORYWEBAPIANDTHEAPPSREQUESTSWILLGOTHROUGHTOTHESERVER", "original": "When your server is ready, detach the *In-memory Web API*, and the app's requests will go through to the server.", "translation": "等你真实的服务器就绪时,就可以删除这个*内存 Web API*,该应用的请求就会直接发给真实的服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "NOWBACKTOTHEHTTPCLIENTSTORY", "original": "Now back to the `HttpClient` story.", "translation": "现在,回来看 `HttpClient`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##HEROESANDHTTP", "original": "## Heroes and HTTP", "translation": "## 英雄与 HTTP", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "IMPORTSOMEHTTPSYMBOLSTHATYOULLNEED:", "original": "Import some HTTP symbols that you'll need:", "translation": "导入一些所需的 HTTP 符号:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "INJECTHTTPCLIENTINTOTHECONSTRUCTORINAPRIVATEPROPERTYCALLEDHTTP", "original": "Inject `HttpClient` into the constructor in a private property called `http`.", "translation": "把 `HttpClient` 注入到构造函数中一个名叫 `http` 的私有属性中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "KEEPINJECTINGTHEMESSAGESERVICEYOULLCALLITSOFREQUENTLYTHATYOULLWRAPITINPRIVATELOGMETHOD", "original": "Keep injecting the `MessageService`. You'll call it so frequently that\nyou'll wrap it in private `log` method.", "translation": "保留对 `MessageService` 的注入。你将会频繁调用它,因此请把它包裹进一个私有的 `log` 方法中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "DEFINETHEHEROESURLWITHTHEADDRESSOFTHEHEROESRESOURCEONTHESERVER", "original": "Define the `heroesUrl` with the address of the heroes resource on the server.", "translation": "把服务器上英雄数据资源的访问地址定义为 `heroesURL`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###GETHEROESWITHHTTPCLIENT", "original": "### Get heroes with _HttpClient_", "translation": "### 通过 `HttpClient` 获取英雄", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THECURRENTHEROSERVICEGETHEROESUSESTHERXJSOFFUNCTIONTORETURNANARRAYOFMOCKHEROESASANOBSERVABLEHERO", "original": "The current `HeroService.getHeroes()` \nuses the RxJS `of()` function to return an array of mock heroes\nas an `Observable<Hero[]>`.", "translation": "当前的 `HeroService.getHeroes()` 使用 RxJS 的 `of()` 函数来把模拟英雄数据返回为 `Observable<Hero[]>` 格式。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "CONVERTTHATMETHODTOUSEHTTPCLIENT", "original": "Convert that method to use `HttpClient`", "translation": "把该方法转换成使用 `HttpClient` 的", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "REFRESHTHEBROWSERTHEHERODATASHOULDSUCCESSFULLYLOADFROMTHEMOCKSERVER", "original": "Refresh the browser. The hero data should successfully load from the\nmock server.", "translation": "刷新浏览器后,英雄数据就会从模拟服务器被成功读取。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUVESWAPPEDOFFORHTTPGETANDTHEAPPKEEPSWORKINGWITHOUTANYOTHERCHANGESBECAUSEBOTHFUNCTIONSRETURNANOBSERVABLEHERO", "original": "You've swapped `of` for `http.get` and the app keeps working without any other changes\nbecause both functions return an `Observable<Hero[]>`.", "translation": "你用 `http.get` 替换了 `of`,没有做其它修改,但是应用仍然在正常工作,这是因为这两个函数都返回了 `Observable<Hero[]>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###HTTPMETHODSRETURNONEVALUE", "original": "### Http methods return one value", "translation": "### Http 方法返回单个值", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ALLHTTPCLIENTMETHODSRETURNANRXJSOBSERVABLEOFSOMETHING", "original": "All `HttpClient` methods return an RxJS `Observable` of something.", "translation": "所有的 `HttpClient` 方法都会返回某个值的 RxJS `Observable`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "HTTPISAREQUESTRESPONSEPROTOCOLYOUMAKEAREQUESTITRETURNSASINGLERESPONSE", "original": "HTTP is a request/response protocol. \nYou make a request, it returns a single response.", "translation": "HTTP 是一个请求/响应式协议。你发起请求,它返回单个的响应。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "INGENERALANOBSERVABLECANRETURNMULTIPLEVALUESOVERTIMEANOBSERVABLEFROMHTTPCLIENTALWAYSEMITSASINGLEVALUEANDTHENCOMPLETESNEVERTOEMITAGAIN", "original": "In general, an `Observable` _can_ return multiple values over time.\nAn `Observable` from `HttpClient` always emits a single value and then completes, never to emit again.", "translation": "通常,`Observable` *可以*在一段时间内返回多个值。\n但来自 `HttpClient` 的 `Observable` 总是发出一个值,然后结束,再也不会发出其它值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THISPARTICULARHTTPCLIENTGETCALLRETURNSANOBSERVABLEHEROLITERALLYANOBSERVABLEOFHEROARRAYSINPRACTICEITWILLONLYRETURNASINGLEHEROARRAY", "original": "This particular `HttpClient.get` call returns an `Observable<Hero[]>`, literally \"_an observable of hero arrays_\". In practice, it will only return a single hero array.", "translation": "具体到这次 `HttpClient.get` 调用,它返回一个 `Observable<Hero[]>`,顾名思义就是“一个英雄数组的可观察对象”。在实践中,它也只会返回一个英雄数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###HTTPCLIENTGETRETURNSRESPONSEDATA", "original": "### _HttpClient.get_ returns response data", "translation": "### `HttpClient.get` 返回响应数据", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "HTTPCLIENTGETRETURNSTHEBODYOFTHERESPONSEASANUNTYPEDJSONOBJECTBYDEFAULTAPPLYINGTHEOPTIONALTYPESPECIFIERHEROGIVESYOUATYPEDRESULTOBJECT", "original": "`HttpClient.get` returns the _body_ of the response as an untyped JSON object by default.\nApplying the optional type specifier, `<Hero[]>` , gives you a typed result object.", "translation": "`HttpClient.get` 默认情况下把响应体当做无类型的 JSON 对象进行返回。\n如果指定了可选的模板类型 `<Hero[]>`,就会给返回你一个类型化的对象。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THESHAPEOFTHEJSONDATAISDETERMINEDBYTHESERVERSDATAAPITHETOUROFHEROESDATAAPIRETURNSTHEHERODATAASANARRAY", "original": "The shape of the JSON data is determined by the server's data API.\nThe _Tour of Heroes_ data API returns the hero data as an array.", "translation": "JSON 数据的具体形态是由服务器的数据 API 决定的。\n*英雄指南*的数据 API 会把英雄数据作为一个数组进行返回。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "OTHERAPISMAYBURYTHEDATATHATYOUWANTWITHINANOBJECTYOUMIGHTHAVETODIGTHATDATAOUTBYPROCESSINGTHEOBSERVABLERESULTWITHTHERXJSMAPOPERATOR", "original": "Other APIs may bury the data that you want within an object.\nYou might have to dig that data out by processing the `Observable` result\nwith the RxJS `map` operator.", "translation": "其它 API 可能在返回对象中深埋着你想要的数据。\n你可能要借助 RxJS 的 `map` 操作符对 `Observable` 的结果进行处理,以便把这些数据挖掘出来。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ALTHOUGHNOTDISCUSSEDHERETHERESANEXAMPLEOFMAPINTHEGETHERONO404METHODINCLUDEDINTHESAMPLESOURCECODE", "original": "Although not discussed here, there's an example of `map` in the `getHeroNo404()`\nmethod included in the sample source code.", "translation": "虽然不打算在此展开讨论,不过你可以到范例源码中的 `getHeroNo404()` 方法中找到一个使用 `map` 操作符的例子。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###ERRORHANDLING", "original": "### Error handling", "translation": "### 错误处理", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THINGSGOWRONGESPECIALLYWHENYOUREGETTINGDATAFROMAREMOTESERVERTHEHEROSERVICEGETHEROESMETHODSHOULDCATCHERRORSANDDOSOMETHINGAPPROPRIATE", "original": "Things go wrong, especially when you're getting data from a remote server.\nThe `HeroService.getHeroes()` method should catch errors and do something appropriate.", "translation": "凡事皆会出错,特别是当你从远端服务器获取数据的时候。\n`HeroService.getHeroes()` 方法应该捕获错误,并做适当的处理。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "TOCATCHERRORSYOUPIPETHEOBSERVABLERESULTFROMHTTPGETTHROUGHANRXJSCATCHERROROPERATOR", "original": "To catch errors, you **\"pipe\" the observable** result from `http.get()` through an RxJS `catchError()` operator.", "translation": "要捕获错误,你就要使用 RxJS 的 `catchError()` 操作符来**建立对 Observable 结果的处理管道(pipe)**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "IMPORTTHECATCHERRORSYMBOLFROMRXJSOPERATORSALONGWITHSOMEOTHEROPERATORSYOULLNEEDLATER", "original": "Import the `catchError` symbol from `rxjs/operators`, along with some other operators you'll need later.", "translation": "从 `rxjs/operators` 中导入 `catchError` 符号,以及你稍后将会用到的其它操作符。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "NOWEXTENDTHEOBSERVABLERESULTWITHTHEPIPEMETHODANDGIVEITACATCHERROROPERATOR", "original": "Now extend the observable result with the `.pipe()` method and\ngive it a `catchError()` operator.", "translation": "现在,使用 `.pipe()` 方法来扩展 `Observable` 的结果,并给它一个 `catchError()` 操作符。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THECATCHERROROPERATORINTERCEPTSANOBSERVABLETHATFAILEDITPASSESTHEERRORANERRORHANDLERTHATCANDOWHATITWANTSWITHTHEERROR", "original": "The `catchError()` operator intercepts an **`Observable` that failed**.\nIt passes the error an _error handler_ that can do what it wants with the error.", "translation": "`catchError()` 操作符会拦截**失败的 `Observable`**。\n它把错误对象传给*错误处理器*,*错误处理器*会处理这个错误。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEFOLLOWINGHANDLEERRORMETHODREPORTSTHEERRORANDTHENRETURNSANINNOCUOUSRESULTSOTHATTHEAPPLICATIONKEEPSWORKING", "original": "The following `handleError()` method reports the error and then returns an\ninnocuous result so that the application keeps working.", "translation": "下面的 `handleError()` 方法会报告这个错误,并返回一个无害的结果(安全值),以便应用能正常工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEFOLLOWINGERRORHANDLERWILLBESHAREDBYMANYHEROSERVICEMETHODSSOITSGENERALIZEDTOMEETTHEIRDIFFERENTNEEDS", "original": "The following `errorHandler()` will be shared by many `HeroService` methods\nso it's generalized to meet their different needs.", "translation": "下面这个 `errorHandler()` 将会在很多 `HeroService` 的方法之间共享,所以要把它通用化,以支持这些彼此不同的需求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "INSTEADOFHANDLINGTHEERRORDIRECTLYITRETURNSANERRORHANDLERFUNCTIONTOCATCHERRORTHATITHASCONFIGUREDWITHBOTHTHENAMEOFTHEOPERATIONTHATFAILEDANDASAFERETURNVALUE", "original": "Instead of handling the error directly, it returns an _error handler_ function to `catchError` that it \nhas configured with both the name of the operation that failed and a safe return value.", "translation": "它不再直接处理这些错误,而是返回给 `catchError` 返回一个*错误处理*函数。还要用操作名和出错时要返回的安全值来对这个错误处理函数进行配置。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "AFTERREPORTINGTHEERRORTOCONSOLETHEHANDLERCONSTRUCTSAUSERFRIENDLYMESSAGEANDRETURNSASAFEVALUETOTHEAPPSOITCANKEEPWORKING", "original": "After reporting the error to console, the handler constructs\na user friendly message and returns a safe value to the app so it can keep working.", "translation": "在控制台中汇报了这个错误之后,这个处理器会汇报一个用户友好的消息,并给应用返回一个安全值,让它继续工作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "BECAUSEEACHSERVICEMETHODRETURNSADIFFERENTKINDOFOBSERVABLERESULTERRORHANDLERTAKESATYPEPARAMETERSOITCANRETURNTHESAFEVALUEASTHETYPETHATTHEAPPEXPECTS", "original": "Because each service method returns a different kind of `Observable` result,\n`errorHandler()` takes a type parameter so it can return the safe value as the type that the app expects.", "translation": "因为每个服务方法都会返回不同类型的 `Observable` 结果,因此 `errorHandler()` 也需要一个类型参数,以便它返回一个此类型的安全值,正如应用所期望的那样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###TAPINTOTHEOBSERVABLE", "original": "### Tap into the _Observable_", "translation": "### 窥探 `Observable`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEHEROSERVICEMETHODSWILLTAPINTOTHEFLOWOFOBSERVABLEVALUESANDSENDAMESSAGEVIALOGTOTHEMESSAGEAREAATTHEBOTTOMOFTHEPAGE", "original": "The `HeroService` methods will **tap** into the flow of observable values\nand send a message (via `log()`) to the message area at the bottom of the page.", "translation": "`HeroService` 的方法将会窥探 `Observable` 的数据流,并通过 `log()` 函数往页面底部发送一条消息。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEYLLDOTHATWITHTHERXJSTAPOPERATORWHICHLOOKSATTHEOBSERVABLEVALUESDOESSOMETHINGWITHTHOSEVALUESANDPASSESTHEMALONGTHETAPCALLBACKDOESNTTOUCHTHEVALUESTHEMSELVES", "original": "They'll do that with the RxJS `tap` operator,\nwhich _looks_ at the observable values, does _something_ with those values,\nand passes them along.\nThe `tap` call back doesn't touch the values themselves.", "translation": "它们可以使用 RxJS 的 `tap` 操作符来实现,该操作符会*查看* Observable 中的值,使用那些值做一些事情,并且把它们传出来。\n这种 `tap` 回调不会改变这些值本身。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "HEREISTHEFINALVERSIONOFGETHEROESWITHTHETAPTHATLOGSTHEOPERATION", "original": "Here is the final version of `getHeroes` with the `tap` that logs the operation.", "translation": "下面是 `getHeroes` 的最终版本,它使用 `tap` 来记录各种操作。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###GETHEROBYID", "original": "### Get hero by id", "translation": "### 通过 id 获取英雄", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "MOSTWEBAPISSUPPORTAGETBYIDREQUESTINTHEFORMAPIHERO:IDSUCHASAPIHERO11ADDAHEROSERVICEGETHEROMETHODTOMAKETHATREQUEST:", "original": "Most web APIs support a _get by id_ request in the form `api/hero/:id` \n(such as `api/hero/11`).\nAdd a `HeroService.getHero()` method to make that request:", "translation": "大多数 web API 都可以通过 `api/hero/:id` 的形式(比如 `api/hero/:id` )支持*根据 id 获取单个对象*。\n添加一个 `HeroService.getHero()` 方法来发起请求:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEREARETHREESIGNIFICANTDIFFERENCESFROMGETHEROES", "original": "There are three significant differences from `getHeroes()`.", "translation": "这里和 `getHeroes()` 相比有三个显著的差异。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ITCONSTRUCTSAREQUESTURLWITHTHEDESIREDHEROSID", "original": "* it constructs a request URL with the desired hero's id.", "translation": "它使用想获取的英雄的 id 构建了一个请求 URL。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THESERVERSHOULDRESPONDWITHASINGLEHERORATHERTHANANARRAYOFHEROES", "original": "* the server should respond with a single hero rather than an array of heroes.", "translation": "服务器应该使用单个英雄作为回应,而不是一个英雄数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEREFOREGETHERORETURNSANOBSERVABLEHEROANOBSERVABLEOFHEROOBJECTSRATHERTHANANOBSERVABLEOFHEROARRAYS", "original": "* therefore, `getHero` returns an `Observable<Hero>` (\"_an observable of Hero objects_\")\n rather than an observable of hero _arrays_ .", "translation": "所以,`getHero` 会返回 `Observable<Hero>`(“一个可观察的*单个英雄对象*”),而不是一个可观察的英雄对象*数组*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##UPDATEHEROES", "original": "## Update heroes", "translation": "## 修改英雄", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "EDITINGAHEROSNAMEINTHEHERODETAILVIEWASYOUTYPETHEHERONAMEUPDATESTHEHEADINGATTHETOPOFTHEPAGEBUTWHENYOUCLICKTHEGOBACKBUTTONTHECHANGESARELOST", "original": "Editing a hero's name in the _hero detail_ view.\nAs you type, the hero name updates the heading at the top of the page.\nBut when you click the \"go back button\", the changes are lost.", "translation": "在*英雄详情*视图中编辑英雄的名字。\n随着输入,英雄的名字也跟着在页面顶部的标题区更新了。\n但是当你点击“后退”按钮时,这些修改都丢失了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "IFYOUWANTCHANGESTOPERSISTYOUMUSTWRITETHEMBACKTOTHESERVER", "original": "If you want changes to persist, you must write them back to\nthe server.", "translation": "如果你希望保留这些修改,就要把它们写回到服务器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ATTHEENDOFTHEHERODETAILTEMPLATEADDASAVEBUTTONWITHACLICKEVENTBINDINGTHATINVOKESANEWCOMPONENTMETHODNAMEDSAVE", "original": "At the end of the hero detail template, add a save button with a `click` event\nbinding that invokes a new component method named `save()`.", "translation": "在英雄详情模板的底部添加一个保存按钮,它绑定了一个 `click` 事件,事件绑定会调用组件中一个名叫 `save()` 的新方法:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ADDTHEFOLLOWINGSAVEMETHODWHICHPERSISTSHERONAMECHANGESUSINGTHEHEROSERVICEUPDATEHEROMETHODANDTHENNAVIGATESBACKTOTHEPREVIOUSVIEW", "original": "Add the following `save()` method, which persists hero name changes using the hero service\n`updateHero()` method and then navigates back to the previous view.", "translation": "添加如下的 `save()` 方法,它使用英雄服务中的 `updateHero()` 方法来保存对英雄名字的修改,然后导航回前一个视图。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "####ADDHEROSERVICEUPDATEHERO", "original": "#### Add _HeroService.updateHero()_", "translation": "#### 添加 _HeroService.updateHero()_", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEOVERALLSTRUCTUREOFTHEUPDATEHEROMETHODISSIMILARTOTHATOFGETHEROESBUTITUSESHTTPPUTTOPERSISTTHECHANGEDHEROONTHESERVER", "original": "The overall structure of the `updateHero()` method is similar to that of\n`getHeroes()`, but it uses `http.put()` to persist the changed hero\non the server.", "translation": "`updateHero()` 的总体结构和 `getHeroes()` 很相似,但它会使用 `http.put()` 来把修改后的英雄保存到服务器上。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEHTTPCLIENTPUTMETHODTAKESTHREEPARAMETERS", "original": "The `HttpClient.put()` method takes three parameters", "translation": "`HttpClient.put()` 方法接受三个参数", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEURL", "original": "* the URL", "translation": "URL 地址", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEDATATOUPDATETHEMODIFIEDHEROINTHISCASE", "original": "* the data to update (the modified hero in this case)", "translation": "要修改的数据(这里就是修改后的英雄)", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "OPTIONS", "original": "* options", "translation": "选项", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEURLISUNCHANGEDTHEHEROESWEBAPIKNOWSWHICHHEROTOUPDATEBYLOOKINGATTHEHEROSID", "original": "The URL is unchanged. The heroes web API knows which hero to update by looking at the hero's `id`.", "translation": "URL 没变。英雄 Web API 通过英雄对象的 `id` 就可以知道要修改哪个英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEHEROESWEBAPIEXPECTSASPECIALHEADERINHTTPSAVEREQUESTSTHATHEADERISINTHEHTTPOPTIONSCONSTANTDEFINEDINTHEHEROSERVICE", "original": "The heroes web API expects a special header in HTTP save requests.\nThat header is in the `httpOptions` constant defined in the `HeroService`.", "translation": "英雄 Web API 期待在保存时的请求中有一个特殊的头。\n这个头是在 `HeroService` 的 `httpOptions` 常量中定义的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "REFRESHTHEBROWSERCHANGEAHERONAMESAVEYOURCHANGEANDCLICKTHEGOBACKBUTTONTHEHERONOWAPPEARSINTHELISTWITHTHECHANGEDNAME", "original": "Refresh the browser, change a hero name, save your change,\nand click the \"go back\" button. \nThe hero now appears in the list with the changed name.", "translation": "刷新浏览器,修改英雄名,保存这些修改,然后点击“后退”按钮。\n现在,改名后的英雄已经显示在列表中了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##ADDANEWHERO", "original": "## Add a new hero", "translation": "## 添加新英雄", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "TOADDAHEROTHISAPPONLYNEEDSTHEHEROSNAMEYOUCANUSEANINPUTELEMENTPAIREDWITHANADDBUTTON", "original": "To add a hero, this app only needs the hero's name. You can use an `input`\nelement paired with an add button.", "translation": "要添加英雄,本应用中只需要英雄的名字。你可以使用一个和添加按钮成对的 `input` 元素。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "INSERTTHEFOLLOWINGINTOTHEHEROESCOMPONENTTEMPLATEJUSTAFTERTHEHEADING:", "original": "Insert the following into the `HeroesComponent` template, just after\nthe heading:", "translation": "把下列代码插入到 `HeroesComponent` 模板中标题的紧后面:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "INRESPONSETOACLICKEVENTCALLTHECOMPONENTSCLICKHANDLERANDTHENCLEARTHEINPUTFIELDSOTHATITSREADYFORANOTHERNAME", "original": "In response to a click event, call the component's click handler and then\nclear the input field so that it's ready for another name.", "translation": "当点击事件触发时,调用组件的点击处理器,然后清空这个输入框,以便用来输入另一个名字。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "WHENTHEGIVENNAMEISNONBLANKTHEHANDLERCREATESAHEROLIKEOBJECTFROMTHENAMEITSONLYMISSINGTHEIDANDPASSESITTOTHESERVICESADDHEROMETHOD", "original": "When the given name is non-blank, the handler creates a `Hero`-like object\nfrom the name (it's only missing the `id`) and passes it to the services `addHero()` method.", "translation": "当指定的名字非空时,这个处理器会用这个名字创建一个类似于 `Hero` 的对象(只缺少 `id` 属性),并把它传给服务的 `addHero()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "WHENADDHEROSAVESSUCCESSFULLYTHESUBSCRIBECALLBACKRECEIVESTHENEWHEROANDPUSHESITINTOTOTHEHEROESLISTFORDISPLAY", "original": "When `addHero` saves successfully, the `subscribe` callback\nreceives the new hero and pushes it into to the `heroes` list for display.", "translation": "当 `addHero` 保存成功时,`subscribe` 的回调函数会收到这个新英雄,并把它追加到 `heroes` 列表中以供显示。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOULLWRITEHEROSERVICEADDHEROINTHENEXTSECTION", "original": "You'll write `HeroService.addHero` in the next section.", "translation": "你将在下一节编写 `HeroService.addHero`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "####ADDHEROSERVICEADDHERO", "original": "#### Add _HeroService.addHero()_", "translation": "#### 添加 `HeroService.addHero()`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ADDTHEFOLLOWINGADDHEROMETHODTOTHEHEROSERVICECLASS", "original": "Add the following `addHero()` method to the `HeroService` class.", "translation": "往 `HeroService` 类中添加 `addHero()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "HEROSERVICEADDHERODIFFERSFROMUPDATEHEROINTWOWAYS", "original": "`HeroService.addHero()` differs from `updateHero` in two ways.", "translation": "`HeroService.addHero()` 和 `updateHero` 有两点不同。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ITCALLSHTTPCLIENTPOSTINSTEADOFPUT", "original": "* it calls `HttpClient.post()` instead of `put()`.", "translation": "它调用 `HttpClient.post()` 而不是 `put()`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ITEXPECTSTHESERVERTOGENERATESANIDFORTHENEWHEROWHICHITRETURNSINTHEOBSERVABLEHEROTOTHECALLER", "original": "* it expects the server to generates an id for the new hero, \nwhich it returns in the `Observable<Hero>` to the caller.", "translation": "它期待服务器为这个新的英雄生成一个 id,然后把它通过 `Observable<Hero>` 返回给调用者。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "REFRESHTHEBROWSERANDADDSOMEHEROES", "original": "Refresh the browser and add some heroes.", "translation": "刷新浏览器,并添加一些英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##DELETEAHERO", "original": "## Delete a hero", "translation": "## 删除某个英雄", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "EACHHEROINTHEHEROESLISTSHOULDHAVEADELETEBUTTON", "original": "Each hero in the heroes list should have a delete button.", "translation": "英雄列表中的每个英雄都有一个删除按钮。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ADDTHEFOLLOWINGBUTTONELEMENTTOTHEHEROESCOMPONENTTEMPLATEAFTERTHEHERONAMEINTHEREPEATEDLIELEMENT", "original": "Add the following button element to the `HeroesComponent` template, after the hero\nname in the repeated `<li>` element.", "translation": "把下列按钮(`button`)元素添加到 `HeroesComponent` 的模板中,就在每个 `<li>` 元素中的英雄名字后方。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEHTMLFORTHELISTOFHEROESSHOULDLOOKLIKETHIS:", "original": "The HTML for the list of heroes should look like this:", "translation": "英雄列表的 HTML 应该是这样的:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "TOPOSITIONTHEDELETEBUTTONATTHEFARRIGHTOFTHEHEROENTRYADDSOMECSSTOTHEHEROESCOMPONENTCSSYOULLFINDTHATCSSINTHEFINALREVIEWCODE#HEROESCOMPONENTBELOW", "original": "To position the delete button at the far right of the hero entry,\nadd some CSS to the `heroes.component.css`. You'll find that CSS\nin the [final review code](#heroescomponent) below.", "translation": "要把删除按钮定位在每个英雄条目的最右边,就要往 `heroes.component.css` 中添加一些 CSS。你可以在下方的 [最终代码](#heroescomponent) 中找到这些 CSS。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ADDTHEDELETEHANDLERTOTHECOMPONENT", "original": "Add the `delete()` handler to the component.", "translation": "把 `delete()` 处理器添加到组件中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ALTHOUGHTHECOMPONENTDELEGATESHERODELETIONTOTHEHEROSERVICEITREMAINSRESPONSIBLEFORUPDATINGITSOWNLISTOFHEROESTHECOMPONENTSDELETEMETHODIMMEDIATELYREMOVESTHEHEROTODELETEFROMTHATLISTANTICIPATINGTHATTHEHEROSERVICEWILLSUCCEEDONTHESERVER", "original": "Although the component delegates hero deletion to the `HeroService`,\nit remains responsible for updating its own list of heroes.\nThe component's `delete()` method immediately removes the _hero-to-delete_ from that list,\nanticipating that the `HeroService` will succeed on the server.", "translation": "虽然这个组件把删除英雄的逻辑委托给了 `HeroService`,但扔保留了更新它自己的英雄列表的职责。\n组件的 `delete()` 方法会在 `HeroService` 对服务器的操作成功之前,先从列表中移除*要删除的英雄*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THERESREALLYNOTHINGFORTHECOMPONENTTODOWITHTHEOBSERVABLERETURNEDBYHEROSERVICEDELETEITMUSTSUBSCRIBEANYWAY", "original": "There's really nothing for the component to do with the `Observable` returned by\n`heroService.delete()`. **It must subscribe anyway**.", "translation": "组件与 `heroService.delete()` 返回的 `Observable` 还完全没有关联。**必须订阅它**。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "IFYOUNEGLECTTOSUBSCRIBETHESERVICEWILLNOTSENDTHEDELETEREQUESTTOTHESERVERASARULEANOBSERVABLEDOESNOTHINGUNTILSOMETHINGSUBSCRIBES", "original": "If you neglect to `subscribe()`, the service will not send the delete request to the server!\n As a rule, an `Observable` _does nothing_ until something subscribes!", "translation": "如果你忘了调用 `subscribe()`,本服务将不会把这个删除请求发送给服务器。\n 作为一条通用的规则,`Observable` 在有人订阅之前*什么都不会做*。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "CONFIRMTHISFORYOURSELFBYTEMPORARILYREMOVINGTHESUBSCRIBECLICKINGDASHBOARDTHENCLICKINGHEROESYOULLSEETHEFULLLISTOFHEROESAGAIN", "original": "Confirm this for yourself by temporarily removing the `subscribe()`,\n clicking \"Dashboard\", then clicking \"Heroes\".\n You'll see the full list of heroes again.", "translation": "你可以暂时删除 `subscribe()` 来确认这一点。点击“Dashboard”,然后点击“Heroes”,就又看到完整的英雄列表了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "####ADDHEROSERVICEDELETEHERO", "original": "#### Add _HeroService.deleteHero()_", "translation": "#### 添加 `HeroService.deleteHero()`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ADDADELETEHEROMETHODTOHEROSERVICELIKETHIS", "original": "Add a `deleteHero()` method to `HeroService` like this.", "translation": "把 `deleteHero()` 方法添加到 `HeroService` 中,代码如下。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "NOTETHAT", "original": "Note that", "translation": "注意", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ITCALLSHTTPCLIENTDELETE", "original": "* it calls `HttpClient.delete`.", "translation": "它调用了 `HttpClient.delete`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEURLISTHEHEROESRESOURCEURLPLUSTHEIDOFTHEHEROTODELETE", "original": "* the URL is the heroes resource URL plus the `id` of the hero to delete", "translation": "URL 就是英雄的资源 URL 加上要删除的英雄的 `id`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUDONTSENDDATAASYOUDIDWITHPUTANDPOST", "original": "* you don't send data as you did with `put` and `post`.", "translation": "你不用像 `put` 和 `post` 中那样发送任何数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUSTILLSENDTHEHTTPOPTIONS", "original": "* you still send the `httpOptions`.", "translation": "你仍要发送 `httpOptions`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "REFRESHTHEBROWSERANDTRYTHENEWDELETEFUNCTIONALITY", "original": "Refresh the browser and try the new delete functionality.", "translation": "刷新浏览器,并试一下这个新的删除功能。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##SEARCHBYNAME", "original": "## Search by name", "translation": "## 根据名字搜索", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "INTHISLASTEXERCISEYOULEARNTOCHAINOBSERVABLEOPERATORSTOGETHERSOYOUCANMINIMIZETHENUMBEROFSIMILARHTTPREQUESTSANDCONSUMENETWORKBANDWIDTHECONOMICALLY", "original": "In this last exercise, you learn to chain `Observable` operators together\nso you can minimize the number of similar HTTP requests\nand consume network bandwidth economically.", "translation": "在最后一次练习中,你要学到把 `Observable` 的操作符串在一起,让你能将相似 HTTP 请求的数量最小化,并节省网络带宽。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUWILLADDAHEROESSEARCHFEATURETOTHEDASHBOARDASTHEUSERTYPESANAMEINTOASEARCHBOXYOULLMAKEREPEATEDHTTPREQUESTSFORHEROESFILTEREDBYTHATNAMEYOURGOALISTOISSUEONLYASMANYREQUESTSASNECESSARY", "original": "You will add a *heroes search* feature to the *Dashboard*.\nAs the user types a name into a search box, \nyou'll make repeated HTTP requests for heroes filtered by that name.\nYour goal is to issue only as many requests as necessary.", "translation": "你将往*仪表盘*中加入*英雄搜索*特性。\n当用户在搜索框中输入名字时,你会不断发送根据名字过滤英雄的 HTTP 请求。\n你的目标是仅仅发出尽可能少的必要请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "STARTBYADDINGASEARCHHEROESMETHODTOTHEHEROSERVICE", "original": "Start by adding a `searchHeroes` method to the `HeroService`.", "translation": "先把 `searchHeroes` 方法添加到 `HeroService` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEMETHODRETURNSIMMEDIATELYWITHANEMPTYARRAYIFTHEREISNOSEARCHTERMTHERESTOFITCLOSELYRESEMBLESGETHEROESTHEONLYSIGNIFICANTDIFFERENCEISTHEURLWHICHINCLUDESAQUERYSTRINGWITHTHESEARCHTERM", "original": "The method returns immediately with an empty array if there is no search term.\nThe rest of it closely resembles `getHeroes()`.\nThe only significant difference is the URL, \nwhich includes a query string with the search term.", "translation": "如果没有搜索词,该方法立即返回一个空数组。\n剩下的部分和 `getHeroes()` 很像。\n唯一的不同点是 URL,它包含了一个由搜索词组成的查询字符串。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###ADDSEARCHTOTHEDASHBOARD", "original": "### Add search to the Dashboard", "translation": "### 为仪表盘添加搜索功能", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "OPENTHEDASHBOARDCOMPONENTTEMPLATEANDADDTHEHEROSEARCHELEMENTAPPHEROSEARCHTOTHEBOTTOMOFTHEDASHBOARDCOMPONENTTEMPLATE", "original": "Open the `DashboardComponent` _template_ and\nAdd the hero search element, `<app-hero-search>`, to the bottom of the `DashboardComponent` template.", "translation": "打开 `DashboardComponent` 的*模板*并且把用于搜索英雄的元素 `<app-hero-search>` 添加到 `DashboardComponent` 模板的底部。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THISTEMPLATELOOKSALOTLIKETHENGFORREPEATERINTHEHEROESCOMPONENTTEMPLATE", "original": "This template looks a lot like the `*ngFor` repeater in the `HeroesComponent` template.", "translation": "这个模板看起来很像 `HeroesComponent` 模板中的 `*ngFor` 复写器。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "UNFORTUNATELYADDINGTHISELEMENTBREAKSTHEAPPANGULARCANTFINDACOMPONENTWITHASELECTORTHATMATCHESAPPHEROSEARCH", "original": "Unfortunately, adding this element breaks the app.\nAngular can't find a component with a selector that matches `<app-hero-search>`.", "translation": "很不幸,添加这个元素让本应用挂了。\nAngular 找不到哪个组件的选择器能匹配上 `<app-hero-search>`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEHEROSEARCHCOMPONENTDOESNTEXISTYETFIXTHAT", "original": "The `HeroSearchComponent` doesn't exist yet. Fix that.", "translation": "`HeroSearchComponent` 还不存在,这就解决。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###CREATEHEROSEARCHCOMPONENT", "original": "### Create _HeroSearchComponent_", "translation": "### 创建 `HeroSearchComponent`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "CREATEAHEROSEARCHCOMPONENTWITHTHECLI", "original": "Create a `HeroSearchComponent` with the CLI.", "translation": "使用 CLI 创建一个 `HeroSearchComponent`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THECLIGENERATESTHETHREEHEROSEARCHCOMPONENTANDADDSTHECOMPONENTTOTHEAPPMODULEDECLARATIONS", "original": "The CLI generates the three `HeroSearchComponent` and adds the component to the `AppModule' declarations", "translation": "CLI 生成了 `HeroSearchComponent` 的三个文件,并把该组件添加到了 `AppModule` 的声明中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "REPLACETHEGENERATEDHEROSEARCHCOMPONENTTEMPLATEWITHATEXTBOXANDALISTOFMATCHINGSEARCHRESULTSLIKETHIS", "original": "Replace the generated `HeroSearchComponent` _template_ with a text box and a list of matching search results like this.", "translation": "把生成的 `HeroSearchComponent` 的*模板*改成一个输入框和一个匹配到的搜索结果的列表。代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ADDPRIVATECSSSTYLESTOHEROSEARCHCOMPONENTCSSASLISTEDINTHEFINALCODEREVIEW#HEROSEARCHCOMPONENTBELOW", "original": "Add private CSS styles to `hero-search.component.css`\nas listed in the [final code review](#herosearchcomponent) below.", "translation": "从下面的 [最终代码](#herosearchcomponent) 中把私有 CSS 样式添加到 `hero-search.component.css` 中。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ASTHEUSERTYPESINTHESEARCHBOXAKEYUPEVENTBINDINGCALLSTHECOMPONENTSSEARCHMETHODWITHTHENEWSEARCHBOXVALUE", "original": "As the user types in the search box, a *keyup* event binding calls the component's `search()`\nmethod with the new search box value.", "translation": "当用户在搜索框中输入时,一个 *keyup* 事件绑定会调用该组件的 `search()` 方法,并传入新的搜索框的值。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ASEXPECTEDTHENGFORREPEATSHEROOBJECTS", "original": "As expected, the `*ngFor` repeats hero objects.", "translation": "如你所愿,`*ngFor` 重复渲染出了这些英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "LOOKCLOSELYANDYOULLSEETHATTHENGFORITERATESOVERALISTCALLEDHEROESNOTHEROES", "original": "Look closely and you'll see that the `*ngFor` iterates over a list called `heroes$`, not `heroes`.", "translation": "仔细看,你会发现 `*ngFor` 是在一个名叫 `heroes$` 的列表上迭代,而不是 `heroes`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEISACONVENTIONTHATINDICATESHEROESISANOBSERVABLENOTANARRAY", "original": "The `$` is a convention that indicates `heroes$` is an `Observable`, not an array.", "translation": "`$` 是一个命名惯例,用来表明 `heroes$` 是一个 `Observable`,而不是数组。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THENGFORCANTDOANYTHINGWITHANOBSERVABLEBUTTHERESALSOAPIPECHARACTERFOLLOWEDBYASYNCWHICHIDENTIFIESANGULARSASYNCPIPE", "original": "The `*ngFor` can't do anything with an `Observable`.\nBut there's also a pipe character (`|`) followed by `async`,\nwhich identifies Angular's `AsyncPipe`.", "translation": "`*ngFor` 不能直接使用 `Observable`。\n不过,它后面还有一个管道字符(`|`),后面紧跟着一个 `async`,它表示 Angular 的 `AsyncPipe`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THEASYNCPIPESUBSCRIBESTOANOBSERVABLEAUTOMATICALLYSOYOUWONTHAVETODOSOINTHECOMPONENTCLASS", "original": "The `AsyncPipe` subscribes to an `Observable` automatically so you won't have to\ndo so in the component class.", "translation": "`AsyncPipe` 会自动订阅到 `Observable`,这样你就不用再在组件类中订阅了。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###FIXTHEHEROSEARCHCOMPONENTCLASS", "original": "### Fix the _HeroSearchComponent_ class", "translation": "### 修正 `HeroSearchComponent` 类", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "REPLACETHEGENERATEDHEROSEARCHCOMPONENTCLASSANDMETADATAASFOLLOWS", "original": "Replace the generated `HeroSearchComponent` class and metadata as follows.", "translation": "修改所生成的 `HeroSearchComponent` 类及其元数据,代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "NOTICETHEDECLARATIONOFHEROESASANOBSERVABLE", "original": "Notice the declaration of `heroes$` as an `Observable`", "translation": "注意,`heroes$` 声明为一个 `Observable`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOULLSETITINNGONINIT#SEARCHPIPEBEFOREYOUDOFOCUSONTHEDEFINITIONOFSEARCHTERMS", "original": "You'll set it in [`ngOnInit()`](#search-pipe). \nBefore you do, focus on the definition of `searchTerms`.", "translation": "你将会在 [`ngOnInit()`](#search-pipe) 中设置它,在此之前,先仔细看看 `searchTerms` 的定义。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###THESEARCHTERMSRXJSSUBJECT", "original": "### The _searchTerms_ RxJS subject", "translation": "### RxJS `Subject` 类型的 `searchTerms`", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THESEARCHTERMSPROPERTYISDECLAREDASANRXJSSUBJECT", "original": "The `searchTerms` property is declared as an RxJS `Subject`.", "translation": "`searchTerms` 属性声明成了 RxJS 的 `Subject` 类型。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "ASUBJECTISBOTHASOURCEOFOBSERVABLEVALUESANDANOBSERVABLEITSELFYOUCANSUBSCRIBETOASUBJECTASYOUWOULDANYOBSERVABLE", "original": "A `Subject` is both a source of _observable_ values and an `Observable` itself.\nYou can subscribe to a `Subject` as you would any `Observable`.", "translation": "`Subject` 既是可观察对象的数据源,本身也是 `Observable`。\n你可以像订阅任何 `Observable` 一样订阅 `Subject`。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUCANALSOPUSHVALUESINTOTHATOBSERVABLEBYCALLINGITSNEXTVALUEMETHODASTHESEARCHMETHODDOES", "original": "You can also push values into that `Observable` by calling its `next(value)` method\nas the `search()` method does.", "translation": "你还可以通过调用它的 `next(value)` 方法往 `Observable` 中推送一些值,就像 `search()` 方法中一样。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THESEARCHMETHODISCALLEDVIAANEVENTBINDINGTOTHETEXTBOXSKEYSTROKEEVENT", "original": "The `search()` method is called via an _event binding_ to the\ntextbox's `keystroke` event.", "translation": "`search()` 是通过对文本框的 `keystroke` 事件的*事件绑定*来调用的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "EVERYTIMETHEUSERTYPESINTHETEXTBOXTHEBINDINGCALLSSEARCHWITHTHETEXTBOXVALUEASEARCHTERMTHESEARCHTERMSBECOMESANOBSERVABLEEMITTINGASTEADYSTREAMOFSEARCHTERMS", "original": "Every time the user types in the textbox, the binding calls `search()` with the textbox value, a \"search term\". \nThe `searchTerms` becomes an `Observable` emitting a steady stream of search terms.", "translation": "每当用户在文本框中输入时,这个事件绑定就会使用文本框的值(搜索词)调用 `search()` 函数。\n`searchTerms` 变成了一个能发出搜索词的稳定的流。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "###CHAININGRXJSOPERATORS", "original": "### Chaining RxJS operators", "translation": "### 串联 RxJS 操作符", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "PASSINGANEWSEARCHTERMDIRECTLYTOTHESEARCHHEROESAFTEREVERYUSERKEYSTROKEWOULDCREATEANEXCESSIVEAMOUNTOFHTTPREQUESTSTAXINGSERVERRESOURCESANDBURNINGTHROUGHTHECELLULARNETWORKDATAPLAN", "original": "Passing a new search term directly to the `searchHeroes()` after every user keystroke would create an excessive amount of HTTP requests,\ntaxing server resources and burning through the cellular network data plan.", "translation": "如果每当用户击键后就直接调用 `searchHeroes()` 将导致创建海量的 HTTP 请求,浪费服务器资源并消耗大量网络流量。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "INSTEADTHENGONINITMETHODPIPESTHESEARCHTERMSOBSERVABLETHROUGHASEQUENCEOFRXJSOPERATORSTHATREDUCETHENUMBEROFCALLSTOTHESEARCHHEROESULTIMATELYRETURNINGANOBSERVABLEOFTIMELYHEROSEARCHRESULTSEACHAHERO", "original": "Instead, the `ngOnInit()` method pipes the `searchTerms` _observable_ through a sequence of RxJS operators that reduce the number of calls to the `searchHeroes()`,\nultimately returning an _observable_ of timely hero search results (each a `Hero[]`).", "translation": "应该怎么做呢?`ngOnInit()` 往 `searchTerms` 这个可观察对象的处理管道中加入了一系列 RxJS 操作符,用以缩减对 `searchHeroes()` 的调用次数,并最终返回一个可及时给出英雄搜索结果的可观察对象(每次都是 `Hero[]` )。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "HERESTHECODE", "original": "Here's the code.", "translation": "代码如下:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "DEBOUNCETIME300WAITSUNTILTHEFLOWOFNEWSTRINGEVENTSPAUSESFOR300MILLISECONDSBEFOREPASSINGALONGTHELATESTSTRINGYOULLNEVERMAKEREQUESTSMOREFREQUENTLYTHAN300MS", "original": "* `debounceTime(300)` waits until the flow of new string events pauses for 300 milliseconds\nbefore passing along the latest string. You'll never make requests more frequently than 300ms.", "translation": "在传出最终字符串之前,`debounceTime(300)` 将会等待,直到新增字符串的事件暂停了 300 毫秒。\n 你实际发起请求的间隔永远不会小于 300ms。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "DISTINCTUNTILCHANGEDENSURESTHATAREQUESTISSENTONLYIFTHEFILTERTEXTCHANGED", "original": "* `distinctUntilChanged` ensures that a request is sent only if the filter text changed.", "translation": "`distinctUntilChanged` 会确保只在过滤条件变化时才发送请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "SWITCHMAPCALLSTHESEARCHSERVICEFOREACHSEARCHTERMTHATMAKESITTHROUGHDEBOUNCEANDDISTINCTUNTILCHANGEDITCANCELSANDDISCARDSPREVIOUSSEARCHOBSERVABLESRETURNINGONLYTHELATESTSEARCHSERVICEOBSERVABLE", "original": "* `switchMap()` calls the search service for each search term that makes it through `debounce` and `distinctUntilChanged`.\nIt cancels and discards previous search observables, returning only the latest search service observable.", "translation": "`switchMap()` 会为每个从 `debounce` 和 `distinctUntilChanged` 中通过的搜索词调用搜索服务。\n 它会取消并丢弃以前的搜索可观察对象,只保留最近的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "WITHTHESWITCHMAPOPERATORHTTP:WWWLEARNRXJSIOOPERATORSTRANSFORMATIONSWITCHMAPHTMLEVERYQUALIFYINGKEYEVENTCANTRIGGERANHTTPCLIENTGETMETHODCALLEVENWITHA300MSPAUSEBETWEENREQUESTSYOUCOULDHAVEMULTIPLEHTTPREQUESTSINFLIGHTANDTHEYMAYNOTRETURNINTHEORDERSENT", "original": "With the [switchMap operator](http://www.learnrxjs.io/operators/transformation/switchmap.html),\n every qualifying key event can trigger an `HttpClient.get()` method call.\n Even with a 300ms pause between requests, you could have multiple HTTP requests in flight\n and they may not return in the order sent.", "translation": "借助 [switchMap 操作符](http://www.learnrxjs.io/operators/transformation/switchmap.html),\n 每个有效的击键事件都会触发一次 `HttpClient.get()` 方法调用。\n 即使在每个请求之间都有至少 300ms 的间隔,仍然可能会同时存在多个尚未返回的 HTTP 请求。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "SWITCHMAPPRESERVESTHEORIGINALREQUESTORDERWHILERETURNINGONLYTHEOBSERVABLEFROMTHEMOSTRECENTHTTPMETHODCALLRESULTSFROMPRIORCALLSARECANCELEDANDDISCARDED", "original": "`switchMap()` preserves the original request order while returning only the observable from the most recent HTTP method call.\n Results from prior calls are canceled and discarded.", "translation": "`switchMap()` 会记住原始的请求顺序,只会返回最近一次 HTTP 方法调用的结果。\n 以前的那些请求都会被取消和舍弃。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "NOTETHATCANCELINGAPREVIOUSSEARCHHEROESOBSERVABLEDOESNTACTUALLYABORTAPENDINGHTTPREQUESTUNWANTEDRESULTSARESIMPLYDISCARDEDBEFORETHEYREACHYOURAPPLICATIONCODE", "original": "Note that _canceling_ a previous `searchHeroes()` _Observable_\n doesn't actually abort a pending HTTP request.\n Unwanted results are simply discarded before they reach your application code.", "translation": "注意,*取消*前一个 `searchHeroes()` 可观察对象并不会中止尚未完成的 HTTP 请求。\n 那些不想要的结果只会在它们抵达应用代码之前被舍弃。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "REMEMBERTHATTHECOMPONENTCLASSDOESNOTSUBSCRIBETOTHEHEROESOBSERVABLETHATSTHEJOBOFTHEASYNCPIPE#ASYNCPIPEINTHETEMPLATE", "original": "Remember that the component _class_ does not subscribe to the `heroes$` _observable_.\nThat's the job of the [`AsyncPipe`](#asyncpipe) in the template.", "translation": "记住,组件类中并没有订阅 `heroes$` 这个可观察对象,而是由模板中的 [`AsyncPipe`](#asyncpipe) 完成的。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "####TRYIT", "original": "#### Try it", "translation": "#### 试试看", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "RUNTHEAPPAGAININTHEDASHBOARDENTERSOMETEXTINTHESEARCHBOXIFYOUENTERCHARACTERSTHATMATCHANYEXISTINGHERONAMESYOULLSEESOMETHINGLIKETHIS", "original": "Run the app again. In the *Dashboard*, enter some text in the search box.\nIf you enter characters that match any existing hero names, you'll see something like this.", "translation": "再次运行本应用。在这个 *仪表盘* 中,在搜索框中输入一些文字。如果你输入的字符匹配上了任何现有英雄的名字,你将会看到如下效果:", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##FINALCODEREVIEW", "original": "## Final code review", "translation": "## 查看最终代码", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOURAPPSHOULDLOOKLIKETHISLIVEEXAMPLELIVEEXAMPLE", "original": "Your app should look like this <live-example></live-example>.", "translation": "你的应用现在变成了这样:<live-example></live-example>。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "HEREARETHECODEFILESDISCUSSEDONTHISPAGEALLINTHESRCAPPFOLDER", "original": "Here are the code files discussed on this page (all in the `src/app/` folder).", "translation": "本文讨论过的代码文件如下(都位于 `src/app/` 文件夹中)。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "##SUMMARY", "original": "## Summary", "translation": "## 小结", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUREATTHEENDOFYOURJOURNEYANDYOUVEACCOMPLISHEDALOT", "original": "You're at the end of your journey, and you've accomplished a lot.", "translation": "旅程即将结束,不过你已经收获颇丰。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUADDEDTHENECESSARYDEPENDENCIESTOUSEHTTPINTHEAPP", "original": "* You added the necessary dependencies to use HTTP in the app.", "translation": "你添加了在应用程序中使用 HTTP 的必备依赖。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUREFACTOREDHEROSERVICETOLOADHEROESFROMAWEBAPI", "original": "* You refactored `HeroService` to load heroes from a web API.", "translation": "你重构了 `HeroService`,以通过 web API 来加载英雄数据。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUEXTENDEDHEROSERVICETOSUPPORTPOSTPUTANDDELETEMETHODS", "original": "* You extended `HeroService` to support `post()`, `put()`, and `delete()` methods.", "translation": "你扩展了 `HeroService` 来支持 `post()`、`put()` 和 `delete()` 方法。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUUPDATEDTHECOMPONENTSTOALLOWADDINGEDITINGANDDELETINGOFHEROES", "original": "* You updated the components to allow adding, editing, and deleting of heroes.", "translation": "你修改了组件,以允许用户添加、编辑和删除英雄。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOUCONFIGUREDANINMEMORYWEBAPI", "original": "* You configured an in-memory web API.", "translation": "你配置了一个内存 Web API。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "YOULEARNEDHOWTOUSEOBSERVABLES", "original": "* You learned how to use Observables.", "translation": "你学会了如何使用“可观察对象”。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" }, { + "key": "THISCONCLUDESTHETOUROFHEROESTUTORIALYOUREREADYTOLEARNMOREABOUTANGULARDEVELOPMENTINTHEFUNDAMENTALSSECTIONSTARTINGWITHTHEARCHITECTUREGUIDEARCHITECTUREARCHITECTUREGUIDE", "original": "This concludes the \"Tour of Heroes\" tutorial.\nYou're ready to learn more about Angular development in the fundamentals section,\nstarting with the [Architecture](guide/architecture \"Architecture\") guide.", "translation": "《英雄指南》教程结束了。\n如果你准备开始学习 Angular 开发的原理,请开始 [架构](guide/architecture \"Architecture\") 一章。", "sourceFile": "/Users/twer/private/GDE/angular-cn/aio/content/tutorial/toh-pt6.md" } -] +] \ No newline at end of file diff --git a/aio/tools/translator/extractor.ts b/aio/tools/translator/extractor.ts index 89d3ac0962..9070bd179b 100644 --- a/aio/tools/translator/extractor.ts +++ b/aio/tools/translator/extractor.ts @@ -1,8 +1,9 @@ import * as globby from 'globby'; import { DictEntry } from './dict-entry'; import { + extractOriginalContent, isNotCnPages, - isOnlyBeginTag, + isOnlyBeginTag, hasInlineText, kernelText, normalizeLines, originalIsNotChinese, originalIsNotCodeExampleTag, @@ -29,7 +30,14 @@ export function gatherTranslations(text: string): DictEntry[] { const result = []; for (let i = 1; i < lines.length; ++i) { const translation = purifyText(lines[i]); - if (isTranslation(translation)) { + if (hasInlineText(translation)) { + const originalContent = extractOriginalContent(translation); + result.push({ + key: kernelText(originalContent), + original: originalContent, + translation + }); + } else if (isTranslation(translation)) { const original = purifyText(lines[i - 1]); // 对于包裹在 html tag 中的翻译文本进行特殊处理 if (isOnlyBeginTag(original)) { @@ -38,18 +46,18 @@ export function gatherTranslations(text: string): DictEntry[] { const thisEndTag = lines[i + 1].trim(); if (original === prevBeginTag && prevEndTag === thisEndTag) { result.push({ + key: kernelText(lines[i - 3]), original: lines[i - 3], translation: lines[i], }); } } else { - result.push({original, translation}); + result.push({key: kernelText(original), original, translation}); } } } return result .filter(isNotCnPages) - .filter(translationHasNotCodeExample) .filter(originalIsNotChinese) .filter(originalIsNotSpecialDivTag) .filter(originalIsNotCodeExampleTag) @@ -84,6 +92,7 @@ export function purifyText(text): string { export function purifyEntry(entry: DictEntry): DictEntry { return { + key: entry.key, original: purifyText(entry.original), translation: purifyText(entry.translation), }; diff --git a/aio/tools/translator/translate.spec.ts b/aio/tools/translator/translate.spec.ts index 1b3974d499..441c86506c 100644 --- a/aio/tools/translator/translate.spec.ts +++ b/aio/tools/translator/translate.spec.ts @@ -1,17 +1,13 @@ import { expect } from 'chai'; -import { lookup } from './translate'; -import { kernelText } from './utils'; +import { lookup, translate } from './translate'; describe('根据字典进行翻译', () => { - it('抽取核心字符', function () { - expect(kernelText(' # Forms ABC. ')).eql('#FormsABC'); - }); - it('查字典', () => { expect(lookup('# Forms')[0].translation).eql('# 表单'); }); - it('对包裹在 a 标签中的内容查字典', () => { + it('翻译 header', () => { + expect(translate(`<header></header>`)).eql(``); }); }); diff --git a/aio/tools/translator/translate.ts b/aio/tools/translator/translate.ts index 563c27b843..163a0e33b3 100644 --- a/aio/tools/translator/translate.ts +++ b/aio/tools/translator/translate.ts @@ -3,36 +3,46 @@ import * as _ from 'lodash'; import { DictEntry } from './dict-entry'; import { dirs } from './dirs'; import { listMarkdownFiles } from './extractor'; -import { exactlyTest, indentOf, normalizeLines, repeat } from './utils'; +import { exactlyTest, extractOriginalContent, indentOf, hasInlineText, kernelText, normalizeLines, repeat } from './utils'; // TODO: 改用 markdown 解析器实现 export const dict = require('./dict-latest.json') as DictEntry[]; -export function lookup(english: string, filename: RegExp = /.*/): DictEntry[] { +export function lookup(english: string): DictEntry[] { + const englishKernel = kernelText(extractOriginalContent(english)); const entries = dict - .filter(entry => filename.test(entry.sourceFile)) - .filter(entry => exactlyTest(entry.original, english)); + .filter(entry => exactlyTest(entry.key, englishKernel)); return _.uniqBy(entries, 'translation'); } +function isPureTag(line: string): boolean { + let content = line.trim(); + return /^<\/?\w+\b[^>]*>$/.test(content) || + /^<(\w+)\b[^>]*>\s*<\/\1>$/.test(content); +} + export function translate(content: string): string[] { const lines = normalizeLines(content) - .split(/\n+\s*\n+/); + .split(/\n{2,}/); return lines .map(line => { - if (!line.trim()) { + if (!line.trim() || isPureTag(line)) { return line; } const translations = lookup(line); - const indent = indentOf(line); - const padding = repeat(indent); - if (translations.length === 0) { - return line; - } else if (translations.length === 1) { - return line + '\n\n' + padding + translations[0].translation; + if (translations.length > 0 && hasInlineText(translations[0].translation)) { + return translations[0].translation; } else { - return line + '\n\n' + padding + translations[translations.length - 1].translation; + const indent = indentOf(line); + const padding = repeat(indent); + if (translations.length === 0) { + return line; + } else if (translations.length === 1) { + return line + '\n\n' + padding + translations[0].translation; + } else { + return line + '\n\n' + padding + translations[translations.length - 1].translation; + } } }); } @@ -40,7 +50,7 @@ export function translate(content: string): string[] { export function translateFile(sourceFile: string, targetFile: string): void { const content = fs.readFileSync(sourceFile, 'utf-8'); const result = translate(content); - fs.writeFileSync(targetFile, result.join('\n\n').trim() + '\n', 'utf-8'); + fs.writeFileSync(targetFile, result.join('\n\n') + '\n', 'utf-8'); } export function translateDirectory(sourceDir: string, targetDir: string): void { diff --git a/aio/tools/translator/utils.spec.ts b/aio/tools/translator/utils.spec.ts index fce9fe0cc3..2d814df923 100644 --- a/aio/tools/translator/utils.spec.ts +++ b/aio/tools/translator/utils.spec.ts @@ -1,48 +1,40 @@ import { expect } from 'chai'; -import { fuzzyTest, normalizeLines, tokenize } from './utils'; +import { fuzzyTest, hasInlineText, kernelText, normalizeLines, tokenize } from './utils'; describe(' 工具函数', () => { it('把“1. ”列表处理成空行分隔的格式,以便处理', function () { const lines = normalizeLines(`1. abc 11. def `); - expect(lines).eql(` -1. abc + expect(lines).eql(`1. abc -11. def -`); +11. def`); }); it('把“- ”列表处理成空行分隔的格式,以便处理', function () { const lines = normalizeLines(`- abc - def `); - expect(lines).eql(` -- abc + expect(lines).eql(`- abc -- def -`); +- def`); }); it('把“* ”列表处理成空行分隔的格式,以便处理', function () { const lines = normalizeLines(`* abc * def `); - expect(lines).eql(` -* abc + expect(lines).eql(`* abc -* def -`); +* def`); }); it('把“# ”标题处理成空行分隔的格式,以便处理', function () { const lines = normalizeLines(`\n# abc def`); - expect(lines).eql(` -# abc + expect(lines).eql(`# abc -def -`); +def`); }); it('拆解单行的成对 tag', function () { @@ -51,13 +43,11 @@ def <div class="abc">DEF</div> b `); - expect(lines).eql(` - a + expect(lines).eql(`a <div class="abc">DEF</div> - b -`); + b`); }); it('拆解单行的自封闭 tag', function () { @@ -66,13 +56,11 @@ def <hr/> b `); - expect(lines).eql(` - a + expect(lines).eql(`a <hr/> - b -`); + b`); }); it('拆解单行的 h\\d 标签', function () { const lines = normalizeLines(` @@ -80,13 +68,11 @@ def <h3 id="abc">line</h3> b `); - expect(lines).eql(` - a + expect(lines).eql(`a <h3 id="abc">line</h3> - b -`); + b`); }); it('把多行 hn 处理成单行', function () { @@ -95,9 +81,7 @@ def abc </h3> `); - expect(lines).eql(` - <h3 id="nav">abc</h3> -`); + expect(lines).eql(`<h3 id="nav">abc</h3>`); }); it('拆解单行的 th 标签', function () { @@ -106,8 +90,7 @@ def <th>line</th> b `); - expect(lines).eql(` - a + expect(lines).eql(`a <th> @@ -115,8 +98,7 @@ def </th> - b -`); + b`); }); it('拆解单行注释', function () { @@ -125,13 +107,11 @@ def <!-- no --> b `); - expect(lines).eql(` - a + expect(lines).eql(`a <!-- no --> - b -`); + b`); }); it('拆解多行注释', function () { @@ -141,14 +121,12 @@ def abc --> b `); - expect(lines).eql(` - a + expect(lines).eql(`a <!-- no abc --> - b -`); + b`); }); it('拆解单行br', function () { @@ -157,41 +135,83 @@ def <br class="clear"> b `); - expect(lines).eql(` - a + expect(lines).eql(`a <br class="clear"> - b -`); + b`); }); it('拆解 code-example', function () { const lines = normalizeLines(` -<code-example language="sh" class="code-shell"> +abc +<code-example +language="sh" class="code-shell"> ng generate directive highlight - +</code-example> +def `); - expect(lines).eql(` -<code-example language="sh" class="code-shell"> + expect(lines).eql(`abc +<code-example +language="sh" class="code-shell"> ng generate directive highlight -`); +</code-example> + +def`); }); + it('不拆解引用的 code-example', function () { + const lines = normalizeLines(` +abc + +> <code-example > abc </code-example> + +def +`); + expect(lines).eql(`abc + +> <code-example > abc </code-example> + +def`); + }); + + it('为单行的 li 和 ul 前后添加空行', function () { + const lines = normalizeLines(` + a + <li> + b + </li> + c + <ul> + +</ul> + `); + expect(normalizeLines(lines)).eql(`a + + <li> + + b + + </li> + + c + + <ul> + +</ul>`); + }); it('拆解 @a 标记', function () { const lines = normalizeLines(` a {@a test} b `); - expect(lines).eql(` - a + expect(lines).eql(`a {@a test} - b -`); + b`); }); it('拆解多行代码', function () { @@ -202,8 +222,7 @@ ng generate directive highlight \`\`\` b `); - expect(lines).eql(` - a + expect(lines).eql(`a \`\`\` @@ -211,43 +230,29 @@ ng generate directive highlight \`\`\` - b -`); + b`); }); - it('拆解多行的成对 tag', function () { + it('把多行的 p 元素合并成单行', function () { const lines = normalizeLines(` <p> a </p> - <p> 一 </p> `); - expect(lines).eq(` - <p> + expect(lines).eq(`<p>a</p> - a - - </p> - - <p> - - 一 - -</p> -`); + <p>一</p>`); }); it('不要拆解 header', function () { const lines = normalizeLines(` <header>Angular forms don't require a style library</header> `); - expect(lines).eq(` - <header>Angular forms don't require a style library</header> -`); + expect(lines).eq(`<header>Angular forms don't require a style library</header>`); }); it('拆解独行的 th/td', function () { @@ -255,20 +260,29 @@ ng generate directive highlight <td> abc </td> -`)).eql(` - <td> +`)).eql(`<td> abc - </td> -`); + </td>`); + }); + + it('拆解 pre', function () { + expect(normalizeLines(` + ABC + <pre>def</pre> + ghi +`)).eql(`ABC + + <pre>def</pre> + + ghi`); }); it('拆解任意位置的 <tr>', function () { expect(normalizeLines(` <tr><td>abc</td></tr> -`)).eql(` - <tr> +`)).eql(`<tr> <td> @@ -276,8 +290,7 @@ ng generate directive highlight </td> - </tr> -`); + </tr>`); }); it('拆解独行的 li', function () { expect(normalizeLines(` @@ -287,8 +300,7 @@ ng generate directive highlight <li><a href="#">c</a></li> </ul> -`)).eql(` -<ul> +`)).eql(`<ul> <li> @@ -308,16 +320,13 @@ ng generate directive highlight </li> -</ul> -`); +</ul>`); }); it('不要拆解行内的 html tag', function () { expect(normalizeLines(` a <b> c -`)).eql(` -a <b> c -`); +`)).eql(`a <b> c`); }); it('把连续的三行及以上空行简化为两个空行', function () { const lines = normalizeLines(` @@ -325,17 +334,23 @@ a <b> c b`); - expect(lines).eql(` - a + expect(lines).eql(`a - b -`); + b`); }); it('拆分', function () { expect(tokenize('abc def,abc.')).eql(['abc', 'def', 'abc']); }); + it('抽取核心字符', function () { + expect(kernelText(' # Forms ABC. ')).eql('#FORMSABC'); + }); + + it('删除非核心字符', function () { + expect(kernelText('Abc-132-@#!abc')).eql('ABC132#ABC'); + }); + it('模糊匹配', function () { expect(fuzzyTest(`a b c d e`, `a b c d e`)).is.false; expect(fuzzyTest(`a b c d e f g`, `a b c d e`)).is.false; @@ -344,4 +359,12 @@ a <b> c in a helper such as the \`click()\` function below: `)).is.true; }); + + it('检测是否表格', function () { + expect(hasInlineText(` +abc | def +----|--- +gh | ij +`)).eql(true); + }); }); diff --git a/aio/tools/translator/utils.ts b/aio/tools/translator/utils.ts index ba67cd8d70..760a713c9b 100644 --- a/aio/tools/translator/utils.ts +++ b/aio/tools/translator/utils.ts @@ -51,51 +51,87 @@ export function isHead(line: string): boolean { } export function normalizeLines(text: string): string { - text = '\n' + text + '\n'; - // 为列表、标题等自带换行含义的markdown多加一个空行 - const blockElementPattern = /(?=\n *(\d+\.|-|\*) )\n/g; - text = text.replace(blockElementPattern, '\n\n'); - const hxPattern = /(\n *#+ .*)(?=\n)/g; - text = text.replace(hxPattern, '\n$1\n'); - const hxMultilinePattern = /(\n *)<(h\d+)([^>\n]*)>\n+ *(.*)\n+ *(<\/\2>)(?=\n)/g; - text = text.replace(hxMultilinePattern, '\n$1<$2$3>$4</$2>\n'); - const oneLinePairedTagPattern = /\n( *)<(p|div|h\d+|code-example|section)( ?[^>\n]*)>([^<\n]*)<\/\2>( *)(?=\n)/g; - text = text.replace(oneLinePairedTagPattern, '\n\n$1<$2$3>$4</$2>$5\n'); - const oneLineThTdTagPattern = /\n( *)(?!`)<(th|td|li)( ?[^>\n]*)>(?!`)(.*)<\/\2>( *)(?=\n)/g; - text = text.replace(oneLineThTdTagPattern, '\n\n$1<$2$3>\n\n$1 $4\n\n$1</$2>$5\n'); - const oneLineCommentPattern = /\n( *)(<!--[\s\S]*?-->)( *)(?=\n)/g; - text = text.replace(oneLineCommentPattern, '\n\n$1$2$3\n'); - const oneLineBrTagPattern = /\n( *)(<br class="clear">)( *)(?=\n)/g; - text = text.replace(oneLineBrTagPattern, '\n\n$1$2$3\n'); - // 原文中有 back to top 被分成两行的情况,这里把它标准化一下 const specialBackToTopPattern = /<a href="#toc">Back to top\s+<\/a>/g; text = text.replace(specialBackToTopPattern, '<a href="#toc">Back to top</a>'); + // 原文中有</table,为它补齐 + text = text.replace(/^ *<\/table$/gm, '</table>'); + // 原文中有的换行会干扰生成 html 的格式,替换一下 + // tslint:disable:max-line-length + text = text.replace(`<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="Installing Node.js and updating npm">Get them now</a> if they're not already installed on your machine. +`); - const backToTopPattern = /\n( *)(<a href="#toc">Back to top<\/a>)( *)(?=\n)/g; - text = text.replace(backToTopPattern, '\n\n$1$2$3\n'); - const atTagCommentPattern = /\n( *)({@a.*})( *)(?=\n)/g; - text = text.replace(atTagCommentPattern, '\n\n$1$2$3\n'); - const oneLineClosedTagPattern = /\n( *)<(hr)(\/?)>( *)(?=\n)/g; - text = text.replace(oneLineClosedTagPattern, '\n\n$1<$2$3>$4\n'); + // 为各种列表多加一个空行 + const listElementPattern = /(?=\n *(\d+\.|-|\*) )\n/g; + text = text.replace(listElementPattern, '\n\n'); + // 为标题增加空行 + const hxPattern = /^( *#+ .*)$/gm; + text = text.replace(hxPattern, '\n$1\n'); + // 把多行的 HTML 标题或 p 元素变成单行 + const hxMultilinePattern = /^( *)<(h\d|p|header)([^>]*)>\s*(.*)\s*<\/\2>$/gm; + text = text.replace(hxMultilinePattern, '\n$1<$2$3>$4</$2>\n'); + // 为单行的成对标签前后添加空行 + const oneLinePairedTagPattern = /^( *)<(p|div|h\d+|code-example|section)\b([^>]*)>([^\n]*?)<\/\2>( *)$/gm; + text = text.replace(oneLinePairedTagPattern, '\n$1<$2$3>$4</$2>$5\n'); + // 为单行的注释前后添加空行 + const oneLineCommentPattern = /^( *<!--[\s\S]*?--> *)$/gm; + text = text.replace(oneLineCommentPattern, '\n$1\n'); + // 为单行的 back to top 前后添加空行 + const backToTopPattern = /^( *<a href="#toc">Back to top<\/a> *)$/gm; + text = text.replace(backToTopPattern, '\n$1\n'); + // 为单行的 {@ 语句前后添加空行 + const atTagCommentPattern = /^( *{@a.*} *)$/gm; + text = text.replace(atTagCommentPattern, '\n$1\n'); + // 为单行的自封闭标签前后添加空行 + const oneLineClosedTagPattern = /^( *<hr *\/?>) *$/gm; + text = text.replace(oneLineClosedTagPattern, '\n$1\n'); + // 为单行的 <br class="clear"> 前后添加空行 + const oneLineBrTagPattern = /^( *<br class="clear"> *)$/gm; + text = text.replace(oneLineBrTagPattern, '\n$1\n'); + // 为单独的 div 前后添加空行 + const oneLineDivTagPattern = /^( *<\/?(div|li|ul|ol)\b([^>]*)> *)$/gm; + text = text.replace(oneLineDivTagPattern, '\n$1\n'); + // 在 pre 前后添加空行 + const preBeginTagPattern = /(^ *<pre)/gm; + text = text.replace(preBeginTagPattern, '\n$1'); + const preEndTagPattern = /(<\/pre> *)$/gm; + text = text.replace(preEndTagPattern, '$1\n'); - const trTagPattern = /( *)(<tr\b *[^>\n]*>)(.*)(<\/tr>)/g; - text = text.replace(trTagPattern, '\n\n$1$2\n\n$1 $3\n\n$1$4\n\n'); + // 为 ``` 前后添加空行 + const multiLineCodePattern = /^( *```\w* *)$/gm; + text = text.replace(multiLineCodePattern, '\n$1\n'); - const thTdTagPattern = /( *)(?!`)<(th|td)\b( *[^>\n]*)>(?!`)([\s\S]*?)<\/\2>/g; + // 把单行的 tr 拆成多行,以便翻译 + const trTagPattern = /^( *)(<tr\b[^>]*>)(.*)(<\/tr>)$/gm; + text = text.replace(trTagPattern, '\n$1$2\n\n$1 $3\n\n$1$4\n'); + + // 把单行的 th/td/li 等拆成多行,以便翻译, + const oneLineThTdTagPattern = /^( *)<(th|td|li)\b([^>]*)>(.*?)<\/\2>$/gm; + text = text.replace(oneLineThTdTagPattern, '\n$1<$2$3>\n\n$1 $4\n\n$1</$2>\n'); + + // 把原本就是多行的 th/td 中间添加空行 + const thTdTagPattern = /^( *)<(th|td)\b( *[^>]*)>([\s\S]*?)<\/\2>$/gm; text = text.replace(thTdTagPattern, '\n\n$1<$2$3>\n\n$1 $4\n\n$1</$2>\n\n'); - const blockTagPattern = /\n( *)(?!`)<(\/?)(td|th|div|code-example|code-tabs|h\d+|p|tr)\b( *[^>\n]*)>(?!`)( *)(?=\n)/g; - text = text.replace(blockTagPattern, '\n\n$1<$2$3$4>$5\n'); + // 在所有的起始标签前面加空行 + const blockBeginTagPattern = /^( *)<(code-example|code-tabs|pre|p)\b( *[^>]*)>( *)$/gm; + text = text.replace(blockBeginTagPattern, '\n$1<$2$3>$4'); - const multiLineCodePattern = /\n( *)```(\w*)( *)(?=\n)/g; - text = text.replace(multiLineCodePattern, '\n\n$1```$2$3\n'); + // 在所有的结束标签前面加空行 + const blockEndTagPattern = /^( *)<\/(code-example|code-tabs|pre|p)>( *)$/gm; + text = text.replace(blockEndTagPattern, '$1</$2>$3\n'); - const multipleBlankLinePattern = /\n\s*\n+/g; + // 把所有由空格组成的空行都去掉 + const blankLinePattern = /^[ \t]+$/gm; + text = text.replace(blankLinePattern, ''); + // 把中间的多个回车都变成两个回车 + const multipleBlankLinePattern = /\n{2,}/g; text = text.replace(multipleBlankLinePattern, '\n\n'); - text = text.replace(/^\n+/, '\n').replace(/\n+$/, '\n'); - + // 去掉全文头尾的空白 + text = text.trim(); return text; } @@ -129,14 +165,13 @@ export function fuzzyTest(text1: string, text2: string): boolean { return sameTokens.length > 5 && sameTokens.length / maxTokens >= 0.8; } -export function exactlyTest(text1: string, text2: string): boolean { - return kernelText(text1) === kernelText(text2); +export function exactlyTest(key: string, text: string): boolean { + return key && key === text; } export function kernelText(text: string): string { return text - .replace(/[\s\n]+/g, '') - .replace(/\.$/g, '') + .replace(/([^a-zA-Z0-9#:]|\s|\.$)/g, '') .toUpperCase() .trim(); } @@ -146,3 +181,15 @@ export function tokenize(text: string): string[] { .map(token => token.trim()) .filter(token => !!token); } + +export function hasInlineText(text: string): boolean { + return /<t>(.*?)<\/t> *<t>.*?<\/t>/g.test(text); +} + +export function extractOriginalContent(text: string): string { + if (!hasInlineText(text)) { + return text; + } + return text.replace(/<t>(.*?)<\/t> *<t>.*?<\/t>/gi, '$1') + .replace(/ +/g, ' '); +}