angular-cn/aio/tools/translator/dict-final.json

98557 lines
7.1 MiB
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[
{
"original": "## Transpile",
"translation": "## 转译transpile)",
"sourceFile": "/Users/twer/private/GDE/content-3/_fragments/glossary-t2.md"
},
{
"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/content-3/_fragments/glossary-t2.md"
},
{
"original": "## TypeScript",
"translation": "## TypeScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-3/_fragments/glossary-t2.md"
},
{
"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/content-3/_fragments/glossary-t2.md"
},
{
"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/content-3/_fragments/glossary-t2.md"
},
{
"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/content-3/_fragments/glossary-t2.md"
},
{
"original": "Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).",
"translation": "更多信息,见[typescript.org](http://www.typescriptlang.org/)。",
"sourceFile": "/Users/twer/private/GDE/content-3/_fragments/glossary-t2.md"
},
{
"original": "# AngularJS to Angular Quick Reference",
"translation": "# 从 AngularJS 到 Angular 快速参考",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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 的 1.x 版本。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "## Template basics",
"translation": "## 模板基础",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Bindings/interpolation",
"translation": "### 绑定/插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Bindings/interpolation",
"translation": "### 绑定/插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Filters",
"translation": "### 过滤器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "To filter output in AngularJS templates, use the pipe character (|) and one or more filters.",
"translation": "要在AngularJS中过滤输出使用管道字符(|)以及一个或多个过滤器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "This example filters the `title` property to uppercase.",
"translation": "在这个例子中,我们把`title`属性过滤成了大写形式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Pipes",
"translation": "### 管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Filters/pipes](guide/ajs-quick-reference#filters-pipes) below.",
"translation": "请参见下面[过滤器/管道](guide/ajs-quick-reference#filters-pipes)了解更多信息。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Local variables",
"translation": "### 局部变量",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Here, `movie` is a user-defined local variable.",
"translation": "这里的`movie`是一个用户定义的局部变量",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Input variables",
"translation": "### 输入变量",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Angular has true template input variables that are explicitly defined using the `let` keyword.",
"translation": "在Angular中我们有了真正的模板输入变量它需要使用`let`关键字进行明确定义。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "## Template directives",
"translation": "## 模板指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "The application startup process is called **bootstrapping**.",
"translation": "应用的启动过程被称为**引导**。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Bootstrapping",
"translation": "### 引导",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "You can specify multiple classes, as shown in the second example.",
"translation": "就像第二个例子中展示的可以指定多个CSS类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "You can specify multiple classes, as shown in the second example.",
"translation": "就像第二个例子中所展示的那样,可以同时指定多个类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `click` event",
"translation": "### 绑定到`click`事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Component decorator",
"translation": "### Component装饰器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Architecture Overview](guide/architecture#components).",
"translation": "要了解更多,请参见[架构概览](guide/architecture#components)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### ng-hide\n 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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `hidden` property",
"translation": "### 绑定`hidden`属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Routing is handled differently in Angular.",
"translation": "路由在Angular中的处理方式不同。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `href` property",
"translation": "### 绑定到`href`属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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中移除。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "For more information on two-way binding with `ngModel`, see the [NgModel&mdash;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&mdash;使用`[(ngModel)]`进行双向绑定](../guide/template-syntax.html#ngModel)部分。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the table row (`<tr>`) element repeats for each movie object in the collection of movies.",
"translation": "在这个例子中,对`movies`集合中的每一个`movie`对象重复渲染了这个表格行元素(`<tr>`)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Structural Directives](guide/structural-directives).",
"translation": "要了解更多信息,参见[结构性指令](guide/structural-directives)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the `<div>` element is shown if the `favoriteHero` variable is truthy.",
"translation": "在这个例子中,如果`favoriteHero`变量为真,`<div>`元素就会显示出来。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `hidden` property",
"translation": "### 绑定到`hidden`属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the `<div>` element is hidden if the `favoriteHero` variable is not truthy.",
"translation": "在这个例子中,如果`favoriteHero`变量不是真值,`<div>`元素就会被隐藏。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `src` property",
"translation": "### 绑定到`src`属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "The (*) before `ngSwitchCase` and `ngSwitchDefault` is required in this example.",
"translation": "在这个例子中,`ngSwitchCase`和`ngSwitchDefault`前面的星号(*)是必须的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "## Filters/pipes",
"translation": "## 过滤器/管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Formats a number as currency.",
"translation": "把一个数字格式化成货币。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `currency` pipe is similar although some of the parameters have changed.",
"translation": "Angular的`currency`管道和1中很相似只是有些参数变化了。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Formats a date to a string based on the requested format.",
"translation": "基于要求的格式把日期格式化成字符串。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `date` pipe is similar.",
"translation": "Angular的`date`管道和它很相似。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Selects a subset of items from the defined collection, based on the filter criteria.",
"translation": "基于过滤条件从指定的集合中选取出一个子集。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Converts a JavaScript object into a JSON string. This is useful for debugging.",
"translation": "把一个JavaScript对象转换成一个JSON字符串。这对调试很有用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `json` pipe does the same thing.",
"translation": "Angular的`json`管道做完全相同的事。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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)个条目。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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中一样如果们改用组件中的代码实现此操作性能将会提升。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Converts the string to lowercase.",
"translation": "把该字符串转成小写形式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `lowercase` pipe does the same thing.",
"translation": "Angular的`lowercase`管道和1中的功能完全相同。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "Formats a number as text.",
"translation": "把数字格式化为文本。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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)百分比格式,如第三个范例所示。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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排序了。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "## Modules/controllers/components",
"translation": "## 模块/控制器/组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### none",
"translation": "### 没了",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Angular modules",
"translation": "### Angular模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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模块用来对控制器、服务和其它代码进行跟踪。第二个参数定义该模块依赖的其它模块列表。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "NgModules, defined with the `NgModule` decorator, serve the same purpose:",
"translation": "Angular的模块用`NgModule`装饰器进行定义,有如下用途:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "* `imports`: specifies the list of other modules that this module depends upon",
"translation": "`imports`: 指定当前模块依赖的其它模块列表",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "* `declaration`: keeps track of your components, pipes, and directives.",
"translation": "`declaration`: 用于记录组件、管道和指令。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "For more information on modules, see [NgModules](guide/ngmodules).",
"translation": "要了解关于模块的更多知识,参见[NgModules](guide/ngmodule)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Component decorator",
"translation": "### 组件装饰器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "This is how you associate a template with logic, which is defined in the component class.",
"translation": "这就是把模板关联到代码的方式,它定义在组件类中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Controller function",
"translation": "### 控制器函数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "In AngularJS, you write the code for the model and methods in a controller function.",
"translation": "在Angular1中我们在控制器函数中写模型和方法的代码。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Component class",
"translation": "### 组件类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "In Angular, you create a component class.",
"translation": "在Angular中我们写组件类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Dependency injection",
"translation": "### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Dependency injection",
"translation": "### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "## Style sheets",
"translation": "## 样式表",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"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`标签来为应用程序定义样式。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "### Styles configuration",
"translation": "### 样式配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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": "在Angular2中我们可以继续在`index.html`中使用link标签来为应用程序定义样式。\n 但是也能在组件中封装样式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"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/content-3/guide/ajs-quick-reference.md"
},
{
"original": "This allows you to set appropriate styles for individual components that wont leak into\n other parts of the application.",
"translation": "这让我们可以为各个组件设置合适的样式,而不用担心它被泄漏到程序中的其它部分。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ajs-quick-reference.md"
},
{
"original": "# Animations",
"translation": "# 动画",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "The examples in this page are available as a <live-example></live-example>.",
"translation": "本章中引用的这个例子可以到<live-example></live-example>去体验。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "## Transitioning between two states",
"translation": "## 快速起步范例:在两个状态间转场",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "Animations can be defined inside `@Component` metadata.",
"translation": "动画会被定义在`@Component`元数据中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "## States and transitions",
"translation": "## 状态与转场",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "Angular animations are defined as logical **states** and **transitions**\nbetween states.",
"translation": "Angular动画是由**状态**和**状态之间的转场效果**所定义的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "We can define *styles* for each animation state:",
"translation": "我们可以为每个动画状态定义了*一组样式*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "### The wildcard state `*`",
"translation": "### `*`(通配符)状态",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "* The `active => *` transition applies when the element's state changes from `active` to anything else.",
"translation": "当该元素的状态从`active`变成任何其它状态时,`active => *`转场都会生效。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "* The `* => *` transition applies when *any* change between two states takes place.",
"translation": "当在*任意*两个状态之间切换时,`* => *`转场都会生效。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "### The `void` state",
"translation": "### `void`状态",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "The wildcard state `*` also matches `void`.",
"translation": "`*`通配符状态也能匹配`void`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "## Example: Entering and leaving",
"translation": "## 例子:进场与离场",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "* Enter: `void => *`",
"translation": "进场:`void => *`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "* Leave: `* => void`",
"translation": "离场:`* => void`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "These two common animations have their own aliases:",
"translation": "这两个常见的动画有自己的别名:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "## Example: Entering and leaving from different states",
"translation": "## 范例:从不同的状态下进场和离场",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "* Inactive hero enter: `void => inactive`",
"translation": "非激活英雄进场:`void => inactive`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "* Active hero enter: `void => active`",
"translation": "激活英雄进场:`void => active`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "* Inactive hero leave: `inactive => void`",
"translation": "非激活英雄离场:`inactive => void`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "* Active hero leave: `active => void`",
"translation": "激活英雄离场:`active => void`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "This gives you fine-grained control over each transition:",
"translation": "现在就对每一种转场都有了细粒度的控制:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "## Animatable properties and units",
"translation": "## 可动的(Animatable)属性与单位",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "If you don't provide a unit when specifying dimension, Angular assumes the default of `px`:",
"translation": "对大多数尺寸类属性而言,还能只定义一个数字,那就表示它使用的是像素(px)数:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "* `50` is the same as saying `'50px'`",
"translation": "`50`相当于`'50px'`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "## Automatic property calculation",
"translation": "## 自动属性值计算",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "## Animation timing",
"translation": "## 动画时间线",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "### Duration",
"translation": "### 持续时间",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "* As a plain number, in milliseconds: `100`",
"translation": "作为一个普通数字,以毫秒为单位,如:`100`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "* In a string, as milliseconds: `'100ms'`",
"translation": "作为一个字符串,以毫秒为单位,如:`'100ms'`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "* In a string, as seconds: `'0.1s'`",
"translation": "作为一个字符串,以秒为单位,如:`'0.1s'`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "### Delay",
"translation": "### 延迟",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "* Wait for 100ms and then run for 200ms: `'0.2s 100ms'`",
"translation": "等待100毫秒然后运行200毫秒`'0.2s 100ms'`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "### Easing",
"translation": "### 缓动函数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "* Run for 200ms, with easing: `'0.2s ease-in-out'`",
"translation": "运行200毫秒并且带缓动`'0.2s ease-in-out'`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "### Example",
"translation": "### 例子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "## Multi-step animations with keyframes",
"translation": "## 基于关键帧(Keyframes)的多阶段动画",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "This example adds some \"bounce\" to the enter and leave animations with\nkeyframes:",
"translation": "在这个例子中,我们使用关键帧来为进场和离场动画添加一些“反弹效果”:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "## Parallel animation groups",
"translation": "## 并行动画组(Group)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "One group animates the element transform and width; the other group animates the opacity.",
"translation": "其中一个动画组对元素的`transform`和`width`做动画,另一个组则对`opacity`做动画。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"original": "A callback is fired when an animation is started and also when it is done.",
"translation": "当动画开始和结束时,会触发一个回调。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"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/content-3/guide/animations.md"
},
{
"original": "Those callbacks will fire whether or not an animation is picked up.",
"translation": "无论动画是否实际执行过,那些回调都会触发。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/animations.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "<a href=\"https://www.youtube.com/watch?v=kW9cJsvcsGo\">Watch compiler author Tobias Bosch explain the Angular Compiler</a> at AngularConnect 2016.",
"translation": "观看 Angular 编译器的作者Tobias Bosch 在 AngularConnect 2016 上对编译器的解释。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "## Angular compilation",
"translation": "## 概览",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "<code-example language=\"sh\" class=\"code-shell\">\n ng build --aot\n ng serve --aot\n</code-example>",
"translation": "Angular应用主要包含组件和它们的HTML模板。\n在浏览器可以渲染应用之前组件和模板必须要被**Angular编译器**转换为可以执行的JavaScript。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "## Why compile with AOT?",
"translation": "## 为什么需要AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "*Faster rendering*",
"translation": "**渲染得更快**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "*Fewer asynchronous requests*",
"translation": "**需要的异步请求更少**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "*Smaller Angular framework download size*",
"translation": "**需要下载的Angular框架体积更小**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "*Detect template errors earlier*",
"translation": "**提早检测模板错误**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "*Better security*",
"translation": "**更安全**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "## Angular Metadata and AOT",
"translation": "## Angular 元数据与 AOT",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "## Metadata restrictions",
"translation": "## 元数据的限制",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "You write metadata in a _subset_ of TypeScript that must conform to the following general constraints:",
"translation": "我们只能使用 TypeScript 的一个**子集**书写元数据,它必须满足下列限制:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "1. Limit [expression syntax](#expression-syntax) to the supported subset of JavaScript.",
"translation": "[表达式语法](#expression-syntax)只支持 JavaScript 的一个有限的子集。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "2. Only reference exported symbols after [code folding](#folding).",
"translation": "只能引用[代码收缩](#folding)后导出的符号。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "3. Only call [functions supported](#supported-functions) by the compiler.",
"translation": "只能调用编译器[支持的那些函数](#supported-functions)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "4. Decorated and data-bound class members must be public.",
"translation": "被装饰和用于数据绑定的类成员必须是公共public的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "The next sections elaborate on these points.",
"translation": "我们将在下一节详细解释这些问题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"original": "## How AOT works",
"translation": "## AOT 工作原理",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "## Phase 1: analysis",
"translation": "## 阶段1分析",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"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/content-3/guide/aot-compiler.md"
},
{
"original": "# Architecture Overview",
"translation": "# 架构概览",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/guide/architecture.md"
},
{
"original": "The framework consists of several libraries, some of them core and some optional.",
"translation": "该框架包括一系列库,有些是核心库,有些是可选库。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "The code referenced on this page is available as a <live-example></live-example>.",
"translation": "本章所引用的代码见<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "## Modules",
"translation": "## 模块",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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": "_Angular 模块_很重要。这里只是简单介绍在 [Angular 模块](guide/ngmodule)中会做深入讲解。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "* `providers` - creators of [services](guide/architecture#services) that this module contributes to\n the global collection of services; they become accessible in all parts of the app.",
"translation": "`providers` - [服务](guide/architecture#services)的创建者,并加入到全局服务列表中,可用于应用任何部分。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* `bootstrap` - the main application view, called the _root component_,\n that hosts all other app views. Only the _root module_ should set this `bootstrap` property.",
"translation": "`bootstrap` - 指定应用的主视图称为_根组件_它是所有其它视图的宿主。只有_根模块_才能设置`bootstrap`属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "Here's a simple root module:",
"translation": "下面是一个简单的根模块:",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "### NgModules vs. JavaScript modules",
"translation": "### NgModules vs. JavaScript 模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "The NgModule &mdash; a class decorated with `@NgModule` &mdash; is a fundamental feature of Angular.",
"translation": "NgModule一个带`@NgModule`装饰器的类)是 Angular 的基础特性之一。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "### Angular libraries",
"translation": "### Angular 模块库",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/guide/architecture.md"
},
{
"original": "Each Angular library name begins with the `@angular` prefix.",
"translation": "每个 Angular 库的名字都带有`@angular`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/guide/architecture.md"
},
{
"original": "You also import NgModules from Angular _libraries_ using JavaScript import statements:",
"translation": "还可以使用 JavaScript 的导入语句从 Angular _库_中导入 Angular _模块_",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "## Components",
"translation": "## 组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "A _component_ controls a patch of screen called a *view*.",
"translation": "_组件_负责控制屏幕上的一小块区域我们称之为*视图*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "For example, the following views are controlled by components:",
"translation": "例如,下列视图都是由组件控制的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* The app root with the navigation links.",
"translation": "带有导航链接的应用根组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* The list of heroes.",
"translation": "英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* The hero editor.",
"translation": "英雄编辑器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "You define a component's application logic&mdash;what it does to support the view&mdash;inside a class.\nThe class interacts with the view through an API of properties and methods.",
"translation": "我们在类中定义组件的应用逻辑,为视图提供支持。\n组件通过一些由属性和方法组成的 API 与视图交互。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "## Templates",
"translation": "## 模板",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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]`和`<hero-detail>`这样的代码使用了 Angular 的[模板语法](guide/template-syntax)。",
"sourceFile": "/Users/twer/private/GDE/content-3/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": "在模板的最后一行,`<hero-detail>`标签就是一个用来表示新组件`HeroDetailComponent`的自定义元素。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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": "注意到了吗?`<hero-detail>`舒适地躺在原生 HTML 元素之间。\n自定义组件和原生 HTML 在同一布局中融合得天衣无缝。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "## Metadata",
"translation": "## 元数据",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "Metadata tells Angular how to process a class.",
"translation": "<p style=\"padding-top:10px\">元数据告诉 Angular 如何处理一个类。</p>\n<br class=\"clear\">",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "Here are a few of the most useful `@Component` configuration options:",
"translation": "`@Component`的配置项包括:",
"sourceFile": "/Users/twer/private/GDE/content-3/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 中查找`<hero-list>`标签,创建并插入该组件。\n 例如,如果应用的 HTML 包含`<hero-list></hero-list>` Angular 就会把`HeroListComponent`的一个实例插入到这个标签中。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "The template, metadata, and component together describe a view.",
"translation": "模板、元数据和组件共同描绘出这个视图。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "## Data binding",
"translation": "## 数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "As the diagram shows, there are four forms of data binding syntax. Each form has a direction &mdash; to the DOM, from the DOM, or in both directions.",
"translation": "如图所示,数据绑定的语法有四种形式。每种形式都有一个方向 —— 绑定到 DOM 、绑定自 DOM 以及双向绑定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "The `HeroListComponent` [example](guide/architecture#templates) template has three forms:",
"translation": "`HeroListComponent`[示例](guide/architecture#templates)模板中有三种形式:",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "Data binding plays an important role in communication between a template and its component.",
"translation": "数据绑定在模板与对应组件的交互中扮演了重要的角色。\n<br class=\"l-clear-both\">",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "Data binding is also important for communication between parent and child components.",
"translation": "数据绑定在父组件与子组件的通讯中也同样重要。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "## Directives",
"translation": "## 指令 (directive)",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "Two *other* kinds of directives exist: _structural_ and _attribute_ directives.",
"translation": "还有两种*其它*类型的指令_结构型_指令和_属性 (attribute) 型_指令。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/guide/architecture.md"
},
{
"original": "**Structural** directives alter layout by adding, removing, and replacing elements in DOM.",
"translation": "**结构型**指令通过在 DOM 中添加、移除和替换元素来修改布局。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "## Services",
"translation": "## 服务",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "Examples include:",
"translation": "例如:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* logging service",
"translation": "日志服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* data service",
"translation": "数据服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* message bus",
"translation": "消息总线",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* tax calculator",
"translation": "税款计算器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* application configuration",
"translation": "应用程序配置",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "Here's an example of a service class that logs to the browser console:",
"translation": "下面是一个服务类的范例,用于把日志记录到浏览器的控制台:",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/guide/architecture.md"
},
{
"original": "Services are everywhere.",
"translation": "服务无处不在。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "## Dependency injection",
"translation": "## 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-3/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 使用依赖注入来提供新组件以及组件所需的服务。<br class=\"clear\">",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "The process of `HeroService` injection looks a bit like this:",
"translation": "`HeroService`注入的过程差不多是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "You can register providers in modules or in components.",
"translation": "我们可以在模块中或组件中注册提供商。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "Points to remember about dependency injection:",
"translation": "需要记住的关于依赖注入的要点是:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* Dependency injection is wired into the Angular framework and used everywhere.",
"translation": "依赖注入渗透在整个 Angular 框架中,被到处使用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* The *injector* is the main mechanism.",
"translation": "**注入器 (injector)** 是本机制的核心。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* An injector maintains a *container* of service instances that it created.",
"translation": "注入器负责维护一个*容器*,用于存放它创建过的服务实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* An injector can create a new service instance from a *provider*.",
"translation": "注入器能使用*提供商*创建一个新的服务实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* A *provider* is a recipe for creating a service.",
"translation": "*提供商*是一个用于创建服务的配方。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* Register *providers* with injectors.",
"translation": "把*提供商*注册到注入器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "## Wrap up",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/guide/architecture.md"
},
{
"original": "* [Modules](guide/architecture#modules)",
"translation": "[模块](guide/architecture#modules)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* [Components](guide/architecture#components)",
"translation": "[组件](guide/architecture#components)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* [Templates](guide/architecture#templates)",
"translation": "[模板](guide/architecture#templates)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* [Metadata](guide/architecture#metadata)",
"translation": "[元数据](guide/architecture#metadata)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* [Data binding](guide/architecture#data-binding)",
"translation": "[数据绑定](guide/architecture#data-binding)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* [Directives](guide/architecture#directives)",
"translation": "[指令](guide/architecture#directives)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* [Services](guide/architecture#services)",
"translation": "[服务](guide/architecture#services)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "* [Dependency injection](guide/architecture#dependency-injection)",
"translation": "[依赖注入](guide/architecture#dependency-injection)",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/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/content-3/guide/architecture.md"
},
{
"original": "> [**Pipes**](guide/pipes): Use pipes in your templates to improve the user experience by transforming values for display. Consider this `currency` pipe expression:",
"translation": "> [**管道**](guide/pipes):在模板中使用管道转换成用于显示的值,以增强用户体验。例如,`currency`管道表达式:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "> It displays a price of 42.33 as `$42.33`.",
"translation": "> 它把价格“42.33”显示为`$42.33`。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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 框架交互时进行单元测试。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/architecture.md"
},
{
"original": "# Attribute Directives",
"translation": "# 属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "An **Attribute** directive changes the appearance or behavior of a DOM element.",
"translation": "**属性**型指令用于改变一个 DOM 元素的外观或行为。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Try the <live-example title=\"Attribute Directive example\"></live-example>.",
"translation": "你可以到这里试试:<live-example title=\"Attribute Directive example\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "## Directives overview",
"translation": "## 指令概览",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "There are three kinds of directives in Angular:",
"translation": "在 Angular 中有三种类型的指令:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "1. Components&mdash;directives with a template.",
"translation": "组件 &mdash; 拥有模板的指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "1. Structural directives&mdash;change the DOM layout by adding and removing DOM elements.",
"translation": "结构型指令 &mdash; 通过添加和移除 DOM 元素改变 DOM 布局的指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "1. Attribute directives&mdash;change the appearance or behavior of an element, component, or another directive.",
"translation": "属性型指令 &mdash; 改变元素、组件或其它指令的外观和行为的指令。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "## Build a simple attribute directive",
"translation": "## 创建一个简单的属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "### Write the directive code",
"translation": "### 编写指令代码",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Create the directive class file in a terminal window with this CLI command.",
"translation": "在命令行窗口下用 CLI 命令创建指令类文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "_Directives_ must be declared in [Angular Modules](guide/ngmodules) in the same manner as _components_.",
"translation": "和**组件**一样,这些**指令**也必须在[Angular模块](guide/ngmodule)中进行声明。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "The generated `src/app/highlight.directive.ts` is as follows:",
"translation": "生成的`src/app/highlight.directive.ts`文件如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "The imported `Directive` symbol provides the Angular the `@Directive` decorator.",
"translation": "这里导入的`Directive`符号提供了 Angular 的 `@Directive` 装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "The _attribute selector_ pattern explains the name of this kind of directive.",
"translation": "正因如此,这类指令被称为 **属性选择器** 。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "#### Why not \"highlight\"?",
"translation": "#### 为什么不直接叫做 \"highlight\"",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "The `import` statement specifies an additional `ElementRef` symbol from the Angular `core` library:",
"translation": "`import`语句还从 Angular 的 `core` 库中导入了一个 `ElementRef` 符号。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "Now run the application to see the `HighlightDirective` in action.",
"translation": "运行这个应用以查看`HighlightDirective`的实际效果。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "## Respond to user-initiated events",
"translation": "## 响应用户引发的事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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": "当前,`myHighlight`只是简单的设置元素的颜色。\n这个指令应该在用户鼠标悬浮一个元素时设置它的颜色。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Begin by adding `HostListener` to the list of imported symbols.",
"translation": "先把`HostListener`加进导入列表中,同时再添加`Input`符号,因为我们很快就要用到它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "1. You have to write the listeners correctly.",
"translation": "必须正确的书写事件监听器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "1. The code must *detach* the listener when the directive is destroyed to avoid memory leaks.",
"translation": "当指令被销毁的时候,必须*拆卸*事件监听器,否则会导致内存泄露。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "1. Talking to DOM API directly isn't a best practice.",
"translation": "必须直接和 DOM API 打交道,应该避免这样做。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "The helper method, `highlight`, was extracted from the constructor.\nThe revised constructor simply declares the injected `el: ElementRef`.",
"translation": "这些处理器委托给了一个辅助方法它用于为DOM元素设置颜色`el`就是你在构造器中声明和初始化过的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Here's the updated directive in full:",
"translation": "下面是修改后的指令代码:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Run the app and confirm that the background color appears when the mouse hovers over the `p` and\ndisappears as it moves out.We run the app and confirm that the background color appears as we move the mouse over the `p` and\ndisappears as we move out.",
"translation": "运行本应用并确认:当把鼠标移到`p`上的时候,背景色就出现了,而移开的时候,它消失了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "## Pass values into the directive with an _@Input_ data binding",
"translation": "## 使用数据绑定向指令传递值",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "Begin by adding `Input` to the list of symbols imported from `@angular/core`.\n<code-example path=\"attribute-directives/src/app/highlight.directive.3.ts\" linenums=\"false\" title=\"src/app/highlight.directive.ts (imports)\" region=\"imports\"></code-example>",
"translation": "我们先从`@angular/core`中导入`Input`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Add a `highlightColor` property to the directive class like this:",
"translation": "然后把`highlightColor`属性添加到指令类中,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "### Binding to an _@Input_ property",
"translation": "### 绑定到_@Input_属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "Try it by adding the following directive binding variations to the `AppComponent` template:",
"translation": "试试把下列指令绑定变量添加到`AppComponent`的模板中:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Add a `color` property to the `AppComponent`.",
"translation": "把`color`属性添加到`AppComponent`中:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Let it control the highlight color with a property binding.",
"translation": "让它通过属性绑定来控制高亮颜色。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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": "`[myHighlight]`属性同时做了两件事:把这个高亮指令应用到了`<p>`元素上,并且通过属性绑定设置了该指令的高亮颜色。\n我们复用了该指令的属性选择器`[myHighlight]`来同时完成它们。\n这是清爽、简约的语法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "This is disagreeable. The word, `appHighlight`, is a terrible property name and it doesn't convey the property's intent.",
"translation": "这可不好。因为`myHighlight`是一个糟糕的属性名,而且不能反映该属性的意图。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "### Bind to an _@Input_ alias",
"translation": "### 绑定到_@Input_别名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Fortunately you can name the directive property whatever you want _and_ **_alias it_** for binding purposes.",
"translation": "幸运的是,我们可以随意命名该指令的属性,并且**给它指定一个用于绑定的别名**。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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`,在外部,当我们绑定到它时,它叫`myHighlight`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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如果有人忘了绑定到`highlightColor`,那就用红色进行高亮。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Here's the latest version of the directive class.",
"translation": "这是最终版本的指令类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "## Write a harness to try it",
"translation": "## 写个测试程序试验下",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "Update <code>app.component.html</code> as follows:",
"translation": "把`app.component.html`修改成这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Revise the `AppComponent.color` so that it has no initial value.",
"translation": "修改`AppComponent.color`,让它不再有初始值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Here are the harness and directive in action.",
"translation": "下面是测试程序和指令的动图。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "## Bind to a second property",
"translation": "## 绑定到第二个属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "This highlight directive has a single customizable property. In a real app, it may need more.",
"translation": "本例的指令只有一个可定制属性,真实的应用通常需要更多。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "At the moment, the default color&mdash;the color that prevails until\nthe user picks a highlight color&mdash;is hard-coded as \"red\".\nLet the template developer set the default color.",
"translation": "目前,默认颜色(它在用户选取了高亮颜色之前一直有效)被硬编码为红色。我们要让模板的开发者也可以设置默认颜色。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "Add a second **input** property to `HighlightDirective` called `defaultColor`:",
"translation": "把第二个名叫`defaultColor`的**输入**属性添加到`HighlightDirective`中:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "How do you bind to a second property when you're already binding to the `appHighlight` attribute name?",
"translation": "当已经绑定过`myHighlight`属性时,要如何绑定到第二个属性呢?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "Here's how the harness should work when you're done coding.",
"translation": "当这些代码完成时,测试程序工作时的动图如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "This page covered how to:",
"translation": "本章介绍了如何:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "* [**Bind** values to the directive](guide/attribute-directives#bindings).",
"translation": "[把值**绑定**到指令中](guide/attribute-directives#bindings)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "The final source code follows:",
"translation": "最终的源码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "### Appendix: Why add _@Input_?",
"translation": "### 附录:为什么要加*@Input*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "You've seen it with an alias:",
"translation": "也见过用别名时的代码:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"original": "Now apply that reasoning to the following example:",
"translation": "试用此原理分析下列范例:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"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/content-3/guide/attribute-directives.md"
},
{
"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": "`myHighlight`属性位于左侧,它引用了`MyHighlightDirective`中一个*带别名的*属性,它不是模板所属组件的一部分,因此存在信任问题。\n所以该属性必须带`@Input`装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/attribute-directives.md"
},
{
"original": "# Browser support",
"translation": "# 浏览器支持",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Angular supports most recent browsers. This includes the following specific versions:",
"translation": "Angular 支持大多数常用浏览器,包括下列版本:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "latest",
"translation": "最新版",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"original": "## Polyfills",
"translation": "## 腻子脚本 (polyfill)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"original": "## Enabling polyfills",
"translation": "## 启用腻子脚本",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"original": "This file incorporates the mandatory and many of the optional polyfills as JavaScript `import` statements.",
"translation": "这个文件把强制的和很多可选的腻子脚本组织成 JavaScript 的 `import` 语句。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"original": "1. install the npm package",
"translation": "安装 npm 包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "1. `import` the file in `polyfills.ts`",
"translation": "在 `polyfills.ts` 中 `import` 这个文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Non-CLI users should follow the instructions [below](#non-cli).",
"translation": "不使用 CLI 的用户可以遵循[下列](#non-cli)步骤自行操作。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "### Mandatory polyfills",
"translation": "### 强制性腻子脚本",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "These are the polyfills required to run an Angular application on each supported browser:",
"translation": "下表中的腻子脚本是每个浏览器都要用到的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Browsers (Desktop & Mobile)",
"translation": "<p>\n 浏览器(桌面和移动)\n </p>\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Polyfills Required",
"translation": "需要的腻子脚本",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "### Optional browser features to polyfill",
"translation": "### 可选浏览器特性的腻子脚本",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Some features of Angular may require additional polyfills.",
"translation": "有些 Angular 特性可能需要额外的腻子脚本。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"original": "Here are the features which may require additional polyfills:",
"translation": "下列特性可能需要更多腻子脚本:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "<th>\n Feature",
"translation": "特性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "<th>\n Polyfill",
"translation": "腻子脚本",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "<th style=\"width: 50%\">\n Browsers (Desktop & Mobile)",
"translation": "浏览器(桌面和移动)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Required to reflect for metadata.",
"translation": "[JIT 编译](guide/aot-compiler) 需要 reflect 来提供元数据。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "<td>\n 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/content-3/guide/browser-support.md"
},
{
"original": "[Animations](guide/animations)",
"translation": "[动画](guide/animations)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "<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": "<br>只有在应用中用到了 `Animation Builder` 时才需要Angular 标准的动画支持是不需要任何腻子脚本的(截至 NG6。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "[Web Animations](guide/browser-support#web-animations)",
"translation": "[Web 动画](guide/browser-support#web-animations)\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "<td>\n <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>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "If you use the following deprecated i18n pipes:",
"translation": "如果你使用下列已废弃的i18n管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "<td>\n <p>All but Chrome, Firefox, Edge, IE11 and Safari 10</p>",
"translation": "除了 Chrome、Firefox、Edge、IE11 和 Safari 10 外的所有浏览器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "on SVG elements</p>",
"translation": "<p>在 SVG 元素上应用 [NgClass](api/common/NgClass)</p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "when sending and receiving binary data</p>",
"translation": "用 [Http](guide/http) 发送和接收二进制数据",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "### Suggested polyfills ##",
"translation": "### 建议的腻子脚本 ##",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"original": "Polyfill",
"translation": "腻子脚本",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Licence",
"translation": "授权方式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Size*",
"translation": "大小*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "Public domain",
"translation": "公共域",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"original": "{@a non-cli}\n## Polyfills for non-CLI users",
"translation": "## 不使用 CLI 的用户的腻子脚本",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/browser-support.md"
},
{
"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/content-3/guide/browser-support.md"
},
{
"original": "# Change Log",
"translation": "# 变更记录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## All mention of moduleId removed. \"Component relative paths\" guide deleted (2017-03-13)",
"translation": "## 移除了所有的moduleId引用。移除了“组件相对路径” 的烹饪书。(2017-03-13)\nWe 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.",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## NEW: Downloadable examples for each guide (2017-02-28)",
"translation": "## 新增:每篇指南都增加了可下载的范例程序 (2017-02-28)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## Template Syntax/Structural Directives: refreshed (2017-02-06)",
"translation": "## 模板语法/结构型指令:更新了 (2017-02-06)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## NEW: Samples re-structured with `src/` folder (2017-02-02)",
"translation": "## 新增:调整了范例程序的结构,移到了`src/`文件夹 (2017-02-02)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "Notably:",
"translation": "要点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "* `app/main.ts` moved to `src/main.ts`.",
"translation": "把`app/main.ts`移到`src/main.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "* `app/` moved to `src/app/`.",
"translation": "把`app/`移到`src/app/`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "* `index.html`, `styles.css` and `tsconfig.json` moved inside `src/`.",
"translation": "把`index.html`、`styles.css`和`tsconfig.json`移到`src/`中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "* `systemjs.config.js` now imports `main.js` instead of `app`.",
"translation": "`systemjs.config.js`现在要导入`main.js`而不是`app`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "* Added `lite-server` configuration (`bs-config.json`) to serve `src/`.",
"translation": "新增了一个`lite-server`配置(`bs-config.json`)以便在`src/`下启动开发服务器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "## NEW: Reactive Forms guide (2017-01-31)",
"translation": "## 新增响应式Reactive表单指南 (2017-01-31)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## NEW: Deployment guide (2017-01-30)",
"translation": "## 新增:部署指南 (2017-01-30)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## Hierarchical Dependency Injection: refreshed (2017-01-13)",
"translation": "## 多级依赖注入:更新完毕 (2017-01-13)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## Miscellaneous (2017-01-05)",
"translation": "## 杂项 (2017-01-05)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "* [Setup](guide/setup) guide:",
"translation": "[环境搭建](guide/setup)指南:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "added (optional) instructions on how to remove _non-essential_ files.",
"translation": "添加了(可选的)步骤说明,告诉你如何移除*非核心*文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "* All samples prepend template/style URLs with `./` as a best practice.",
"translation": "所有范例都在模板/样式的URL之前添加`./`前缀 …… 而且你在实际开发中也应该这么做。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "* [Style Guide](guide/styleguide): copy edits and revised rules.",
"translation": "[风格指南](guide/styleguide):复制了编辑过的和修改过的规则。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "## Router: more detail (2016-12-21)",
"translation": "## 路由:更详细 (2016-12-21)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "Added section on how to set default request headers (and other request options) to\nHTTP guide.",
"translation": "添加了一节“如何设置默认的请求头(以及其它配置项)”",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "## Testing: added component test plunkers (2016-12-02)",
"translation": "## 测试添加了组件测试的plunker范例 (2016-12-02)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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并在[测试](guide/testing#live-examples)和[环境设置剖析](guide/setup-systemjs-anatomy)中链接到它们。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "## Internationalization: pluralization and _select_ (2016-11-30)",
"translation": "## 国际化:单复数和`select` (2016-11-30)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## Testing: karma file updates (2016-11-30)",
"translation": "## 测试更新了karma文件 (2016-11-30)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "* Displays Jasmine Runner output in the karma-launched browser.",
"translation": "在启动了karma的浏览器中显示Jasmine的输出。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "## QuickStart Rewrite (2016-11-18)",
"translation": "## 全新《快速上手》 (2016-11-18)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## ES6 described in \"TypeScript to JavaScript\" (2016-11-14)",
"translation": "## 在“从TypeScript到JavaScript”增加ES6的描述 (2016-11-14)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "The updated TypeScript to JavaScript guide explains how to write apps in ES6/7",
"translation": "更新了“[从TypeScript到JavaScript](guide/ts-to-js)”烹饪宝典解释如何使用ES6/7编写应用\nby translating the common idioms in the TypeScript documentation examples\n(and elsewhere on the web) to ES6/7 and ES5.",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## npm _@types_ packages replace _typings_ (2016-10-20)",
"translation": "## 使用npm的_@types_包替换_typings_ (2016-10-20)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## \"Template Syntax\" explains two-way data binding syntax (2016-10-20)",
"translation": "## \"模板语法\"添加了双向数据绑定语法的解释(2016-10-20)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## \"Router\" _preload_ syntax and _:enter_/_:leave_ animations (2016-10-19)",
"translation": "## \"路由器\"_预加载_语法和_:enter_/_:leave_动画(2016-10-19)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "New `:enter` and `:leave` aliases make animation more natural.",
"translation": "新`:enter`和`:leave`语法,让动画更加自然。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## NEW \"Ahead of time (AOT) Compilation\" guide (2016-10-11)",
"translation": "## 添加了新的“预编译(AoT)\"烹饪书(2016-10-11)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## \"Routing and Navigation\" guide with the _Router Module_ (2016-10-5)",
"translation": "## 在“路由和导航”向导中添加**路由模块** (2016-10-5)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "[Routing and Navigation](guide/router)",
"translation": "[路由与导航](guide/router)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/ngmodule)章和[Angular模块常见问题](guide/ngmodule-faq)烹饪书。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "## New \"Internationalization\" guide (2016-09-30)",
"translation": "## 全新“国际化”烹饪书(2016-09-30)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## \"Style Guide\" with _NgModules_ (2016-09-27)",
"translation": "## “风格指南”中添加了_NgModules_(2016-09-27)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "[StyleGuide](guide/styleguide) explains recommended conventions for NgModules.",
"translation": "[StyleGuide](guide/styleguide)解释了我们为Angular模块NgModule而推荐的约定。\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.",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"original": "## _moduleId: module.id_ everywhere (2016-09-25)",
"translation": "## moduleId到处添加module.id(2016-09-25)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "## \"Lifecycle Hooks\" guide simplified (2016-09-24)",
"translation": "## 简化了“生命周期钩子”章(2016-09-24)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/change-log.md"
},
{
"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/content-3/guide/change-log.md"
},
{
"original": "<h1 class=\"no-toc\">Cheat Sheet</h1",
"translation": "速查表",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/cheatsheet.md"
},
{
"original": "# Component Interaction",
"translation": "# 组件之间的交互",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "This cookbook contains recipes for common component communication scenarios\nin which two or more components share information.",
"translation": "本烹饪宝典包含了常见的组件通讯场景,也就是让两个或多个组件之间共享信息的方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "For an in-depth look at each fundamental concepts in component communication, we can find detailed description and\nsamples in the [Component Communication]() document.",
"translation": "要深入了解组件通讯的各个基本概念,在[组件通讯]()文档中可以找到详细的描述和例子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "# Contents",
"translation": "# 目录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "* [Parent and children communicate via a service](guide/component-interaction#bidirectional-service)",
"translation": "[通过服务进行父子通讯](guide/component-interaction#bidirectional-service)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "**See the <live-example name=\"component-interaction\"></live-example>**.",
"translation": "**参见<live-example name=\"cb-component-interaction\"></live-example>**。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "## Pass data from parent to child with input binding",
"translation": "## 通过输入型绑定把数据从父组件传到子组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "The second `@Input` aliases the child component property name `masterName` as `'master'`.",
"translation": "第二个`@Input`为子组件的属性名`masterName`指定一个别名`master`(译者注:不推荐为起别名,请参见风格指南).",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "The `HeroParentComponent` nests the child `HeroChildComponent` inside an `*ngFor` repeater, \nbinding its `master` string property to the child's `master` alias, and each iteration's `hero` instance to the child's `hero` property.",
"translation": "父组件`HeroParentComponent`把子组件的`HeroChildComponent`放到`*ngFor`循环器中,把自己的`master`字符串属性绑定到子组件的`master`别名上,并把每个循环的`hero`实例绑定到子组件的`hero`属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "The running application displays three heroes:",
"translation": "运行应用程序会显示三个英雄:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "E2E test that all children were instantiated and displayed as expected:",
"translation": "端到端测试,用于确保所有的子组件都像所期待的那样被初始化并显示出来。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "## Intercept input property changes with a setter",
"translation": "## 通过setter截听输入属性值的变化",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "Use an input property setter to intercept and act upon a value from the parent.",
"translation": "使用一个输入属性的setter以拦截父组件中值的变化并采取行动。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "Here's the `NameParentComponent` demonstrating name variations including a name with all spaces:",
"translation": "下面的`NameParentComponent`展示了各种名字的处理方式,包括一个全是空格的名字。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "E2E tests of input property setter with empty and non-empty names:",
"translation": "端到端测试输入属性的setter分别使用空名字和非空名字。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "## Intercept input property changes with *ngOnChanges()*",
"translation": "## 通过*ngOnChanges()*来截听输入属性值的变化",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "You may prefer this approach to the property setter when watching multiple, interacting input properties.",
"translation": "当需要监视多个、交互式输入属性的时候本方法比用属性的setter更合适。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "Learn about `ngOnChanges()` in the [LifeCycle Hooks](guide/lifecycle-hooks) chapter.",
"translation": "学习关于`ngOnChanges()`的更多知识,参见[生命周期钩子](guide/lifecycle-hooks)一章。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "Here's the output of a button-pushing sequence:",
"translation": "下面是点击按钮的结果。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "## Parent listens for child event",
"translation": "## 父组件监听子组件的事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "Clicking a button triggers emission of a `true` or `false` ,the boolean *payload*.",
"translation": "点击按钮会触发`true`或`false`(布尔型*有效载荷*)的事件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "The framework passes the event argument &mdash; represented by `$event` &mdash; to the handler method, \nand the method processes it:",
"translation": "框架(Angular)把事件参数(用`$event`表示)传给事件处理方法,这个方法会处理:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "Test that clicking the *Agree* and *Disagree* buttons update the appropriate counters:",
"translation": "测试确保点击*Agree*和*Disagree*按钮时,计数器被正确更新。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "## Parent interacts with child via *local variable*",
"translation": "## 父组件与子组件通过*本地变量*互动",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "{@a countdown-timer-example} \nThe following is a child `CountdownTimerComponent` that repeatedly counts down to zero and launches a rocket. It has `start` and `stop` methods that control the clock and it displays a countdown status message in its own template.",
"translation": "子组件`CountdownTimerComponent`进行倒计时,归零时发射一个导弹。`start`和`stop`方法负责控制时钟并在模板里显示倒计时的状态信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "The `CountdownLocalVarParentComponent` that hosts the timer componentis as follows:",
"translation": "让我们来看看计时器组件的宿主组件`CountdownLocalVarParentComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "Here we see the parent and child working together.",
"translation": "下面是父组件和子组件一起工作时的效果。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "## Parent calls an _@ViewChild()_",
"translation": "## 父组件调用*@ViewChild()*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "Here is the parent, `CountdownViewChildParentComponent`:",
"translation": "下面是父组件`CountdownViewChildParentComponent`:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "It takes a bit more work to get the child view into the parent component *class*.",
"translation": "把子组件的视图插入到父组件类需要做一点额外的工作。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "First, you have to import references to the `ViewChild` decorator and the `AfterViewInit` lifecycle hook.",
"translation": "首先,你要使用`ViewChild`装饰器导入这个引用,并挂上`AfterViewInit`生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "These methods access the injected timer component directly.",
"translation": "这些方法可以直接访问被注入的计时器组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "测试一下!",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "## Parent and children communicate via a service",
"translation": "## 父组件和子组件通过服务来通讯",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "A parent component and its children share a service whose interface enables bi-directional communication *within the family*.",
"translation": "父组件和它的子组件共享同一个服务,利用该服务*在家庭内部*实现双向通讯。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "This `MissionService` connects the `MissionControlComponent` to multiple `AstronautComponent` children.",
"translation": "这个`MissionService`把`MissionControlComponent`和多个`AstronautComponent`子组件连接起来。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"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/content-3/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-interaction.md"
},
{
"original": "# Component Styles",
"translation": "# 组件样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "Additionally, Angular can bundle *component styles*\nwith components, enabling a more modular design than regular stylesheets.",
"translation": "另外Angular 还能把*组件样式*捆绑在我们的组件上,以实现比标准样式表更加模块化的设计。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "This page describes how to load and apply these component styles.",
"translation": "在本章中,我们将学到如何加载和使用这些*组件样式*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "You can run the <live-example></live-example> in Stackblitz and download the code from there.",
"translation": "你可以在Plunker上运行本章这些代码的<live-example></live-example>并下载这些代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "## Using component styles",
"translation": "## 使用组件样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "## Style scope",
"translation": "## 范围化的样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "The styles specified in `@Component` metadata _apply only within the template of that component_.",
"translation": "在 `@Component` 的元数据中指定的样式只会对该组件的模板生效。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "This scoping restriction is a ***styling modularity feature***.",
"translation": "这种范围限制就是所谓的***样式模块化***特性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "* Changes to styles elsewhere in the application don't affect the component's styles.",
"translation": "我们组件的样式*不会*因为别的地方修改了样式而被意外改变。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "## Special selectors",
"translation": "## 特殊的选择器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "### :host",
"translation": "### :host 选择器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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": "这是我们能以宿主元素为目标的*唯一*方式。除此之外,我们将没办法指定它,\n因为宿主不是组件自身模板的一部分而是父组件模板的一部分。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "### :host-context",
"translation": "### :host-context 选择器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "### (deprecated) `/deep/`, `>>>`, and `::ng-deep`",
"translation": "### 已废弃 `/deep/`、`>>>`和`::ng-deep`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "Component styles normally apply only to the HTML in the component's own template.",
"translation": "组件样式通常只会作用于组件自身的 HTML 上。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "The `/deep/` combinator also has the aliases `>>>`, and `::ng-deep`.",
"translation": "`/deep/` 组合器还有两个别名:`>>>`和`::ng-deep`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "## Loading component styles",
"translation": "## 把样式加载进组件中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "There are several ways to add styles to a component:",
"translation": "有几种方式把样式加入组件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "* By setting `styles` or `styleUrls` metadata.",
"translation": "设置`styles`或`styleUrls`元数据",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "* Inline in the template HTML.",
"translation": "内联在模板的 HTML 中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "* With CSS imports.",
"translation": "通过 CSS 文件导入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "The scoping rules outlined earlier apply to each of these loading patterns.",
"translation": "上述作用域规则对所有这些加载模式都适用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "### Styles in component metadata",
"translation": "### 元数据中的样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "You can add a `styles` array property to the `@Component` decorator.",
"translation": "我们可以给`@Component`装饰器添加一个`styles`数组型属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "Each string in the array defines some CSS for this component.",
"translation": "这个数组中的每一个字符串(通常也只有一个)定义一份 CSS。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "### Style files in component metadata",
"translation": "### 组件元数据中的样式文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "### Template inline styles",
"translation": "### 模板内联样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "You can also write `<link>` tags into the component's HTML template.",
"translation": "我们也可以在组件的 HTML 模板中写`<link>`标签。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "### CSS @imports",
"translation": "### CSS @imports 语法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "## View encapsulation",
"translation": "## 控制视图的封装模式:原生 (Native)、仿真 (Emulated) 和无 (None)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "## Inspecting generated CSS",
"translation": "## 附录 1查看仿真 (Emulated) 模式下生成的 CSS",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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 元素都被加上了一些额外的属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"original": "There are two kinds of generated attributes:",
"translation": "我们看到了两种被生成的属性:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"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/content-3/guide/component-styles.md"
},
{
"original": "# Dependency Injection",
"translation": "# 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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依赖注入的许多特性。\n{@a toc}",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Application-wide dependencies",
"translation": "## 应用程序全局依赖",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Register providers for dependencies used throughout the application in the root application component, `AppComponent`.",
"translation": "在应用程序根组件`AppComponent`中注册那些被应用程序全局使用的依赖提供商。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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#injector-providers)一章可以学到关于提供商的更多知识。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## External module configuration",
"translation": "## 外部模块配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Generally, register providers in the `NgModule` rather than in the root application component.",
"translation": "我们通常会在`NgModule`中注册提供商,而不是在应用程序根组件中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## _@Injectable()_ and nested service dependencies",
"translation": "## *@Injectable*和嵌套服务依赖",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The following example shows injecting both the `LoggerService` and the `UserContext` in the `AppComponent`.",
"translation": "在下列例子中,我们往`AppComponent`里注入的`LoggerService`和`UserContext`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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 justuse `new` to instantiateone .",
"translation": "当Angular新建`AppComponent`时,依赖注入框架先创建一个`LoggerService`的实例,然后创建`UserContextService`实例。\n`UserContextService`需要框架已经创建好的`LoggerService`实例和尚未创建的`UserService`实例。\n`UserService`没有其它依赖,所以依赖注入框架可以直接`new`一个实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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`) and the framework does the rest.",
"translation": "依赖注入最帅的地方在于,`AppComponent`的作者不需要在乎这一切。作者只是在(`LoggerService`和`UserContextService`的)构造函数里面简单的声明一下,框架就完成了剩下的工作。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Once all the dependencies are in place, the `AppComponent` displays the user information:",
"translation": "一旦所有依赖都准备好了,`AppComponent`就会显示用户信息:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### *@Injectable()*",
"translation": "### *@Injectable()* 注解",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Notice the `@Injectable()`decorator on the `UserContextService` class.",
"translation": "注意在`UserContextService`类里面的`@Injectable()`装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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 of consistency and to avoid future pain.",
"translation": "但是在给它添加依赖的那一瞬间,该服务就会停止工作,要想修复它,就必须要添加`@Injectable()`。\n为了保持一致性和防止将来的麻烦推荐从一开始就加上`@Injectable()`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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&mdash;*any* decorator&mdash;is sufficient to identify dependency types.",
"translation": "`AppComponent`类有两个依赖,但它没有`@Injectable()`。\n它不需要`@Injectable()`,这是因为组件类有`@Component`装饰器。\n在用TypeScript的Angular应用里有一个*单独的*装饰器 &mdash; *任何*装饰器 &mdash; 来标识依赖的类型就够了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Limit service scope to a component subtree",
"translation": "## 把服务作用域限制到一个组件支树",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### Take a break!",
"translation": "### 休息一下!",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Multiple service instances (sandboxing)",
"translation": "## 多个服务实例(sandboxing)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Sometimes you want multiple instances of a service at *the same level of the component hierarchy*.",
"translation": "在*同一个级别的组件树*里,有时需要一个服务的多个实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Imagine a `HeroBiosComponent` that presents three instances of the `HeroBioComponent`.",
"translation": "想象一下,一个`HeroBiosComponent`组件显示三个`HeroBioComponent`的实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Qualify dependency lookup with _@Optional()_ and `@Host()`",
"translation": "## 使用*@Optional()*和`@Host()`装饰器来限定依赖查找方式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "As you now know, dependencies can be registered at any level in the component hierarchy.",
"translation": "我们知道,依赖可以被注入到任何组件级别。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The `@Host` decorator stops the upward search at the *host component*.",
"translation": "`@Host`装饰器将把往上搜索的行为截止在*宿主组件*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### Demonstration",
"translation": "### 示范",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Focus on the template:",
"translation": "注意看模板:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Here's the `HeroContactComponent` which demonstrates the qualifying decorators:",
"translation": "下面的`HeroContactComponent`,示范了限定型装饰器(@Optional和@Host)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Focus on the constructor parameters:",
"translation": "注意看构造函数的参数:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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 in the component tree happens to have it.",
"translation": "`@Host()`函数是`heroCache`属性的装饰器,确保从其父组件`HeroBioComponent`得到一个缓存服务。如果该父组件不存在这个服务Angular就会抛出错误即使组件树里的再上级有某个组件拥有这个服务Angular也会抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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`的装饰器,我们知道在应用程序中,只有一个`LoggerService`实例,也就是在`AppComponent`级提供的服务。\n该宿主`HeroBioComponent`没有自己的`LoggerService`提供商。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Here's the `HeroBiosAndContactsComponent` in action.",
"translation": "下面是`HeroBiosAndContactsComponent`的执行结果:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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)`\n{@a component-element}",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Inject the component's DOM element",
"translation": "## 注入组件的DOM元素",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Define dependencies with providers",
"translation": "## 使用提供商来定义依赖",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "This section demonstrates how to write providers that deliver dependent services.",
"translation": "在这个部分,我们将演示如何编写提供商来提供被依赖的服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Get a service from a dependency injector by giving it a ***token***.",
"translation": "我们给依赖注入器提供***令牌***来获取服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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&mdash;unless the request was [optional](guide/dependency-injection-in-action#optional).",
"translation": "如果注入器无法根据令牌在自己内部找到对应的提供商,它便将请求移交给它的父级注入器,这个过程不断重复,直到没有更多注入器为止。\n如果没找到注入器就抛出一个错误...除非这个请求是[可选的](guide/dependency-injection-in-action#optional)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### Defining providers",
"translation": "### 定义提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The code behind it gives you plenty to think about.",
"translation": "这段代码的背后有很多值得深入思考的地方。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "#### The *provide* object literal",
"translation": "#### *provide*对象",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "#### useValue &mdash; the *value provider*",
"translation": "#### useValue - *值-提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The other providers create their values *lazily* when they're needed for injection.",
"translation": "其它提供商只在需要注入它们的时候才创建并*惰性加载*它们的值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "#### useClass &mdash; the *class provider*",
"translation": "#### useClass - *类-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The `useClass` provider creates and returns new instance of the specified class.",
"translation": "`userClass`提供商创建并返回一个指定类的新实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Here are two examples in the `HeroOfTheMonthComponent`:",
"translation": "请看下面`HeroOfTheMonthComponent`里的两个例子:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The `DateLoggerService` inherits from `LoggerService`; it appends the current date/time to each message:",
"translation": "`DateLoggerService`从`LoggerService`继承;它把当前的日期/时间附加到每条信息上。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "#### _useExisting_&mdash;the *alias provider*",
"translation": "#### useExisting - *别名-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Now put it to use in a simplified version of the `HeroOfTheMonthComponent`.",
"translation": "现在,在一个简化版的`HeroOfTheMonthComponent`中使用它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Behind the scenes,Angular actually sets the `logger` parameter to the full service registered under the `LoggingService` token \nwhich 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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The following image, which displays the logging date, confirms the point:",
"translation": "在下面的图片中,显示了日志日期,可以确认这一点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "#### _useFactory_&mdash; the *factory provider*",
"translation": "#### useFactory - *工厂-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The `useFactory` provider creates a dependency object by calling a factory function\nas in this example.",
"translation": "`useFactory` 提供商通过调用工厂函数来新建一个依赖对象,如下例所示。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "That returned function takes a winning `Hero` and a `HeroService` as arguments.",
"translation": "这个返回的函数需要一个`Hero`和一个`HeroService`参数。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Provider token alternatives: the *class-interface* and *InjectionToken*",
"translation": "## 备选提供商令牌:*类-接口*和*InjectionToken*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Angular dependency injection is easiest when the provider *token* is a class\nthat is also the type of the returned dependency object , orwhat you usually call the *service*.",
"translation": "Angular依赖注入当*令牌*是类的时候是最简单的,该类同时也是返回的依赖对象的类型(通常直接称之为*服务*)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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": "但令牌不一定都是类,就算它是一个类,它也不一定都返回类型相同的对象。这是下一节的主题。\n{@a class-interface}",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### class-interface",
"translation": "### 类-接口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The `MinimalLogger` is an abstract class.",
"translation": "该`MinimalLogger`是一个抽象类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "You usually inherit from an abstract class.\nBut *no class* in this application inherits from `MinimalLogger`.",
"translation": "我们通常从一个抽象类继承。但这个应用中并没有类会继承`MinimalLogger`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "#### Why *MinimalLogger* is a class and not a TypeScript interface",
"translation": "#### 为什么*MinimalLogger*是一个类而不是一个TypeScript接口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### _InjectionToken_",
"translation": "### _InjectionToken_ 值",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "You created the `TITLE` token like this:",
"translation": "这样创建`TITLE`令牌:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Inject into a derived class",
"translation": "## 注入到派生类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "In this contrived example, `SortedHeroesComponent` inherits from `HeroesBaseComponent` \nto display a *sorted* list of heroes.",
"translation": "在这个刻意生成的例子里,`SortedHeroesComponent`继承自`HeroesBaseComponent`,显示一个*被排序*的英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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这就是为什么我们要在`ngOnInit`里面调用`HeroService`,而不是在构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Overriding the base class's `afterGetHeroes()` method solves the problem.",
"translation": "覆盖基类的`afterGetHeroes()`方法可以解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "These complications argue for *avoiding component inheritance*.",
"translation": "分析上面的这些复杂性是为了强调*避免使用组件继承*这一点。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Find a parent component by injection",
"translation": "## 通过注入来找到一个父组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "This section describes some techniques for doing that.",
"translation": "本章节描述了这项技术。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### Find a parent component of known type",
"translation": "### 找到已知类型的父组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "You use standard class injection to acquire a parent component whose type you know.",
"translation": "我们使用标准的类注入来获取已知类型的父组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "In the following example, the parent `AlexComponent` has several children including a `CathyComponent`:",
"translation": "在下面的例子中,父组件`AlexComponent`有几个子组件,包括`CathyComponent`:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### Cannot find a parent by its base class",
"translation": "### 无法通过它的基类找到一个父级",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "What if you *don't* know the concrete parent component class?",
"translation": "如果*不*知道具体的父组件类名怎么办?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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]{#alex},我们看到`Alex`组件*扩展*(*派生*)自一个叫`Base`的类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### Find a parent by its class-interface",
"translation": "### 通过类-接口找到父组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Write an [*alias provider*](guide/dependency-injection-in-action#useexisting)&mdash;a `provide` object literal with a `useExisting`\ndefinition&mdash;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`函数 &mdash;\n它新建一个*备选的*方式来注入同一个组件实例,并把这个提供商添加到`AlexComponent`的`@Component`元数据里的`providers`数组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Alex* and family in action:",
"translation": "下面是*Alex*和其家庭的运行结果:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### Find the parent in a tree of parentswith _@SkipSelf()_",
"translation": "### 通过父级树找到父组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Imagine one branch of a component hierarchy: *Alice* -> *Barry* -> *Carol*. \nBoth *Alice* and *Barry* implement the `Parent` *class-interface*.",
"translation": "想象组件树中的一个分支为:*Alice* -> *Barry* -> *Carol*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Barry*:",
"translation": "下面是*Barry*的代码:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "For now, focus on *Barry*'s constructor:",
"translation": "眼下,请注意*Barry*的构造函数:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "It's identical to *Carol*'s constructor except for the additional `@SkipSelf` decorator.",
"translation": "除额外添加了一个的`@SkipSelf`外,它和*Carol*的构造函数一样。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "`@SkipSelf` is essential for two reasons:",
"translation": "添加`@SkipSelf`主要是出于两个原因:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "2. Angular throws a cyclic dependency error if you omit the `@SkipSelf` decorator.",
"translation": "如果没写`@SkipSelf`装饰器的话Angular就会抛出一个循环依赖错误。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "`Cannot instantiate cyclic dependency! (BethComponent -> Parent -> BethComponent)`",
"translation": "`不能创建循环依赖实例!(BethComponent -> Parent -> BethComponent)`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Alice*, *Barry* and family in action:",
"translation": "这里是*Alice**Barry*和该家庭的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### The *Parent* class-interface",
"translation": "### *Parent*类-接口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The example defines a `Parent` *class-interface*.",
"translation": "我们的例子定义了一个`Parent`*类-接口*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### A _provideParent()_ helper function",
"translation": "### *provideParent()*助手函数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "You can extract that logic into a helper function like this:",
"translation": "可以像这样把该逻辑抽取到一个助手函数里:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Now you can add a simpler, more meaningful parent provider to your components:",
"translation": "现在就可以为组件添加一个更简单、直观的父级提供商了:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "And here's how you could use it with a different parent type:",
"translation": "下面的代码演示了如何使它添加一个不同类型的父级:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "## Break circularities with a forward class reference (*forwardRef*)",
"translation": "## 使用一个前向引用(*forwardRef*)来打破循环",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The Angular `forwardRef()` function creates an *indirect* reference that Angular can resolve later.",
"translation": "Angular的`forwardRef()`函数建立一个*间接地*引用Angular可以随后解析。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "The *Parent Finder* sample is full of circular class references that are impossible to break.",
"translation": "*Parent Finder*是一个充满了无法解决的循环引用的例子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"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/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "Break the circularity with `forwardRef`:",
"translation": "我们使用`forwardRef`来打破这种循环:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection-in-action.md"
},
{
"original": "### _@Component_ providers",
"translation": "### 在组件中注册提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "Here's a revised `HeroesComponent` that registers the `HeroService` in its `providers` array.",
"translation": "下面是修改过的`HerosComponent`,把`HeroService`注册到了它的`providers`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "{@a testing-the-component}",
"translation": "## Testing the component\n## 测试组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "Learn more in the [Testing](guide/testing) guide.",
"translation": "要学习更多知识,参见[测试](guide/testing)一章。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "## When the service needs a service",
"translation": "## 当服务需要别的服务时",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "The `HeroService` is very simple. It doesn't have any dependencies of its own.",
"translation": "这个`HeroService`非常简单。它本身不需要任何依赖。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "## Providers",
"translation": "## 服务提供商们",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "But it's not the only way.",
"translation": "但它不是唯一的途径。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "### The _provide_ object literal",
"translation": "### *provide* 对象字面量",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "### Alternative class providers",
"translation": "### 备选的类提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "### Class provider with dependencies",
"translation": "### 带依赖的类提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "Configure it like `BetterLogger`.",
"translation": "就像之前在`BetterLogger`中那样配置它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "### Aliased class providers",
"translation": "### 别名类提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "The solution: alias with the `useExisting` option.",
"translation": "解决方案:使用`useExisting`选项指定别名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "### Value providers",
"translation": "### 值提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "### Factory providers",
"translation": "### 工厂提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "Suppose also that the injectable service has no independent access to the source of this information.",
"translation": "还假设这个可注入的服务没法通过独立的源访问此信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "This situation calls for a **factory provider**.",
"translation": "这种情况下,请调用**工厂提供商**。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "Instead, the `HeroService` constructor takes a boolean flag to control display of secret heroes.",
"translation": "让`HeroService`的构造函数带上一个布尔型的标志,来控制是否显示隐藏的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "A factory provider needs a factory function:",
"translation": "工厂提供商需要一个工厂方法:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "Although the `HeroService` has no access to the `UserService`, the factory function does.",
"translation": "虽然`HeroService`不能访问`UserService`,但是工厂方法可以。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "## Dependency injection tokens",
"translation": "## 依赖注入令牌",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "This is especially convenient when you consider that most dependency values are provided by classes.",
"translation": "这是一个特殊的规约,因为大多数依赖值都是以类的形式提供的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "### Non-class dependencies",
"translation": "### 非类依赖",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "### TypeScript interfaces aren't valid tokens",
"translation": "### TypeScript 接口不是一个有效的令牌",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "The `HERO_DI_CONFIG` constant conforms to the `AppConfig` interface. \nUnfortunately, you cannot use a TypeScript interface as a token:",
"translation": "`CONFIG`常量有一个接口:`AppConfig`。不幸的是,不能把 TypeScript 接口用作令牌:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "### _InjectionToken_",
"translation": "### _InjectionToken_ 值",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "{@a optional}",
"translation": "## Optional dependencies\n## 可选依赖",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "## Appendix: Working with injectors directly",
"translation": "## 附录:直接使用注入器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "Developers rarely work directly with an injector, but\nhere's an `InjectorComponent` that does.",
"translation": "这里的`InjectorComponent`直接使用了注入器,\n但我们很少直接使用它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "An `Injector` is itself an injectable service.",
"translation": "`Injector`本身是可注入的服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "Framework developers may take this approach when they\nmust acquire services generically and dynamically.",
"translation": "框架开发人员必须采用通用的或者动态的方式获取服务时,可能采用这个方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"original": "## Appendix: one class per file",
"translation": "## 附录:为什么建议每个文件只放一个类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"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/content-3/guide/dependency-injection.md"
},
{
"original": "# Deployment",
"translation": "# 部署",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "This page describes techniques for deploying your Angular application to a remote server.",
"translation": "本章会描述在远程服务器上部署Angular应用的工具与技术。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "## Simplest deployment possible",
"translation": "## 最简化的部署方式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "For the simplest deployment, build for development and copy the output directory to a web server.",
"translation": "最简化的部署方式就是为开发环境构建,并把其输出复制到 Web 服务器上。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "1. Start with the development build",
"translation": "使用开发环境进行构建",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "2. Copy _everything_ within the output folder (`dist/` by default) to a folder on the server.",
"translation": "把输出目录(默认为`dist/`)下的*每个文件*都复制到到服务器上的某个目录下。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "* [Production mode](#enable-prod-mode): deploys the production environment which enables _production mode_.",
"translation": "[生产模式](#enable-prod-mode):启用生产模式部署到生产环境。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "* Bundling: concatenates your many application and library files into a few bundles.",
"translation": "打捆Bundle把这些模块串接成一个单独的捆文件bundle。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "* Minification: removes excess whitespace, comments, and optional tokens.",
"translation": "最小化移除不必要的空格、注释和可选令牌Token。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "* Uglification: rewrites code to use short, cryptic variable and function names.",
"translation": "混淆:使用短的、无意义的变量名和函数名来重写代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "* Dead code elimination: removes unreferenced modules and much unused code.",
"translation": "消除死代码:移除未引用过的模块和未使用过的代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "The remaining [copy deployment steps](#copy-files) are the same as before.",
"translation": "剩下的 [拷贝部署步骤](#copy-files) 和以前的方式是一样的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "### Enable production mode",
"translation": "### 启用生产模式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "### Lazy loading",
"translation": "### 惰性加载",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "#### Don't eagerly import something from a lazy loaded module",
"translation": "#### 不要立即导入惰性加载模块中的任何东西",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "## Server configuration",
"translation": "## 服务端配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "### Routed apps must fallback to `index.html`",
"translation": "### 带路由的应用必须以`index.html`作为后备页面",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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 &mdash;\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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "#### Fallback configuration examples",
"translation": "#### 后备页面配置范例",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "#### Development servers",
"translation": "#### 开发服务器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "#### Production servers",
"translation": "#### 生产服务器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"original": "* [Apache](https://httpd.apache.org/): add a\n[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html)\nto 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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "### Requesting services from a different server (CORS)",
"translation": "### 请求来自另一个服务器的服务CORS",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"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/content-3/guide/deployment.md"
},
{
"original": "# Displaying Data",
"translation": "# 显示数据",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "The final UI looks like this:",
"translation": "最终的用户界面是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "## Showing component properties with interpolation",
"translation": "## 使用插值表达式显示组件属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "Follow the [quickstart](guide/quickstart) instructions for creating a new project\nnamed <code>displaying-data</code>.",
"translation": "按照[开发环境](guide/setup)的说明,创建一个新项目,名为<code>displaying-data</code>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "When you're done, it should look like this:",
"translation": "修改完之后,它应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "You added two properties to the formerly empty component: `title` and `myHero`.",
"translation": "再把两个属性`title`和`myHero`添加到之前空白的组件中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "The template displays the two component properties using double curly brace\ninterpolation:",
"translation": "修改完的模板会使用双花括号形式的插值表达式来显示这两个模板属性:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "The template is a multi-line string within ECMAScript 2015 backticks (<code>\\`</code>).\nThe backtick (<code>\\`</code>)&mdash;which is *not* the same character as a single\nquote (`'`)&mdash;allows you to compose a string over several lines, which makes the\nHTML more readable.",
"translation": "模板是包在 ECMAScript 2015 反引号 (<code>\\`</code>) 中的一个多行字符串。\n反引号 (<code>\\`</code>) &mdash; 注意,不是单引号 (') &mdash; 允许把一个字符串写在多行上,\n使 HTML 模板更容易阅读。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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`中查找一个`<my-app>`元素,\n然后实例化一个`AppComponent`,并将其渲染到`<my-app>`标签中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "Now run the app. It should display the title and hero name:",
"translation": "运行应用。它应该显示出标题和英雄名:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "The next few sections review some of the coding choices in the app.",
"translation": "回顾一下前面所做的决定,看看还有哪些其它选择。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "## Template inline or template file?",
"translation": "## 内联 (inline) 模板还是模板文件?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "In either style, the template data bindings have the same access to the component's properties.",
"translation": "无论用哪种风格,模板数据绑定在访问组件属性方面都是完全一样的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "## Constructor or variable initialization?",
"translation": "## 使用构造函数还是变量初始化?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "This app uses more terse \"variable assignment\" style simply for brevity.",
"translation": "为了让本应用更加简短,它采用了更简单的“变量赋值”风格。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "## Showing an array property with ***ngFor**",
"translation": "## 使用***ngFor***显示数组属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "Now the heroes appear in an unordered list.",
"translation": "现在,英雄们出现在了一个无序列表中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "## Creating a class for the data",
"translation": "## 为数据创建一个类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "With the following code:",
"translation": "代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "You've defined a class with a constructor and two properties: `id` and `name`.",
"translation": "你定义了一个类,具有一个构造函数和两个属性:`id`和`name`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "It might not look like the class has properties, but it does.\n The declaration of the constructor parameters takes advantage of a TypeScript shortcut.",
"translation": "它可能看上去不像是有属性的类,但它确实有,利用的是 TypeScript 提供的简写形式 —— 用构造函数的参数直接定义属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "Consider the first parameter:",
"translation": "来看第一个参数:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "That brief syntax does a lot:",
"translation": "这个简写语法做了很多:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "* Declares a constructor parameter and its type",
"translation": "声明了一个构造函数参数及其类型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "* Declares a public property of the same name",
"translation": "声明了一个同名的公共属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "* Initializes that property with the corresponding argument when we \"new\" an instance of the class",
"translation": "当我们`new`出该类的一个实例时,把该属性初始化为相应的参数值",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "### Using the Hero class",
"translation": "### 使用 Hero 类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "Our display looks the same, but now we know much better what a hero really is.",
"translation": "从显示上看还是一样,但现在我们知道了更多英雄信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "## Conditional display with NgIf",
"translation": "## 通过 NgIf 进行条件显示",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "Let's change the example to display a message if there are more than three heroes.",
"translation": "让我们来修改这个例子,如果多于三位英雄,显示一条消息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "Now you know how to use:",
"translation": "现在你知道了如何使用:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "* **Interpolation** with double curly braces to display a component property.",
"translation": "带有双花括号的**插值表达式 (interpolation) **来显示一个组件属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "* **ngFor** to display an array of items.",
"translation": "用 **ngFor** 显示数组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"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/content-3/guide/displaying-data.md"
},
{
"original": "* **ngIf** to conditionally display a chunk of HTML based on a boolean expression.",
"translation": "用 **ngIf** 根据一个布尔表达式有条件地显示一段 HTML。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "Here's the final code:",
"translation": "下面是最终的代码:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/displaying-data.md"
},
{
"original": "# Dynamic Component Loader",
"translation": "# 动态组件加载器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "Component templates are not always fixed. An application may need to load new components at runtime.",
"translation": "组件的模板不会永远是固定的。应用可能会需要在运行期间加载一些新的组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "This cookbook shows you how to use `ComponentFactoryResolver` to add components dynamically.",
"translation": "这本烹饪书为你展示如何使用`ComponentFactoryResolver`来动态添加组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "See the <live-example name=\"dynamic-component-loader\"></live-example>\nof the code in this cookbook.",
"translation": "到<live-example name=\"cb-dynamic-component-loader\"></live-example>查看本烹饪书的源码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "## Dynamic component loading",
"translation": "## 动态组件加载",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "The following example shows how to build a dynamic ad banner.",
"translation": "下面的例子展示了如何构建动态广告条。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"original": "Angular comes with its own API for loading components dynamically.",
"translation": "Angular 自带的API就能支持动态加载组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "## The anchor directive",
"translation": "## 指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"original": "## Loading components",
"translation": "## 加载组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"original": "## Resolving components",
"translation": "## 解析组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "Take a closer look at the methods in `ad-banner.component.ts`.",
"translation": "深入看看`ad-banner.component.ts`中的方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"original": "**How _loadComponent()_ chooses an ad**",
"translation": "**`loadComponent()`如何选择广告**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "The `loadComponent()` method chooses an ad using some math.",
"translation": "`loadComponent()`方法使用某种算法选择了一个广告。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"original": "To add the component to the template, you call `createComponent()` on `ViewContainerRef`.",
"translation": "要把这个组件添加到模板中,我们可以调用`ViewContainerRef`的`createComponent()`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"original": "#### Selector references",
"translation": "#### 对选择器的引用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"original": "## The _AdComponent_ interface",
"translation": "## 公共的`AdComponent`接口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"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/content-3/guide/dynamic-component-loader.md"
},
{
"original": "Here are two sample components and the `AdComponent` interface for reference:",
"translation": "下面就是两个范例组件及其`AdComponent`接口:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "## Final ad banner",
"translation": "## 最终的广告栏",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "The final ad banner looks like this:",
"translation": "最终的广告栏是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "See the <live-example name=\"dynamic-component-loader\"></live-example>.",
"translation": "参见<live-example name=\"cb-dynamic-component-loader\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-component-loader.md"
},
{
"original": "# Dynamic Forms",
"translation": "# 动态表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "Building handcrafted forms canbe 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/content-3/guide/dynamic-form.md"
},
{
"original": "It may be more economical to create the forms dynamically, based on metadata that describes the business object model.",
"translation": "基于业务对象模型的元数据,动态创建表单可能会更划算。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"original": "See the <live-example name=\"dynamic-form\"></live-example>.",
"translation": "参见<live-example name=\"dynamic-form\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "## Bootstrap",
"translation": "## 程序启动",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "Start by creating an `NgModule` called `AppModule`.",
"translation": "让我们从创建一个名叫`AppModule`的`NgModule`开始。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "This cookbook uses [reactive forms](guide/reactive-forms).",
"translation": "这个烹饪书使用[响应式表单](guide/reactive-forms)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"original": "Bootstrap the `AppModule` in `main.ts`.",
"translation": "我们在`main.ts`中启动`AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "## Question model",
"translation": "## 问卷问题模型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"original": "The following `QuestionBase` is a fundamental question class.",
"translation": "下面是我们建立的最基础的问卷问题基类,名叫`QuestionBase`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"original": "`DropdownQuestion` presents a list of choices in a select box.",
"translation": "`DropdownQuestion`表示一个带可选项列表的选择框。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"original": "## Question form components",
"translation": "## 问卷表单组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"original": "`DynamicFormComponent` is the entry point and the main container for the form.",
"translation": "`DynamicFormComponent`是表单的主要容器和入口点。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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": "它代表了问卷问题列表,每个问题都被绑定到一个`<df-question>`组件元素。\n`<df-question>`标签匹配到的是组件`DynamicFormQuestionComponent`,该组件的职责是根据各个问卷问题对象的值来动态渲染表单控件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"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`。\n{@a questionnaire-data}",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "## Questionnaire data",
"translation": "## 问卷数据",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"original": "Finally, display an instance of the form in the `AppComponent` shell.",
"translation": "最后,在`AppComponent`里显示出表单。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "## Dynamic Template",
"translation": "## 动态模板",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"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/content-3/guide/dynamic-form.md"
},
{
"original": "The final form looks like this:",
"translation": "完整的表单是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "[Back to top](guide/dynamic-form#top)",
"translation": "[回到顶部](guide/dynamic-form#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/dynamic-form.md"
},
{
"original": "# Form Validation",
"translation": "# 表单验证",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"original": "Improve overall data quality by validating user input for accuracy and completeness.",
"translation": "我们可以通过验证用户输入的准确性和完整性,来增强整体数据质量。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "## Template-driven validation",
"translation": "## 模板驱动验证",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "Note the following:",
"translation": "请注意以下几点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "#### Why check _dirty_ and _touched_?",
"translation": "#### 为何检查**dirty**和**touched**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "## Reactive form validation",
"translation": "## 响应式表单的验证",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "### Validator functions",
"translation": "### 验证器函数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"original": "There are two types of validator functions: sync validators and async validators.",
"translation": "有两种验证器函数:同步验证器和异步验证器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "### Built-in validators",
"translation": "### 内置验证器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "To update the hero form to be a reactive form, you can use some of the same \nbuilt-in validators&mdash;this time, in function form. See below:",
"translation": "要想把这个英雄表单改造成一个响应式表单,我们还是用那些内置验证器,但这次改为用它们的函数形态。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"original": "Note that:",
"translation": "注意",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"original": "* The name control sets up two built-in validators&mdash;`Validators.required` and `Validators.minLength(4)`&mdash;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/content-3/guide/form-validation.md"
},
{
"original": "* As these validators are all sync validators, you pass them in as the second argument.",
"translation": "由于这些验证器都是同步验证器,因此我们要把它们作为第二个参数传进去。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"original": "* Support multiple validators by passing the functions in as an array.",
"translation": "可以通过把这些函数放进一个数组后传进去,可以支持多重验证器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "Key takeaways:",
"translation": "关键改动是:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "## Custom validators",
"translation": "## 自定义验证器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "### Adding to reactive forms",
"translation": "### 添加响应式表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "### Adding to template-driven forms",
"translation": "### 添加到模板驱动表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "The corresponding `ForbiddenValidatorDirective` serves as a wrapper around the `forbiddenNameValidator`.",
"translation": "`ForbiddenValidatorDirective`指令相当于`forbiddenNameValidator`的包装器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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`&mdash;the instance in the form with\nits `forbiddenName` property bound to “bob\". If you were to replace\n`useExisting` with `useClass`, then youd be registering a new class instance, one that\ndoesnt have a `forbiddenName`.",
"translation": "你可能注意到了自定义验证器指令是用`useExisting`而不是`useClass`来实例化的。注册的验证器必须是这个 `ForbiddenValidatorDirective` 实例本身,也就是表单中 `forbiddenName` 属性被绑定到了\"bob\"的那个。如果用`useClass`来代替`useExisting`,就会注册一个新的类实例,而它是没有`forbiddenName`的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"original": "## Control status CSS classes",
"translation": "## 表示控件状态的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"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/content-3/guide/form-validation.md"
},
{
"original": "# Forms",
"translation": "# 表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "* Build an Angular form with a component and template.",
"translation": "用组件和模板构建 Angular 表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* Use `ngModel` to create two-way data bindings for reading and writing input-control values.",
"translation": "用`ngModel`创建双向数据绑定,以读取和写入输入控件的值",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* Track state changes and the validity of form controls.",
"translation": "跟踪状态的变化,并验证表单控件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* Provide visual feedback using special CSS classes that track the state of the controls.",
"translation": "使用特殊的CSS类来跟踪控件的状态并给出视觉反馈",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* Display validation errors to users and enable/disable form controls.",
"translation": "向用户显示验证错误提示,以及启用/禁用表单控件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* Share information across HTML elements using template reference variables.",
"translation": "使用模板引用变量在 HTML 元素之间共享信息",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "You can run the <live-example></live-example> in Stackblitz and download the code from there.",
"translation": "你可以在Plunker中运行<live-example></live-example>,并且从那里下载代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Template-driven forms",
"translation": "## 模板驱动的表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "You can build almost any form with an Angular template&mdash;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 模板,可以构建几乎所有表单 &mdash; 登录表单、联系人表单…… 以及任何的商务表单。\n 可以创造性的摆放各种控件、把它们绑定到数据、指定校验规则、显示校验错误、有条件的禁用或\n 启用特定的控件、触发内置的视觉反馈等等,不胜枚举。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "You'll learn to build a template-driven form that looks like this:",
"translation": "我们将学习构建如下的“模板驱动”表单:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "If you delete the hero name, the form displays a validation error in an attention-grabbing style:",
"translation": "如果删除了英雄的名字,表单就会用醒目的样式把验证错误显示出来。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "You can customize the colors and location of the \"required\" bar with standard CSS.",
"translation": "稍后,会使用标准 CSS 来定制“必填”条的颜色和位置。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "You'll build this form in small steps:",
"translation": "我们将一点点构建出此表单:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Create the `Hero` model class.",
"translation": "创建`Hero`模型类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Create the component that controls the form.",
"translation": "创建控制此表单的组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Create a template with the initial form layout.",
"translation": "创建具有初始表单布局的模板。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Bind data properties to each form control using the `ngModel` two-way data-binding syntax.",
"translation": "使用`ngModel`双向数据绑定语法把数据属性绑定到每个表单输入控件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Add a `name` attribute to each form-input control.",
"translation": "往每个表单输入控件上添加`name`属性 (attribute)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Add custom CSS to provide visual feedback.",
"translation": "添加自定义 CSS 来提供视觉反馈。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Show and hide validation-error messages.",
"translation": "显示和隐藏有效性验证的错误信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Handle form submission with *ngSubmit*.",
"translation": "使用 **ngSubmit** 处理表单提交。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Disable the forms *Submit* button until the form is valid.",
"translation": "禁用此表单的提交按钮,直到表单变为有效。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Setup",
"translation": "## 搭建",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Create a new project named <code>angular-forms</code>:",
"translation": "创建一个名为 <code>angular-forms</code> 的新项目:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Create the Hero model class",
"translation": "## 创建 Hero 模型类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "Using the Angular CLI, generate a new class named `Hero`:",
"translation": "使用 Angular CLI 生成一个名叫`Hero`的新类:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "With this content:",
"translation": "内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "It's an anemic model with few requirements and no behavior. Perfect for the demo.",
"translation": "这是一个少量需求和零行为的贫血模型。对演示来说很完美。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "The TypeScript compiler generates a public field for each `public` constructor parameter and\nautomatically assigns the parameters value to that field when you create heroes.",
"translation": "TypeScript 编译器为每个`public`构造函数参数生成一个公共字段,在创建新的英雄实例时,自动把参数值赋给这些公共字段。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "## Create a form component",
"translation": "## 创建表单组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "Using the Angular CLI, generate a new component named `HeroForm`:",
"translation": "使用 Angular CLI 生成一个名叫 `HeroForm` 的新组件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "With this content:",
"translation": "内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Theres 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/content-3/guide/forms.md"
},
{
"original": "Understanding this component requires only the Angular concepts covered in previous pages.",
"translation": "只需要前面章节中学过的概念,就可以完全理解这个组件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* The code imports the Angular core library and the `Hero` model you just created.",
"translation": "这段代码导入了Angular核心库以及我们刚刚创建的`Hero`模型。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "* The `templateUrl` property points to a separate file for the template HTML.",
"translation": "`moduleId: module.id`属性设置了基地址,用于从相对模块路径加载`templateUrl`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* You defined dummy data for `model` and `powers`, as befits a demo.",
"translation": "`templateUrl`属性指向一个独立的 HTML 模板文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "## Revise *app.module.ts*",
"translation": "## 修改 *app.module.ts*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "Update it with the following:",
"translation": "对它做如下修改:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "There are two changes:",
"translation": "有三处更改",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. You import `FormsModule`.",
"translation": "导入`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. You add the `FormsModule` to the list of `imports` defined in the `@NgModule` decorator. This gives the application\naccess to all of the template-driven forms features, including `ngModel`.",
"translation": "把`FormsModule`添加到`ngModule`装饰器的`imports`列表中,这样应用就能访问模板驱动表单的所有特性,包括`ngModel`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "## Revise *app.component.html*",
"translation": "## 修改 *app.component.ts*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "`AppComponent` is the application's root component. It will host the new `HeroFormComponent`.",
"translation": "`AppComponent`是应用的根组件,`HeroFormComponent`将被放在其中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "## Create an initial HTML form template",
"translation": "## 创建初始 HTML 表单模板",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Create the template file with the following contents:",
"translation": "创建模板文件,内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "You added a *Submit* button at the bottom with some classes on it for styling.",
"translation": "在底部添加个 *Submit* 按钮,它还带一些 CSS 样式类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "*You're not using Angular yet*. There are no bindings or extra directives, just layout.",
"translation": "**我们还没有真正用到Angular**。没有绑定,没有额外的指令,只有布局。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/)。纯粹是装饰。\n我们使用 Bootstrap 来美化表单。嘿,一点样式都没有的表单算个啥!",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Angular forms don't require a style library",
"translation": "Angular 表单不需要任何样式库",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "## Add powers with _*ngFor_",
"translation": "## 用 ***ngFor*** 添加超能力",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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模板输入变量`p`在每个迭代指向不同的超能力,使用双花括号插值表达式语法来显示它的名称。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Two-way data binding with _ngModel_",
"translation": "## 使用 *ngModel* 进行双向数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Running the app right now would be disappointing.",
"translation": "如果立即运行此应用,你将会失望。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "Now you need to display, listen, and extract at the same time.",
"translation": "现在,需要同时进行显示、监听和提取。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "Focus on the binding syntax: `[(ngModel)]=\"...\"`.",
"translation": "聚焦到绑定语法`[(ngModel)]=\"...\"`上。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "### The _NgForm_ directive",
"translation": "### `NgForm`指令What `NgForm` directive?\nYou didn't add an [NgForm](api/forms/NgForm) directive.",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "*Delete* the `{{diagnostic}}` binding at the top as it has served its purpose.",
"translation": "表单顶部的`{{diagnostic}}`绑定已经完成了它的使命,**删除**它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Track control state and validity with _ngModel_",
"translation": "## 通过 **ngModel** 跟踪修改状态与有效性验证",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "State",
"translation": "状态",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Class if true",
"translation": "为真时的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Class if false",
"translation": "为假时的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "The control has been visited.",
"translation": "控件被访问过。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "The control's value has changed.",
"translation": "控件的值变化了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "The control's value is valid.",
"translation": "控件的值有效。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Now run the app and look at the _Name_ input box.\nFollow these steps *precisely*:",
"translation": "现在,运行本应用,并让*姓名*输入框获得焦点。\n然后严格按照下面四个步骤来做",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Look but don't touch.",
"translation": "查看输入框,但别碰它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Click inside the name box, then click outside it.",
"translation": "点击输入框,然后点击输入框外面。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Add slashes to the end of the name.",
"translation": "在名字的末尾添加些斜杠。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Erase the name.",
"translation": "删除名字。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "The actions and effects are as follows:",
"translation": "动作和它对应的效果如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "You should see the following transitions and class names:",
"translation": "我们会看到下列转换及其类名:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "*Delete* the `#spy` template reference variable and the `TODO` as they have served their purpose.",
"translation": "**删除**模板引用变量`#spy`和`TODO`,因为它们已经完成了使命。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Add custom CSS for visual feedback",
"translation": "## 添加用于视觉反馈的自定义 CSS",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "Update the `<head>` of `index.html` to include this style sheet:",
"translation": "更新`index.html`中的`<head>`,以包含这个样式表:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Show and hide validation error messages",
"translation": "## 显示和隐藏验证错误信息",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "When the user deletes the name, the form should look like this:",
"translation": "当用户删除姓名时,应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "To achieve this effect, extend the `<input>` tag with the following:",
"translation": "要达到这个效果,在`<input>`标签中添加:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* A [template reference variable](guide/template-syntax#ref-vars).",
"translation": "[模板引用变量](guide/template-syntax#ref-vars)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "The hero *Alter Ego* is optional so you can leave that be.",
"translation": "英雄的*第二人格*是可选项,所以不用改它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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 *did not restore the pristine state* of the form controls.",
"translation": "使用浏览器工具审查这个元素就会发现,这个 *name* 输入框并不是全新的。\n表单记得我们在点击 *New Hero* 前输入的名字。\n更换了英雄*并不会重置控件的“全新”状态*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Now clicking \"New Hero\" resets both the form and its control flags.",
"translation": "现在点击“New Hero”重设表单和它的控制标记。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Submit the form with _ngSubmit_",
"translation": "## 使用 *ngSubmit* 提交该表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "If you run the application now, you find that the button is enabled&mdash;although\nit doesn't do anything useful yet.",
"translation": "重新运行应用。表单打开时,状态是有效的,按钮是可用的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "For you, it was as simple as this:",
"translation": "有了 Angular它就是这么简单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "1. Define a template reference variable on the (enhanced) form element.",
"translation": "定义模板引用变量放在强化过的form 元素上",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "2. Refer to that variable in a button many lines away.",
"translation": "从很多行之外的按钮上引用这个变量。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Toggle two form regions (extra credit)",
"translation": "## 切换两个表单区域(额外的奖励)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Submitting the form isn't terribly dramatic at the moment.",
"translation": "提交表单还是不够激动人心。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "For a more strikingly visual effect,\nhide the data entry area and display something else.",
"translation": "来实现一些更炫的视觉效果吧。\n 隐藏掉数据输入框,显示一些其它东西。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "When you click the *Edit* button, this block disappears and the editable form reappears.",
"translation": "当点*Edit*按钮时,这个只读块消失了,可编辑的表单重新出现了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"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/content-3/guide/forms.md"
},
{
"original": "* An Angular HTML form template.",
"translation": "Angular HTML 表单模板。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* A form component class with a `@Component` decorator.",
"translation": "带有`@Component`装饰器的表单组件类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* Handling form submission by binding to the `NgForm.ngSubmit` event property.",
"translation": "通过绑定到`NgForm.ngSubmit`事件属性来处理表单提交。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* Template-reference variables such as `#heroForm` and `#name`.",
"translation": "模板引用变量,例如`#heroForm`和`#name`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* `[(ngModel)]` syntax for two-way data binding.",
"translation": "`[(ngModel)]`语法用来实现双向数据绑定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* The use of `name` attributes for validation and form-element change tracking.",
"translation": "`name`属性的用途是有效性验证和对表单元素的变更进行追踪。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* The reference variables `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/content-3/guide/forms.md"
},
{
"original": "* Controlling the *Submit* button's enabled state by binding to `NgForm` validity.",
"translation": "通过绑定到`NgForm`的有效性状态,控制*Submit*按钮的禁用状态。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "* Custom CSS classes that provide visual feedback to users about invalid controls.",
"translation": "定制 CSS 类来给用户提供无效控件的视觉反馈。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "Heres the code for the final version of the application:",
"translation": "下面是该应用最终版本的代码:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/forms.md"
},
{
"original": "# Angular Glossary",
"translation": "# Angular 词汇表",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Ahead-of-time (AOT) compilation",
"translation": "## 预 (ahead-of-time, AoT) 编译",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Annotation",
"translation": "## 注解",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "In practice, a synonym for [Decoration](guide/glossary#decorator).",
"translation": "实际上,是[装饰 (decoration)](guide/glossary#decorator) 的同义词。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Attribute directives",
"translation": "## 属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "For example, you can use the `ngClass` directive to add and remove CSS class names.",
"translation": "例如,`ngClass`指令就是典型的属性型指令。它可以添加或移除 CSS 类名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Learn about them in the [_Attribute Directives_](guide/attribute-directives) guide.",
"translation": "要了解更多信息,请参见[_属性型指令_](guide/attribute-directives)页。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Barrel",
"translation": "## 封装桶",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "For example, imagine three ES2015 modules in a `heroes` folder:",
"translation": "例如,设想在`heroes`目录下有三个 ES2015 模块:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Without a barrel, a consumer needs three import statements:",
"translation": "如果没有封装桶,消费者需要三条导入语句:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Now a consumer can import what it needs from the barrel.",
"translation": "现在,消费者就就可以从这个封装桶中导入它需要的东西了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "You can often achieve the same result using [NgModules](guide/glossary#ngmodule) instead.",
"translation": "注意,你可以利用 [Angular 模块](guide/glossary#ngmodule)达到同样的目的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Binding",
"translation": "## 绑定 (binding)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Sometimes refers to a [dependency-injection](guide/glossary#dependency-injection) binding\nbetween a \"token\"&mdash;also referred to as a \"key\"&mdash;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/content-3/guide/glossary.md"
},
{
"original": "## Bootstrap",
"translation": "## 启动/引导 (bootstrap)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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": "通过应用程序根 Angular 模块来启动 Angular 应用程序。\n 启动过程标识应用的顶级“根”[组件 (component)](guide/glossary#component),也就是应用加载的第一个组件。\n 更多信息,见[设置](guide/setup)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## camelCase",
"translation": "## 驼峰式命名法 (camelCase)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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)。\n在文档中提到“驼峰式命名法 (camelCase) ”的时候,我们所指的都是小驼峰命名法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Component",
"translation": "## 组件 (component)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "An Angular class responsible for exposing data to a [view](guide/glossary#view) and handling most of the views display and user-interaction logic.",
"translation": "组件是一个 Angular 类,用于把数据展示到[视图 (view)](guide/glossary#view),并处理几乎所有的视图显示和交互逻辑。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## dash-case",
"translation": "## 中线命名法 (dash-case)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Data binding",
"translation": "## 数据绑定 (data binding)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "* [Interpolation](guide/template-syntax#interpolation)",
"translation": "[插值表达式 (interpolation)](guide/template-syntax#interpolation)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* [Property binding](guide/template-syntax#property-binding)",
"translation": "[property 绑定 (property binding)](guide/template-syntax#property-binding)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* [Event binding](guide/template-syntax#event-binding)",
"translation": "[事件绑定 (event binding)](guide/template-syntax#event-binding)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* [Attribute binding](guide/template-syntax#attribute-binding)",
"translation": "[attribute 绑定 (attribute binding)](guide/template-syntax#attribute-binding)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* [Class binding](guide/template-syntax#class-binding)",
"translation": "[CSS 类绑定 (class binding)](guide/template-syntax#class-binding)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* [Style binding](guide/template-syntax#style-binding)",
"translation": "[样式绑定 (style binding)](guide/template-syntax#style-binding)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Decorator | decoration",
"translation": "## 装饰器decorator | decoration",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "A *function* that adds metadata to a class, its members (properties, methods) and function arguments.",
"translation": "装饰器是一个**函数**,它将元数据添加到类、类成员(属性、方法)和函数参数。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "To apply a decorator, position it immediately above or to the left of the item it decorates.",
"translation": "要想应用装饰器,把它放到被装饰对象的上面或左边。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Always include parentheses `()` when applying a decorator.",
"translation": "永远别忘了在装饰器后面加括号`()`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Dependency injection",
"translation": "## 依赖注入dependency injection",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Read more in the [Dependency Injection](guide/dependency-injection) page.",
"translation": "更多信息,参见[依赖注入 (dependency injection)](guide/dependency-injection)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Directive",
"translation": "## 指令 (directive)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "A directive is usually associated with an HTML element or attribute.\nThis element or attribute is often referred to as the directive itself.\nWhen 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": "指令几乎总与 HTML 元素或属性 (attribute) 相关。\n我们通常把这些关联到的 HTML 元素或者属性 (attribute) 当做指令本身。\n当 Angular 在 HTML 模板中遇到一个指令的时候,\n它会创建匹配的指令类的实例并把浏览器中这部分 DOM 的控制权交给它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Directives fall into one of the following categories:",
"translation": "指令分为三类:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## ECMAScript",
"translation": "## ECMAScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Angular developers can write in ES5 directly.",
"translation": "Angular 的开发人员也可以选择直接使用 ES5 编程。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## ES2015",
"translation": "## ES2015 语言",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.",
"translation": "[ECMAScript](guide/glossary#ecmascript) 2015 的缩写。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## ES5",
"translation": "## ES5 语言",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## ES6",
"translation": "## ES6 语言",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.",
"translation": "[ECMAScript](guide/glossary#ecmascript) 2015 的简写。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Injector",
"translation": "## 注入器 (injector)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Input",
"translation": "## 输入属性 (input)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Interpolation",
"translation": "## 插值表达式 (interpolation)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Just-in-time (JIT) compilation",
"translation": "## 即时 (just-in-time, JiT) 编译",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## kebab-case",
"translation": "## 烤串命名法 (kebab-case)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "See [dash-case](guide/glossary#dash-case).",
"translation": "见[中线命名法 (dash-case)](guide/glossary#dash-case)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Lifecycle hooks",
"translation": "## 生命周期钩子 (lifecycle hook)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Angular calls these hook methods in the following order:",
"translation": "Angular 会按以下顺序调用钩子方法:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "* `ngOnInit`: after the first `ngOnChanges`.",
"translation": "`ngOnInit` - 在第一次`ngOnChanges`完成后调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* `ngDoCheck`: developer's custom change detection.",
"translation": "`ngDoCheck` - 开发者自定义变更检测。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* `ngAfterContentInit`: after component content initialized.",
"translation": "`ngAfterContentInit` - 在组件内容初始化后调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* `ngAfterContentChecked`: after every check of component content.",
"translation": "`ngAfterContentChecked` - 在组件内容每次检查后调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* `ngAfterViewInit`: after a component's views are initialized.",
"translation": "`ngAfterViewInit` - 在组件视图初始化后调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* `ngAfterViewChecked`: after every check of a component's views.",
"translation": "`ngAfterViewChecked` - 在组件视图每次检查后调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* `ngOnDestroy`: just before the directive is destroyed.",
"translation": "`ngOnDestroy` - 在指令销毁前调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Read more in the [Lifecycle Hooks](guide/lifecycle-hooks) page.",
"translation": "更多信息,见[生命周期钩子 (lifecycle hook)](guide/lifecycle-hooks)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Module",
"translation": "## 模块 (module)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Angular has the following types of modules:",
"translation": "Angular有下列模块类型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* [NgModules](guide/glossary#ngmodule).\nFor details and examples, see the [NgModules](guide/ngmodules) page.",
"translation": "[Angular 模块](guide/glossary#ngmodule),见[Angular 模块](guide/ngmodule)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* ES2015 modules, as described in this section.",
"translation": "ES2015模块如本节所述。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "A cohesive block of code dedicated to a single purpose.",
"translation": "模块是一个内聚的代码块,具有单一用途。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Angular apps are modular.",
"translation": "Angular 应用程序是模块化的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Observable",
"translation": "## Observable 对象",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "To use observables, Angular uses a third-party library called Reactive Extensions (RxJS).\nObservables are a proposed feature for ES 2016, the next version of JavaScript.",
"translation": "为了使用`Observable` Angular 采用了名为 Reactive Extensions (RxJS) 的第三方包。\n在下个版本的 JavaScript - ES 2016 中,`Observable`是建议的特性之一。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Output",
"translation": "## 输出属性 (output)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## PascalCase",
"translation": "## Pascal 命名法 (PascalCase)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Pipe",
"translation": "## 管道 (pipe)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Provider",
"translation": "## 提供商 (provider)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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&mdash;sometimes called a \"recipe\"&mdash;that can create a dependency value.",
"translation": "依赖注入系统依靠提供商来创建依赖的实例。\n它把一个查找令牌和代码有时也叫“配方”关联到一起以便创建依赖值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Reactive forms",
"translation": "## 响应式表单 (reactive forms)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "When building reactive forms:",
"translation": "构建响应式表单时:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "* The \"source of truth\" is the component. The validation is defined using code in the component.",
"translation": "组件是“真理之源”。表单验证在组件代码中定义。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "* The template input elements do *not* use `ngModel`.",
"translation": "模板中的`input`元素**不**使用`ngModel`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Router",
"translation": "## 路由器 (router)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "A [routing component's](guide/glossary#routing-component) template has a `RouterOutlet` element\n where it can display views produced by the router.",
"translation": "[路由组件](guide/glossary#routing-component)的模板中带有一个`RouterOutlet`元素,那是显示路由器生成的视图的地方。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Other views in the application likely have anchor tags or buttons with `RouterLink`\n directives that users can click to navigate.",
"translation": "应用中的其它视图中某些锚标签或按钮上带有`RouterLink`指令,用户可以点击它们进行导航。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Routing component",
"translation": "## 路由组件 (routing component)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Scoped package",
"translation": "## 范围化包 (scoped package)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Service",
"translation": "## 服务 (service)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Applications often require services such as a hero data service or a logging service.",
"translation": "应用程序经常需要服务,例如英雄数据服务或者日志服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Applications often require services such as a data service or a logging service.",
"translation": "应用通常都需要服务,比如数据服务或者日志服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## snake_case",
"translation": "## 蛇形命名法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Structural directives",
"translation": "## 结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Read more in the [Structural Directives](guide/structural-directives) page.",
"translation": "更多信息,见[结构型指令](guide/structural-directives)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Template",
"translation": "## 模板 (template)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Template-driven forms",
"translation": "## 模板驱动表单 (template-driven forms)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "When building template-driven forms:",
"translation": "当构建模板驱动表单时:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Read about how to build template-driven forms\nin the [Forms](guide/forms) page.",
"translation": "要了解如何构建模板驱动表单的更多信息,参见[表单](guide/forms)页。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## Template expression",
"translation": "## 模板表达式 (template expression)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Transpile",
"translation": "## 转译transpile)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## TypeScript",
"translation": "## TypeScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).",
"translation": "更多信息,见[typescript.org](http://www.typescriptlang.org/)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "## View",
"translation": "## 视图 (view)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "## Zone",
"translation": "## 区域 (zone)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "A mechanism for encapsulating and intercepting\na JavaScript application's asynchronous activity.",
"translation": "区域是一种用来封装和截听 JavaScript 应用程序异步活动的机制。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "The browser DOM and JavaScript have a limited number\n of 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)\n calls 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/content-3/guide/glossary.md"
},
{
"original": "Zones intercept all of these activities and give a \"zone client\" the opportunity\n to take action before and after the async activity finishes.",
"translation": "区域能截听所有这些活动,并让“区域的客户”有机会在异步活动完成之前和之后采取行动。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"original": "Angular runs your application in a zone where it can respond to\n asynchronous events by checking for data changes and updating\n the information it displays via [data bindings](guide/glossary#data-binding).",
"translation": "Angular 会在一个 Zone 区域中运行应用程序,在这个区域中,它可以对异步事件做出反应,可以通过检查数据变更、利用[数据绑定 (data bindings)](guide/glossary#data-binding) 来更新信息显示。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/glossary.md"
},
{
"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/content-3/guide/glossary.md"
},
{
"original": "# Hierarchical Dependency Injectors",
"translation": "# 多级依赖注入器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "This guide explores this system and how to use it to your advantage.",
"translation": "在本章中,我们将浏览这个体系,并告诉你如何善用它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "Try the <live-example></live-example>.",
"translation": "试试<live-example></live-example>.",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "## The injector tree",
"translation": "## 注入器树",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Injector bubbling",
"translation": "### 注入器冒泡",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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.\n This is a topic for another day.",
"translation": "我们还可以“盖住”这次冒泡。一个中层的组件可以声称自己是“宿主”组件。\n向上查找提供商的过程会截止于这个“宿主”组件。\n我们先保留这个问题等改天再讨论这个选项。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Re-providing a service at different levels",
"translation": "### 在不同层级再次提供同一个服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "## Component injectors",
"translation": "## 组件注入器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "The ability to configure one or more providers at different levels opens up interesting and useful possibilities.",
"translation": "在不同层次上重新配置一个或多个提供商的能力,开启了一些既有趣又有用的可能性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: service isolation",
"translation": "### 场景:服务隔离",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "Instead, provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:",
"translation": "我们可以换一种方案:在`VillainsListComponent`元数据的`providers`中提供`VillainsService`,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: multiple edit sessions",
"translation": "### 场景:多重编辑会话",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "Each tax return component has the following characteristics:",
"translation": "每个报税单组件都有下列特征:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Is its own tax return editing session.",
"translation": "属于它自己的报税单会话。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Can change a tax return without affecting a return in another component.",
"translation": "可以修改一个报税单,而不会影响另一个组件中的申报单。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Has the ability to save the changes to its tax return or cancel them.",
"translation": "能把所做的修改保存到它的报税单中,或者放弃它们。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "Here is the `HeroTaxReturnComponent` that makes use of it.",
"translation": "下面是正在使用它的`HeroTaxReturnComponent`组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "Look closely at the metadata for the `HeroTaxReturnComponent`. Notice the `providers` property.",
"translation": "但仔细看`HeroTaxReturnComponent`的元数据,注意`providers`属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: specialized providers",
"translation": "### 场景:专门的提供商",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "You create a car component (A) that displays a car constructed from these three generic services.",
"translation": "我们创建了一个车辆组件A它显示一个从另外三个通用服务构造出的车辆。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"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/content-3/guide/hierarchical-dependency-injection.md"
},
{
"original": "# HttpClient",
"translation": "# HttpClient 库",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"original": "### Reading the full response",
"translation": "### 读取完整的响应体",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"original": "Tell `HttpClient` that you want the full response with the `observe` option:",
"translation": "要这样做,我们就要通过`observe`选项来告诉`HttpClient`,你想要完整的响应信息,而不是只有响应体:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "## Error handling",
"translation": "## 错误处理",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"original": "{@a error-details}\n### Getting error details",
"translation": "### 获取错误详情",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"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操作符中抛出的异常或某些阻碍完成这个请求的网络错误就会抛出一个`Error`类型的异常。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "## Sending data to the server",
"translation": "## 把数据发送到服务器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "### Making a POST request",
"translation": "### 发起一个 POST 请求",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "In fact, each `subscribe()` initiates a separate, independent execution of the observable.\nSubscribing twice results in two HTTP requests.",
"translation": "*注意这个`subscribe()`方法*。 所有从`HttpClient`返回的可观察对象都是*冷的cold*,也就是说,它们只是发起请求的*蓝图*而已。在我们调用`subscribe()`之前,什么都不会发生,而当我们每次调用`subscribe()`时,就会独立发起一次请求。\n比如下列代码会使用同样的数据发送两次同样的 POST 请求:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "<code-example \n path=\"http/src/app/heroes/heroes.service.ts\"\n region=\"update-headers\" linenums=\"false\">\n</code-example>",
"translation": "`HttpHeaders`类是不可变对象immutable所以每个`set()`都会返回一个新实例,并且应用上这些修改。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "#### URL Parameters",
"translation": "#### URL 参数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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": "这种克隆一个请求并设置一组新的请求头的操作非常常见,因此有了一种快捷写法:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "An interceptor that alters headers can be used for a number of different operations, including:",
"translation": "这种可以修改头的拦截器可以用于很多不同的操作,比如:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "* Authentication/authorization",
"translation": "认证 / 授权",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "* Caching behavior; for example, `If-Modified-Since`",
"translation": "控制缓存行为。比如`If-Modified-Since`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "* XSRF protection",
"translation": "XSRF 防护",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "#### Logging",
"translation": "#### 记日志",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "#### Caching",
"translation": "#### 缓存",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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": "现在,如果 URL 被缓存过,那么任何人调用`http.get(url)`时都会收到*两次*响应。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "### Listening to progress events",
"translation": "### 监听进度事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "## Security: XSRF Protection",
"translation": "## 安全XSRF 防护",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"original": "### Configuring custom cookie/header names",
"translation": "### 配置自定义 cookie/header 名称",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"original": "## Testing HTTP requests",
"translation": "## 测试 HTTP 请求",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"original": "### Mocking philosophy",
"translation": "### Mock 方法论",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "</div>",
"translation": "Angular 的 HTTP 测试库是为这种模式的测试而设计的应用执行代码并首先发起请求之后测试代码会期待expect特定的请求发起过或没发起然后对那些请求进行断言最终通过刷新flushing每个被期待的请求来提供响应此后还可能会触发更多新的请求。最后测试代码还可以根据需要去验证应用不曾发起过预期之外的请求。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "### Setup",
"translation": "### 初始设置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"original": "### Expecting and answering requests",
"translation": "### 期待并回复请求",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"original": "#### Custom request expectations",
"translation": "#### 自定义请求的预期",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"original": "#### Handling more than one request",
"translation": "#### 处理一个以上的请求",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/http.md"
},
{
"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/content-3/guide/http.md"
},
{
"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 name=\"i18n\">i18n 例子</live-example>作为一个简单的例子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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": "**国际化**工作者通常将一个可翻译的文本叫作“信息”。\n本章使用了“文本”和“信息”它们可以互换也可以组合“文本信息”。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "To mark the greeting for translation, add the `i18n` attribute to the `<h1>` tag.",
"translation": "添加`i18n`属性到该标签上,把它标记为需要翻译的文本。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"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": "在描述的前面,我们为指定的字符串添加一些上下文含义,用`|`将其与描述文字隔开(`<意图>|<描述>`)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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": "如果所有地方出现的文本具有**相同**含义时,它们应该有**相同**的翻译,\n但是如果在某些地方它具有**不同含义**,那么它应该有不同的翻译。\nAngular的提取工具在翻译源文件中保留**含义**和**描述**,以支持符合特定上下文的翻译。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a custom-id}\n### Set a custom id for persistence and maintenance",
"translation": "### 设置一个自定义的`id`来提升可搜索性和可维护性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "When you specify a custom id, the extractor tool and compiler generate a translation unit with that\ncustom id.",
"translation": "现在,提取工具和编译器就会用*你的自定义id`生成一个翻译单元,而不会再改变它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "You also can add a meaning, as shown in this example:",
"translation": "下面这个例子带有*含义*和*描述*,最后是`id`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "{@a no-element}\n### Translate text without creating an element",
"translation": "### 翻译文本,而不必创建元素",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "{@a translate-attributes}\n## Add i18n translation attributes",
"translation": "## 添加 *i18n* 翻译属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "This `title` attribute needs to be translated.",
"translation": "这个 `title` 属性也需要翻译。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "{@a plural-ICU}\n## Translate singular and plural",
"translation": "## 处理单数与复数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "Different languages have different pluralization rules.",
"translation": "不同的语言有不同的单复数规则。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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": "假设应用中需要谈论一些狼。\n在英语中根据狼的数量可能要显示为\"no wolves\"、\"one wolf\"、\"two wolves\"或\"a wolf pack\"。\n而在其它语言中则可能会有不同的**基数**规则。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* The first parameter is the key. It is bound to the component property (`minutes`), which determines the number of minutes.",
"translation": "第一个参数是key。它绑定到了组件中表示狼的数量的`wolves`属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* The second parameter identifies this as a `plural` translation type.",
"translation": "第二个参数表示这是一个`plural`(复数)翻译类型。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* The third parameter defines a pluralization pattern consisting of pluralization categories and their matching values.",
"translation": "第三个参数定义了一组复数表示模式,这个模式由复数类别和它们所匹配的值组成。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "Pluralization categories include (depending on the language):",
"translation": "复数类别包括(取决于语言):",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* =0 (or any other number)",
"translation": "=0 (或其它数字)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* zero",
"translation": "zero",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* one",
"translation": "one一个)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* two",
"translation": "two两个",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* few",
"translation": "few少数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* many",
"translation": "many很多",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "After the pluralization category, put the default English text in braces (`{}`).",
"translation": "把默认的*英语*翻译结果放在复数类别之后的括号(`{}`)中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a select-ICU}\n## Select among alternative text messages",
"translation": "## 在候选文本中选择",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "{@a nesting-ICUS}\n## Nesting plural and select ICU expressions",
"translation": "## 把\"复数\"与\"选择\"表达式嵌套在一起",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "You can also nest different ICU expressions together, as shown in this example:",
"translation": "我们也可以把不同的 ICU 表达式嵌套在一起,比如:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a ng-xi18n}\n## Create a translation source file with _ng xi18n_",
"translation": "## 使用_ng-xi18n_工具创建翻译源文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "Use the `ng xi18n` command provided by the CLI to extract the text messages marked with`i18n`into\n a translation source file .",
"translation": "使用`ng-xi18n`提取工具来将带`i18n`标记的文本提取到一个翻译源文件中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "{@a other-formats}\n### Other translation formats",
"translation": "### 其它翻译格式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "{@a ng-xi18n-options}\n### Other options",
"translation": "### 其它选项",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "You can specify the output path used by the CLI to extract your translation source file with\nthe parameter `--outputPath`:",
"translation": "我们还可能需要指定其它选项。\n比如如果TypeScript的配置文件`tsconfig.json`位于其它地方而不是根目录,我们就要通过`-p`选项来明确指出它的路径。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a translate}\n## Translate text messages",
"translation": "## 翻译文本信息",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "The `ng xi18n` command generates a translation source file\nnamed `messages.xlf`in the project `src` folder .",
"translation": "`ng xi18n`命令在项目根目录生成一个名为`messages.xlf`的翻译源文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "{@a localization-folder}\n### Create a localization folder",
"translation": "### 新建一个本土化目录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "{@a translate-text-nodes}\n### Translate text nodes",
"translation": "### 翻译文本节点",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "In a large translation project, you wouldsend the `messages.fr.xlf` file to a French translator who would enter the translations\nusing an XLIFF file editor.",
"translation": "在现实世界中,`messages.es.xlf`文件会被发给西班牙语翻译,他们使用<a href=\"https://en.wikipedia.org/wiki/XLIFF#Editors\" target=\"_blank\">这些XLIFF文件编辑器</a>中的一种来翻译它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "This sample file is easy to translate without a special editor or knowledge of French.",
"translation": "我们不需要任何编辑器或者法语知识就可以轻易的翻译本例子文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "To translate a `plural`, translate its ICU format match values:",
"translation": "要翻译一个复数就要翻译它的ICU格式中匹配的值",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a translate-select}\n### Translate _select_",
"translation": "### 翻译*选择*select",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "The extraction tool broke that into two translation units because ICU expressions are extracted\nseparately.",
"translation": "提取工具会把它拆成*两个*翻译单元,因为 ICU 表达式是分别提取的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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翻译这段文本并把占位符放在那里。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "Here they are together, after translation:",
"translation": "在翻译之后,它们会放在一起:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a translate-nested}\n### Translate a nested expression",
"translation": "### 翻译嵌套的表达式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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": "嵌套的表达式和前一节没有什么不同。就像上一个例子中那样,我们有*两个*翻译单元。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "The second unit contains the complete nested expression:",
"translation": "第二个包含完整的嵌套表达式:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "And both together:",
"translation": "放在一起时:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a app-pre-translation}\n### The app and its translation file",
"translation": "### 应用及其翻译文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "The sample app and its translation file are now as follows:",
"translation": "下面是例子应用及其翻译文件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a merge}\n## Merge the completed translation file into the app",
"translation": "## 合并已经翻译的文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* The translation file.",
"translation": "翻译文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* The translation file format.",
"translation": "翻译文件的格式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "{@a merge-jit}\n### Merge with the JIT compiler",
"translation": "### 用JiT编译器合并",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "1. Importing the appropriate language translation file as a string constant.",
"translation": "把合适的语言翻译文件导入成一个字符串常量",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "2. Creating corresponding translation providers for the JIT compiler.",
"translation": "为JiT编译器创建相应的翻译提供商。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "3. Bootstrapping the app with those providers.",
"translation": "使用这些提供商来启动应用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "* `TRANSLATIONS` is a string containing the content of the translation file.",
"translation": "`TRANSLATIONS`是含有翻译文件内容的字符串。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlf2`, or `xtb`.",
"translation": "`TRANSLATIONS_FORMAT`是文件的格式: `xlf`、`xlif`或`xtb`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"original": "* `LOCALE_ID` is the locale of the target language.",
"translation": "`LOCALE_ID`是目标语言的语言环境。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/i18n.md"
},
{
"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/content-3/guide/i18n.md"
},
{
"original": "# Angular Language Service",
"translation": "# Angular 语言服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "## Autocompletion",
"translation": "## 自动完成",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "## Error checking",
"translation": "## 错误检查",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "## Navigation",
"translation": "## 导航",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "## Angular Language Service in your editor",
"translation": "## 编辑器中的 Angular 语言服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "### Visual Studio Code",
"translation": "### Visual Studio Code 中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "Then click the install button to install the Angular Language Service.",
"translation": "然后点击安装按钮来安装 Angular 语言服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"original": "### WebStorm",
"translation": "### WebStorm 中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "Here's the dev dependency \nyou need to have in `package.json`:",
"translation": "下面这个开发依赖需要添加到`package.json`中:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "*OR*",
"translation": "*或*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"original": "*OR*",
"translation": "*或*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"original": "### Sublime Text",
"translation": "### Sublime Text 编辑器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "Then install the Angular Language Service in the same location:",
"translation": "然后把 Angular 语言服务安装到同一位置:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "Next, in your user preferences (`Cmd+,` or `Ctrl+,`), add:",
"translation": "接下来,在你的用户首选项中(按`Cmd+,`或`Ctrl+,`)添加:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"original": "## Installing in your project",
"translation": "## 安装到工程中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"original": "You can also install Angular Language Service in your project with the \nfollowing `npm` command:",
"translation": "我们还可以使用下列`npm`命令来把 Angular 语言服务安装到工程中:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"original": "```sh\nnpm install --save-dev @angular/language-service\n```\nAdditionally, add the following to the `\"compilerOptions\"` section of \nyour project's `tsconfig.json`.",
"translation": "另外,还要在工程的`tsconfig.json`中添加下列`\"compilerOptions\"`区域:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"original": "```json\n \"plugins\": [\n {\"name\": \"@angular/language-service\"}\n ]\n```\nNote 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/content-3/guide/language-service.md"
},
{
"original": "## How the Language Service works",
"translation": "## 语言服务的工作原理",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "## More on Information",
"translation": "## 更多信息",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/language-service.md"
},
{
"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/content-3/guide/language-service.md"
},
{
"original": "# Lifecycle Hooks",
"translation": "# 生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "A component has a lifecycle managed by Angular.",
"translation": "每个组件都有一个被Angular管理的生命周期。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "A directive has the same set of lifecycle hooks.",
"translation": "除了那些组件内容和视图相关的钩子外,指令有相同生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## Component lifecycle hooks overview",
"translation": "## 组件生命周期钩子概览",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## Lifecycle sequence",
"translation": "## 生命周期的顺序",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Hook\n </p>",
"translation": "钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Purpose and Timing\n </p>",
"translation": "<p>\n 目的和时机\n </p></th>\n </tr>\n <tr style='vertical-align:top'>\n <td>\n <code>ngOnChanges()</code>\n </td>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Called before `ngOnInit()` and whenever one or more data-bound input properties change.",
"translation": "当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在`ngOnInit()`之前。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_, after the _first_ `ngOnChanges()`.",
"translation": "在第一轮`ngOnChanges()`完成之后调用,只调用**一次**。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Detect and act upon changes that Angular can't or won't detect on its own.",
"translation": "检测并在发生Angular无法或不愿意自己检测的变化时作出反应。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Called during every change detection run, immediately after `ngOnChanges()` and `ngOnInit()`.",
"translation": "在每个Angular变更检测周期中调用`ngOnChanges()`和`ngOnInit()`之后。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_ after the first `ngDoCheck()`.",
"translation": "第一次`ngDoCheck()`之后调用,只调用一次。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular checks the content projected into the directive/component.",
"translation": "每次完成被投影组件内容的变更检测之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Called after the `ngAfterContentInit()` and every subsequent `ngDoCheck()`.",
"translation": "`ngAfterContentInit()`和每次`ngDoCheck()`之后调用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_ after the first `ngAfterContentChecked()`.",
"translation": "第一次`ngAfterContentChecked()`之后调用,只调用一次。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Called after the `ngAfterViewInit` and every subsequent `ngAfterContentChecked()`.",
"translation": "`ngAfterViewInit()`和每次`ngAfterContentChecked()`之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Called _just before_ Angular destroys the directive/component.",
"translation": "在Angular销毁指令/组件之前调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## Interfaces are optional (technically)",
"translation": "## 接口是可选的(理论上)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Fortunately, they aren't necessary.",
"translation": "幸运的是,它们并不是必须的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "You don't have to add the lifecycle hook interfaces to directives and components to benefit from the hooks themselves.",
"translation": "我们并不需要在指令和组件上添加生命周期钩子接口就能获得钩子带来的好处。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## Other Angular lifecycle hooks",
"translation": "## 其它生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Other Angular sub-systems may have their own lifecycle hooks apart from these component hooks.",
"translation": "Angular的其它子系统除了有这些组件钩子外还可能有它们自己的生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## Lifecycle examples",
"translation": "## 生命周期练习",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Here's a brief description of each exercise:",
"translation": "下面是每个练习简短的描述:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Component\n </p>",
"translation": "组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Description\n </p>",
"translation": "<p>\n 描述\n </p></th>\n </tr>\n <tr style='vertical-align:top'>\n <td>\n <a href=\"#peek-a-boo\">Peek-a-boo</a>\n </td>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Demonstrates every lifecycle hook.\n Each hook method writes to the on-screen log.",
"translation": "展示每个生命周期钩子,每个钩子方法都会在屏幕上显示一条日志。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Counter",
"translation": "计数器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Demonstrates a combination of a component and a directive\n each with its own hooks.",
"translation": "演示了组件和指令的组合,它们各自有自己的钩子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The remainder of this page discusses selected exercises in further detail.",
"translation": "接下来,我们将详细讨论这些练习。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## Peek-a-boo: all hooks",
"translation": "## Peek-a-boo全部钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The `PeekABooComponent` demonstrates all of the hooks in one component.",
"translation": "`PeekABooComponent`组件演示了组件中所有可能存在的钩子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The sequence of log messages follows the prescribed hook calling order:\n`OnChanges`, `OnInit`, `DoCheck`&nbsp;(3x), `AfterContentInit`, `AfterContentChecked`&nbsp;(3x),\n`AfterViewInit`, `AfterViewChecked`&nbsp;(3x), and `OnDestroy`.",
"translation": "日志信息的日志和所规定的钩子调用顺序是一致的:\n`OnChanges`、`OnInit`、`DoCheck`&nbsp;(3x)、`AfterContentInit`、`AfterContentChecked`&nbsp;(3x)、\n`AfterViewInit`、`AfterViewChecked`&nbsp;(3x)和`OnDestroy`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The next examples focus on hook details.",
"translation": "下一个例子就聚焦于这些钩子的细节上。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## Spying *OnInit* and *OnDestroy*",
"translation": "## 窥探*OnInit*和*OnDestroy*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Go undercover with these two spy hooks to discover when an element is initialized or destroyed.",
"translation": "潜入这两个spy钩子来发现一个元素是什么时候被初始化或者销毁的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Kidding aside, pay attention to two key points:",
"translation": "不开玩笑了,注意下面两个关键点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "1. Angular calls hook methods for *directives* as well as components.<br><br>",
"translation": "就像对组件一样Angular也会对*指令*调用这些钩子方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "2. A spy directive can provide insight into a DOM object that you cannot change directly.\nObviously you can't touch the implementation of a native `<div>`.\nYou can't modify a third party component either.\nBut you can watch both with a directive.",
"translation": "一个侦探(spy)指令可以让我们在无法直接修改DOM对象实现代码的情况下透视其内部细节。\n显然你不能修改一个原生`<div>`元素的实现代码。\n你同样不能修改第三方组件。\n但我们用一个指令就能监视它们了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The `ngOnInit()` and `ngOnDestroy()` methods have more vital roles to play in real applications.",
"translation": "在真实的应用程序中,`ngOnInit()`和`ngOnDestroy()`方法扮演着更重要的角色。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "### _OnInit()_",
"translation": "### _OnInit()钩子_",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Use `ngOnInit()` for two main reasons:",
"translation": "使用`ngOnInit()`有两个原因:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "1. To perform complex initializations shortly after construction.",
"translation": "在构造函数之后马上执行复杂的初始化逻辑",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "1. To set up the component after Angular sets the input properties.",
"translation": "在Angular设置完输入属性之后对该组件进行准备。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Experienced developers agree that components should be cheap and safe to construct.",
"translation": "有经验的开发者会认同组件的构建应该很便宜和安全。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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 HeveryAngular项目的组长在[这里解释](http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/)了你为什么应该避免复杂的构造函数逻辑。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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) guideshows how.",
"translation": "`ngOnInit()`是组件获取初始数据的好地方。[指南](tutorial/toh-pt4#oninit)中讲解了如何这样做。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "### _OnDestroy()_",
"translation": "### _OnDestroy()钩子_",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Put cleanup logic in `ngOnDestroy()`, the logic that *must* run before Angular destroys the directive.",
"translation": "一些清理逻辑*必须*在Angular销毁指令之前运行把它们放在`ngOnDestroy()`中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "This is the time to notify another part of the application that the component is going away.",
"translation": "这是在该组件消失之前,可用来通知应用程序中其它部分的最后一个时间点。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## _OnChanges()_",
"translation": "## _OnChanges()_ 钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive).",
"translation": "一旦检测到该组件(或指令)的***输入属性***发生了变化Angular就会调用它的`ngOnChanges()`方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "This example monitors the `OnChanges` hook.",
"translation": "本例监控`OnChanges`钩子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The example component, `OnChangesComponent`, has two input properties: `hero` and `power`.",
"translation": "这个例子中的`OnChangesComponent`组件有两个输入属性:`hero`和`power`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The host `OnChangesParentComponent` binds to them like this:",
"translation": "宿主`OnChangesParentComponent`绑定了它们,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Here's the sample in action as the user makes changes.",
"translation": "下面是此例子中的当用户做出更改时的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## _DoCheck()_",
"translation": "## _DoCheck()_ 钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Use this method to detect a change that Angular overlooked.",
"translation": "用这个方法来检测那些被Angular忽略的更改。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck()` hook:",
"translation": "*DoCheck*范例通过下面的`ngDoCheck()`实现扩展了*OnChanges*范例:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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&mdash;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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## AfterView",
"translation": "## AfterView 钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Here's a child view that displays a hero's name in an `<input>`:",
"translation": "下面是一个子视图,它用来把英雄的名字显示在一个`<input>`中:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The `AfterViewComponent` displays this child view *within its template*:",
"translation": "`AfterViewComponent`把这个子视图显示*在它的模板中*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "### Abide by the unidirectional data flow rule",
"translation": "### 遵循单向数据流规则",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The `doSomething()` method updates the screen when the hero name exceeds 10 characters.",
"translation": "当英雄的名字超过10个字符时`doSomething()`方法就会更新屏幕。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Why does the `doSomething()` method wait a tick before updating `comment`?",
"translation": "为什么在更新`comment`属性之前,`doSomething()`方法要等上一拍(tick)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Here's *AfterView* in action:",
"translation": "这里是*AfterView*的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "## AfterContent",
"translation": "## AfterContent 钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "### Content projection",
"translation": "### 内容投影",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "AngularJS developers know this technique as *transclusion*.",
"translation": "AngularJS的开发者大概知道一项叫做*transclusion*的技术,对,这就是它的马甲。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "Now look at the component's template:",
"translation": "现在来看下`<after-content>`组件的模板:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "The telltale signs of *content projection* are twofold:",
"translation": "下列迹象表明存在着*内容投影*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "* HTML between component element tags.",
"translation": "在组件的元素标签中有HTML",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "* The presence of `<ng-content>` tags in the component's template.",
"translation": "组件的模板中出现了`<ng-content>`标签",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"original": "### AfterContent hooks",
"translation": "### AfterContent钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "* The *AfterContent* hooks concern `ContentChildren`, the child components that Angular\nprojected into the component.",
"translation": "*AfterContent*钩子所关心的是`ContentChildren`这些子组件被Angular投影进该组件中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "### No unidirectional flow worries with _AfterContent_",
"translation": "### 使用**AfterContent**时,无需担心单向数据流规则",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"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/content-3/guide/lifecycle-hooks.md"
},
{
"original": "# NgModule FAQs",
"translation": "# Angular 模块常见问题",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "#### Prerequisites:",
"translation": "#### 前提条件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "A basic understanding of the following concepts:",
"translation": "对下列概念有基本的理解:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "NgModules help organize an application into cohesive blocks of functionality.",
"translation": "NgModules可以帮我们把应用组织成一些紧密相关的代码块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "This page answers the questions many developers ask about NgModule design and implementation.",
"translation": "这里回答的是开发者常问起的关于Angular模块的设计与实现问题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What classes should I add to the `declarations` array?",
"translation": "## 我应该把哪些类加到*declarations*中?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "Add [declarable](guide/bootstrapping#the-declarations-array) classes&mdash;components, directives, and pipes&mdash;to a `declarations` list.",
"translation": "把[可声明](guide/bootstrapping#the-declarations-array)的类(组件、指令和管道)添加到 `declarations` 列表中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What is a _declarable_?",
"translation": "## 什么是*可声明的*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "Declarables are the class types&mdash;components, directives, and pipes&mdash;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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What classes should I _not_ add to `declarations`?",
"translation": "## 哪些类*不*应该加到`declarations`中?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "Do *not* declare the following:",
"translation": "*不要*声明:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "* Module classes.",
"translation": "模块类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "* Service classes.",
"translation": "服务类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Why list the same component in multiple `NgModule` properties?",
"translation": "## 为什么要把同一个组件声明在不同的*NgModule*属性中?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "* `AppComponent` could be declared in this module but not bootstrapped.",
"translation": "`AppComponent`可能被声明在此模块中,但可能不是引导组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "* `AppComponent` could be bootstrapped in this module but declared in a different feature module.",
"translation": "`AppComponent`可能在此模块中引导,但可能是由另一个特性模块声明的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What should I import?",
"translation": "## 我应该导入什么?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "Import _shared_ and _feature_ modules when this module's components incorporate their\ncomponents, directives, and pipes.",
"translation": "如果当前模块中的组件包含了*共享*模块和*特性*模块中的组件、指令和管道,就导入这些模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Should I import `BrowserModule` or `CommonModule`?",
"translation": "## 我应该导入*BrowserModule*还是*CommonModule*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "`BrowserModule` provides services that are essential to launch and run a browser app.",
"translation": "`BrowserModule`提供了启动和运行浏览器应用的那些基本的服务提供商。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "Importing `CommonModule` also frees feature modules for use on _any_ target platform, not just browsers.",
"translation": "特性模块中导入`CommonModule`可以让它能用在任何目标平台上,不仅是浏览器。那些跨平台库的作者应该喜欢这种方式的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What if I import the same module twice?",
"translation": "## 如果我两次导入同一个模块会怎么样?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What should I export?",
"translation": "## 我应该导出什么?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "You _can_ export any declarable class&mdash;components, directives, and pipes&mdash;whether\nit's declared in this NgModule or in an imported NgModule.",
"translation": "你*可以*导出任何可声明类组件、指令和管道而不用管它是声明在当前模块中还是某个导入的模块中。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.\n你*可以*重新导出整个导入过的模块,这将导致重新导出它们导出的所有类。模块甚至还可以导出它未曾导入过的模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What should I *not* export?",
"translation": "## 我*不应该*导出什么?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "Don't export the following:",
"translation": "*不要*导出:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "* Non-declarable objects such as services, functions, configurations, and entity models.",
"translation": "不可声明的对象,比如服务、函数、配置、实体模型等。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Can I re-export classes and modules?",
"translation": "## 我可以重新导出类和模块吗?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "Absolutely.",
"translation": "毫无疑问!",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "An NgModule can export a combination of its own declarations, selected imported classes, and imported NgModules.",
"translation": "模块还能导出一个组合,它可以包含自己的声明、某些导入的类以及导入的模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What is the `forRoot()` method?",
"translation": "## *forRoot*方法是什么?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "`RouterModule` also offers a `forChild` static method for configuring the routes of lazy-loaded modules.",
"translation": "`RouterModule`也提供了静态方法`forChild`,用于配置惰性加载模块的路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "Angular doesn't recognize these names but Angular developers do.\nFollow this convention when you write similar modules with configurable service providers.\n<!--KW--I don't understand how Angular doesn't understand these methods...-->",
"translation": "Angular并不识别这些名字但是Angular的开发人员可以。\n当你写类似的需要可配置的服务提供商时请遵循这个约定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Why is a service provided in a feature module visible everywhere?",
"translation": "## 为什么服务提供商在特性模块中的任何地方都是可见的?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Why is a service provided in a lazy-loaded module visible only to that module?",
"translation": "## 为什么在惰性加载模块中声明的服务提供商只对该模块自身可见?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "Unlike providers of the modules loaded at launch,\nproviders of lazy-loaded modules are *module-scoped*.",
"translation": "和启动时就加载的模块中的提供商不同,惰性加载模块中的提供商是*局限于模块*的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What if two modules provide the same service?",
"translation": "## 如果两个模块提供了*同一个*服务会怎么样?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## How do I restrict service scope to a module?",
"translation": "## 我们应该如何把服务的范围限制到模块中?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "To avoid this problem, import the `HttpClientModule` only in the `AppModule`, the application _root module_.",
"translation": "要消除这个问题,就只能在应用的根模块`AppModule`中导入`HttpClientModule`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "Be sure to create module components as children of this module's top component.",
"translation": "确保把模块中的组件都创建成这个顶级组件的子组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Should I add application-wide providers to the root `AppModule` or the root `AppComponent`?",
"translation": "## 我应该把全应用级提供商添加到根模块`AppModule`中还是根组件`AppComponent`中?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "Register application-wide providers in the root `AppModule`, not in the `AppComponent`.",
"translation": "在根模块`AppModule`中注册全应用级提供商,而不是`AppComponent`中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "Discussion",
"translation": "讨论",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Should I add other providers to a module or a component?",
"translation": "## 我应该把其它提供商注册到模块中还是组件中?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Why is it bad if a shared module provides a service to a lazy-loaded module?",
"translation": "## 为什么在共享模块中为惰性加载模块提供服务是个馊主意?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "### The eagerly loaded scenario",
"translation": "### 立即加载的场景",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "### The lazy loaded scenario",
"translation": "### 惰性加载场景",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "Now consider a lazy loaded module that also provides a service called `UserService`.",
"translation": "现在,该考虑`HeroModule`了,*它是惰性加载的!*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "This scenario causes your app to create a new instance every time, instead of using the singleton.",
"translation": "这个场景导致我们的应用每次都创建一个新的服务实例,而不是使用单例的服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Why does lazy loading create a child injector?",
"translation": "## 为什么惰性加载模块会创建一个子注入器?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## How can I tell if an NgModule or service was previously loaded?",
"translation": "## 我要如何知道一个模块或服务是否已经加载过了?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What is an `entry component`?",
"translation": "## 什么是*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "An entry component is any component that Angular loads _imperatively_ by type.",
"translation": "Angular根据其类型*不可避免地*加载的组件是*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "A component loaded _declaratively_ via its selector is _not_ an entry component.",
"translation": "而通过组件选择器*声明式*加载的组件则*不是*入口组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "For more information, see [Entry Components](guide/entry-components).",
"translation": "要了解更多,参见[入口组件](guide/entry-components)一章。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What's the difference between a _bootstrap_ component and an _entry component_?",
"translation": "### *引导组件*和*入口组件*有什么不同?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "For more information, see [Entry Components](guide/entry-components).",
"translation": "要了解更多,参见[入口组件](guide/entry-components)一章。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## When do I add components to _entryComponents_?",
"translation": "## 什么时候我应该把组件加到`entryComponents`中?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "Most application developers won't need to add components to the `entryComponents`.",
"translation": "大多数应用开发者都不需要把组件添加到`entryComponents`中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "For more information, see [Entry Components](guide/entry-components).",
"translation": "要了解更多,参见[入口组件](guide/entry-components)一章。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## Why does Angular need _entryComponents_?",
"translation": "## 为什么 Angular 需要*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "Instead, the compiler adopts a recursive strategy that generates code only for the components you use.",
"translation": "所以,编译器转而采用一种递归策略,它只为我们用到的那些组件生成代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What kinds of modules should I have and how should I use them?",
"translation": "## 有哪些类型的模块?我应该如何使用它们?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "### `SharedModule`\n`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/content-3/guide/ngmodule-faq.md"
},
{
"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`可以重新导出其它[小部件模块](guide/ngmodule-faq#widget-feature-module),比如`CommonModule`、`FormsModule`和提供你广泛使用的UI控件的那些模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "### `CoreModule`\n`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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "Consider making `CoreModule` a pure services module\nwith no `declarations`.",
"translation": "考虑把 `CoreModule` 做成一个没有 `declarations` 的纯服务模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "### Feature Modules",
"translation": "### 特性模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "An Angular NgModule is a class with the `@NgModule` decorator&mdash;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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "The compiler finds a pipe if the pipe's *name* appears within the pipe syntax of the template HTML.",
"translation": "编译器通过分析模板HTML中的管道语法中是否出现了特定的管道名来查找对应的管道。Angular only matches selectors and pipe names for classes that are declared by this module\nor exported by a module that this module imports.\nAngular只查询两种组件、指令或管道1那些在当前模块中声明过的以及2那些被当前模块导入的模块所导出的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"original": "## What is the Angular compiler?",
"translation": "## 什么是Angular编译器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"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/content-3/guide/ngmodule-faq.md"
},
{
"original": "# Npm Packages",
"translation": "# Npm 包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "This guide focuses on the most important packages in the starter set.",
"translation": "本指南中会集中讲解这些初始包中的重点部分。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"original": "#### *dependencies* and *devDependencies*",
"translation": "#### *dependencies* 和 *devDependencies*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "The `dependencies` section of `package.json` contains:",
"translation": "应用程序的`package.json`文件中,`dependencies`下包括:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"original": "* **Angular packages **: Angular core and optional modules; their package names begin `@angular/`.",
"translation": "**Angular 包**Angular 的核心和可选模块,它们的包名以`@angular/`开头。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"original": "* **Support packages**: 3rd party libraries that must be present for Angular apps to run.",
"translation": "**支持包**那些Angular 应用运行时必需的第三方库。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"original": "* **Polyfill packages**: Polyfills plug gaps in a browser's JavaScript implementation.",
"translation": "**腻子脚本**:腻子脚本负责抹平不同浏览器的 JavaScript 实现之间的差异。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"original": "### Angular Packages",
"translation": "### Angular 包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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 dont 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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "**@angular/http**: Angular's old, soon-to-be-deprecated, HTTP client.",
"translation": "**@angular/http**Angular 的老的、很快就会废弃的 HTTP 客户端库。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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)和[bootstrap](guide/ngmodule#bootstrap)方法,以便在客户端编译模板。不要用于离线编译。\n我们使用这个包在开发期间引导应用以及引导plunker中的范例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "**@angular/upgrade**: Set of utilities for upgrading AngularJS applications to Angular.",
"translation": "**@angular/upgrade**: 一组用来把 AngularJS 应用升级到 Angular 的工具。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"original": "### Polyfill packages",
"translation": "### 腻子脚本包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "### Support packages",
"translation": "### 支持包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "You don't deploy them with the production application although there is no harm in doing so.",
"translation": "我们不必在生产环境的应用中部署它们,当然,就算部署了也没什么坏处。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "**@types/... **: TypeScript definition files for 3rd party libraries such as Jasmine and node.",
"translation": "**@types/... **:第三方库(比如 Jasmine 和 node的 TypeScript 类型定义文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "## So many packages! So many files!",
"translation": "## 那么多包!那么多文件!",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"original": "The default `package.json` installs more packages than you'll need for your project.",
"translation": "默认的 `package.json` 所安装的包比项目实际需要的多。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"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/content-3/guide/npm-packages.md"
},
{
"original": "See the [Deployment](guide/deployment) to learn more.",
"translation": "参见[部署](guide/deployment)一章了解详情。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/npm-packages.md"
},
{
"original": "# Pipes",
"translation": "# 管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "You can run the <live-example></live-example> in Stackblitz and download the code from there.",
"translation": "试试<live-example>在线例子</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "## Using pipes",
"translation": "## 使用管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "Focus on the component's template.",
"translation": "重点看下组件的模板。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "## Built-in pipes",
"translation": "## 内置的管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "## Parameterizing a pipe",
"translation": "## 对管道进行参数化",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "</div>",
"translation": "## Chaining pipes\n## 链式管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "This example&mdash;which displays **<samp>FRIDAY, APRIL 15, 1988</samp>**&mdash;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/content-3/guide/pipes.md"
},
{
"original": "## Custom pipes",
"translation": "## 自定义管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "This pipe definition reveals the following key points:",
"translation": "在这个管道的定义中体现了几个关键点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "* A pipe is a class decorated with pipe metadata.",
"translation": "管道是一个带有“管道元数据(pipe metadata)”装饰器的类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "## The *PipeTransform* interface",
"translation": "### *PipeTransform*接口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "Now you need a component to demonstrate the pipe.",
"translation": "现在,我们需要一个组件来演示这个管道。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "Note the following:",
"translation": "要注意的有两点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "* You use your custom pipe the same way you use built-in pipes.",
"translation": "我们使用自定义管道的方式和内置管道完全相同。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "* You must include your pipe in the `declarations` array of the `AppModule`.",
"translation": "我们必须在`AppModule`的`declarations`数组中包含这个管道。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "Remember the declarations array",
"translation": "别忘了`declarations`数组",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "## Power Boost Calculator",
"translation": "## 能力倍增计算器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "## Pipes and change detection",
"translation": "## 管道与变更检测",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "No pipe",
"translation": "无管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "The companion component class provides heroes, adds heroes into the array, and can reset the array.",
"translation": "和模板相伴的组件类可以提供英雄数组,能把新的英雄添加到数组中,还能重置英雄数组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "FlyingHeroesPipe",
"translation": "“会飞的英雄”管道FlyingHeroesPipe",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "Here's the `FlyingHeroesPipe` implementation, which follows the pattern for custom pipes described earlier.",
"translation": "下面是`FlyingHeroesPipe`的实现,它遵循了我们以前见过的那些写自定义管道的模式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "Notice how a hero is added:",
"translation": "来看看我们是如何添加新英雄的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "For filtering flying heroes, consider an *impure pipe*.",
"translation": "为了过滤会飞的英雄,我们要使用*非纯(impure)管道*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "## Pure and impure pipes",
"translation": "## 纯(pure)管道与非纯(impure)管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "Before doing that, understand the difference between pure and impure, starting with a pure pipe.",
"translation": "在继续往下走之前,我们先理解一下*纯*和*非纯*之间的区别,从*纯*管道开始。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "Pure pipes",
"translation": "纯管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "This may seem restrictive but it's also fast.\nAn object reference check is fast&mdash;much faster than a deep check for\ndifferences&mdash;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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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 laterin this page.",
"translation": "或者我们也可以完全不用管道。\n有时候使用组件的属性能比用管道更好的达到目的这一点我们等后面会再提起。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "Impure pipes",
"translation": "### 非纯管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "An impure <i>FlyingHeroesPipe</i>",
"translation": "### 非纯版本的*FlyingHeroesPipe*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`.",
"translation": "我们可以从`FlyingHeroesComponent`派生出一个`FlyingHeroesImpureComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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>中确认,当我们输入新的英雄甚至修改#[code heroes]数组时,这个#[i 会飞的英雄]的显示也跟着更新了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "{@a async-pipe}\n<h3 class=\"no-toc\">The impure <i>AsyncPipe</i></h3>",
"translation": "非纯 <i>AsyncPipe</i>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "An impure caching pipe",
"translation": "一个非纯而且带缓存的管道",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "Write one more impure pipe, a pipe that makes an HTTP request.",
"translation": "我们来写更多的非纯管道一个向服务器发起HTTP请求的管道。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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": "我们确实得小心点。\n这个管道只有当所请求的URL发生变化时才会向服务器发起请求。它会缓存服务器的响应。\n代码如下它使用[Angular http](guide/http)客户端来接收数据",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "The component renders as the following:",
"translation": "组件渲染起来是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "A breakpoint on the pipe's request for data shows the following:",
"translation": "这个管道上的断点请求数据的过程显示:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "* Each binding gets its own pipe instance.",
"translation": "每个绑定都有它自己的管道实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "* Each pipe instance caches its own URL and data.",
"translation": "每个管道实例都缓存了它自己的URL和数据。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"original": "* Each pipe instance only calls the server once.",
"translation": "每个管道实例都只调用一次服务器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "Debugging with the json pipe",
"translation": "借助json管道进行调试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "Pure pipes and pure functions",
"translation": "### 纯管道与纯函数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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`&mdash;an impure pipe with a pure function.",
"translation": "我们在本章前面见过的管道都是用纯函数实现的。\n内置的`DatePipe`就是一个用纯函数实现的纯管道。\n`ExponentialStrengthPipe`是如此,\n`FlyingHeroesComponent`也是如此。\n不久前我们刚看过的`FlyingHeroesImpurePipe`,是一个*用纯函数实现的非纯管道*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "## Next steps",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "## Appendix: No *FilterPipe* or *OrderByPipe*",
"translation": "## 附录:没有*FilterPipe*或者*OrderByPipe*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"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/content-3/guide/pipes.md"
},
{
"original": "# QuickStart",
"translation": "# 快速上手",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "Good tools make application development quicker and easier to maintain than\nif you did everything by hand.",
"translation": "好的工具能让开发更加简单快捷。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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": "在这一章CLI快速起步中我们的目标是构建并运行一个超级简单的Angular应用。我们会使用Angular-CLI来让每个Angular应用从[风格指南](guide/styleguide)中获益。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "Step 1. Set up the Development Environment",
"translation": "步骤1. 设置开发环境",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "You need to set up your development environment before you can do anything.",
"translation": "在开始工作之前,我们必须设置好开发环境。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "Step 2. Create a new project",
"translation": "步骤2. 创建新项目",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "Open a terminal window.",
"translation": "打开终端窗口。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "Generate a new project and skeleton application by running the following commands:",
"translation": "运行下列命令来生成一个新项目以及应用的骨架代码:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "Step 3: Serve the application",
"translation": "步骤3. 启动开发服务器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "Go to the project directory and launch the server.",
"translation": "进入项目目录,并启动服务器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "Your app greets you with a message:",
"translation": "本应用会用一条消息来跟你打招呼:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "Step 4: Edit your first Angular component",
"translation": "步骤4. 编辑我们的第一个Angular组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/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!!_ ",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "The browser reloads automatically with the revised title. That's nice, but it could look better.",
"translation": "浏览器会自动刷新,而我们会看到修改之后的标题。不错,不过它还可以更好看一点。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "Open `src/app/app.component.css` and give the component some style.",
"translation": "打开 `src/app/app.component.css` 并给这个组件设置一些样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "Looking good!",
"translation": "漂亮!",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "## What's next?",
"translation": "## 接下来呢?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "That's about all you'd expect to do in a \"Hello, World\" app.",
"translation": "如你所愿我们完成了这个“Hello, World”应用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "## Project file review",
"translation": "## 项目文件概览",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "An Angular CLI project is the foundation for both quick experiments and enterprise solutions.",
"translation": "Angular CLI项目是做快速试验和开发企业解决方案的基础。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "Some of the generated files might be unfamiliar to you.",
"translation": "有些生成的文件你可能觉得陌生。接下来我们就讲讲它们。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "### The `src` folder",
"translation": "### `src`文件夹",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "<table width=\"100%\">\n <col width=\"20%\">\n </col>\n <col width=\"80%\">\n </col>\n <tr>\n <th>\n File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "</th>\n <th>\n Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "A folder where you can put images and anything else to be copied wholesale\n when you build your application.",
"translation": "这个文件夹下你可以放图片等任何东西,在构建应用时,它们全都会拷贝到发布包中。\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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都替你考虑到了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "Every site wants to look good on the bookmark bar.\n Get started with your very own Angular icon.",
"translation": "每个网站都希望自己在书签栏中能好看一点。\n 请把它换成你自己的图标。\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "### The root folder",
"translation": "### 根目录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "<table width=\"100%\">\n <col width=\"20%\">\n </col>\n <col width=\"80%\">\n </col>\n <tr>\n <th>\n File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"original": "</th>\n <th>\n Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "Git configuration to make sure autogenerated files are not commited to source control.",
"translation": "一个Git的配置文件用来确保某些自动生成的文件不会被提交到源码控制系统中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "TypeScript compiler configuration for your IDE to pick up and give you helpful tooling.",
"translation": "TypeScript编译器的配置你的IDE会借助它来给你提供更好的帮助。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "### Next Step",
"translation": "### 下一步",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/quickstart.md"
},
{
"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/content-3/guide/quickstart.md"
},
{
"original": "# Reactive Forms",
"translation": "# 响应式表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "Try the <live-example stackblitz=\"final\" title=\"Reactive Forms (final) in Stackblitz\">Reactive Forms live-example</live-example>.",
"translation": "试试<live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\">响应式表单的在线例子</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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 Plunker\">响应式表单的演示程序</live-example>,并从顶部选取一个中间步骤。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Introduction to Reactive Forms",
"translation": "## 响应式表单简介",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### _Reactive_ forms",
"translation": "### *响应式*表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### _Template-driven_ forms",
"translation": "### *模板驱动*表单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "_Template-driven_ forms, introduced in the [Template guide](guide/forms), take a completely different approach.",
"translation": "在[模板](guide/forms)一章我们介绍过的*模板驱动*表单,是一种完全不同的方式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "For this reason, the `ngModel` directive is not part of the ReactiveFormsModule.",
"translation": "因此,`ngModel`并不是`ReactiveFormsModule`模块的一部分。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### Async vs. sync",
"translation": "### 异步 vs. 同步",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Reactive forms are synchronous. Template-driven forms are asynchronous. It's a difference that matters.",
"translation": "响应式表单是同步的。模板驱动表单是异步的。这个不同点很重要。",
"sourceFile": "/Users/twer/private/GDE/content-3/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.",
"translation": "使用响应式表单,我们会在代码中创建整个表单控件树。\n我们可以立即更新一个值或者深入到表单中的任意节点因为所有的控件都始终是可用的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### Which is better, reactive or template-driven?",
"translation": "### 哪一个更好?响应式还是模板驱动?",
"sourceFile": "/Users/twer/private/GDE/content-3/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请自行选择更合适的方法甚至可以在同一个应用中同时使用它们。",
"sourceFile": "/Users/twer/private/GDE/content-3/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": "在这章*响应式表单*中,我们只专注于*响应式*范式以及响应式表单技术的详情。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "## Setup",
"translation": "## 准备工作",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Create a new project named <code>angular-reactive-forms</code>:",
"translation": "创建一个名叫<code>angular-reactive-forms</code>的新项目:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Create a data model",
"translation": "## 创建数据模型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "Using the CLI, generate a new class named `data-model`:",
"translation": "使用 CLI 创建一个名叫 `data-model` 的新类:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "And copy the content below:",
"translation": "并复制下列内容:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "## Create a _reactive forms_ component",
"translation": "## 创建*响应式表单*组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Generate a new component named `HeroDetail`:",
"translation": "生成一个名叫 `HeroDetail` 的新组件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "And import:",
"translation": "并导入:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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`框,表示英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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/content-3/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)一章。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Create the template",
"translation": "## 创建模板",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Now update the component's template, with the following markup.",
"translation": "现在,在创建组件的模板文件`src/app/hero-detail.component.html`,内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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.",
"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/content-3/guide/reactive-forms.md"
},
{
"original": "## Import the _ReactiveFormsModule_",
"translation": "## 导入`ReactiveFormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "The HeroDetailComponent template uses `formControlName`\ndirective from the `ReactiveFormsModule`.",
"translation": "`HeroDetailComponent`的模板中使用了来自`ReactiveFormsModule`的`formControlName`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Do the following two things in `app.module.ts`:",
"translation": "在 `app.module.ts` 中做了下面两件事:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "1. Use a JavaScript `import` statement to access\nthe `ReactiveFormsModule`.",
"translation": "使用JavaScript的`import`语句访问`ReactiveFormsModule`和`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "1. Add `ReactiveFormsModule` to the `AppModule`'s `imports` list.",
"translation": "把`ReactiveFormsModule`添加到`AppModule`的`imports`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Display the _HeroDetailComponent_",
"translation": "## 显示`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Revise the `AppComponent` template so it displays the `HeroDetailComponent`.",
"translation": "修改`AppComponent`的模板,以便显示`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### Essential form classes",
"translation": "### 基础的表单类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "It may be helpful to read a brief description of the core form classes.",
"translation": "阅读一下这些核心表单类的简短描述也许会有用。",
"sourceFile": "/Users/twer/private/GDE/content-3/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*。",
"sourceFile": "/Users/twer/private/GDE/content-3/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表单控件比如输入框和下拉框。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`实例组成的有序数组的值和有效性状态。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "You'll learn more about these classes as you work through this guide.",
"translation": "随着本章的深入,我们将学到关于这三个类的更多知识。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### Style the app",
"translation": "### 为应用添加样式",
"sourceFile": "/Users/twer/private/GDE/content-3/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`区。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Now that everything is wired up, the browser should display something like this:",
"translation": "这些做好之后,浏览器中应该显示成这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Add a FormGroup",
"translation": "## 添加FormGroup",
"sourceFile": "/Users/twer/private/GDE/content-3/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`区就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "In the class, wrap the `FormControl` in a `FormGroup` called `heroForm` as follows:",
"translation": "在这个类中,把`FormControl`包裹进了一个名叫`heroForm`的`FormGroup`中,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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中的表单验证器。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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当用户输入名字时它的值去了哪里",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Taking a look at the form model",
"translation": "## 表单模型概览",
"sourceFile": "/Users/twer/private/GDE/content-3/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`标签紧后面添加如下代码:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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/content-3/guide/reactive-forms.md"
},
{
"original": "Great! You have the basics of a form.",
"translation": "真棒!我们有了一个基本版表单。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "## Introduction to _FormBuilder_",
"translation": "## `FormBuilder`简介",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "The `FormBuilder` class helps reduce repetition and\nclutter by handling details of control creation for you.",
"translation": "`FormBuilder`类能通过处理控件创建的细节问题来帮我们减少重复劳动。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "To use `FormBuilder`, you need to import it into `hero-detail.component.ts`:",
"translation": "要使用`FormBuilder`,我们就要先把它导入到`hero-detail.component.ts`中:",
"sourceFile": "/Users/twer/private/GDE/content-3/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`重构得更加容易读写。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "* Inject a `FormBuilder` into the constructor.",
"translation": "把`FormBuilder`注入到构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "* Call `createForm` in the constructor.",
"translation": "在构造函数中调用`createForm`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "The revised `HeroDetailComponent` looks like this:",
"translation": "修改过的`HeroDetailComponent`代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "`FormBuilder.group` is a factory method that creates a `FormGroup`. &nbsp;\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/content-3/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/content-3/guide/reactive-forms.md"
},
{
"original": "### Validators.required",
"translation": "### Validators.required 验证器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "First, import the `Validators` symbol.",
"translation": "首先,导入`Validators`符号。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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.",
"translation": "响应式验证器是一些简单、可组合的函数。\n在模板驱动表单中配置验证器有些困难因为我们必须把验证器包装进指令中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Update the diagnostic message at the bottom of the template to display the form's validity status.",
"translation": "修改模板底部的诊断信息,以显示表单的有效性状态。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "The browser displays the following:",
"translation": "浏览器会显示下列内容:",
"sourceFile": "/Users/twer/private/GDE/content-3/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`.",
"translation": "`Validators.required`生效了,但状态还是`INVALID`,因为输入框中还没有值。\n在输入框中输入就会看到这个状态从`INVALID`变成了`VALID`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "In a real app, you'd replace the diagnosic message with a user-friendly experience.",
"translation": "在真实的应用中,我们要把这些诊断信息替换成用户友好的信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### More FormControls",
"translation": "### 更多的表单控件FormControl",
"sourceFile": "/Users/twer/private/GDE/content-3/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": "每个英雄可以有多个名字,还有一个住址、一项超能力,有时还会有一个副手。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`(州列表)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Declare the `states` property and add some address `FormControls` to the `heroForm` as follows.",
"translation": "声明`states`属性并往`heroForm`中添加一些表示住址的`FormControl`,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Then add corresponding markup in `hero-detail.component.html`\nwithin the `form` element.",
"translation": "然后在`hero-detail.component.html`文件中把对应的脚本添加到`form`元素中。",
"sourceFile": "/Users/twer/private/GDE/content-3/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.",
"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/content-3/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`.",
"translation": "修改过的模板包含更多文本输入框,一个`state`选择框,`power`(超能力)的单选按钮和一个`sidekick`检查框。",
"sourceFile": "/Users/twer/private/GDE/content-3/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如果不绑定这个值这个选择框就会显示来自数据模型中的第一个选项。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### Nested FormGroups",
"translation": "### 多级`FormGroup`",
"sourceFile": "/Users/twer/private/GDE/content-3/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": "这个表单变得越来越大、越来越笨重。我们可以把一些相关的`FormControl`组织到多级`FormGroup`中。\n`street`、`city`、`state`和`zip`属性就可以作为一个名叫`address`的`FormGroup`。\n用这种方式多级表单组和控件可以让我们轻松地映射多层结构的数据模型以便帮助我们跟踪这组相关控件的有效性和状态。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`.",
"translation": "我们用`FormBuilder`在这个名叫`heroForm`的组件中创建一个`FormGroup`,并把它用作父`FormGroup`。\n再次使用`FormBuilder`创建一个子级`FormGroup`,其中包括这些住址控件。把结果赋值给父`FormGroup`中新的`address`属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Youve changed 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/content-3/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`。",
"sourceFile": "/Users/twer/private/GDE/content-3/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如下",
"sourceFile": "/Users/twer/private/GDE/content-3/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`的住址。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Great! Youve made a group and you can see that the template\nand the form model are talking to one another.",
"translation": "真棒!我们制作了一个控件组,并且可以看到模板和表单模型已经能彼此通讯了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Inspect _FormControl_ Properties",
"translation": "## 查看`FormControl`的属性",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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:",
"translation": "我们可以使用`.get()`方法来提取表单中一个单独`FormControl`的状态。\n我们可以在组件类中这么做或者通过往模板中添加下列代码来把它显示在页面中就添加在`{{form.value | json}}`插值表达式的紧后面:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "To get the state of a `FormControl` thats inside a `FormGroup`, use dot notation to path to the control.",
"translation": "要点取得`FormGroup`中的`FormControl`的状态,使用点语法来指定到控件的路径。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`的*任意*属性,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Property",
"translation": "属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Description",
"translation": "说明",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "the value of a `FormControl`.",
"translation": "`FormControl`的值。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "the validity of a `FormControl`. Possible values: `VALID`,\n `INVALID`, `PENDING`, or `DISABLED`.",
"translation": "`FormControl`的有效性。可能的值有`VALID`、`INVALID`、`PENDING`或`DISABLED`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "`true` if the user has _not_ changed the value in the UI.\n Its opposite is `myControl.dirty`.",
"translation": "如果用户*尚未*改变过这个控件的值,则为`true`。它总是与`myControl.dirty`相反。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Learn 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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "## The _data model_ and the _form model_",
"translation": "## *数据模型*与*表单模型*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "In this app, the `HeroDetailComponent` gets its hero from a parent `HeroListComponent`",
"translation": "在这个应用中,`HeroDetailComponent`从它的父组件`HeroListComponent`中取得一个英雄。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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": "组件必须把*数据模型*中的英雄值复制到*表单模型*中。这里隐含着两个非常重要的点。",
"sourceFile": "/Users/twer/private/GDE/content-3/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": "开发人员必须理解*数据模型*是如何映射到*表单模型*中的属性的。",
"sourceFile": "/Users/twer/private/GDE/content-3/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元素流向*表单模型*的,而不是*数据模型*。表单控件永远不会修改*数据模型*。",
"sourceFile": "/Users/twer/private/GDE/content-3/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但是*表单模型*的形态越接近*数据模型*,事情就会越简单。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "In this `HeroDetailComponent`, the two models are quite close.",
"translation": "在`HeroDetailComponent`中,这两个模型是非常接近的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Recall the definition of `Hero` in `data-model.ts`:",
"translation": "回忆一下`data-model.ts`中的`Hero`定义:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Here, again, is the component's `FormGroup` definition.",
"translation": "这里又是组件的`FormGroup`定义。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "There are two significant differences between these models:",
"translation": "在这些模型中有两点显著的差异:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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\")则可以表示多个。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`方法来把*数据模型*拷贝到*表单模型*中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Take a moment to refactor the _address_ `FormGroup` definition for brevity and clarity as follows:",
"translation": "花一点时间来重构一下`address`这个`FormGroup`定义,来让它更简洁清晰,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "## Populate the form model with _setValue_ and _patchValue_",
"translation": "## 使用`setValue`和`patchValue`来操纵表单模型",
"sourceFile": "/Users/twer/private/GDE/content-3/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`来初始化或重置这些值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### _setValue_",
"translation": "### _setValue_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-3/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`**,我们可以*立即*设置*每个*表单控件的值,只要把与*表单模型*的属性精确匹配的数据模型传进去就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "The `setValue` method checks the data object thoroughly before assigning any form control values.",
"translation": "`setValue`方法会在赋值给任何表单控件之前先检查数据对象的值。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`会默默地失败。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "On the other hand,`setValue` will catch\nthe error and report it clearly.",
"translation": "而`setValue`会捕获错误,并清晰的报告它。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`结构是非常像的。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/guide/reactive-forms.md"
},
{
"original": "### _patchValue_",
"translation": "### _patchValue_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-3/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`中的指定控件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "This example sets only the form's `name` control.",
"translation": "这个例子只会设置表单的`name`控件。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`不会检查缺失的控件值,并且不会抛出有用的错误信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### When to set form model values (_ngOnChanges_)",
"translation": "### 什么时候设置表单的模型值(`ngOnChanges`",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/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/content-3/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/content-3/guide/reactive-forms.md"
},
{
"original": "Add the `hero` input property.",
"translation": "添加输入属性`hero`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Add the `ngOnChanges` method to the class as follows:",
"translation": "向该类中添加`ngOnChanges`方法,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### _reset_ the form flags",
"translation": "### *重置*表单的标识。",
"sourceFile": "/Users/twer/private/GDE/content-3/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/content-3/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/content-3/guide/reactive-forms.md"
},
{
"original": "### Create the _HeroListComponent_ and _HeroService_",
"translation": "### 创建`HeroListComponent`和`HeroService`",
"sourceFile": "/Users/twer/private/GDE/content-3/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:",
"translation": "`HeroDetalComponent`是一个嵌套在`HeroListComponent`的*主从*视图中的子组件。如果把它们放在一起就是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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`检测到英雄的变化,并使用当前英雄的值重置此表单。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "A \"Refresh\" button clears the hero list and the current selected hero before refetching the heroes.",
"translation": "\"刷新\"按钮清除英雄列表和当前选中的英雄,然后重新获取英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-3/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\")。",
"sourceFile": "/Users/twer/private/GDE/content-3/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接下来我们回到正轨继续学习*表单数组*属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Use _FormArray_ to present an array of _FormGroups_",
"translation": "## 使用`FormArray`来表示`FormGroup`数组",
"sourceFile": "/Users/twer/private/GDE/content-3/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`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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`的数组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "To _work_ with a `FormArray` you do the following:",
"translation": "要想使用`FormArray`,我们要这么做:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "1. Define the items (`FormControls` or `FormGroups`) in the array.",
"translation": "在数组中定义条目(`FormControl`或`FormGroup`)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "1. Initialize the array with items created from data in the _data model_.",
"translation": "把这个数组初始化微一组从*数据模型*中的数据创建的条目。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "1. Add and remove items as the user requires.",
"translation": "根据用户的需求添加或移除这些条目。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`,并且让用户添加或修改这些住址(移除住址功能请课后自行实现)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Youll 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`显示第一个英雄住址。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### From _address_ to _secret lairs_",
"translation": "### 从*住址*到*秘密小屋*Secret Lair",
"sourceFile": "/Users/twer/private/GDE/content-3/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`定义:",
"sourceFile": "/Users/twer/private/GDE/content-3/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`让我们遇到了一个重要问题:*表单模型*与*数据模型*不再匹配了。",
"sourceFile": "/Users/twer/private/GDE/content-3/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.",
"translation": "显然,必须在两者之间建立关联。但它在应用领域中的意义不限于此,它可以用于任何东西。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### Initialize the \"secretLairs\" _FormArray_",
"translation": "### 初始化`FormArray`型的`secretLairs`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "The default form displays a nameless hero with no addresses.",
"translation": "默认的表单显示一个无地址的无名英雄。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`来进行初始化。",
"sourceFile": "/Users/twer/private/GDE/content-3/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我们所要替换的是*控件*,而不是控件的*值*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Notice also that the _secretLairs_ `FormArray` contains **`FormGroups`**, not `Addresses`.",
"translation": "还要注意,`secretLairs`数组中包含的是**`FormGroup`,而不是`Address`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### Get the _FormArray_",
"translation": "### 获取`FormArray`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "The `HeroDetailComponent` should be able to display, add, and remove items from the _secretLairs_ `FormArray`.",
"translation": "`HeroDetailComponent`应该能从`secretLairs`中显示、添加和删除条目。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`的便捷属性中来让它更清晰,并供复用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### Display the _FormArray_",
"translation": "### 显示`FormArray`",
"sourceFile": "/Users/twer/private/GDE/content-3/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`.",
"translation": "当前HTML模板显示单个的地址`FormGroup`。\n我们要把它修改成能显示0、1或更多个表示英雄地址的`FormGroup`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "The trick lies in knowing how to write the `*ngFor`. There are three key points:",
"translation": "诀窍在于要知道如何编写`*ngFor`。主要有三点:",
"sourceFile": "/Users/twer/private/GDE/content-3/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.",
"translation": "在`*ngFor`的`<div>`之外套上另一个包装`<div>`,并且把它的`formArrayName`指令设为`\"secretLairs\"`。\n 这一步为内部的表单控件建立了一个`FormArray`型的`secretLairs`作为上下文以便重复渲染HTML模板。",
"sourceFile": "/Users/twer/private/GDE/content-3/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.",
"translation": "这些重复条目的数据源是`FormArray.controls`而不是`FormArray`本身。\n 每个控件都是一个`FormGroup`型的地址对象与以前的模板HTML所期望的格式完全一样。",
"sourceFile": "/Users/twer/private/GDE/content-3/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.",
"translation": "每个被重复渲染的`FormGroup`都需要一个独一无二的`formGroupName`,它必须是`FormGroup`在这个`FormArray`中的索引。\n 我们将复用这个索引,以便为每个地址组合出一个独一无二的标签。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Here's the skeleton for the _secret lairs_ section of the HTML template:",
"translation": "下面是HTML模板中*秘密小屋*部分的代码骨架:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Here's the complete template for the _secret lairs_ section:",
"translation": "这里是*秘密小屋*部分的完整模板:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### Add a new lair to the _FormArray_",
"translation": "### 把新的小屋添加到`FormArray`中",
"sourceFile": "/Users/twer/private/GDE/content-3/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`添加到其中。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/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”按钮时就保存一次。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### Try it!",
"translation": "### 试试看!",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### Remove a lair",
"translation": "### 移除一个小屋",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "## Observe control changes",
"translation": "## 监视控件的变化",
"sourceFile": "/Users/twer/private/GDE/content-3/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`。",
"sourceFile": "/Users/twer/private/GDE/content-3/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幸运的是我们可以通过订阅表单控件的属性之一来了解这些变化此属性会发出变更通知。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "Add the following method to log changes to the value of the _name_ `FormControl`.",
"translation": "添加下列方法,以监听姓名这个`FormControl`中值的变化。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Call it in the constructor, after creating the form.",
"translation": "在构造函数中调用它,就在创建表单的代码之后:",
"sourceFile": "/Users/twer/private/GDE/content-3/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`绑定在组件模板的底部显示这个数组:",
"sourceFile": "/Users/twer/private/GDE/content-3/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我们会看到每次按键都会记录一个新名字。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### When to use it",
"translation": "### 什么时候用它",
"sourceFile": "/Users/twer/private/GDE/content-3/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*在组件类中*订阅表单控件属性变化的可观察对象以触发应用逻辑则是比较难的方式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Save form data",
"translation": "## 保存表单数据",
"sourceFile": "/Users/twer/private/GDE/content-3/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:",
"translation": "`HeroDetailComponent`捕获了用户输入,但没有用它做任何事。\n在真实的应用中我们可能要保存这些英雄的变化。\n在真实的应用中我们还要能丢弃未保存的变更然后继续编辑。\n在实现完本节的这些特性之后表单是这样的",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### Save",
"translation": "### 保存",
"sourceFile": "/Users/twer/private/GDE/content-3/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`的一个方法来进行保存。",
"sourceFile": "/Users/twer/private/GDE/content-3/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`助手来深层复制变化后的模型值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "**Address deep copy**",
"translation": "**地址的深层复制**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"original": "### Revert (cancel changes)",
"translation": "### 丢弃(撤销修改)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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`数据模型来构建出*表单模型*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "### Buttons",
"translation": "### 按钮",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "Add the \"Save\" and \"Revert\" buttons near the top of the component's template:",
"translation": "把“Save”和“Revert”按钮添加到组件模板的顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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/content-3/guide/reactive-forms.md"
},
{
"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/content-3/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 plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\"></live-example>吧。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "* How to create a reactive form component and its corresponding template.",
"translation": "如何创建一个响应式表单控件及其对应的模板。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "* How to use `FormBuilder` to simplify coding a reactive form.",
"translation": "如何使用`FormBuilder`来简化响应式表单的编码工作。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "* Grouping `FormControls`.",
"translation": "分组`FormControl`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "* Inspecting `FormControl` properties.",
"translation": "审查`FormControl`的属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "* Setting data with `patchValue` and `setValue`.",
"translation": "使用`patchValue`和`setValue`设置数据。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "* Adding groups dynamically with `FormArray`.",
"translation": "使用`FormArray`动态添加控件组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "* Observing changes to the value of a `FormControl`.",
"translation": "监听`FormControl`中值的变化。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "* Saving form changes.",
"translation": "保存表单中的更改。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "The key files of the final version are as follows:",
"translation": "最终版中的核心文件如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"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 Plunker\">响应式表单在线例子</live-example>中下载本章所有步骤的完整代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/reactive-forms.md"
},
{
"original": "# Routing & Navigation",
"translation": "# 路由与导航",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "## Overview",
"translation": "## 概览",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The browser is a familiar model of application navigation:",
"translation": "浏览器具有我们熟悉的导航模式:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Enter a URL in the address bar and the browser navigates to a corresponding page.",
"translation": "在地址栏输入URL浏览器就会导航到相应的页面。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Click links on the page and the browser navigates to a new page.",
"translation": "在页面中点击链接,浏览器就会导航到一个新页面。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "## The Basics",
"translation": "## 基础知识",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "An introduction to a few core router concepts will help orient you to the details that follow.",
"translation": "在接触细节之前,我们先来介绍关于路由的一些核心概念。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### *&lt;base href>*",
"translation": "### *&lt;base href>* 元素",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Router imports",
"translation": "### 从路由库中导入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Configuration",
"translation": "### 配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Router outlet",
"translation": "### 路由出口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Router links",
"translation": "### 路由器链接",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Consider the following template:",
"translation": "考虑下列模板:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Router state",
"translation": "### 路由器状态",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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": "路由器状态为我们提供了从任意激活路由开始向上或向下遍历路由树的一种方式,以获得关于父、子、兄弟路由的信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Activated route",
"translation": "### 激活的路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Property",
"translation": "属性\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述\n </th>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "An `Observable` of the route path(s), represented as an array of strings for each part of the route path.",
"translation": "路由路径的`Observable`对象,是一个由路由路径中的各个部分组成的字符串数组。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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)解析而来的值。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The name of the `RouterOutlet` used to render the route. For an unnamed outlet, the outlet name is _primary_.",
"translation": "要把该路由渲染到的`RouterOutlet`的名字。对于无名路由,它的路由名是`primary`,而不是空串。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The route configuration used for the route that contains the origin path.",
"translation": "用于该路由的路由配置信息,其中包含原始路径。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The route's parent `ActivatedRoute` when this route is a [child route](#child-routing-component).",
"translation": "当该路由是一个[子路由](#child-routing-component)时,表示该路由的父级`ActivatedRoute`。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Contains the first `ActivatedRoute` in the list of this route's child routes.",
"translation": "包含该路由的子路由列表中的第一个`ActivatedRoute`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Contains all the [child routes](#child-routing-component) activated under the current route.",
"translation": "包含当前路由下所有已激活的[子路由](#child-routing-component)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "**`params`** &mdash; 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/content-3/guide/router.md"
},
{
"original": "**`queryParams`** &mdash; 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/content-3/guide/router.md"
},
{
"original": "### Router events",
"translation": "### 路由事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Router Event",
"translation": "路由器事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "An [event](api/router/NavigationStart) triggered when navigation starts.",
"translation": "本[事件](api/router/NavigationStart)会在导航开始时触发。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "An [event](api/router/RouteConfigLoadEnd) triggered after a route has been lazy loaded.",
"translation": "本[事件](api/router/RouteConfigLoadEnd)会在路由被惰性加载之后触发。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "An [event](api/router/NavigationEnd) triggered when navigation ends successfully.",
"translation": "本[事件](api/router/NavigationEnd)会在导航成功结束之后触发。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "An [event](api/router/NavigationError) triggered when navigation fails due to an unexpected error.",
"translation": "这个[事件](api/router/NavigationError)会在导航由于意料之外的错误而失败时触发。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Summary",
"translation": "### 总结一下",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Here are the key `Router` terms and their meanings:",
"translation": "下面是一些*路由器*中的关键词汇及其含义:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Router Part",
"translation": "路由器部件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Meaning",
"translation": "含义",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Router",
"translation": "<code>Router</code>(路由器)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "RouterModule",
"translation": "<code>RouterModule</code>(路由器模块)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "A separate NgModule that provides the necessary service providers\n and directives for navigating through application views.",
"translation": "<p>\n 一个独立的Angular模块用于提供所需的服务提供商以及用来在应用视图之间进行导航的指令。\n </p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Routes",
"translation": "<code>Routes</code>(路由数组)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Defines an array of Routes, each mapping a URL path to a component.",
"translation": "定义了一个路由数组每一个都会把一个URL路径映射到一个组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Route",
"translation": "<code>Route</code>(路由)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "RouterOutlet",
"translation": "<code>RouterOutlet</code>(路由出口)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The directive (<code>&lt;router-outlet></code>) that marks where the router displays a view.",
"translation": "该指令(<code>&lt;router-outlet></code>)用来标记出路由器该在哪里显示视图。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "RouterLink",
"translation": "<code>RouterLink</code>(路由链接)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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>link parameters array</i> triggers a navigation.",
"translation": "该指令用来把一个可点击的HTML元素绑定到路由。\n 点击带有绑定到<i>字符串</i>或<i>链接参数数组</i>的<code>routerLink</code>指令的元素就会触发一次导航。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "RouterLinkActive",
"translation": "<code>RouterLinkActive</code>(活动路由链接)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "ActivatedRoute",
"translation": "<code>ActivatedRoute</code>(激活的路由)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "RouterState",
"translation": "<code>RouterState</code>(路由器状态)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "<i>Link parameters array</i>",
"translation": "链接参数数组",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "An array that the router interprets as a routing instruction.\n You can bind that array toa <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/content-3/guide/router.md"
},
{
"original": "<i>Routing component</i>",
"translation": "<i>路由组件</i>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "<td>\n<p> An Angular component with a <code>RouterOutlet</code> that displays views based on router navigations.\n</p>",
"translation": "<p>\n 一个带有<code>RouterOutlet</code>的Angular组件它根据路由器的导航来显示相应的视图。\n </p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "## The sample application",
"translation": "## 范例应用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* Organizing the application features into modules.",
"translation": "把应用的各个特性组织成模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Navigating to a component (*Heroes* link to \"Heroes List\").",
"translation": "导航到组件(*Heroes*链接到“英雄列表”组件)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Including a route parameter (passing the Hero `id` while routing to the \"Hero Detail\").",
"translation": "包含一个路由参数(当路由到“英雄详情”时,把该英雄的`id`传进去)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Child routes (the *Crisis Center* has its own routes).",
"translation": "子路由(*危机中心*特性有一组自己的路由)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The `CanActivate` guard (checking route access).",
"translation": "`CanActivate`守卫(检查路由的访问权限)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The `CanActivateChild` guard (checking child route access).",
"translation": "`CanActivateChild`守卫(检查子路由的访问权限)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The `CanDeactivate` guard (ask permission to discard unsaved changes).",
"translation": "`CanDeactivate`守卫(询问是否丢弃未保存的更改)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The `Resolve` guard (pre-fetching route data).",
"translation": "`Resolve`守卫(预先获取路由数据)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Lazy loading feature modules.",
"translation": "惰性加载特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The `CanLoad` guard (check before loading feature module assets).",
"translation": "`CanLoad`守卫(在加载特性模块之前进行检查)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### The sample application in action",
"translation": "### 范例程序的动图",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The application has three main feature areas:",
"translation": "本应用具有三个主要的特性区:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. A *Crisis Center* for maintaining the list of crises for assignment to heroes.",
"translation": "*危机中心*用于维护要指派给英雄的危机列表。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. A *Heroes* area for maintaining the list of heroes employed by the agency.",
"translation": "*英雄*区用于维护管理局雇佣的英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. An *Admin* area to manage the list of crises and heroes.",
"translation": "*管理*区会管理危机和英雄的列表。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Try it by clicking on this <live-example title=\"Hero Employment Agency Live Example\">live example link</live-example>.",
"translation": "点击<live-example title=\"Hero Employment Agency Live Example\"></live-example>试用一下。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Select one hero and the app takes you to a hero editing screen.",
"translation": "选择其中之一,该应用就会把我们带到此英雄的编辑页面。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Now click the *Crisis Center* link for a list of ongoing crises.",
"translation": "现在,点击*危机中心*链接,前往*危机*列表页。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Up pops a dialog box.",
"translation": "我们会看到弹出了一个对话框。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You can say \"OK\" and lose your changes or click \"Cancel\" and continue editing.",
"translation": "我们可以回答“确定”以放弃这些更改,或者回答“取消”来继续编辑。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Proceed to the first application milestone.",
"translation": "我们这就开始本应用的第一个里程碑。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "## Milestone 1: Getting started with the router",
"translation": "## 里程碑1从路由器开始",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Begin with a simple version of the app that navigates between two empty views.",
"translation": "开始本应用的一个简版,它在两个空路由之间导航。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Set the *&lt;base href>*",
"translation": "### 设置*&lt;base href>*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "You must **add a\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base\" title=\"base href\">&lt;base href&gt; 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\">&lt;base href&gt; 元素</a>**,这样`pushState`才能正常工作。\n当引用CSS文件、脚本和图片时浏览器会用`<base href>`的值作为*相对*URL的前缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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": "像Plunker这样的在线编程环境会动态设置应用的基地址base href因此我们没办法指定固定的地址。\n这就是为什么我们要用一个脚本动态写入`<base>`标签,而不是直接写`<base href...>`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You only need this trick for the live example, not production code.",
"translation": "我们只应该在在线例子这种情况下使用这种小花招,不要把它用到产品的正式代码中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Importing from the router library",
"translation": "### 从路由库中导入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "You teach the router how to navigate by configuring it with routes.",
"translation": "通过一些路由来配置路由器,我们可以教它如何进行导航。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### Define routes",
"translation": "#### 定义路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "A router must be configured with a list of route definitions.",
"translation": "路由器必须用“路由定义”的列表进行配置。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "In simpler terms, you might say this of the first route:",
"translation": "直白的说,我们可以这样解释第一个路由:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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随着应用的成长我们将需要将路由配置重构到单独的文件并创建**[路由模块](guide/router#routing-module)** - 一种特别的、专门为特性模块的路由器服务的**服务模块**。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Providing the `RouterModule` in the `AppModule` makes the Router available everywhere in the application.",
"translation": "在`AppModule`中提供`RouterModule`,让该路由器在应用的任何地方都能被使用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### The *AppComponent* shell",
"translation": "### *AppComponent*外壳组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The corresponding component template looks like this:",
"translation": "该组件所对应的模板是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### *RouterOutlet*",
"translation": "### *RouterOutlet* 指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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>`。\n但路由器可以支持多个*命名的*出口outlet将来我们会涉及到这部分特性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### *RouterLink* binding",
"translation": "### `routerLink` 绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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=\"...\"`。我们从路由库中导入了`RouterLink`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### *RouterLinkActive* binding",
"translation": "### `routerLinkActive`绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### *Router directives*",
"translation": "### *路由器指令集*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The current state of `app.component.ts` looks like this:",
"translation": "`app.component.ts`目前是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Wildcard route",
"translation": "### 通配符路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Create the `PageNotFoundComponent` to display when users visit invalid URLs.",
"translation": "创建`PageNotFoundComponent`,以便在用户访问无效网址时显示它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "As with the other components, add the `PageNotFoundComponent` to the `AppModule` declarations.",
"translation": "像其它组件一样,把`PageNotFoundComponent`添加到`AppModule`的声明中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### The _default_ route to heroes",
"translation": "### 把*默认*路由设置为英雄列表",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "When the application launches, the initial URL in the browser bar is something like:",
"translation": "应用启动时浏览器地址栏中的初始URL是这样的",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Redirecting routes",
"translation": "### 重定向路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Basics wrap up",
"translation": "### “起步阶段”总结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "You've learned how to do the following:",
"translation": "我们已经学会了如何:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Load the router library.",
"translation": "加载路由库",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* Add a `router-outlet` to the shell template where views will be displayed.",
"translation": "往壳组件的模板中添加一个`router-outlet`指令,视图将会被显示在那里",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Configure the router module with `RouterModule.forRoot`.",
"translation": "用`RouterModule.forRoot`配置路由器模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Set the router to compose HTML5 browser URLs.",
"translation": "设置路由器使其合成HTML5模式的浏览器URL。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* handle invalid routes with a `wildcard` route.",
"translation": "使用通配符路由来处理无效路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* navigate to the default route when the app launches with an empty path.",
"translation": "当应用在空路径下启动时,导航到默认路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The starter app's structure looks like this:",
"translation": "这个初学者应用的结构是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Here are the files discussed in this milestone.",
"translation": "下面是当前里程碑中讨论过的文件列表:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "## Milestone 2: *Routing module*",
"translation": "## 里程碑 #2**路由模块**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The **Routing Module** has several characteristics:",
"translation": "**路由模块**有一系列特性:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Separates routing concerns from other application concerns.",
"translation": "把路由这个关注点从其它应用类关注点中分离出去",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Provides a module to replace or remove when testing the application.",
"translation": "测试特性模块时,可以替换或移除路由模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Provides a well-known location for routing service providers including guards and resolvers.",
"translation": "为路由服务提供商(包括守卫和解析器等)提供一个共同的地方",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Does **not** declare components.",
"translation": "**不要**[声明组件](guide/ngmodule-faq#routing-module)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Refactor the routing configuration into a _routing module_",
"translation": "### 将路由配置重构为*路由模块*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "After these steps, the file should look like this.",
"translation": "做完这些之后,该文件变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Do you need a _Routing Module_?",
"translation": "### 你需要**路由模块**吗?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Choose one pattern or the other and follow that pattern consistently.",
"translation": "我们建议你选择其中一种模式,并坚持模式的一致性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Most developers should always implement a Routing Module for the sake of consistency.",
"translation": "大多数开发者应该采用路由模块,以保持一致性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "It 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开发者可以很自然的从路由模块中查找和扩展路由配置。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "## Milestone 3: Heroes feature",
"translation": "## 里程碑 #2 英雄特征区",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You've seen how to navigate using the `RouterLink` directive.\nNow you'll learn the following:",
"translation": "我们刚刚学习了如何用`RouterLink`指令进行导航。接下来我们将到:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Organize the app and routes into *feature areas* using modules.",
"translation": "用模块把应用和路由组织为一些*特性区*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Navigate imperatively from one component to another.",
"translation": "命令式地从一个组件导航到另一个组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Pass required and optional information in route parameters.",
"translation": "通过路由传递必要信息和可选信息",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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=\"Tour of Heroes: Services example code\"></live-example>中赋值大部分代码过来。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Here's how the user will experience this version of the app:",
"translation": "下面是用户将看到的版本:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "A typical application has multiple *feature areas*,\neach dedicated to a particular business purpose.",
"translation": "典型的应用具有多个*特性区*,每个特性区都专注于特定的业务用途。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Add heroes functionality",
"translation": "### 添加英雄管理功能",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Follow these steps:",
"translation": "按照下列步骤:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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=\"Tour of Heroes: Services example code\">教程中的“服务”部分</live-example>的代码复制到`app.component.ts`中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Make a few minor but necessary changes:",
"translation": "做一些微小但必要的修改:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Delete the `selector` (routed components don't need them).",
"translation": "删除`selector`(路由组件不需要它们)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Delete the `<h1>`.",
"translation": "删除`<h1>`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Relabel the `<h2>` to `<h2>HEROES</h2>`.",
"translation": "给`<h2>`加文字,改成`<h2>HEROES</h2>`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Delete the `<hero-detail>` at the bottom of the template.",
"translation": "删除模板底部的`<hero-detail>`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Rename the `AppComponent` class to `HeroListComponent`.",
"translation": "把`AppComponent`类改名为`HeroListComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "When you're done, you'll have these *hero management* files:",
"translation": "安排完这些,我们就有了四个*英雄管理*特性区的文件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### *Hero* feature routing requirements",
"translation": "### *英雄*特性区的路由需求",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### *Hero* feature route configuration",
"translation": "### *英雄*特性区的路由配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Add the routing module to the _HeroesModule_",
"translation": "### 把路由模块添加到`HeroesModule`中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Add the `HeroRoutingModule` to the `HeroModule`\njust as you added `AppRoutingModule` to the `AppModule`.",
"translation": "我们在`Heroes`模块中从`heroes-routing.module.ts`中导入`HeroRoutingModule`,并注册其路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Remove duplicate hero routes",
"translation": "### 移除重复的“英雄管理”路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Import hero module into AppModule",
"translation": "### 把“英雄管理”模块导入到AppModule",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "After these steps, the `AppModule` should look like this:",
"translation": "经过这些步骤,`AppModule`变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Module import order matters",
"translation": "### 导入模块的顺序很重要",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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 &mdash; which matches _every_ URL &mdash;\nwill intercept the attempt to navigate to a hero route.",
"translation": "每个路由模块都会根据*导入的顺序*把自己的路由配置追加进去。\n如果我们先列出了`AppRoutingModule`,那么通配符路由就会被注册在“英雄管理”路由*之前*。\n通配符路由它匹配*任意*URL将会拦截住每一个到“英雄管理”路由的导航因此事实上屏蔽了所有“英雄管理”路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Route definition with a parameter",
"translation": "### 带参数的路由定义",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Setting the route parameters in the list view",
"translation": "### 在列表视图中设置路由参数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### _Activated Route_ in action",
"translation": "#### _Activated Route_ 实战",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Import the `Router`, `ActivatedRoute`, and `ParamMap` tokens from the router package.",
"translation": "我们要从路由器(`router`)包中导入`Router`、`ActivatedRoute`和`Params`类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Import the `switchMap` operator because you need it later to process the `Observable` route parameters.",
"translation": "这里导入`switchMap`操作符是因为我们稍后将会处理路由参数的可观察对象`Observable`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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": "由于参数是作为`Observable`提供的,所以我们得用`switchMap`操作符来根据名字取得`id`参数,并告诉`HeroService`来获取带有那个`id`的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "#### _ParamMap_ API",
"translation": "#### _ParamMap_ 参数 API",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Member",
"translation": "成员\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述\n </th>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Returns `true` if the parameter name is in the map of parameters.",
"translation": "如果参数名位于参数列表中,就返回 `true` 。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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`。如果参数值实际上是一个数组,就返回它的*第一个*元素。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Returns a `string array` of all parameter names in the map.",
"translation": "返回这个map中的所有参数名组成的字符串数组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### Observable <i>paramMap</i> and component reuse",
"translation": "#### <i>参数</i>的可观察对象Observable与组件复用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Feel free to unsubscribe anyway. It is harmless and never a bad practice.",
"translation": "不过,我们仍然可以随意取消订阅,这不会造成任何损害,而且也不是一项坏的实践。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### _Snapshot_: the _no-observable_ alternative",
"translation": "#### *Snapshot*快照当不需要Observable时的替代品",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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如果有可能连续多次导航到此组件那么就该用`params`可观察对象的方式。\n我们在这里选择使用`params`可观察对象策略,以防万一。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Navigating back to the list component",
"translation": "### 导航回列表组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "{@a optional-route-parameters}",
"translation": "### Route Parameters: Required or optional?\n### 路由参数:必须还是可选?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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`返回时在URL中带上英雄Magneta的`id`,不就可以了吗?接下来我们就尝试实现这个场景。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Optional information takes other forms. Search criteria are often loosely structured, e.g., `name='wind*'`.\nMultiple values are common&mdash;`after='12/31/2015' & before='1/1/2017'`&mdash;in no\nparticular order&mdash;`before='1/1/2017' & after='12/31/2015'`&mdash; in a\nvariety of formats&mdash;`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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Heroes list: optionally selecting a hero",
"translation": "### 英雄列表:选定一个英雄(也可不选)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The application still works. Clicking \"back\" returns to the hero list view.",
"translation": "该应用仍然能工作。点击“back”按钮返回英雄列表视图。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Look at the browser address bar.",
"translation": "注意浏览器的地址栏。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "It should look something like this, depending on where you run it:",
"translation": "它应该是这样的,不过也取决于你在哪里运行它:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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 &mdash; something you may not have seen before.",
"translation": "可选的路由参数没有使用“?”和“&”符号分隔因为它们将用在URL查询字符串中。\n它们是**用“;”分隔的**。\n这是*矩阵URL*标记法 —— 我们以前可能从未见过。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Route parameters in the *ActivatedRoute* service",
"translation": "### *ActivatedRoute*服务中的路由参数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The list of heroes is unchanged. No hero row is highlighted.",
"translation": "英雄列表仍没有改变,没有哪个英雄列被加亮显示。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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`中。我们把该服务注入到了`HeroDetailComponent`的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "First you extend the router import statement to include the `ActivatedRoute` service symbol:",
"translation": "首先,我们扩展该路由的导入语句,以包含进`ActivatedRoute`服务的类;",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Import the `switchMap` operator to perform an operation on the `Observable` of route parameter map.",
"translation": "我们将导入`switchMap`操作符,在路由参数的`Observable`对象上执行操作。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Then you inject the `ActivatedRoute` in the `HeroListComponent` constructor.",
"translation": "接着,我们注入`ActivatedRoute`到`HeroListComponent`的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The optional `foo` route parameter is harmless and continues to be ignored.",
"translation": "这儿可选的`foo`路由参数人畜无害,并继续被忽略。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Adding animations to the routed component",
"translation": "### 为路由组件添加动画",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The heroes feature module is almost complete, but what is a feature without some smooth transitions?",
"translation": "这个“英雄”特性模块就要完成了,但这个特性还没有平滑的转场效果。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "This section shows you how to add some [animations](guide/animations)\nto the `HeroDetailComponent`.",
"translation": "在这一节,我们将为*英雄详情*组件添加一些[动画](guide/animations)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "First import `BrowserAnimationsModule`:",
"translation": "首先导入`BrowserAnimationsModule`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "This file does the following:",
"translation": "该文件做了如下工作:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Imports the animation symbols that build the animation triggers, control state, and manage transitions between states.",
"translation": "导入动画符号以构建动画触发器、控制状态并管理状态之间的过渡。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* Specifies the _wildcard state_ , `*`, that matches any animation state that the route component is in.",
"translation": "指定了一个*通配符状态* —— `*`,它匹配该路由组件存在时的任何动画状态。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Add an `animations` array to the `@Component` metadata's that contains the `slideInDownAnimation`.",
"translation": "把一个包含`slideInDownAnimation`的`animations`数组添加到`@Component`的元数据中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The other two `@HostBinding` properties style the display and position of the component.",
"translation": "另外两个`@HostBinding`属性指定组件的外观和位置。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Milestone 3 wrap up",
"translation": "### 里程碑#3的总结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You've learned how to do the following:",
"translation": "我们学到了如何:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Organize the app into *feature areas*.",
"translation": "把应用组织成*特性区*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Navigate imperatively from one component to another.",
"translation": "命令式的从一个组件导航到另一个",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Pass information along in route parameters and subscribe to them in the component.",
"translation": "通过路由参数传递信息,并在组件中订阅它们",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Import the feature area NgModule into the `AppModule`.",
"translation": "把这个特性分区模块导入根模块`AppModule`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Apply animations to the route component.",
"translation": "把动画应用到路由组件上",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "After these changes, the folder structure looks like this:",
"translation": "做完这些修改之后,目录结构是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Here are the relevant files for this version of the sample application.",
"translation": "这里是当前版本的范例程序相关文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "## Milestone 4: Crisis center feature",
"translation": "## 里程碑#4危机中心",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "It's time to add real features to the app's current placeholder crisis center.",
"translation": "是时候往该应用的危机中心(现在是占位符)中添加一些真实的特性了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Begin by imitating the heroes feature:",
"translation": "我们先从模仿“英雄管理”中的特性开始:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Delete the placeholder crisis center file.",
"translation": "删除危机中心的占位文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Create an `app/crisis-center` folder.",
"translation": "创建`app/crisis-center`文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Copy the files from `app/heroes` into the new crisis center folder.",
"translation": "把`app/heroes`中的文件复制到新的危机中心文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "You'll turn the `CrisisService` into a purveyor of mock crises instead of mock heroes:",
"translation": "我们将会把`CrisisService`转换成模拟的危机列表,而不再是模拟的英雄列表:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The resulting crisis center is a foundation for introducing a new concept&mdash;**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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### A crisis center with child routes",
"translation": "### 带有子路由的危机中心",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "This section shows you how to organize the crisis center\nto conform to the following recommended pattern for Angular applications:",
"translation": "本节会展示如何组织危机中心来满足Angular应用所推荐的模式* Each feature area resides in its own folder. 把每个特性放在自己的目录中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Each feature has its own Angular feature module.",
"translation": "每个特性都有自己的Angular特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Each area has its own area root component.",
"translation": "每个特性区都有自己的根组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Each area root component has its own router outlet and child routes.",
"translation": "每个特性区的根组件中都有自己的路由出口及其子路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Feature area routes rarely (if ever) cross with routes of other features.",
"translation": "特性区的路由很少(或完全不)与其它特性区的路由交叉。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "If your app had many feature areas, the app component trees might look like this:",
"translation": "如果我们有更多特性区,它们的组件树是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Child routing component",
"translation": "### 子路由组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The `CrisisCenterComponent` has the following in common with the `AppComponent`:",
"translation": "`CrisisCenterComponent`和`AppComponent`有下列共同点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Child route configuration",
"translation": "### 子路由配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "These two routes navigate to the crisis center child components,\n`CrisisCenterHomeComponent` and `CrisisDetailComponent`, respectively.",
"translation": "这两个路由导航到了*危机中心*的两个子组件:`CrisisCenterHomeComponent`和`CrisisDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "There are *important differences* in the way the router treats these _child routes_.",
"translation": "对这些路由的处理中有一些*重要的不同*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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.",
"translation": "`Crisis Detail`路由是`Crisis List`的子路由。由于路由器默认会[复用组件](guide/router#reuse),因此当我们选择了另一个危机时,`CrisisDetailComponent`会被复用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "In contrast, back in the `Hero Detail` route, the component was recreated each time you selected a different hero.",
"translation": "作为对比,回到`Hero Detail`路由时,每当我们选择了不同的英雄时,该组件都会被重新创建。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The absolute URL for the latter example, including the `localhost` origin, is",
"translation": "本例子中包含站点部分的绝对URL就是",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Here's the complete `crisis-center-routing.module.ts` file with its imports.",
"translation": "这里是完整的`crisis-center.routing.ts`及其导入语句。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Import crisis center module into the *AppModule* routes",
"translation": "### 把危机中心模块导入到`AppModule`的路由中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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`中移除了危机中心的初始路由。我们的路由现在是由`HeroesModule`和`CrisisCenter`特性模块提供的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The `app-routing.module.ts` file retains the top-level application routes such as the default and wildcard routes.",
"translation": "我们将保持`app.routing.ts`文件中只有通用路由,本章稍后会讲解它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Relative navigation",
"translation": "### 相对导航",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The router matches such _absolute_ paths to routes starting from the top of the route configuration.",
"translation": "路由器会从路由配置的顶层来匹配像这样的*绝对路径*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Here's an example:",
"translation": "例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The router supports directory-like syntax in a _link parameters list_ to help guide route name lookup:",
"translation": "在*链接参数数组*中,路由器支持“目录式”语法来指导我们如何查询路由名:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "`./` or `no leading slash` is relative to the current level.",
"translation": "`./`或`无前导斜线`形式是相对于当前级别的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "`../` to go up one level in the route path.",
"translation": "`../`会回到当前路由路径的上一级。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "**Always** specify the complete _absolute_ path when calling router's `navigateByUrl` method.",
"translation": "当调用路由器的`navigateByUrl`时,**总是**要指定完整的*绝对路径*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Navigate to crisis list with a relative URL",
"translation": "把*危机列表*的`onSelect`方法改成使用相对导航,以便我们不用每次都从路由配置的顶层开始。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You've already injected the `ActivatedRoute` that you need to compose the relative navigation path.",
"translation": "我们已经注入过了`ActivatedRoute`,我们需要它来和相对导航路径组合在一起。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Displaying multiple routes in named outlets",
"translation": "### 用命名出口outlet显示多重路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Add an outlet named \"popup\" in the `AppComponent`, directly below the unnamed outlet.",
"translation": "在`AppComponent`中添加一个名叫“popup”的出口就在无名出口的下方。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "#### Secondary routes",
"translation": "#### 第二路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Named outlets are the targets of _secondary routes_.",
"translation": "命名出口是*第二路由*的目标。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* They are displayed in named outlets.",
"translation": "它们显示在命名出口中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Here's the component and its template:",
"translation": "下面是该组件及其模板:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "#### Add a secondary route",
"translation": "#### 添加第二路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Open the `AppRoutingModule` and add a new `compose` route to the `appRoutes`.",
"translation": "打开`AppRoutingModule`,并把一个新的`compose`路由添加到`appRoutes`中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "#### Secondary route navigation: merging routes during navigation",
"translation": "#### 第二路由导航:在导航期间合并路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The interesting part of the URL follows the `...`:",
"translation": "这个URL中有意思的部分是`...`后面的这些:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The `crisis-center` is the primary navigation.",
"translation": "`crisis-center`是主导航。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Parentheses surround the secondary route.",
"translation": "圆括号包裹的部分是第二路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Click the _Heroes_ link and look at the URL again.",
"translation": "点击*Heroes*链接并再次查看URL",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The primary navigation part has changed; the secondary route is the same.",
"translation": "主导航的部分变化了,而第二路由没有变。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Experiment with these possibilities at your leisure.",
"translation": "有空的时候你可以自行试验这些可能性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### Clearing secondary routes",
"translation": "#### 清除第二路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "## Milestone 5: Route guards",
"translation": "## 里程碑5路由守卫",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* Perhaps the user is not authorized to navigate to the target component.",
"translation": "该用户可能无权导航到目标组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Maybe the user must login (*authenticate*) first.",
"translation": "可能用户得先登录(认证)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Maybe you should fetch some data before you display the target component.",
"translation": "在显示目标组件前,我们可能得先获取某些数据。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* You might want to save pending changes before leaving a component.",
"translation": "在离开组件前,我们可能要先保存修改。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* You might ask the user if it's OK to discard pending changes rather than save them.",
"translation": "我们可能要询问用户:你是否要放弃本次更改,而不用保存它们?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You can add _guards_ to the route configuration to handle these scenarios.",
"translation": "我们可以往路由配置中添加***守卫***,来处理这些场景。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "A guard's return value controls the router's behavior:",
"translation": "守卫返回一个值,以控制路由器的行为:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* If it returns `true`, the navigation process continues.",
"translation": "如果它返回`true`,导航过程会继续",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* If it returns `false`, the navigation process stops and the user stays put.",
"translation": "如果它返回`false`,导航过程会终止,且用户会留在原地。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation.",
"translation": "守卫还可以告诉路由器导航到别处,这样也取消当前的导航。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* [`CanActivate`](api/router/CanActivate) to mediate navigation *to* a route.",
"translation": "用[`CanActivate`](api/router/CanActivate)来处理导航*到*某路由的情况。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* [`CanActivateChild`](api/router/CanActivateChild) to mediate navigation *to* a child route.",
"translation": "用[`CanActivateChild`](api/router/CanActivateChild)来处理导航*到*某子路由的情况。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* [`CanDeactivate`](api/router/CanDeactivate) to mediate navigation *away* from the current route.",
"translation": "用[`CanDeactivate`](api/router/CanDeactivate)来处理从当前路由*离开*的情况.",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* [`Resolve`](api/router/Resolve) to perform route data retrieval *before* route activation.",
"translation": "用[`Resolve`](api/router/Resolve)在路由激活*之前*获取路由数据。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* [`CanLoad`](api/router/CanLoad) to mediate navigation *to* a feature module loaded _asynchronously_.",
"translation": "用[`CanLoad`](api/router/CanLoad)来处理*异步*导航到某特性模块的情况。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "There are several examples over the next few sections.",
"translation": "我们会在接下来的小节中看到一些例子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### _CanActivate_: requiring authentication",
"translation": "### *CanActivate*: 要求认证",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The `CanActivate` guard is the tool to manage these navigation business rules.",
"translation": "`CanActivate`守卫是一个管理这些导航类业务规则的工具。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### Add an admin feature module",
"translation": "#### 添加一个“管理”特性模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Create an `admin` folder with a feature module file, a routing configuration file, and supporting components.",
"translation": "创建一个`admin`目录,它带有一个特性模块文件、一个路由配置文件和一些支持性组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The admin feature file structure looks like this:",
"translation": "管理特性区的文件是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The initial admin routing configuration:",
"translation": "我们的初始管理路由配置如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Component-less route: grouping routes without a component",
"translation": "### 无组件路由: 不借助组件对路由进行分组",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Add an \"Admin\" link to the `AppComponent` shell so that users can get to this feature.",
"translation": "然后我们往壳组件`AppComponent`中添加一个链接,让用户能点击它,以访问该特性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### Guard the admin feature",
"translation": "#### 守护“管理特性”区",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "This is a general purpose guard&mdash;you can imagine other features\nthat require authenticated users&mdash;so you create an\n`auth-guard.service.ts` in the application root folder.",
"translation": "这是一种具有通用性的守护目标(通常会有其它特性需要登录用户才能访问),所以我们在应用的根目录下创建一个`auth-guard.ts`文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The admin feature is now protected by the guard, albeit protected poorly.",
"translation": "我们的管理特性区现在受此守卫保护了,不过这样的保护还不够。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### Teach *AuthGuard* to authenticate",
"translation": "#### 教*AuthGuard*进行认证",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Make the `AuthGuard` at least pretend to authenticate.",
"translation": "我们先让`AuthGuard`至少能“假装”进行认证。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Revise the `AuthGuard` to call it.",
"translation": "我们这就修改`AuthGuard`来调用它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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&mdash;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/content-3/guide/router.md"
},
{
"original": "#### Add the *LoginComponent*",
"translation": "#### 添加*LoginComponent*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You need a `LoginComponent` for the user to log in to the app. After logging in, you'll redirect\n to the stored URL if available, or use the default URL.\n There 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/content-3/guide/router.md"
},
{
"original": "Register a `/login` route in the `login-routing.module.ts` and add the necessary providers to the `providers`\n array. In `app.module.ts`, import the `LoginComponent` and add it to the `AppModule` `declarations`.\n Import 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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### _CanActivateChild_: guarding child routes",
"translation": "### `CanAcitvateChild`:保护子路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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`守卫和`CanAcitvate`守卫很像。\n它们的区别在于`CanActivateChild`会在*任何子路由*被激活之前运行。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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": "接下来,实现`CanAcitvateChild`方法,它所接收的参数与`CanAcitvate`方法一样:一个`ActivatedRouteSnapshot`和一个`RouterStateSnapshot`。\n`CanAcitvateChild`方法可以返回`Observable<boolean>`或`Promise<boolean>`来支持异步检查,或`boolean`来支持同步检查。\n这里返回的是`boolean`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### _CanDeactivate_: handling unsaved changes",
"translation": "### *CanDeactivate*:处理未保存的更改",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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": "我们应该暂停,并让用户决定该怎么做。如果用户选择了取消,我们就留下来,并允许更多改动。如果用户选择了确认,那就进行保存。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "You can't block while waiting for the server&mdash;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/content-3/guide/router.md"
},
{
"original": "You need the `CanDeactivate` guard.",
"translation": "我们需要`CanDeactivate`守卫。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Cancel and save",
"translation": "### 取消与保存",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Both buttons navigate back to the crisis list after save or cancel.",
"translation": "这两个按钮都会在保存或取消之后导航回危机列表。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "You could wait for the user's answer with synchronous, blocking code.\nThe app will be more responsive&mdash;and can do other work&mdash;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/content-3/guide/router.md"
},
{
"original": "The `DialogService`, provided in the `AppModule` for app-wide use, does the asking.",
"translation": "`DialogService`(为了在应用级使用,已经注入到了`AppModule`)就可以做到这些。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Create a _guard_ that checks for the presence of a `canDeactivate()` method in a component&mdash;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`函数的工作现场,在这里,它就是`CrisisDetailComponent`。我们并不需要知道`CrisisDetailComponent`确认退出激活状态的详情。这让我们的守卫可以被复用,这是一次轻而易举的胜利。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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`守卫。在需要访问外部信息时,`canDeactivate()`方法为提供了组件、`ActivatedRoute`和`RouterStateSnapshot`的当前实例。如果只想为这个组件使用该守卫,并且需要使用该组件属性、或者需要路由器确认是否允许从该组件导航出去时,这个守卫就非常有用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Looking back at the `CrisisDetailComponent`, it implements the confirmation workflow for unsaved changes.",
"translation": "看看`CrisisDetailComponent`组件,我们已经实现了对未保存的更改进行确认的工作流。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Add the `Guard` to the crisis detail route in `crisis-center-routing.module.ts` using the `canDeactivate` array property.",
"translation": "我们往`crisis-center.routing.ts`的危机详情路由中用`canDeactivate`数组添加一个`Guard`(守卫)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Now you have given the user a safeguard against unsaved changes.",
"translation": "现在,我们已经给了用户一个能保护未保存更改的安全守卫。\n{@a Resolve}",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### _Resolve_: pre-fetching component data",
"translation": "### _Resolve_: 预先获取组件数据",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "In summary, you want to delay rendering the routed component until all necessary data have been fetched.",
"translation": "总之,你希望的是只有当所有必要数据都已经拿到之后,才渲染这个路由组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You need a *resolver*.",
"translation": "我们需要`Resolve`守卫。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Fetch data before navigating",
"translation": "### 导航前预先加载路由信息",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Be explicit. Implement the `Resolve` interface with a type of `Crisis`.",
"translation": "为了更明确一点,可以实现一个带有`Crisis`类型的`Resolve`接口。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Remember to add the `CrisisDetailResolver` service to the `CrisisCenterRoutingModule`'s `providers` array.",
"translation": "别忘了把`CrisisDetailResolver`服务添加到`CrisisCenterRoutingModule`的`providers`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "**Three critical points**",
"translation": "**两个关键点**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The relevant *Crisis Center* code for this milestone follows.",
"translation": "本里程碑中与*危机中心*有关的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Query parameters and fragments",
"translation": "### 查询参数及片段",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Add an `anchor` element so you can jump to a certain point on the page.",
"translation": "再添加一个锚点(`A`)元素,来让你能跳转到页面中的正确位置。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Add the `NavigationExtras` object to the `router.navigate` method that navigates you to the `/login` route.",
"translation": "我们还将为`router.nativate`方法传入一个`NavigationExtras`对象,用来导航到`/login`路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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 在更新过的*英雄管理*组件中,我们将直接把`Observable`传给模板,借助`AsyncPipe`在组件被销毁时自动_取消_对`Observable`的订阅。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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*按钮,它会带着我们提供的“查询参数”和“片段”跳转到登录页。\n 点击登录按钮,我们就会被带到`Crisis Admin`页,仍然带着上一步提供的“查询参数”和“片段”。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "## Milestone 6: Asynchronous routing",
"translation": "## 里程碑6异步路由",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "How do you combat this problem? With asynchronous routing, which loads feature modules _lazily_, on request.\nLazy loading has multiple benefits.",
"translation": "如何才能解决这个问题呢?我们引进了异步路由到应用程序中,并获得在请求时才**惰性**加载特性模块的能力。这样给我们带来了下列好处:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* You can load feature areas only when requested by the user.",
"translation": "我们可以只在用户请求时才加载某些特性区。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* You can speed up load time for users that only visit certain areas of the application.",
"translation": "对于那些只访问应用程序某些区域的用户,这样能加快加载速度。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* You can continue expanding lazy loaded feature areas without increasing the size of the initial load bundle.",
"translation": "我们可以持续扩充惰性加载特性区的功能,而不用增加初始加载的包体积。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You're already made part way there.\nBy organizing the application into modules&mdash;`AppModule`,\n`HeroesModule`, `AdminModule` and `CrisisCenterModule`&mdash;you\nhave natural candidates for lazy loading.",
"translation": "我们已经完成了一部分。通过把应用组织成一些模块:`AppModule`、`HeroesModule`、`AdminModule`和`CrisisCenterModule`\n我们已经有了可用于实现惰性加载的候选者。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Lazy Loading route configuration",
"translation": "### 惰性加载路由配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Open the `AppRoutingModule` and add a new `admin` route to its `appRoutes` array.",
"translation": "打开`AppRoutingModule`,并把一个新的`admin`路由添加到它的`appRoutes`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### _CanLoad_ Guard: guarding unauthorized loading of feature modules",
"translation": "### `CanLoad`守卫:保护对特性模块的未授权加载",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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": "我们已经使用`CanAcitvate`保护`AdminModule`了,它会阻止未授权用户访问管理特性区。如果用户未登录,它就会跳转到登录页。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Preloading: background loading of feature areas",
"translation": "### 预加载:特性区的后台加载",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You've learned how to load modules on-demand.\nYou can also load modules asynchronously with _preloading_.",
"translation": "我们已经学会了如何按需加载模块,接下来再看看如何使用*预加载*技术异步加载模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "That's _preloading_.",
"translation": "这就是*预加载*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### How preloading works",
"translation": "#### 预加载的工作原理",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The `Router` offers two preloading strategies out of the box:",
"translation": "`Router`内置了两种预加载策略:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* No preloading at all which is the default. Lazy loaded feature areas are still loaded on demand.",
"translation": "完全不预加载,这是默认值。惰性加载的特性区仍然会按需加载。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Preloading of all lazy loaded feature areas.",
"translation": "预加载所有惰性加载的特性区。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "#### Lazy load the _crisis center_",
"translation": "#### 惰性加载*危机中心*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "1. Change the `crisis-center` path in the `CrisisCenterRoutingModule` to an empty string.",
"translation": "把`CrisisCenterRoutingModule`中的路径从`crisis-center`改为空字符串。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Add a `crisis-center` route to the `AppRoutingModule`.",
"translation": "往`AppRoutingModule`中添加一个`crisis-center`路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Set the `loadChildren` string to load the `CrisisCenterModule`.",
"translation": "设置`loadChildren`字符串来加载`CrisisCenterModule`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Remove all mention of the `CrisisCenterModule` from `app.module.ts`.",
"translation": "从`app.module.ts`中移除所有对`CrisisCenterModule`的引用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "Here are the updated modules _before enabling preload_:",
"translation": "下面是打开预加载之前的模块修改版:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Surprisingly, the `AdminModule` does _not_ preload. Something is blocking it.",
"translation": "意外的是,`AdminModule`*没有*预加载,有什么东西阻塞了它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "#### CanLoad blocks preload",
"translation": "#### CanLoad会阻塞预加载",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Custom Preloading Strategy",
"translation": "### 自定义预加载策略",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "You can control what and how the router preloads with a custom preloading strategy.",
"translation": "使用自定义预加载策略,我们可以控制路由器预加载哪些路由以及如何加载。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "`SelectivePreloadingStrategy` implements the `PreloadingStrategy`, which has one method, `preload`.",
"translation": "`SelectivePreloadingStrategy`实现了`PreloadingStrategy`,它只有一个方法`preload`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "The router calls the `preload` method with two arguments:",
"translation": "路由器会用两个参数调用调用`preload`方法:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. The route to consider.",
"translation": "要加载的路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. A loader function that can load the routed module asynchronously.",
"translation": "一个加载器loader函数它能异步加载带路由的模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Shortly, you'll extend the `AdminDashboardComponent` to inject this service and display its `preloadedModules` array.",
"translation": "很快,我们就会扩展`AdminDashboardComponent`来注入该服务,并且显示它的`preloadedModules`数组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "But first, make a few changes to the `AppRoutingModule`.",
"translation": "但是首先,要对`AppRoutingModule`做少量修改。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Import `SelectivePreloadingStrategy` into `AppRoutingModule`.",
"translation": "把`SelectivePreloadingStrategy`导入到`AppRoutingModule`中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Replace the `PreloadAllModules` strategy in the call to `forRoot` with this `SelectivePreloadingStrategy`.",
"translation": "把`PreloadAllModules`策略替换成对`forRoot`的调用,并且传入这个`SelectivePreloadingStrategy`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Now edit the `AdminDashboardComponent` to display the log of preloaded routes.",
"translation": "现在,编辑`AdminDashboardComponent`以显示这些预加载路由的日志。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Import the `SelectivePreloadingStrategy` (it's a service).",
"translation": "导入`SelectivePreloadingStrategy`(它是一个服务)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Inject it into the dashboard's constructor.",
"translation": "把它注入到仪表盘的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Update the template to display the strategy service's `preloadedModules` array.",
"translation": "修改模板来显示这个策略服务的`preloadedModules`数组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "When you're done it looks like this.",
"translation": "当完成时,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "## Migrating URLs with Redirects",
"translation": "## 使用重定向迁移 URL",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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": "我们已经设置好了路由,并且用命令式和声明式的方式导航到了很多不同的路由。但是,任何应用的需求都会随着时间而改变。我们把链接`/heroes`和`hero/:id`指向了`HeroListComponent`和`HeroDetailComponent`组件。如果有这样一个需求,要把链接`heroes`变成`superheroes`我们希望以前的URL仍然能正常导航。但我们也不想在应用中找到并修改每一个链接这时候重定向就可以省去这些琐碎的重构工作。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Changing /heroes to /superheroes",
"translation": "### 把`/heroes`修改为`/superheros`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* When using relative redirects, the `Router` use the query params and the fragment from the source URL.",
"translation": "当使用相对地址重定向时,路由器将会使用源地址(跳转前的地址)中的查询参数和片段。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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`。这样*不行*,从设计上就不行。因为路由器在每一层的路由配置中只会处理一次重定向。这样可以防止出现无限循环的重定向。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "## Inspect the router's configuration",
"translation": "## 审查路由器配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "## Wrap up and final app",
"translation": "## 总结与最终的应用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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 Plunker\"></live-example>,在那里你可以下载最终的源码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "## Appendices",
"translation": "## 附录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The appendix material isn't essential. Continued reading is for the curious.",
"translation": "该附件中的内容不是必须的,感兴趣的人才需要阅读它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "### Appendix: link parameters array",
"translation": "### 附录:链接参数数组",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "A link parameters array holds the following ingredients for router navigation:",
"translation": "链接参数数组保存路由导航时所需的成分:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The *path* of the route to the destination component.",
"translation": "指向目标组件的那个路由的*路径path*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* Required and optional route parameters that go into the route URL.",
"translation": "必备路由参数和可选路由参数它们将进入该路由的URL",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You can bind the `RouterLink` directive to such an array like this:",
"translation": "我们可以把`RouterLink`指令绑定到一个数组,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You've written a two element array when specifying a route parameter like this:",
"translation": "在指定路由参数时,我们写过一个双元素的数组,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "You can provide optional route parameters in an object like this:",
"translation": "我们可以在对象中提供可选的路由参数,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Parse it out.",
"translation": "分解一下。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The first item in the array identifies the parent route (`/crisis-center`).",
"translation": "数组中的第一个条目标记出了父路由(`/crisis-center`)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* There are no parameters for this parent route so you're done with it.",
"translation": "这个父路由没有参数,因此这步已经完成了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* There is no default for the child route so you need to pick one.",
"translation": "没有默认的子路由,因此我们得选取一个。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* Voilà! `['/crisis-center']`.",
"translation": "哇!`['/crisis-center']`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* The first item in the array identifies the parent route (`/crisis-center`).",
"translation": "数组中的第一个条目用来标记出父路由('/crisis-center')。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* There are no parameters for this parent route so you're done with it.",
"translation": "这个父路由没有参数,因此这步已经完成了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The second item identifies the child route details about a particular crisis (`/:id`).",
"translation": "数组中的第二个条目('/:id')用来标记出到指定危机的详情页的子路由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "* The details child route requires an `id` route parameter.",
"translation": "详细的子路由需要一个`id`路由参数。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "* The resulting path is `/crisis-center/1`.",
"translation": "最终生成的路径是`/crisis-center/1`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "If you wanted to, you could redefine the `AppComponent` template with *Crisis Center* routes exclusively:",
"translation": "只要想,我们也可以用*危机中心*路由单独重定义`AppComponent`的模板:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "### Appendix: *LocationStrategy* and browser URL styles",
"translation": "### 附录:*LocationStrategy*以及浏览器URL样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Here's the *Crisis Center* URL in this \"HTML5 pushState\" style:",
"translation": "下面是*危机中心*的URL在“HTML 5 pushState”风格下的样子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "The router supports both styles with two `LocationStrategy` providers:",
"translation": "路由器通过两种`LocationStrategy`提供商来支持所有这些风格:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. `PathLocationStrategy`&mdash;the default \"HTML5 pushState\" style.",
"translation": "`PathLocationStrategy` - 默认的策略支持“HTML 5 pushState”风格。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. `HashLocationStrategy`&mdash;the \"hash URL\" style.",
"translation": "`HashLocationStrategy` - 支持“hash URL”风格。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "#### Which strategy is best?",
"translation": "#### 哪种策略更好?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "#### HTML5 URLs and the *&lt;base href>*",
"translation": "#### HTML 5 URL与*&lt;base href>*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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\">&lt;base href&gt; element</a>\ntag in the `<head>` of the `index.html`.",
"translation": "配置该策略的首选方式是往`index.html`的`<head>`中添加一个[&lt;base href> element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)标签。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "Those developers may still use HTML5 URLs by taking two remedial steps:",
"translation": "它们仍然可以使用HTML 5格式的URL但要采取两个步骤进行补救",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"original": "1. Provide the router with an appropriate [APP_BASE_HREF][] value.",
"translation": "用适当的[APP_BASE_HREF][]值提供provide路由器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "#### *HashLocationStrategy*",
"translation": "#### *HashLocationStrategy* 策略",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/router.md"
},
{
"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/content-3/guide/router.md"
},
{
"original": "# Security",
"translation": "# 安全",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "You can run the <live-example></live-example> in Stackblitz and download the code from there.",
"translation": "运行<live-example></live-example>来试用本页的代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"original": "<h2 id='report-issues'>\nReporting vulnerabilities\n</h2",
"translation": "举报漏洞",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "Best practices",
"translation": "最佳实践",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "## Preventing cross-site scripting (XSS)",
"translation": "## 防范跨站脚本(XSS)攻击",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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&mdash;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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "### Sanitization and security contexts",
"translation": "### 无害化处理与安全环境",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "Angular defines the following security contexts:",
"translation": "Angular定义了四个安全环境 - HTML样式URL和资源URL",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "* **Style** is used when binding CSS into the `style` property.",
"translation": "**样式**值需要作为CSS绑定到`style`属性时使用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"original": "* **URL** is used for URL properties such as `<a href>`.",
"translation": "**URL**值需要被用作URL属性时使用比如`<a href>`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "### Sanitization example",
"translation": "### 无害化示例",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "Interpolated content is always escaped&mdash;the HTML isn't interpreted and the browser displays\nangle brackets in the element's text content.",
"translation": "插值表达式的内容总会被编码 - 其中的HTML不会被解释所以浏览器会在元素的文本内容中显示尖括号。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "### Avoid direct use of the DOM APIs",
"translation": "### 避免直接使用DOM API",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "### Content security policy",
"translation": "### 内容安全策略",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "### Use the offline template compiler",
"translation": "### 使用离线模板编译器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "### Server-side XSS protection",
"translation": "### 服务器端XSS保护",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "Trusting safe values",
"translation": "信任安全值",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "To mark a value as trusted, inject `DomSanitizer` and call one of the\nfollowing methods:",
"translation": "注入`DomSanitizer`服务,然后调用下面的方法之一,你就可以把一个值标记为可信任的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "HTTP-level vulnerabilities",
"translation": "HTTP级别的漏洞",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "Cross-site request forgery",
"translation": "跨站请求伪造XSRF",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "Cross-site script inclusion (XSSI)",
"translation": "跨站脚本包含(XSSI)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "Auditing Angular applications",
"translation": "审计Angular应用程序",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/security.md"
},
{
"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/content-3/guide/security.md"
},
{
"original": "# Set the Document Title",
"translation": "# 设置文档标题",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"original": "## The problem with *&lt;title&gt;*",
"translation": "## *&lt;title&gt;*的问题",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"original": "## Use the `Title` service",
"translation": "## 使用 `Title` 服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"original": "* `getTitle() : string`&mdash;Gets the title of the current HTML document.",
"translation": "`getTitle(): string` —— 获取当前HTML文档的标题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"original": "* `setTitle( newTitle : string )`&mdash;Sets the title of the current HTML document.",
"translation": "`setTitle( newTitle: string)` —— 设置当前HTML文档的标题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"original": "Bind that method to three anchor tags and voilà!",
"translation": "我们把这个方法绑定到三个A标签瞧瞧",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"original": "Here's the complete solution:",
"translation": "这里是完整的方案(代码)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"original": "## Why provide the `Title` service in `bootstrap`",
"translation": "## 为什么要在*bootstrap*里面提供这个*Title*服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"original": "Generally you want to provide application-wide services in the root application component, `AppComponent`.",
"translation": "我们通常会推荐在应用程序的根组件`AppComponent`中提供应用程序级的服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"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/content-3/guide/set-document-title.md"
},
{
"original": "# Anatomy of the Setup Project",
"translation": "# 搭建项目环境",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Application files _inside the_ **`src/`** and **`e2e/`** folders matter most to developers.",
"translation": "对程序员来讲最重要的是在 *`src/`* 和 *`e2e/`* 文件夹*之内*的应用文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "File",
"translation": "文件\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Purpose",
"translation": "用途\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Angular application files go here.",
"translation": "你的 Angular 应用文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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\" plnkr=\"quickstart-specs\">单元测试</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Initialized with an e2e test for the \"Hello Angular\" sample.",
"translation": "初始化后有个“Hello Angular” 的例子的端对端测试。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "The _npm_ packages installed with the `npm install` command.",
"translation": "用 `npm install` 命令安装的 *npm* 包。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Tooling configuration files and folders.",
"translation": "配置文件和文件夹的工具。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Ignore them until you have a compelling reason to do otherwise.",
"translation": "除非非常必要,否则可以忽略。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "The history of changes to the _QuickStart_ repository.",
"translation": "*快速上手*库的更新历史。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Delete or ignore.",
"translation": "删除或忽略。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "The application icon that appears in the browser tab.",
"translation": "出现在浏览器标签上的应用图标。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "The same `index.html` satisfies all documentation application samples.",
"translation": "同一个 `index.html`满足所有文档应用例子。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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配置*\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "The open source MIT license to use this setup code in your application.",
"translation": "应用的搭建代码中用到的开源 MIT 许可证。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Identifies `npm `package dependencies for the project.",
"translation": "为项目指定`npm`依赖包。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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>阅读更多关于它们的说明。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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) 测试器运行器的配置。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Instruction for using this git repository in your project.\n Worth reading before deleting.",
"translation": "项目中使用这个 git 库的说明。\n 在删除前值得阅读。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Global styles for the application. Initialized with an `<h1>` style for the QuickStart demo.",
"translation": "应用的全局样式。初始化后,有个为《快速上手》演示准备的`<h1>`样式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "Don't touch this file unless you are fully versed in SystemJS configuration.",
"translation": "除非你完全理解 SystemJS 的配置,不要修改它。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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/content-3/guide/setup-systemjs-anatomy.md"
},
{
"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)与本文档站作者喜爱的语法检查规则。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup-systemjs-anatomy.md"
},
{
"original": "# Setup for local development",
"translation": "# 搭建本地开发环境",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"original": "## Clone",
"translation": "## 克隆",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "Perform the _clone-to-launch_ steps with these terminal commands.",
"translation": "运行下列命令来执行*克隆并启动*步骤。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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-04为止它还不支持访问网络上的服务器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "## Download",
"translation": "## 下载\n<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.",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"original": "## Delete _non-essential_ files (optional)",
"translation": "## 删除*非必需*文件(可选)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"original": "Do this only in the beginning to avoid accidentally deleting your own tests and git setup!",
"translation": "请只在开始时执行此删除操作以防你自己的测试和git文件被意外删除",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "Open a terminal window in the project folder and enter the following commands for your environment:",
"translation": "在项目目录下打开一个终端窗口,并根据你的操作系统执行以下命令:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "### OS/X (bash)",
"translation": "### OS/X (bash) 命令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "### Windows",
"translation": "### Windows 命令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "## What's in the QuickStart seed?",
"translation": "## 《快速上手》种子库里都有什么?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"original": "Focus on the following three TypeScript (`.ts`) files in the **`/src`** folder.",
"translation": "注意**`/src`**目录中以下三个 TypeScript (`.ts`) 文件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"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除非明确指出否则教程中添加的 TypeScriptHTML和CSS文件都在`src/`目录下,\n大多数在`src/app`目录中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "The following are all in `src/`",
"translation": "`src/`目录文件详情如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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 不久,它将声明更多组件。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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#main \"启动应用\")并运行应用。\n 对于大多数项目的开发,这都是合理的选择。而且它是在像 Plunker 这样的*在线编程*环境中运行例子的唯一选择。\n 你将在本文档中学习其他编译和开发选择。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "### Next Step",
"translation": "### 下一步",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"original": "## Appendix: node and npm",
"translation": "## 附录node 与 npm",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"original": "<a href=\"https://docs.npmjs.com/getting-started/installing-node\" target=\"_blank\" title=\"Installing Node.js and updating npm\">\n</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\">\n立刻安装它们</a>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"original": "## Appendix: Why develop locally",
"translation": "## 附录:为何在本地开发",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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 Plunker\">在线编程</live-example>是很好的探索 Angular 的方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"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/content-3/guide/setup.md"
},
{
"original": "As much fun as this is ...",
"translation": "虽然有这么多的乐趣,但是...",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "* you can't ship your app in Stackblitz",
"translation": "你不能在 Stackblitz 里面发布你的应用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "* you aren't always online when writing code",
"translation": "编程时你不可能总是在线",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "* transpiling TypeScript in the browser is slow",
"translation": "在浏览器中编译 TypeScript 很慢",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "* the type support, refactoring, and code completion only work in your local IDE",
"translation": "只有本地 IDE 有类型支持、代码重构和代码自动完成",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"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 Plunker\">在线编程</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/content-3/guide/setup.md"
},
{
"original": "For real development, we strongly recommend [developing locally](guide/setup#develop-locally).",
"translation": "对于现实项目开发,我们强烈推荐在[本地开发](guide/setup#develop-locally)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/setup.md"
},
{
"original": "# Structural Directives",
"translation": "# 结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Try the <live-example></live-example>.",
"translation": "试试<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "## What are structural directives?",
"translation": "## 什么是结构型指令?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "No brackets. No parentheses. Just `*ngIf` set to a string.",
"translation": "没有方括号,没有圆括号,只是把`*ngIf`设置为一个字符串。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "You'll learn in this guide that the [asterisk (*) is a convenience notation](guide/structural-directives#asterisk)\nand the string isa [_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/content-3/guide/structural-directives.md"
},
{
"original": "Three of the common, built-in structural directives&mdash;[NgIf](guide/template-syntax#ngIf),\n[NgFor](guide/template-syntax#ngFor), and [NgSwitch...](guide/template-syntax#ngSwitch)&mdash;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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Directive spelling",
"translation": "指令的拼写形式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "There are two other kinds of Angular directives, described extensively elsewhere:\n(1)&nbsp;components and (2)&nbsp;attribute directives.",
"translation": "还有另外两种Angular指令在本开发指南的其它地方有讲解(1) 组件 (2) 属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## NgIf case study",
"translation": "## NgIf案例分析",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "### Why *remove* rather than *hide*?",
"translation": "### 为什么*移除*而不是*隐藏*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "A directive could hide the unwanted paragraph instead by setting its `display` style to `none`.",
"translation": "指令也可以通过把它的`display`风格设置为`none`而隐藏不需要的段落。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "While invisible, the element remains in the DOM.",
"translation": "当不可见时这个元素仍然留在DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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": "对于简单的段落,隐藏和移除之间的差异影响不大,但对于资源占用较多的组件是不一样的。当我们隐藏掉一个元素时,组件的行为还在继续 —— 它仍然附加在它所属的DOM元素上\n它也仍在监听事件。Angular会继续检查哪些能影响数据绑定的变更。\n组件原本要做的那些事情仍在继续。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "Although invisible, the component&mdash;and all of its descendant components&mdash;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/content-3/guide/structural-directives.md"
},
{
"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&mdash;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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## The asterisk (*) prefix",
"translation": "## 星号(*)前缀",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Here is `*ngIf` displaying the hero's name if `hero` exists.",
"translation": "这里的`*ngIf`会在`hero`存在时显示英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## Inside _*ngFor_",
"translation": "## `*ngFor`内幕",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Here's a full-featured application of `NgFor`, written both ways:",
"translation": "这里有一个`NgFor`的全特性应用,同时用了这三种写法:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "### Microsyntax",
"translation": "### 微语法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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`属性,`NgFor`会用当前迭代中的英雄初始化它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "### Template input variable",
"translation": "### 模板输入变量",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "### One structural directive per host element",
"translation": "### 每个宿主元素上只能有一个结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## Inside _NgSwitch_ directives",
"translation": "## `NgSwitch` 内幕",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Here's an example.",
"translation": "例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "*Design thought*: minimize initialization effort and consider caching state in a \ncompanion service.",
"translation": "*设计思路*:要最小化初始化的成本,并考虑把状态缓存在一个伴生的服务中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## Prefer the asterisk (*) syntax.",
"translation": "## 优先使用星号(`*`)语法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "The asterisk (*) syntax is more clear than the desugared form.\nUse [&lt;ng-container&gt;](guide/structural-directives#ng-container) when there's no single element\nto host the directive.",
"translation": "星号(`*`)语法比不带语法糖的形式更加清晰。\n如果找不到单一的元素来应用该指令可以使用[&lt;ng-container&gt;](guide/structural-directives#ng-container)作为该指令的容器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## The *&lt;ng-template&gt;*",
"translation": "## *&lt;ng-template&gt;*指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "The &lt;ng-template&gt; 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": "&lt;ng-template&gt;是一个 Angular 元素用来渲染HTML。\n它永远不会直接显示出来。\n事实上在渲染视图之前Angular 会把`<ng-template>`及其内容*替换为*一个注释。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Angular erases the middle \"Hip!\", leaving the cheer a bit less enthusiastic.",
"translation": "Angular 抹掉了中间的那个 \"Hip!\" ,让欢呼声显得不再那么热烈了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## Group sibling elements with &lt;ng-container&gt;",
"translation": "## 使用&lt;ng-container&gt;把一些兄弟元素归为一组",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Introducing another container element&mdash;typically a `<span>` or `<div>`&mdash;to\ngroup the elements under a single _root_ is usually harmless.\n_Usually_ ... but not _always_.",
"translation": "但引入另一个容器元素(通常是`<span>`或`<div>`)来把一些元素归到一个单一的*根元素*下,通常也会带来问题。注意,是\"通常\"而不是\"总会\"。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "The constructed paragraph renders strangely.",
"translation": "这样渲染出来的段落就会非常奇怪。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "The `p span` style, intended for use elsewhere, was inadvertently applied here.",
"translation": "本来为其它地方准备的`p span`样式,被意外的应用到了这里。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "When you try this,",
"translation": "如果这样做:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "the drop down is empty.",
"translation": "下拉列表就是空的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "The browser won't display an `<option>` within a `<span>`.",
"translation": "浏览器不会显示`<span>`中的`<option>`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "### &lt;ng-container&gt; to the rescue",
"translation": "### &lt;ng-container&gt; 的救赎",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Here's the conditional paragraph again, this time using `<ng-container>`.",
"translation": "下面是重新实现的条件化段落,这次我们使用`<ng-container>`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "It renders properly.",
"translation": "这次就渲染对了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "Now conditionally exclude a _select_ `<option>` with `<ng-container>`.",
"translation": "我们再用`<ng-container>`来根据条件排除选择框中的某个`<option>`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "The drop down works properly.",
"translation": "下拉框也工作正常。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## Write a structural directive",
"translation": "## 写一个结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Creating a directive is similar to creating a component.",
"translation": "创建指令很像创建组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "* Import the `Directive` decorator (instead of the `Component` decorator).",
"translation": "导入`Directive`装饰器(而不再是`Component`)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "* Apply the decorator to the directive class.",
"translation": "给指令类添加装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Here's how you might begin:",
"translation": "这里是起点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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": "指令的*选择器*通常是把指令的属性名括在方括号中,如`[myUnless]`。\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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "### _TemplateRef_ and _ViewContainerRef_",
"translation": "### _TemplateRef_ 和 _ViewContainerRef_",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "You inject both in the directive constructor as private variables of the class.",
"translation": "我们可以把它们都注入到指令的构造函数中,作为该类的私有属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "### The _appUnless_ property",
"translation": "### *myUnless* 属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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条件绑定到`[myUnless]`属性上。\n也就是说该指令需要一个带有`@Input`的`myUnless`属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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 就会去设置 `myUnless` 属性这时候我们就需要为它定义一个设置器setter。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Nobody reads the `appUnless` property so it doesn't need a getter.",
"translation": "没有人会读取`myUnless`属性因此它不需要定义设置器getter。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "The completed directive code looks like this:",
"translation": "完整的指令代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "Add this directive to the `declarations` array of the AppModule.",
"translation": "把这个指令添加到AppModule的`declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "Then create some HTML to try it.",
"translation": "然后创建一些 HTML 来试用一下。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "Here is the source from the `src/app/` folder.",
"translation": "本章相关的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "You learned",
"translation": "我们学到了",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "* that structural directives manipulate HTML layout.",
"translation": "结构型指令可以操纵 HTML 的元素布局。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "* how that works for the `NgIf`, `NgFor` and `NgSwitch` built-in directives.",
"translation": "内置指令`NgIf`、`NgFor`和`NgSwitch`的工作原理。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"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/content-3/guide/structural-directives.md"
},
{
"original": "* to write a [custom structural directive](guide/structural-directives#unless), `UnlessDirective`.",
"translation": "写了一个[自定义结构型指令](guide/structural-directives#unless) —— `UnlessDirective`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/structural-directives.md"
},
{
"original": "# Style Guide",
"translation": "# 风格指南",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "## Style vocabulary",
"translation": "## 风格词汇",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Each guideline describes either a good or bad practice, and all have a consistent presentation.",
"translation": "每个指导原则都会描述好的或者坏的做法,所有指导原则风格一致。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "The wording of each guideline indicates how strong the recommendation is.",
"translation": "指导原则中使用的词汇表明推荐的程度。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Consider** guidelines should generally be followed.",
"translation": "**考虑**标志着通常应该遵循的指导原则。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "If you fully understand the meaning behind the guideline and have a good reason to deviate, then do so. Please strive to be consistent.",
"translation": "如果能完全理解指导原则背后的含义,并且很好的理由背离它,那就可以那么做。但是请保持一致。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Avoid** indicates something you should almost never do. Code examples to *avoid* have an unmistakeable red header.",
"translation": "**避免**标志着我们决不应该做的事。需要*避免*的代码范例会有明显的红色标题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** gives reasons for following the previous recommendations.",
"translation": "**为何?**会给出随后的建议的理由。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## File structure conventions",
"translation": "## 文件结构约定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "## Single responsibility",
"translation": "## 单一职责",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "### Rule of One",
"translation": "### 单一规则",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 01-01",
"translation": "#### 风格 01-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** define one thing, such as a service or component, per file.",
"translation": "**坚持**每个文件只定义一样东西(例如服务或组件)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** limiting files to 400 lines of code.",
"translation": "**考虑**把文件大小限制在 400 行代码以内。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "The key is to make the code more reusable, easier to read, and less mistake prone.",
"translation": "最关键的是,可以增强代码可重用性和阅读性,减少出错的可能性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "As the app grows, this rule becomes even more important.",
"translation": "随着应用程序的成长,本法则会变得越来越重要。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Small functions",
"translation": "### 小函数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 01-02",
"translation": "#### 风格 01-02",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** define small functions",
"translation": "**坚持**定义简单函数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** limiting to no more than 75 lines.",
"translation": "**考虑**限制在 75 行之内。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to test, especially when they do one thing and serve one purpose.",
"translation": "**为何?**简单函数更易于测试,特别是当它们只做一件事,只为一个目的服务时。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Small functions promote reuse.",
"translation": "**为何?**简单函数促进代码重用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to read.",
"translation": "**为何?**简单函数更易于阅读。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to maintain.",
"translation": "**为何?**简单函数更易于维护。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## Naming",
"translation": "## 命名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "### General Naming Guidelines",
"translation": "### 总体命名原则",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-01",
"translation": "#### 风格 02-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all symbols.",
"translation": "**坚持**所有符号使用一致的命名规则。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** The naming conventions should simply help find desired code faster and make it easier to understand.",
"translation": "**为何?**命名约定帮助我们更快得找到不在手头的代码,更容易理解它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Separate file names with dots and dashes",
"translation": "### 使用点和横杠来分隔文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-02",
"translation": "#### 风格 02-02",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use dashes to separate words in the descriptive name.",
"translation": "**坚持** 在描述性名字中,用横杠来分隔单词。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use dots to separate the descriptive name from the type.",
"translation": "**坚持**使用点来分隔描述性名字和类型。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Type names provide a consistent way to quickly identify what is in the file.",
"translation": "**为何?**类型名字提供一致的方式来快速的识别文件中有什么。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Type names provide pattern matching for any automated tasks.",
"translation": "**为何?**为自动化任务提供模式匹配。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Symbols and file names",
"translation": "### 符号名与文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-03",
"translation": "#### 风格 02-03",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all assets named after what they represent.",
"translation": "**坚持**为所有东西使用一致的命名约定,以它们所代表的东西命名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use upper camel case for class names.",
"translation": "**坚持**使用大写驼峰命名法来命名类。符号名匹配它所在的文件名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Consistent conventions make it easy to quickly identify\nand reference assets of different types.",
"translation": "**为何?**遵循一致的约定可以快速识别和引用不同类型的资产。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Service names",
"translation": "### 服务名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-04",
"translation": "#### 风格 02-04",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all services named after their feature.",
"translation": "**坚持**使用一致的规则命名服务,以它们的特性来命名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference services.",
"translation": "**为何?**提供一致的方式来快速识别和引用服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Clear service names such as `Logger` do not require a suffix.",
"translation": "**为何?**像`Logger`这样的清楚的服务名不需要后缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Bootstrapping",
"translation": "### 引导",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-05",
"translation": "#### 风格 02-05",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** put bootstrapping and platform logic for the app in a file named `main.ts`.",
"translation": "**坚持**把应用的引导程序和平台相关的逻辑放到名为`main.ts`的文件里。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** include error handling in the bootstrapping logic.",
"translation": "**坚持**在引导逻辑中包含错误处理代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Follows a consistent convention for the startup logic of an app.",
"translation": "**为何?**应用的启动逻辑遵循一致的约定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Follows a familiar convention from other technology platforms.",
"translation": "**为何?**这是从其它技术平台借鉴的常用约定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Directive selectors",
"translation": "### 指令选择器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-06",
"translation": "#### 风格 02-06",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** Use lower camel case for naming the selectors of directives.",
"translation": "**坚持**使用小驼峰命名法来命名指令的选择器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.",
"translation": "**为何?**Angular HTML 解析器是大小写敏感的,它识别小写驼峰写法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Custom prefix for components",
"translation": "### 为组件添加自定义前缀",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-07",
"translation": "#### 风格 02-07",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use a hyphenated, lowercase element selector value (e.g. `admin-users`).",
"translation": "**坚持**使用带连字符的小写元素选择器值(例如`admin-users`)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Do** use a prefix that identifies the feature area or the app itself.",
"translation": "**坚持**使用前缀来识别特性区或者应用程序本身。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Prevents element name collisions with components in other apps and with native HTML elements.",
"translation": "**为何?**防止与其它应用中的组件和原生 HTML 元素发生命名冲突。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Makes it easier to promote and share the component in other apps.",
"translation": "**为何?**更容易在其它应用中推广和共享组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Components are easy to identify in the DOM.",
"translation": "**为何?**组件在 DOM 中更容易被区分出来。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Custom prefix for directives",
"translation": "### 为指令添加自定义前缀",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-08",
"translation": "#### 风格 02-08",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Prevents name collisions.",
"translation": "**为何?**防止名字冲突。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Directives are easily identified.",
"translation": "**为何?**指令更加容易被识别。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Pipe names",
"translation": "### 管道名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-09",
"translation": "#### 风格 02-09",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all pipes, named after their feature.",
"translation": "**坚持**为所有管道使用一致的命名约定,用它们的特性来命名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference pipes.",
"translation": "**为何?**提供一致方式快速识别和引用管道。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Unit test file names",
"translation": "### 单元测试文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-10",
"translation": "#### 风格 02-10",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** name test specification files the same as the component they test.",
"translation": "**坚持**测试规格文件名与被测试组件文件名相同。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** name test specification files with a suffix of `.spec`.",
"translation": "**坚持**测试规格文件名添加`.spec`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify tests.",
"translation": "**为何?**提供一致的方式来快速识别测试。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "<th>\n Test Type",
"translation": "测试类型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "<th>\n File Names",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Components",
"translation": "组件\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Services",
"translation": "服务\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Pipes",
"translation": "管道\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### _End-to-End_ (E2E) test file names",
"translation": "### *端到端*E2E测试的文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-11",
"translation": "#### 风格 02-11",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify end-to-end tests.",
"translation": "**为何?**提供一致的方式快速识别端到端测试文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Provides pattern matching for test runners and build automation.",
"translation": "**为何?**提供一个与测试运行器和构建自动化匹配的模式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "<th>\n Test Type",
"translation": "测试类型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "<th>\n File Names",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "End-to-End Tests",
"translation": "端到端测试\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Angular _NgModule_ names",
"translation": "### Angular *NgModule* 命名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 02-12",
"translation": "#### 风格 02-12",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** append the symbol name with the suffix `Module`.",
"translation": "**坚持**为符号名添加`Module`后缀",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** give the file name the `.module.ts` extension.",
"translation": "**坚持**为文件名添加`.module.ts`扩展名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** name the module after the feature and folder it resides in.",
"translation": "**坚持**用特性名和所在目录命名模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference modules.",
"translation": "**为何?**提供一致的方式来快速标识和引用模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Upper camel case is conventional for identifying objects that can be instantiated using a constructor.",
"translation": "**为何?**大驼峰命名法是一种命名约定,用来标识可用构造函数实例化的对象。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Easily identifies the module as the root of the same named feature.",
"translation": "**为何?**很容易就能看出这个模块是同名特性的根模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** suffix a _RoutingModule_ class name with `RoutingModule`.",
"translation": "**坚持**为 *RoutingModule* 类名添加`RoutingModule`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** end the filename of a _RoutingModule_ with `-routing.module.ts`.",
"translation": "**坚持**为 *RoutingModule* 的文件名添加`-routing.module.ts`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## Coding conventions",
"translation": "## 编程约定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Have a consistent set of coding, naming, and whitespace conventions.",
"translation": "坚持一致的编程、命名和空格的约定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Classes",
"translation": "### 类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 03-01",
"translation": "#### 风格 03-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use upper camel case when naming classes.",
"translation": "**坚持**使用大写驼峰命名法来命名类。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Follows conventional thinking for class names.",
"translation": "**为何?**遵循类命名传统约定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Constants",
"translation": "### 常量",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 03-02",
"translation": "#### 风格 03-02",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** declare variables with `const` if their values should not change during the application lifetime.",
"translation": "**坚持**用`const`声明变量,除非它们的值在应用的生命周期内会发生变化。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Conveys to readers that the value is invariant.",
"translation": "**为何?**告诉读者这个值是不可变的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** TypeScript helps enforce that intent by requiring immediate initialization and by\npreventing subsequent re-assignment.",
"translation": "**为何?** TypeScript 会要求在声明时立即初始化,并阻止再次赋值,以确保达成我们的意图。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** spelling `const` variables in lower camel case.",
"translation": "**考虑** 把常量名拼写为小驼峰格式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Do** tolerate _existing_ `const` variables that are spelled in UPPER_SNAKE_CASE.",
"translation": "**坚持**容许_现存的_`const`常量沿用大写蛇形命名法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Interfaces",
"translation": "### 接口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 03-03",
"translation": "#### 风格 03-03",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** name an interface using upper camel case.",
"translation": "**坚持**使用大写驼峰命名法来命名接口。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** naming an interface without an `I` prefix.",
"translation": "**考虑**不要在接口名字前面加`I`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** using an interface for data models.",
"translation": "**考虑**用类代替接口。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** A class alone is less code than a _class-plus-interface_.",
"translation": "**为何?**单独一个类的代码量小于*类+接口*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** A class can act as an interface (use `implements` instead of `extends`).",
"translation": "**为何?**类可以作为接口使用(只是用`implements`代替`extends`而已)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** An interface-class can be a provider lookup token in Angular dependency injection.",
"translation": "**为何?**在 Angular 依赖注入系统中,接口类可以作为服务提供商的查找令牌。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Properties and methods",
"translation": "### 属性和方法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 03-04",
"translation": "#### 样式 03-04",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use lower camel case to name properties and methods.",
"translation": "**坚持**使用小写驼峰命名法来命名属性和方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Avoid** prefixing private properties and methods with an underscore.",
"translation": "**避免**为私有属性和方法添加下划线前缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Follows conventional thinking for properties and methods.",
"translation": "**为何?**遵循传统属性和方法的命名约定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** JavaScript lacks a true private property or method.",
"translation": "**为何?** JavaScript 不支持真正的私有属性和方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** TypeScript tooling makes it easy to identify private vs. public properties and methods.",
"translation": "**为何?** TypeScript 工具让识别私有或公有属性和方法变得很简单。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Import line spacing",
"translation": "### 导入语句中的空行",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 03-06",
"translation": "#### 风格 03-06",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** leaving one empty line between third party imports and application imports.",
"translation": "**坚持**在第三方导入和应用导入之间留一个空行。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** listing import lines alphabetized by the module.",
"translation": "**考虑**按模块名字的字母顺排列导入行。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** listing destructured imported symbols alphabetically.",
"translation": "**考虑**在解构表达式中按字母顺序排列导入的东西。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** The empty line separates _your_ stuff from _their_ stuff.",
"translation": "**为何?**空行可以让阅读和定位本地导入更加容易。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Alphabetizing makes it easier to read and locate symbols.",
"translation": "**为何?**按字母顺序排列可以让阅读和定位本地导入更加容易。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## Application structure and NgModules",
"translation": "## 应用程序结构与 Angular 模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-01",
"translation": "#### 风格 04-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Do** define the structure to follow these four basic guidelines, listed in order of importance.",
"translation": "**坚持**四项基本原则定义文件结构,上面的原则是按重要顺序排列的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Locate",
"translation": "### 定位",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-02",
"translation": "#### 风格04-02",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** make locating code intuitive, simple and fast.",
"translation": "**坚持**直观、简单和快速地定位代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Identify",
"translation": "### 识别",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-03",
"translation": "#### 风格 04-03",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** name the file such that you instantly know what it contains and represents.",
"translation": "**坚持**命名文件到这个程度:看到名字立刻知道它包含了什么,代表了什么。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** be descriptive with file names and keep the contents of the file to exactly one component.",
"translation": "**坚持**文件名要具有说明性,确保文件中只包含一个组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Avoid** files with multiple components, multiple services, or a mixture.",
"translation": "**避免**创建包含多个组件、服务或者混合体的文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Flat",
"translation": "### 扁平",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-04",
"translation": "#### 风格 04-04",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** keep a flat folder structure as long as possible.",
"translation": "**坚持**尽可能保持扁平的目录结构。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** creating sub-folders when a folder reaches seven or more files.",
"translation": "**考虑**当同一目录下达到 7 个或更多个文件时创建子目录。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### _T-DRY_ (Try to be _DRY_)",
"translation": "### *T-DRY*(尽量不重复自己)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-05",
"translation": "#### 风格 04-05",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** be DRY (Don't Repeat Yourself).",
"translation": "**坚持** DRYDon't Repeat Yourself不重复自己。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Avoid** being so DRY that you sacrifice readability.",
"translation": "**避免**过度 DRY以致牺牲了阅读性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Overall structural guidelines",
"translation": "### 总体结构的指导原则",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-06",
"translation": "#### 风格 04-06",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** start small but keep in mind where the app is heading down the road.",
"translation": "**坚持**从零开始,但要考虑应用程序接下来的路往哪儿走。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** have a near term view of implementation and a long term vision.",
"translation": "**坚持**有一个近期实施方案和一个长期的愿景。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** put all of the app's code in a folder named `src`.",
"translation": "**坚持**把所有源代码都放到名为`src`的目录里。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Here is a compliant folder and file structure:",
"translation": "下面是符合规范的目录和文件结构",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### _Folders-by-feature_ structure",
"translation": "### 按特性组织的目录结构",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-07",
"translation": "#### 风格 04-07",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** create folders named for the feature area they represent.",
"translation": "**坚持**根据特性区命名目录。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** The LIFT guidelines are all covered.",
"translation": "**为何?** LIFT 原则中包含了所有这些。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Do** create an NgModule for each feature area.",
"translation": "**坚持**为每个特性区创建一个 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** NgModules make it easy to lazy load routable features.",
"translation": "**为何?** Angular 模块使惰性加载可路由的特性变得更容易。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** NgModules make it easier to isolate, test, and re-use features.",
"translation": "**为何?**Angular 模块隔离、测试和复用特性更容易。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### App _root module_",
"translation": "### 应用的*根模块*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-08",
"translation": "#### 风格 04-08",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Every app requires at least one root NgModule.",
"translation": "**为何?**每个应用都至少需要一个根 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** naming the root module `app.module.ts`.",
"translation": "**考虑**把根模块命名为`app.module.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Makes it easier to locate and identify the root module.",
"translation": "**为何?**能让定位和识别根模块变得更容易。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Feature modules",
"translation": "### 特性模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-09",
"translation": "#### 风格 04-09",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** create an NgModule for all distinct features in an application;\nfor example, a `Heroes` feature.",
"translation": "**坚持**为应用中每个明显的特性创建一个 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can expose or hide its implementation from other modules.",
"translation": "**为何?**特性模块可以对其它模块暴露或隐藏自己的实现。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** A feature module identifies distinct sets of related components that comprise the feature area.",
"translation": "**为何?**特性模块标记出组成该特性分区的相关组件集合。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can easily be routed to both eagerly and lazily.",
"translation": "**为何?**方便路由到特性模块 —— 无论是用主动加载还是惰性加载的方式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** A feature module defines clear boundaries between specific functionality and other application features.",
"translation": "**为何?**特性模块在特定的功能和其它应用特性之间定义了清晰的边界。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** A feature module helps clarify and make it easier to assign development responsibilities to different teams.",
"translation": "**为何?**特性模块帮助澄清开发职责,以便于把这些职责指派给不同的项目组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can easily be isolated for testing.",
"translation": "**为何?**特性模块易于隔离,以便测试。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Shared feature module",
"translation": "### 共享特性模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-10",
"translation": "#### 风格 04-10",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Do** declare all components, directives, and pipes in the `SharedModule`.",
"translation": "**坚持**在`SharedModule`中声明所有组件、指令和管道。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** export all symbols from the `SharedModule` that other feature modules need to use.",
"translation": "**坚持**从`SharedModule`中导出其它特性模块所需的全部符号。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Avoid** specifying app-wide singleton providers in a `SharedModule`. Intentional singletons are OK. Take care.",
"translation": "**避免**在`SharedModule`中指定应用级的单例服务提供商。如果是刻意要得到多个服务单例也行,不过还是要小心。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Core feature module",
"translation": "### 核心特性模块",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-11",
"translation": "#### 风格04-11",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Avoid** importing the `CoreModule` anywhere except in the `AppModule`.",
"translation": "**避免**在`AppModule`之外的任何地方导入`CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Prevent re-import of the core module",
"translation": "### 防止多次导入`CoreModule`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-12",
"translation": "#### 风格 04-12",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Only the root `AppModule` should import the `CoreModule`.",
"translation": "应该只有`AppModule`才允许导入`CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** guard against reimporting of `CoreModule` and fail fast by adding guard logic.",
"translation": "**坚持**防范多次导入`CoreModule`,并通过添加守卫逻辑来尽快失败。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Guards against reimporting of the `CoreModule`.",
"translation": "**为何?**守卫可以阻止对`CoreModule`的多次导入。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Guards against creating multiple instances of assets intended to be singletons.",
"translation": "**为何?**守卫会禁止创建单例服务的多个实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Lazy Loaded folders",
"translation": "### 惰性加载的目录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-13",
"translation": "#### 样式 04-13",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** The folder makes it easy to identify and isolate the feature content.",
"translation": "**为何?**这种目录让标识和隔离这些特性内容变得更轻松。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Never directly import lazy loaded folders",
"translation": "### 永远不要直接导入惰性加载的目录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 04-14",
"translation": "#### 样式 04-14",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## Components",
"translation": "## 组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Component selector names",
"translation": "### 组件选择器命名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-02",
"translation": "#### 风格05-02",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.",
"translation": "**坚持**使用*中线 (dashed) 命名法*或*烤串 (kebab) 命名法*来命名组件中的元素选择器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Components as elements",
"translation": "### 把组件当做元素",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-03",
"translation": "#### 风格 05-03",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Consider** giving components an _element_ selector, as opposed to _attribute_ or _class_ selectors.",
"translation": "**坚持**给组件一个*元素*选择器,而不是*属性*或*类*选择器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Extract templates and styles to their own files",
"translation": "### 把模板和样式提取到它们自己的文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-04",
"translation": "#### 风格 05-04",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** extract templates and styles into a separate file, when more than 3 lines.",
"translation": "**坚持**当超过 3 行时,把模板和样式提取到一个单独的文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Do** specify _component-relative_ URLs, prefixed with `./`.",
"translation": "**坚持**指定*相对于模块的* URL ,给它加上`./`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Large, inline templates and styles obscure the component's purpose and implementation, reducing readability and maintainability.",
"translation": "**为何?**巨大的、内联的模板和样式表会遮盖组件的意图和实现方式,削弱可读性和可维护性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Decorate _input_ and _output_ properties",
"translation": "### 内联输入和输出属性装饰器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-12",
"translation": "#### 风格 05-12",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Consider** placing `@Input()` or `@Output()` on the same line as the property it decorates.",
"translation": "**坚持**把`@Input()`或者`@Output()`放到所装饰的属性的同一行。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** The metadata declaration attached to the directive is shorter and thus more readable.",
"translation": "**为何?**依附到指令的元数据声明会比较简短,更易于阅读。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Avoid aliasing _inputs_ and _outputs_",
"translation": "### 避免为输入和输出属性指定别名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-13",
"translation": "#### 风格 05-13",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Avoid** _input_ and _output_ aliases except when it serves an important purpose.",
"translation": "**避免**除非有重要目的,否则不要为输入和输出指定别名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Two names for the same property (one private, one public) is inherently confusing.",
"translation": "**为何?**同一个属性有两个名字(一个对内一个对外)很容易导致混淆。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Member sequence",
"translation": "### 成员顺序",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-14",
"translation": "#### 风格 05-14",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** place properties up top followed by methods.",
"translation": "**坚持**把属性成员放在前面,方法成员放在后面。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** place private members after public members, alphabetized.",
"translation": "**坚持**先放公共成员,再放私有成员,并按照字母顺序排列。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Delegate complex component logic to services",
"translation": "### 把逻辑放到服务里",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-15",
"translation": "#### 风格 05-15",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Do** move reusable logic to services and keep components simple and focused on their intended purpose.",
"translation": "**坚持**把可重用的逻辑放到服务中,保持组件简单,聚焦于它们预期目的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Removes dependencies and hides implementation details from the component.",
"translation": "**为何?**从组件移除依赖并隐藏实施细节。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Keeps the component slim, trim, and focused.",
"translation": "**为何?**保持组件苗条、精简和聚焦。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Don't prefix _output_ properties",
"translation": "### 不要给输出属性加前缀",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-16",
"translation": "#### 风格 05-16",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** name events without the prefix `on`.",
"translation": "**坚持**命名事件时,不要带前缀`on`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** name event handler methods with the prefix `on` followed by the event name.",
"translation": "**坚持**把事件处理器方法命名为`on`前缀之后紧跟着事件名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** This is consistent with built-in events such as button clicks.",
"translation": "**为何?**与内置事件命名一致,例如按钮点击。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Put presentation logic in the component class",
"translation": "### 把表现层逻辑放到组件类里",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 05-17",
"translation": "#### 风格 05-17",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** put presentation logic in the component class, and not in the template.",
"translation": "**坚持**把表现层逻辑放进组件类中,而不要放在模板里。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Use directives to enhance an element",
"translation": "### 使用指令来增强已有元素",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 06-01",
"translation": "#### 风格 06-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use attribute directives when you have presentation logic without a template.",
"translation": "**坚持**当你需要有表现层逻辑,但没有模板时,使用属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Attribute directives don't have an associated template.",
"translation": "**为何?**属性型指令没有模板。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** An element may have more than one attribute directive applied.",
"translation": "**为何?**一个元素可以使用多个属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### _HostListener_/_HostBinding_ decorators versus _host_ metadata",
"translation": "### *HostListener* 和 *HostBinding* 装饰器 vs. 组件元数据 *host*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 06-03",
"translation": "#### 风格 06-03",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Do** be consistent in your choice.",
"translation": "**坚持**让你的选择保持一致。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** The property associated with `@HostBinding` or the method associated with `@HostListener`\ncan be modified only in a single place&mdash;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/content-3/guide/styleguide.md"
},
{
"original": "Compare with the less preferred `host` metadata alternative.",
"translation": "与不推荐的方式(`host`元数据)比较一下。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## Services",
"translation": "## 服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Services are singletons",
"translation": "### 服务总是单例的",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 07-01",
"translation": "#### 风格 07-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** use services as singletons within the same injector. Use them for sharing data and functionality.",
"translation": "**坚持**在同一个注入器内,把服务当做单例使用。用它们来共享数据和功能。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Services are ideal for sharing methods across a feature area or an app.",
"translation": "**为何?**服务是在特性范围或应用内共享方法的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Services are ideal for sharing stateful in-memory data.",
"translation": "**为何?**服务是共享状态性内存数据的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Single responsibility",
"translation": "### 单一职责",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 07-02",
"translation": "#### 风格 07-02",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** create services with a single responsibility that is encapsulated by its context.",
"translation": "**坚持**创建单一职责的服务,用职责封装在它的上下文中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** create a new service once the service begins to exceed that singular purpose.",
"translation": "**坚持**当服务成长到超出单一用途时,创建一个新服务。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** When a service has multiple responsibilities, it becomes difficult to test.",
"translation": "**为何?**当服务有多个职责时,它很难被测试。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Providing a service",
"translation": "### 提供一个服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 07-03",
"translation": "#### 风格 07-03",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** The Angular injector is hierarchical.",
"translation": "**为何?** Angular 注入器是层次化的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Why?** This is ideal when a service is sharing methods or state.",
"translation": "**为何?**服务是共享方法或状态的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Use the @Injectable() class decorator",
"translation": "### 使用 @Injectable() 类装饰器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 07-04",
"translation": "#### 风格 07-04",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## Data Services",
"translation": "## 数据服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Talk to the server through a service",
"translation": "### 通过服务与 Web 服务器通讯",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 08-01",
"translation": "#### 风格 08-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** refactor logic for making data operations and interacting with data to a service.",
"translation": "**坚持**把数据操作和与数据交互的逻辑重构到服务里。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## Lifecycle hooks",
"translation": "## 生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Use Lifecycle hooks to tap into important events exposed by Angular.",
"translation": "使用生命周期钩子来介入到 Angular 暴露的重要事件里。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### Implement lifecycle hook interfaces",
"translation": "### 实现生命周期钩子接口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style 09-01",
"translation": "#### 风格 09-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Do** implement the lifecycle hook interfaces.",
"translation": "**坚持**实现生命周期钩子接口。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "**Why?** Lifecycle interfaces prescribe typed method\nsignatures. use those signatures to flag spelling and syntax mistakes.",
"translation": "**为何?**如果使用强类型的方法签名,编译器和编辑器可以帮你揪出拼写错误。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "## Appendix",
"translation": "## 附录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Useful tools and tips for Angular.",
"translation": "有用的 Angular 工具和小提示",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style A-01",
"translation": "#### 风格 A-01",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "**Consider** adjusting the rules in codelyzer to suit your needs.",
"translation": "**考虑**调整 codelyzer 的规则来满足你的需求。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "### File templates and snippets",
"translation": "### 文档模板和代码片段",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "#### Style A-02",
"translation": "#### 风格 A-02",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"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/content-3/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/styleguide.md"
},
{
"original": "# Template Syntax",
"translation": "# 模板语法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "{@a html}\n## HTML in templates",
"translation": "## 模板中的HTML",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Begin with the first form of data binding&mdash;interpolation&mdash;to see how much richer template HTML can be.",
"translation": "我们首先看看数据绑定的第一种形式 —— 插值表达式,它展示了模板的 HTML 可以有多丰富。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "## Interpolation ( <span class=\"syntax\">{&#xfeff;{...}}</span> )",
"translation": "## 插值表达式 ( <span class=\"syntax\">{&#xfeff;{...}}</span> )",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "You met the double-curly braces of interpolation, `{{` and `}}`, early in your Angular education.",
"translation": "在以前的 Angular 教程中,我们遇到过由双花括号括起来的插值表达式,`{{`和`}}`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "The expression can invoke methods of the host component such as `getVal()`, seen here:",
"translation": "这个表达式可以调用宿主组件的方法,就像下面用的`getVal()`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "But first, let's take a closer look at template expressions and statements.",
"translation": "讲解属性绑定之前,先深入了解一下模板表达式和模板语句。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "## Template expressions",
"translation": "## 模板表达式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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&nbsp;`=` symbol as in `[property]=\"expression\"`.",
"translation": "`{{1 + 1}}`中所包含的模板表达式是`1 + 1`。\n 在[属性绑定](guide/template-syntax#property-binding)中会再次看到模板表达式,它出现在`=`右侧的引号中,就像这样:`[property]=\"expression\"`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "JavaScript expressions that have or promote side effects are prohibited,\nincluding:",
"translation": "JavaScript 中那些具有或可能引发副作用的表达式是被禁止的,包括:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* assignments (`=`, `+=`, `-=`, ...)",
"translation": "赋值 (`=`, `+=`, `-=`, ...)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* <code>new</code>",
"translation": "`new`运算符",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* chaining expressions with <code>;</code> or <code>,</code>",
"translation": "使用`;`或`,`的链式表达式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* increment and decrement operators (`++` and `--`)",
"translation": "自增或自减操作符 (`++`和`--`)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Other notable differences from JavaScript syntax include:",
"translation": "和 JavaScript语 法的其它显著不同包括:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* no support for the bitwise operators `|` and `&`",
"translation": "不支持位运算`|`和`&`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* new [template expression operators](guide/template-syntax#expression-operators), such as `|`, `?.` and `!`.",
"translation": "具有新的[模板表达式运算符](guide/template-syntax#expression-operators),比如`|`、`?.`和`!`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### Expression context",
"translation": "### 表达式上下文",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Expression guidelines",
"translation": "### 表达式指南",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Template expressions can make or break an application.\nPlease follow these guidelines:",
"translation": "模板表达式能成就或毁掉一个应用。请遵循下列指南:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "* [Quick execution](guide/template-syntax#quick-execution)",
"translation": "[执行迅速](guide/template-syntax#quick-execution)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* [Simplicity](guide/template-syntax#simplicity)",
"translation": "[非常简单](guide/template-syntax#simplicity)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* [Idempotence](guide/template-syntax#idempotence)",
"translation": "[幂等性](guide/template-syntax#idempotence)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "The only exceptions to these guidelines should be in specific circumstances that you thoroughly understand.",
"translation": "超出上面指南外的情况应该只出现在那些你确信自己已经彻底理解的特定场景中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "#### No visible side effects",
"translation": "#### 没有可见的副作用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "A template expression should not change any application state other than the value of the\ntarget property.",
"translation": "模板表达式除了目标属性的值以外,不应该改变应用的任何状态。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "#### Quick execution",
"translation": "#### 执行迅速",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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.\nExpressions should finish quickly or the user experience may drag, especially on slower devices.\nConsider caching values when their computation is expensive.",
"translation": "Angular 执行模板表达式比我们想象的频繁。\n它们可能在每一次按键或鼠标移动后被调用。\n表达式应该快速结束否则用户就会感到拖沓特别是在较慢的设备上。\n当计算代价较高时应该考虑缓存那些从其它值计算得出的值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "#### Simplicity",
"translation": "#### 非常简单",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Although it's possible to write quite complex template expressions, you should avoid them.",
"translation": "虽然也可以写出相当复杂的模板表达式,但不要那么写。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "#### Idempotence",
"translation": "#### 幂等性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "## Template statements",
"translation": "## 模板语句",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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 `=`&nbsp;symbol as in `(event)=\"statement\"`.",
"translation": "模板**语句**用来响应由绑定目标(如 HTML 元素、组件或指令)触发的**事件**。\n模板语句将在[事件绑定](guide/template-syntax#event-binding)一节看到,它出现在`=`号右侧的引号中,就像这样:`(event)=\"statement\"`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "However, certain JavaScript syntax is not allowed:",
"translation": "然而,某些 JavaScript 语法仍然是不允许的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* <code>new</code>",
"translation": "`new`运算符",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* increment and decrement operators, `++` and `--`",
"translation": "自增和自减运算符:`++`和`--`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* operator assignment, such as `+=` and `-=`",
"translation": "操作并赋值,例如`+=`和`-=`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* the bitwise operators `|` and `&`",
"translation": "位操作符`|`和`&`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* the [template expression operators](guide/template-syntax#expression-operators)",
"translation": "[模板表达式运算符](guide/template-syntax#expression-operators)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### Statement context",
"translation": "### 语句上下文",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Statement guidelines",
"translation": "### 语句指南",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "## Binding syntax: An overview",
"translation": "## 绑定语法:概览",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Data binding is a mechanism for coordinating what users see, with application data values.\n While you could push values to and pull values from HTML,\n the application is easier to write, read, and maintain if you turn these chores over to a binding framework.\n You 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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Data direction",
"translation": "数据方向",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Syntax",
"translation": "语法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Type",
"translation": "绑定类型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "One-way",
"translation": "单向",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "from data source",
"translation": "从数据源",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "to view target",
"translation": "到视图目标",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Interpolation",
"translation": "插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Class",
"translation": "类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Style",
"translation": "样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "<td>\n<p> One-way</p>",
"translation": "单向",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "from view target",
"translation": "从视图目标",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "to data source",
"translation": "到数据源",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "<td><p>\n Event\n </p>",
"translation": "事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "<td><p>\n Two-way\n </p>",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "<td><p>\n Two-way\n </p>",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### A new mental model",
"translation": "### 新的思维模型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "You still create a structure and initialize attribute values this way in Angular templates.",
"translation": "在 Angular 模板中,我们仍使用同样的方式来创建结构和初始化 attribute 值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "That's HTML Plus.",
"translation": "这就是HTML+。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Then you learn about data binding. The first binding you meet might look like this:",
"translation": "现在开始学习数据绑定。我们碰到的第一种数据绑定是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### HTML attribute vs. DOM property",
"translation": "### HTML attribute 与 DOM property 的对比",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "* Some HTML attributes don't have corresponding properties. `colspan` is one example.",
"translation": "有些 HTML attribute 没有对应的 property如`colspan`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* Some DOM properties don't have corresponding attributes. `textContent` is one example.",
"translation": "有些 DOM property 没有对应的 attribute如`textContent`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "That last category is confusing until you grasp this general rule:",
"translation": "最后一类尤其让人困惑…… 除非我们能理解这个普遍原则:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.",
"translation": "HTML attribute `value`指定了*初始*值DOM `value` property 是*当前*值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "This fact bears repeating:",
"translation": "这句话值得再强调一次:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "**Template binding works with *properties* and *events*, not *attributes*.**",
"translation": "**模板绑定是通过 *property* 和*事件*来工作的,而不是 *attribute*。**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "A world without attributes",
"translation": "没有 attribute 的世界",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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 eventsof the target object.\nHTML attributes effectively disappear.",
"translation": "在 Angular 的世界中attribute 唯一的作用是用来初始化元素和指令的状态。\n当进行数据绑定时只是在与元素和指令的 property 和事件打交道,而 attribute 就完全靠边站了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "With this model firmly in mind, read on to learn about binding targets.",
"translation": "把这个思维模型牢牢的印在脑子里,接下来,学习什么是绑定目标。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### Binding targets",
"translation": "### 绑定目标",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Type",
"translation": "绑定类型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Target",
"translation": "目标",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Examples",
"translation": "范例",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Element&nbsp;property",
"translation": "元素的 property",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Component&nbsp;property",
"translation": "组件的 property",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Directive&nbsp;property",
"translation": "指令的 property",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Event",
"translation": "事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Element&nbsp;event",
"translation": "元素的事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Component&nbsp;event",
"translation": "组件的事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Directive&nbsp;event",
"translation": "指令的事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Two-way",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Event and property",
"translation": "事件与 property",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Attribute (the&nbsp;exception)",
"translation": "attribute例外情况",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Class",
"translation": "CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Style",
"translation": "样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "With this broad view in mind, you're ready to look at binding types in detail.",
"translation": "放开眼界,我们来看看每种绑定类型的具体情况。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "## Property binding ( <span class=\"syntax\">[property]</span> )",
"translation": "## 属性绑定 ( <span class=\"syntax\">[属性名]</span> )",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Another example is disabling a button when the component says that it `isUnchanged`:",
"translation": "另一个例子是当组件说它`isUnchanged`(未改变)时禁用按钮:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Another is setting a property of a directive:",
"translation": "另一个例子是设置指令的属性:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### One-way *in*",
"translation": "### 单向*输入*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Similarly, you cannot use property binding to *call* a method on the target element.",
"translation": "也不能使用属性 绑定 来*调用*目标元素上的方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Binding target",
"translation": "### 绑定目标",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "An element property between enclosing square brackets identifies the target property. The target property in the following code is the image element's `src` property.",
"translation": "包裹在方括号中的元素属性名标记着目标属性。下列代码中的目标属性是 image 元素的`src`属性。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Some people prefer the `bind-` prefix alternative, known as the *canonical form*:",
"translation": "有些人喜欢用`bind-`前缀的可选形式,并称之为*规范形式*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Avoid side effects",
"translation": "### 消除副作用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Of course, the expression might invoke a property or method that has side effects.\n Angular has no way of knowing that or stopping you.",
"translation": "当然,表达式可能会调用具有副作用的属性或方法。但 Angular 没法知道这一点,也没法阻止我们。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Return the proper type",
"translation": "### 返回恰当的类型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Remember the brackets",
"translation": "### 别忘了方括号",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Don't make the following mistake:",
"translation": "不要出现这样的失误:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### One-time string initialization",
"translation": "### 一次性字符串初始化",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "You *should* omit the brackets when all of the following are true:",
"translation": "当满足下列条件时,*应该*省略括号:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* The target property accepts a string value.",
"translation": "目标属性接受字符串值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* The string is a fixed value that you can bake into the template.",
"translation": "字符串是个固定值,可以直接合并到模块中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* This initial value never changes.",
"translation": "这个初始值永不改变。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Property binding or interpolation?",
"translation": "### 属性绑定还是插值表达式?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "_Interpolation_ is a convenient alternative to _property binding_ in many cases.",
"translation": "在多数情况下,插值表达式是更方便的备选项。\n实际上在渲染视图之前Angular 把这些插值表达式翻译成相应的属性绑定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "When setting an element property to a non-string data value, you must use _property binding_.",
"translation": "但数据类型不是字符串时,就必须使用*属性绑定*了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "#### Content security",
"translation": "#### 内容安全",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Imagine the following *malicious content*.",
"translation": "假设下面的*恶意内容*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Interpolation handles the script tags differently than property binding but both approaches render the\ncontent harmlessly.",
"translation": "插值表达式处理 script 标签与属性绑定有所不同,但是二者都只渲染没有危害的内容。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "<img src='generated/images/guide/template-syntax/evil-title.png' alt=\"evil title made safe\">",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "## Attribute, class, and style bindings",
"translation": "## attribute、class 和 style 绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "The template syntax provides specialized one-way bindings for scenarios less well suited to property binding.",
"translation": "模板语法为那些不太适合使用属性绑定的场景提供了专门的单向数据绑定形式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### Attribute binding",
"translation": "### attribute 绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "You can set the value of an attribute directly with an **attribute binding**.",
"translation": "可以通过**attribute 绑定**来直接设置 attribute 的值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "**You must use attribute binding when there is no element property to bind.**",
"translation": "**因为当元素没有属性可绑的时候,就必须使用 attribute 绑定。**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "This fact becomes painfully obvious when you write something like this.",
"translation": "如果想写出类似下面这样的东西,现状会令我们痛苦:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "And you get this error:",
"translation": "会得到这个错误:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "You need attribute bindings to create and bind to such attributes.",
"translation": "我们需要 attribute 绑定来创建和绑定到这样的 attribute。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Bind `[attr.colspan]` to a calculated value:",
"translation": "这里把`[attr.colspan]`绑定到一个计算值:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Here's how the table renders:",
"translation": "这里是表格渲染出来的样子:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Class binding",
"translation": "### CSS 类绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Style binding",
"translation": "### 样式绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "You can set inline styles with a **style binding**.",
"translation": "通过**样式绑定**,可以设置内联样式。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Some style binding styles have a unit extension. The following example conditionally sets the font size in “em” and “%” units.",
"translation": "有些样式绑定中的样式带有单位。在这里,以根据条件用 “em” 和 “%” 来设置字体大小的单位。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "{@a event-binding}",
"translation": "## Event binding ( <span class=\"syntax\">(event)</span> )\n## 事件绑定 ( <span class=\"syntax\">(事件名)</span> )",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Target event",
"translation": "### 目标事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "A **name between parentheses** &mdash; for example, `(click)` &mdash;\nidentifies the target event. In the following example, the target is the button's click event.",
"translation": "**圆括号中的名称** —— 比如`(click)` —— 标记出目标事件。在下面例子中,目标是按钮的 click 事件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Some people prefer the `on-` prefix alternative, known as the **canonical form**:",
"translation": "有些人更喜欢带`on-`前缀的备选形式,称之为**规范形式**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### *$event* and event handling statements",
"translation": "### *$event* 和事件处理语句",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "In an event binding, Angular sets up an event handler for the target event.",
"translation": "在事件绑定中Angular 会为目标事件设置事件处理器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "The binding conveys information about the event, including data values, through\nan **event object named `$event`**.",
"translation": "绑定会通过**名叫`$event`的事件对象**传递关于此事件的信息(包括数据值)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Consider this example:",
"translation": "考虑这个范例:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Custom events with <span class=\"syntax\">EventEmitter</span>",
"translation": "### 使用 <span class=\"syntax\">EventEmitter</span> 实现自定义事件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Here are the pertinent excerpts from that `HeroDetailComponent`:",
"translation": "下面的代码节选自`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Now imagine a hosting parent component that binds to the `HeroDetailComponent`'s `deleteRequest` event.",
"translation": "现在,假设有个宿主的父组件,它绑定了`HeroDetailComponent`的`deleteRequest`事件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Template statements have side effects",
"translation": "### 模板语句有副作用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "## Two-way binding ( <span class=\"syntax\">[(...)]</span> )",
"translation": "## 双向数据绑定 ( <span class=\"syntax\">[(...)]</span> )",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "[( )] = banana in a box",
"translation": "[( )] = 盒子里的香蕉",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Visualize a *banana in a box* to remember that the parentheses go _inside_ the brackets.",
"translation": "想象*盒子里的香蕉*来记住方括号套圆括号。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Clearly the two-way binding syntax is a great convenience compared to separate property and event bindings.",
"translation": "显然,比起单独绑定属性和事件,双向数据绑定语法显得非常方便。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "## Built-in directives",
"translation": "## 内置指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "## Built-in _attribute_ directives",
"translation": "## 内置*属性型*指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### NgClass",
"translation": "### NgClass 指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Adding an `ngClass` property binding to `currentClasses` sets the element's classes accordingly:",
"translation": "把`NgClass`属性绑定到`currentClasses`根据它来设置此元素的CSS类",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "It's up to you to call `setCurrentClasses()`, both initially and when the dependent properties change.",
"translation": "你既可以在初始化时调用`setCurrentClassess()`,也可以在所依赖的属性变化时调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### NgStyle",
"translation": "### NgStyle 指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Adding an `ngStyle` property binding to `currentStyles` sets the element's styles accordingly:",
"translation": "把`NgStyle`属性绑定到`currentStyles`,以据此设置此元素的样式:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "It's up to you to call `setCurrentStyles()`, both initially and when the dependent properties change.",
"translation": "你既可以在初始化时调用`setCurrentStyles()`,也可以在所依赖的属性变化时调用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Two-way data binding with the `NgModel` directive makes that easy. Here's an example:",
"translation": "使用`NgModel`指令进行双向数据绑定可以简化这种工作。例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "#### _FormsModule_ is required to use _ngModel_",
"translation": "#### 使用 `ngModel` 时需要 `FormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Here's how to import the `FormsModule` to make `[(ngModel)]` available.",
"translation": "导入`FormsModule`并让`[(ngModel)]`可用的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "#### Inside <span class=\"syntax\">[(ngModel)]</span>",
"translation": "#### <span class=\"syntax\">[(ngModel)]</span>内幕",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "The following contrived example forces the input value to uppercase:",
"translation": "下面这个生造的例子强制输入框的内容变成大写:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Here are all variations in action, including the uppercase version:",
"translation": "这里是所有这些变体的动画,包括这个大写转换的版本:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "## Built-in _structural_ directives",
"translation": "## 内置*结构型*指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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>`](structural-directives.html#ngcontainer \"<ng-container>对元素进行分组。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* how to write your own structural directive.",
"translation": "如何写自己的结构型指令。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "_This_ section is an introduction to the common structural directives:",
"translation": "*本节*是对常见结构型指令的简介:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "* [NgForOf](guide/template-syntax#ngFor) - repeat a template for each item in a list",
"translation": "[`NgSwitch`](guide/template-syntax#ngSwitch) - 一组指令,用于切换一组视图",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### NgIf",
"translation": "### NgIf 指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Don't forget the asterisk (`*`) in front of `ngIf`.",
"translation": "别忘了`ngIf`前面的星号(`*`)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "#### Show/hide is not the same thing",
"translation": "#### 这和显示/隐藏不是一回事",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Hiding an element is quite different from removing an element with `NgIf`.",
"translation": "但隐藏子树和用`NgIf`排除子树是截然不同的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "#### Guard against null",
"translation": "#### 防范空指针错误",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### NgForOf",
"translation": "### NgFor 指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "`NgForOf` is a _repeater_ directive &mdash; 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/content-3/guide/template-syntax.md"
},
{
"original": "Here is an example of `NgForOf` applied to a simple `<div>`:",
"translation": "下例中,`NgFor`应用在一个简单的`<div>`上:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "You can also apply an `NgForOf` to a component element, as in this example:",
"translation": "也可以把`NgFor`应用在一个组件元素上,就下例这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Don't forget the asterisk (`*`) in front of `ngFor`.",
"translation": "不要忘了`ngFor`前面的星号 (`*`)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "The text assigned to `*ngFor` is the instruction that guides the repeater process.",
"translation": "赋值给`*ngFor`的文本是用于指导重复器如何工作的指令。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "#### *ngFor microsyntax",
"translation": "#### NgFor 微语法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "The string assigned to `*ngFor` is not a [template expression](guide/template-syntax#template-expressions).\nIt's a *microsyntax* &mdash; 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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Learn about the _microsyntax_ in the [_Structural Directives_](guide/structural-directives#microsyntax) guide.",
"translation": "要了解*微语法*的更多知识,参见[_结构型指令_](guide/structural-directives#microsyntax)一章。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### Template input variables",
"translation": "### 模板输入变量",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "#### *ngFor with _index_",
"translation": "#### 带索引的`*ngFor`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "#### *ngFor with _trackBy_",
"translation": "#### 带`trackBy`的`*ngFor`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "For example, re-querying the server could reset the list with all new hero objects.",
"translation": "例如,我们可以通过重新从服务器查询来刷新英雄列表。\n 刷新后的列表可能包含很多(如果不是全部的话)以前显示过的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "In the microsyntax expression, set `trackBy` to this method.",
"translation": "在微语法中,把`trackBy`设置为该方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "* With no `trackBy`, both buttons trigger complete DOM element replacement.",
"translation": "如果没有`trackBy`这些按钮都会触发完全的DOM元素替换。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* With `trackBy`, only changing the `id` triggers element replacement.",
"translation": "有了`trackBy`,则只有修改了`id`的按钮才会触发元素替换。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "<img src=\"generated/images/guide/template-syntax/ng-for-track-by-anim.gif\" alt=\"trackBy\">",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### The _NgSwitch_ directives",
"translation": "### `NgSwitch`指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "* `NgSwitchCase` adds its element to the DOM when its bound value equals the switch value.",
"translation": "`NgSwitchCase`会在它绑定到的值等于候选值时把它所在的元素加入到DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "* `NgSwitchDefault` adds its element to the DOM when there is no selected `NgSwitchCase`.",
"translation": "`NgSwitchDefault`会在没有任何一个`NgSwitchCase`被选中时把它所在的元素加入DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "## Template reference variables ( <span class=\"syntax\">#var</span> )",
"translation": "## 模板引用变量 ( <span class=\"syntax\">#var</span> )",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "How a reference variable gets its value",
"translation": "### 模板引用变量怎么得到它的值?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Template reference variable warning notes",
"translation": "关于模板引用变量的提醒",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "## Input and Output properties",
"translation": "## 输入和输出属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "You can only bind to _another_ component or directive through its _Input_ and _Output_ properties.",
"translation": "我们只能通过它的**输入**和**输出**属性将其绑定到**其它**组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Remember that all **components** are **directives**.",
"translation": "记住,所有的**组件**都是**指令**。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### Input or output?",
"translation": "### 输入还是输出?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "The terms _input_ and _output_ reflect the perspective of the target directive.",
"translation": "_输入_和_输出_这两个词是从目标指令的角度来说的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Aliasing input/output properties",
"translation": "给输入/输出属性起别名",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Sometimes the public name of an input/output property should be different from the internal name.",
"translation": "有时需要让输入/输出属性的公开名字不同于内部名字。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "## Template expression operators",
"translation": "## 模板表达式操作符",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### The pipe operator ( <span class=\"syntax\">|</span> )",
"translation": "### 管道操作符 ( | )",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "You can chain expressions through multiple pipes:",
"translation": "还可以通过多个管道串联表达式:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "And you can also [apply parameters](guide/pipes#parameterizing-a-pipe) to a pipe:",
"translation": "还能对它们使用参数:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "The `json` pipe is particularly helpful for debugging bindings:",
"translation": "`json`管道对调试绑定特别有用:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "The generated output would look something like this",
"translation": "它生成的输出是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "### The safe navigation operator ( <span class=\"syntax\">?.</span> ) and null property paths",
"translation": "### 安全导航操作符 ( ?. ) 和空属性路径",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "What happens when the following data bound `title` property is null?",
"translation": "如果下列数据绑定中`title`属性为空,会发生什么?",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "JavaScript throws a null reference error, and so does Angular:",
"translation": "JavaScript 抛出了空引用错误Angular 也是如此:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "Worse, the *entire view disappears*.",
"translation": "晕,*整个视图都不见了*。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "Unfortunately, the app crashes when the `currentHero` is null.",
"translation": "不幸的是,当`currentHero`为空的时候,应用崩溃了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "You could code around that problem with [*ngIf](guide/template-syntax#ngIf).",
"translation": "可以通过用[NgIf](guide/template-syntax#ngIf)代码环绕它来解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "### The non-null assertion operator ( <span class=\"syntax\">!</span> )",
"translation": "### 非空断言操作符(<span class=\"syntax\">!</span>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "The _Angular_ **non-null assertion operator (`!`)** serves the same purpose in an Angular template.",
"translation": "*Angular* 模板中的**非空断言操作符(`!`)也是同样的用途。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "You'll need this template operator when you turn on strict null checks. It's optional otherwise.",
"translation": "如果我们打开了严格控制检测,那就要用到这个模板操作符,而其它情况下则是可选的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/template-syntax.md"
},
{
"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/content-3/guide/template-syntax.md"
},
{
"original": "# TypeScript Configuration",
"translation": "# TypeScript 配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "* [tsconfig.json](guide/typescript-configuration#tsconfig) &mdash; TypeScript compiler configuration.",
"translation": "[tsconfig.json](guide/typescript-configuration#tsconfig) - TypeScript编译器配置。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "* [typings](guide/typescript-configuration#typings) &mdash; TypesScript declaration files.",
"translation": "[typings](guide/typescript-configuration#typings) - TypesScript类型声明文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "## *tsconfig.json*",
"translation": "## *tsconfig.json* 文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "The [Setup](guide/setup) guide uses the following `tsconfig.json`:",
"translation": "我们在[搭建本地开发环境](guide/setup)中创建过如下的`tsconfig.json`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "This file contains options and flags that are essential for Angular applications.",
"translation": "该文件中的选项和标志是写Angular应用程序的基础。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "### *noImplicitAny* and *suppressImplicitAnyIndexErrors*",
"translation": "### *noImplicitAny*与*suppressImplicitAnyIndexErrors*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "The documentation setup sets the `noImplicitAny` flag to `true`.",
"translation": "本文档在环境搭建时将`noImplicitAny`标志设置为`true`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "When 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`并且TypeScript编译器无法推断出类型时它仍然会生成JavaScript文件。\n但是它也会**报告一个错误**。\n很多饱经沧桑的程序员更喜欢这种严格的设置因为类型检查能在编译期间捕获更多意外错误。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "The documentation setup sets this flag to `true` as well.",
"translation": "本文档在环境搭建时将`noImplicitAny`标志设置为`true`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "## TypeScript Typings",
"translation": "## TypeScript类型定义(typings)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "Use [TypeScript type definition files](https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html)&mdash;`d.ts files`&mdash;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/content-3/guide/typescript-configuration.md"
},
{
"original": "TypeScript-aware editors leverage these same definition files to display type information about library features.",
"translation": "TypeScript敏感的编辑器借助这些定义文件来显示这些库中各个特性的类型定义。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "**You need do nothing to get *typings* files for library packages that include `d.ts` files. Angular packages include them already.**",
"translation": "**我们不需要为那些包含了`d.ts`文件的库获取*类型定义*文件 —— Angular的所有包都是如此。**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "### lib.d.ts",
"translation": "### lib.d.ts 文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "Thanks to that, you have all the `es6` typings even when targeting `es5`.",
"translation": "得益于这项设置,即使编译目标设置为`es5`,我们也能获得所有的`es6`类型信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "### Installable typings files",
"translation": "### 安装类型定义文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "Many libraries&mdash;jQuery, Jasmine, and Lodash among them&mdash;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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "QuickStart identifies two *typings*, or `d.ts`, files:",
"translation": "我们在“快速上手”中指定过两个*类型定义*文件(`d.ts`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework.",
"translation": "[jasmine](http://jasmine.github.io/)是Jasmine测试框架的类型定义",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"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/content-3/guide/typescript-configuration.md"
},
{
"original": "QuickStart doesn't require these typings but many of the samples do.",
"translation": "“快速上手”本身不需要这些类型定义,但是文档中的很多例子都需要。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/typescript-configuration.md"
},
{
"original": "# Upgrading from AngularJS",
"translation": "# 从 AngularJS 升级",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "## Preparation",
"translation": "## 准备工作",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Follow the AngularJS Style Guide",
"translation": "### 遵循AngularJS风格指南",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "There are a few rules in particular that will make it much easier to do *an incremental upgrade* using the Angular `upgrade/static` module:",
"translation": "有一些特别的规则可以让使用Angular的`upgrade/static`模块进行*增量升级*变得更简单:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Using a Module Loader",
"translation": "### 使用模块加载器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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&lt;script&gt; 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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Migrating to TypeScript",
"translation": "### 迁移到TypeScript",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "#### Using Component Directives",
"translation": "#### 使用组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "To be Angular compatible, an AngularJS component directive should configure\nthese attributes:",
"translation": "要与Angular兼容AngularJS的组件型指令应该配置下列属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* `restrict: 'E'`. Components are usually used as elements.",
"translation": "`restrict: 'E'`。组件通常会以元素的方式使用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "* `controller` and `controllerAs`. Components have their own controllers.",
"translation": "`controller`和`controllerAs`。组件要有自己的控制器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* `template` or `templateUrl`. Components have their own templates.",
"translation": "`template`或`templateUrl`。组件要有自己的模板。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Component directives may also use the following attributes:",
"translation": "组件型指令还可能使用下列属性:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* `transclude: true/{}`, if the component needs to transclude content from elsewhere.",
"translation": "`transclude: true`:如果组件需要从其它地方透传内容,就设置它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* `require`, if the component needs to communicate with some parent component's\n controller.",
"translation": "`require`:如果组件需要和父组件的控制器通讯,就设置它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Component directives **should not** use the following attributes:",
"translation": "组件型指令**不能**使用下列属性:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* `compile`. This will not be supported in Angular.",
"translation": "`compile`。Angular不再支持它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "* It requires less boilerplate code.",
"translation": "它需要更少的样板代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* It enforces the use of component best practices like `controllerAs`.",
"translation": "它强制你遵循组件的最佳实践,比如`controllerAs`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* It has good default values for directive attributes like `scope` and `restrict`.",
"translation": "指令中像`scope`和`restrict`这样的属性应该有良好的默认值。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "The component directive example from above looks like this when expressed\nusing the component API:",
"translation": "如果使用这个组件API进行快捷定义那么上面看到的组件型指令就变成了这样",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "## Upgrading with ngUpgrade",
"translation": "## 使用升级适配器进行升级",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### How ngUpgrade Works",
"translation": "### 升级模块工作原理",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "#### Dependency Injection",
"translation": "#### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Dependency injection tokens are always strings",
"translation": "依赖注入的令牌(Token)永远是字符串(译注:指服务名称)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "#### Components and the DOM",
"translation": "#### 组件与DOM",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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 thatcomponent . Consider a situation\nwhere you use an Angular component from AngularJS like this:",
"translation": "当我们使用一个属于另一个框架的组件时,就会发生一个跨框架边界的切换。不过,这种切换只发生在该组件元素的*子节点*上。\n考虑一个场景我们从AngularJS中使用一个Angular组件就像这样",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "#### Change Detection",
"translation": "#### 变更检测",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Using UpgradeModule with Angular _NgModules_",
"translation": "### 通过Angular的*NgModule*来使用UpgradeModule",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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的模块进行引导时就得把Anuglar 2的模块传给`UpgradeModule`。我们来看看怎么做。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "For more information, see [NgModules](guide/ngmodules).",
"translation": "要了解Angular模块的更多信息请参阅[Angular模块](guide/ngmodule)页。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "### Bootstrapping hybrid applications",
"translation": "### 引导混合式应用程序",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Say you have an `ng-app` driven bootstrap such as this one:",
"translation": "比如我们现在有这样一个通过 `ng-app` 进行引导的应用:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Next, create an `app.module.ts` file and add the following `NgModule` class:",
"translation": "接下来,创建一个`app.module.ts`文件,并添加下列`NgModule`类:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Now you can bootstrap `AppModule` using the `platformBrowserDynamic.bootstrapModule` method.",
"translation": "现在,我们就可以使用 `platformBrowserDynamic.bootstrapModule` 方法来启动 `AppModule` 了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Using Angular Components from AngularJS Code",
"translation": "### 在AngularJS的代码中使用Angular的组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Say you have a simple Angular component that shows information about a hero:",
"translation": "假设我们有一个简单的用来显示英雄信息的Angular组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "All Angular components, directives and pipes must be declared in an NgModule.",
"translation": "所有Angular组件、指令和管道都必须声明在NgModule中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Use kebab-case for downgraded component attributes",
"translation": "在降级过的组件属性中使用中线命名法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "But when using them from AngularJS templates, you must use kebab-case:",
"translation": "但是从AngularJS的模板中使用它们时我们得使用中线命名法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Using AngularJS Component Directives from Angular Code",
"translation": "### 从Angular代码中使用AngularJS组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "A simple example of an upgradable component is one that just has a template\nand a controller:",
"translation": "可升级组件的简单例子是只有一个模板和一个控制器的指令:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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,\n provide the inputs and outputs using **Angular template syntax**,\nobserving the following rules:",
"translation": "升级后的组件也可能有输入属性和输出属性它们是在原AngularJS组件型指令的scope/controller绑定中定义的。\n当我们从Angular模板中使用该组件时我们要使用**Angular模板语法**来提供这些输入属性和输出属性,但要遵循下列规则:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Binding definition",
"translation": "绑定定义",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Template syntax",
"translation": "模板语法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Attribute binding",
"translation": "属性(Attribute)绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Expression binding",
"translation": "表达式绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "One-way binding",
"translation": "单向绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Two-way binding",
"translation": "双向绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "For example, imagine a hero detail AngularJS component directive\nwith one input and one output:",
"translation": "举个例子假设我们在AngularJS中有一个表示“英雄详情”的组件型指令它带有一个输入属性和一个输出属性",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Projecting AngularJS Content into Angular Components",
"translation": "### 把AngularJS的内容投影到Angular组件中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "</div>",
"translation": "### Transcluding Angular Content into AngularJS Component Directives\n### 把Angular的内容透传进AngularJS的组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "<code-example path=\"upgrade-module/src/app/a-to-ajs-transclusion/container.component.ts\" title=\"container.component.ts\">\n</code-example>",
"translation": "### Making AngularJS Dependencies Injectable to Angular\n### 让AngularJS中的依赖可被注入到Angular",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "You can then inject it in Angular using its class as a type annotation:",
"translation": "然后我们可以一个字符串型令牌把它注入到Angular中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Making Angular Dependencies Injectable to AngularJS",
"translation": "### 让Angular的依赖能被注入到AngularJS中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "For example, you might have an Angular service called `Heroes`:",
"translation": "例如我们可能有一个Angular的`Heroes`服务:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "After this, the service is injectable anywhere in AngularJS code:",
"translation": "此后该服务就能被注入到AngularJS代码中的任何地方了",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "## Using Ahead-of-time compilation with hybrid apps",
"translation": "## 在混合式应用中使用AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "## PhoneCat Upgrade Tutorial",
"translation": "## PhoneCat升级教程",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "In terms of project structure, this is where the work begins:",
"translation": "在项目结构方面,我们工作的起点是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Switching to TypeScript",
"translation": "### 切换到TypeScript",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Begin by installing TypeScript to the project.",
"translation": "让我们先把TypeScript包安装到项目中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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": "我们还应该配置TypeScript编译器以便它能理解我们的项目结构。我们要往项目目录下添加一个`tsconfig.json`文件,\n就像在[搭建本地开发环境](guide/setup)中做过的那样。它将告诉TypeScript编译器该如何编译我们的源文件。\n`tsconfig.json`文件会告诉 TypeScript 编译器如何把 TypeScript 文件转成 ES5 代码,并打包进 CommonJS 模块中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Now launch the TypeScript compiler from the command line in watch mode:",
"translation": "现在,从命令行中用监视模式启动 TypeScript 编译器:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Keep this process running in the background, watching and recompiling as you make changes.",
"translation": "让这个进程一直在后台运行,监听任何变化并自动重新编译。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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的类型定义。\n当我们正确调用AngularJS的API时TypeScript会帮我们检查它 —— 比如往Angular模块中注册组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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": "我们用typings工具安装的这个[AngularJS.x类型定义文件](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/angularjs)\n并不是由Angular开发组维护的但它也已经足够全面了。借助这些类型定义的帮助它可以为AngularJS.x程序加上全面的类型注解。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Here's what the new class for the phone list component controller looks like:",
"translation": "新的“电话列表(phone list)”组件控制器类是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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": "该项目还包含一些动画,在此指南的当前版本我们先不升级它,等到后面的发行版再改。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "* Add Angular and the other new dependencies to `package.json`",
"translation": "把Angular和其它新依赖添加到`package.json`中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* The SystemJS configuration file `systemjs.config.js` to the project root directory.",
"translation": "把SystemJS的配置文件`systemjs.config.js`添加到项目的根目录。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Once these are done, run:",
"translation": "这些完成之后,就运行:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Creating the _AppModule_",
"translation": "### 创建*AppModule*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Now create a new `app.module.ts` with the minimum `NgModule` class:",
"translation": "然后创建一个新的`app.module.ts`文件,其中是一个最小化的`NgModule`类:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "### Bootstrapping a hybrid PhoneCat",
"translation": "### 引导PhoneCat的混合式应用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "#### Why declare _angular_ as _angular.IAngularStatic_?",
"translation": "#### 为何要声明*angular*为*angular.IAngularStatic*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### Upgrading the Phone service",
"translation": "### 升级`Phone`服务",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "* For loading the list of all phones into the phone list component.",
"translation": "把所有电话的列表加载到电话列表组件中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* For loading the details of a single phone into the phone detail component.",
"translation": "把一台电话的详情加载到电话详情组件中。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Here's the full, final code for the service:",
"translation": "最终,该类的全部代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Now that you are loading `phone.service.ts` through an import that is resolved\nby SystemJS, you should **remove the &lt;script&gt; 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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "You could use the `toPromise` method of `Observable` to turn those\nObservables into Promises in the service. In many cases that\nreduce the number of changes to the component controllers.",
"translation": "我们也能使用`Observable`的`toPromise`方法来在服务中把这些可观察对象转变成承诺,以进一步减小组件控制器中需要修改的代码量。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "### Upgrading Components",
"translation": "### 升级组件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "#### No Angular _filter_ or _orderBy_ filters",
"translation": "#### Angular中没有`filter`或`orderBy`过滤器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Remove the &lt;script&gt; tag for the phone list component from `index.html`.",
"translation": "从`index.html`中移除电话列表组件的&lt;script&gt;标签。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Now set the remaining `phone-detail.component.ts` as follows:",
"translation": "现在,剩下的`phone-detail.component.ts`文件变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Convert the phone detail component template into Angular syntax as follows:",
"translation": "我们现在也要把该组件的模板转变成Angular的语法。\n这里是它完整的新模板",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "There are several notable changes here:",
"translation": "这里有几个值得注意的改动:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* You've removed the `$ctrl.` prefix from all expressions.",
"translation": "我们从所有表达式中移除了`$ctrl.`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-src` with property\n bindings for the standard `src` property.",
"translation": "正如我们在电话列表中做过的那样,我们把`ng-src`替换成了标准的`src`属性绑定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-repeat`s with `*ngFor`s.",
"translation": "我们把`ng-repeat`替换成了`*ngFor`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-click` with an event binding for the standard `click`.",
"translation": "我们把`ng-click`替换成了一个到标准`click`事件的绑定。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Add `PhoneDetailComponent` component to the `NgModule` _declarations_ and _entryComponents_:",
"translation": "把`PhoneDetailComponent`组件添加到`NgModule`的_declarations_和_entryComponents_中",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "You should now also remove the phone detail component &lt;script&gt; tag from `index.html`.",
"translation": "我们现在应该从`index.html`中移除电话详情组件的&lt;script>。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "#### Add the _CheckmarkPipe_",
"translation": "#### 添加*CheckmarkPipe*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "The AngularJS directive had a `checkmark` _filter_.\nTurn that into an Angular **pipe**.",
"translation": "AngularJS指令中有一个`checkmark`*过滤器*我们把它转换成Angular的**管道**。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Now import and declare the newly created pipe and\nremove the filter &lt;script&gt; tag from `index.html`:",
"translation": "当我们做这个修改时,也要同时从`core`模块文件中移除对该过滤器的注册。该模块的内容变成了:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "### AOT compile the hybrid app",
"translation": "### 对混合式应用做AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "And that's all you need to use AOT while upgrading your app!",
"translation": "这就是想要在升级应用期间AOT编译所需的一切",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "### Adding The Angular Router And Bootstrap",
"translation": "### 添加Angular路由器和引导程序",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "#### Add the Angular router",
"translation": "#### 添加Angular路由器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Angular has an [all-new router](guide/router).",
"translation": "Angular有一个[全新的路由器](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "<code-example path=\"upgrade-phonecat-3-final/index.html\" region=\"appcomponent\" title=\"index.html (body)\" linenums=\"false\">\n</code-example>",
"translation": "#### Create the _Routing Module_\n#### 创建*路由模块*\nA router needs configuration whether it's the AngularJS or Angular or any other router.",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "#### Generate links for each phone",
"translation": "#### 为每个电话生成链接",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "See the [Routing](guide/router) page for details.",
"translation": "要了解详情,请查看[路由与导航](guide/router)页。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "#### Use route parameters",
"translation": "#### 使用路由参数",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "You are now running a pure Angular application!",
"translation": "我们现在运行的就是纯正的Angular应用了",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "### Say Goodbye to AngularJS",
"translation": "### 再见AngularJS",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "The application is still bootstrapped as a hybrid app.\nThere's no need for that anymore.",
"translation": "应用仍然以混合式应用的方式启动,然而这再也没有必要了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Switch the bootstrap method of the application from the `UpgradeModule` to the Angular way.",
"translation": "把应用的引导(`bootstrap`)方法从`UpgradeAdapter`的改为Angular的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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的那些。\n`systemjs.config.js`中的`@angular/upgrade`包及其映射也可以移除了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "## Appendix: Upgrading PhoneCat Tests",
"translation": "## 附录升级PhoneCat的测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "### E2E Tests",
"translation": "### E2E测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Update the `protractor-conf.js` to sync with hybrid apps:",
"translation": "再对`protractor-conf.js`做下列修改,与混合应用同步:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "When you start to upgrade components and their templates to Angular, you'll make more changes \n because 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/content-3/guide/upgrade.md"
},
{
"original": "Previous code",
"translation": "老代码",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "New code",
"translation": "新代码",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "Notes",
"translation": "说明",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "The repeater matcher relies on AngularJS `ng-repeat`",
"translation": "repeater匹配器依赖于AngularJS中的`ng-repeat`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "The repeater matcher relies on AngularJS `ng-repeat`",
"translation": "repeater匹配器依赖于AngularJS中的`ng-repeat`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "The model matcher relies on AngularJS `ng-model`",
"translation": "model匹配器依赖于AngularJS中的`ng-model`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "The model matcher relies on AngularJS `ng-model`",
"translation": "model匹配器依赖于AngularJS中的`ng-model`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "The binding matcher relies on AngularJS data binding",
"translation": "binding匹配器依赖于AngularJS的数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "Replace the `ng12Hybrid` previously added with the following in `protractor-conf.js`:",
"translation": "替换之前在`protractor-conf.js`中加入 `ng12Hybrid`,象这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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": "同样我们的测试代码中有两个Protractor API调用内部使用了`$location`。该服务没有了,\n我们就得把这些调用用一个WebDriver的通用URL API代替。第一个API是“重定向(redirect)”规约:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "And the second is the phone links spec:",
"translation": "然后是“电话链接(phone links)”规约:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"original": "### Unit Tests",
"translation": "### 单元测试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "For instance, in the phone detail component spec , you can use ES2015\nfeatures like arrow functions and block-scoped variablesand benefit from the type\ndefinitions of the AngularJS services you're consuming:",
"translation": "比如在这个电话详情组件的规约中我们不仅用到了ES2015中的箭头函数和块作用域变量这些特性还为所用的一些\nAngularJS服务提供了类型定义。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"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/content-3/guide/upgrade.md"
},
{
"original": "# User Input",
"translation": "# 用户输入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "Run the <live-example></live-example>.",
"translation": "运行<live-example></live-example",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "The following example shows an event binding that implements a click handler:",
"translation": "下例展示了一个事件绑定,它实现了一个点击事件处理器:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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 reponds\nto the click event by calling the component's `onClickMe` method.",
"translation": "等号左边的`(click)`表示把按钮的点击事件作为**绑定目标**。\n等号右边引号中的文本是**模板语句**,通过调用组件的`onClickMe`方法来响应这个点击事件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "When the user clicks the button, Angular calls the `onClickMe` method from `ClickMeComponent`.",
"translation": "当用户点击按钮时Angular 调用`ClickMeComponent`的`onClickMe`方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "### Type the _$event_",
"translation": "### *$event*的类型",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "The following example rewrites the method with types:",
"translation": "下面的例子,使用了带类型方法:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "### Passing _$event_ is a dubious practice",
"translation": "### 传入 *$event* 是靠不住的做法",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "The next section shows how to use template reference variables to address this problem.",
"translation": "下面将介绍如何用模板引用变量来解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "## Get user input from a template reference variable",
"translation": "## 从一个模板引用变量中获得用户输入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "The following example uses a template reference variable\nto implement a keystroke loopback in a simple template.",
"translation": "下面的例子使用了局部模板变量,在一个超简单的模板中实现按键反馈功能。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "Type something in the input box, and watch the display update with each keystroke.",
"translation": "在输入框中输入,就会看到每次按键时,显示也随之更新了。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "**This won't work at all unless you bind to an event**.",
"translation": "**除非你绑定一个事件,否则这将完全无法工作。**",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "Angular updates the bindings (and therefore the screen)\nonly if the app does something in response to asynchronous events, such as keystrokes.",
"translation": "只有在应用做了些异步事件如击键Angular 才更新绑定(并最终影响到屏幕)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "This 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": "本例代码将`keyup`事件绑定到了数字0这是可能是最短的模板语句。\n虽然这个语句不做什么但它满足 Angular 的要求,所以 Angular 将更新屏幕。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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`变量及其结构了。\n{@a key-event}",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "## Key event filtering (with `key.enter`)",
"translation": "## 按键事件过滤(通过`key.enter`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "Here's how it works.",
"translation": "下面展示了它是如何工作的。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "## On blur",
"translation": "## 失去焦点事件 (blur)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "To fix this issue, listen to both the _Enter_ key and the _blur_ event.",
"translation": "下面通过同时监听输入框的回车键和失去焦点事件来修正这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "</code-example>",
"translation": "## Put it all together\n## 把它们放在一起",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "Below is the \"Little Tour of Heroes\" component.",
"translation": "下面就是“简版英雄指南”组件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "</code-example>",
"translation": "### Observations\n### 小结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "* **Use template variables to refer to elements** &mdash;\nThe `newHero` template variable refers to the `<input>` element.\nYou can reference `newHero` from any sibling or child of the `<input>` element.",
"translation": "**使用模板变量来引用元素** &mdash; `newHero`模板变量引用了`<input>`元素。\n你可以在`<input>`的任何兄弟或子级元素中引用`newHero`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "* **Pass values, not elements** &mdash;\nInstead of passing the `newHero` into the component's `addHero` method,\nget the input box value and pass *that* to `addHero`.",
"translation": "**传递数值,而非元素** &mdash;\n获取输入框的值并将*它*传递给组件的`addHero`,而不要传递`newHero`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "* **Keep template statements simple** &mdash;\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": "**保持模板语句简单** &mdash;\n`(blur)`事件被绑定到两个 JavaScript 语句。\n第一句调用`addHero`。第二句`newHero.value=''`在添加新英雄到列表中后清除输入框。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "## Source code",
"translation": "## 源代码",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "Following is all the code discussed in this page.",
"translation": "下面是本章讨论过的所有源码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"original": "You have mastered the basic primitives for responding to user input and gestures.",
"translation": "你已经掌握了响应用户输入和操作的基础技术。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/user-input.md"
},
{
"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/content-3/guide/user-input.md"
},
{
"original": "# Visual Studio 2015 QuickStart",
"translation": "# Visual Studio 2015 快速上手",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "Some developers prefer Visual Studio as their Integrated Development Environment (IDE).",
"translation": "有些开发者喜欢用Visual Studio。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "## ASP.NET 4.x Project",
"translation": "## ASP.NET 4.x 项目",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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 template for Visual Studio 2015</a>。 \n 注意,最终代码与本文不对应,请适当调节。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Node.js",
"translation": "前提条件: Node.js",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Visual Studio 2015 Update 3",
"translation": "前提条件: Visual Studio 2015 Update 3",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Configure External Web tools",
"translation": "前提条件: 配置External Web tools",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "* Open the **Options** dialog with `Tools` | `Options`.",
"translation": "到`Tools` | `Options`打开**Options**对话框",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "Click OK to close the dialog.",
"translation": "* 点击OK关闭对话框。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "Restart Visual Studio for this change to take effect.",
"translation": "* 重启Visual Studio以让设置变化生效。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Install TypeScript 2.2 for Visual Studio 2015",
"translation": "前提条件: 安装TypeScript 2.2 for Visual Studio 2015",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "While Visual Studio Update 3 ships with TypeScript support out of the box, it currently doesnt 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/content-3/guide/visual-studio-2015.md"
},
{
"original": "To install TypeScript 2.2:",
"translation": "要安装TypeScript 2.2",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "At this point, Visual Studio is ready. Its a good idea to close Visual Studio and \nrestart it to make sure everything is clean.",
"translation": "至此Visual Studio准备好了。重新启动Visual Stuido这样我们可以有一个崭新的开始。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "Step 1: Download the QuickStart files",
"translation": "第一步: 现在“快速上手”文件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "Step 2: Create the Visual Studio ASP.NET project",
"translation": "第二步创建Visual Studio ASP.net项目",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "Create the ASP.NET 4.x project in the usual way as follows:",
"translation": "按照下列步骤创建ASP.NET 4.x项目",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "* In Visual Studio, select `File` | `New` | `Project` from the menu.",
"translation": "在Visual Studio中选择`File` | `New` | `Project`菜单。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "Step 3: Copy the QuickStart files into the ASP.NET project folder",
"translation": "第三步: 把“快速上手”的文件复制到ASP.NET项目所在的目录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "* src/app folder (answer *No* if asked to search for TypeScript Typings)",
"translation": "src/app目录如果询问是否要搜索TypeScript类型回答*No*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "Step 4: Restore the required packages",
"translation": "第四步: 恢复需要的包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "Restore the packages required for an Angular application as follows:",
"translation": "按下面的步骤恢复Angular应用程序需要的包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "* Ignore the warnings.",
"translation": "忽略所有警告。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "* Click the `Refresh` icon in Solution Explorer.",
"translation": "在Solution Explorer里点击`Refresh`图标。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "Step 5: Build and run the app",
"translation": "第五步:构建和运行应用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "### To run in VS with F5",
"translation": "### 按 F5 以在 VS 中运行",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "### For apps that use routing",
"translation": "### 为了使用路由的应用",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "#### Configure IIS rewrite rules",
"translation": "#### 配置 IIS 重写规则",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"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/content-3/guide/visual-studio-2015.md"
},
{
"original": "It's faster to run without the debugger by pressing `Ctrl-F5`.",
"translation": "按`Ctrl-F5`不带调试器的运行应用,速度会更快。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "The default browser opens and displays the QuickStart sample application.",
"translation": "默认浏览器打开并显示《快速上手》例子应用。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "Try editing any of the project files. Save and refresh the browser to\nsee the changes.",
"translation": "尝试编辑任何项目文件,*保存*并刷新浏览器来查看效果。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/visual-studio-2015.md"
},
{
"original": "# Webpack: An Introduction",
"translation": "# Webpack简介",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "# Contents",
"translation": "# 目录",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [What is Webpack?](guide/webpack#what-is-webpack)",
"translation": "[什么是Webpack](guide/webpack#what-is-webpack)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Entries and outputs](guide/webpack#entries-outputs)",
"translation": "[入口与输出](guide/webpack#entries-outputs)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Multiple bundles](guide/webpack#multiple-bundles)",
"translation": "[多重包](guide/webpack#multiple-bundles)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Loaders](guide/webpack#loaders)",
"translation": "[加载器](guide/webpack#loaders)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Plugins](guide/webpack#plugins)",
"translation": "[插件](guide/webpack#plugins)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Configuring Webpack](guide/webpack#configure-webpack)",
"translation": "[配置Webpack](guide/webpack#configure-webpack)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Common configuration](guide/webpack#common-configuration)",
"translation": "[公共配置](guide/webpack#common-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Inside `webpack.common.js`](guide/webpack#inside-webpack-commonjs)",
"translation": "[深入`webpack.common.js`](guide/webpack#inside-webpack-commonjs)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [entry](guide/webpack#common-entries)",
"translation": "[入口](guide/webpack#common-entries)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [resolve extension-less imports](guide/webpack#common-resolves)",
"translation": "[解析无扩展名的导入](guide/webpack#common-resolves)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Plugins](guide/webpack#plugins)",
"translation": "[插件](guide/webpack#plugins)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Environment specific configuration](guide/webpack#environment-configuration)",
"translation": "[针对特定环境进行配置](guide/webpack#environment-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Development configuration](guide/webpack#development-configuration)",
"translation": "[开发环境配置](guide/webpack#development-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Production configuration](guide/webpack#production-configuration)",
"translation": "[生产环境配置](guide/webpack#production-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Trying it out](guide/webpack#try)",
"translation": "[试一下](guide/webpack#try)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Highlights](guide/webpack#highlights)",
"translation": "[重点](guide/webpack#highlights)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [Conclusion](guide/webpack#conclusion)",
"translation": "[总结](guide/webpack#conclusion)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "## What is Webpack?",
"translation": "## 什么是Webpack",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "### Entries and outputs",
"translation": "### 入口与输出",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Webpack inspects that file and traverses its `import` dependencies recursively.",
"translation": "Webpack探查那个文件并且递归遍历它的`import`依赖。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:",
"translation": "然后它把这些文件**输出**到当前配置所指定的_包文件_`app.js`中:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "#### Multiple bundles",
"translation": "#### 多重包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "### Loaders",
"translation": "### 加载器(Loader)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "When Webpack encounters `import` statements like the following,\nit applies the `test` RegEx patterns.",
"translation": "当Webpack遇到如下所示的`import`语句时,它就会调用正则表达式的`test`方法。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "When a pattern matches the filename, Webpack processes the file with the associated loader.",
"translation": "如果一个模式匹配上文件名Webpack就用它所关联的加载器处理这个文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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.\n Then 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追加到页面上的*&lt;style&gt;*元素中)。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "### Plugins",
"translation": "### 插件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "## Configuring Webpack",
"translation": "## 配置Webpack",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Begin by setting up the development environment.",
"translation": "从设置开发环境开始。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "Create a new project folder.",
"translation": "创建一个新的项目文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "Add these files :",
"translation": "把下列文件添加到根目录下:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Open a terminal window and install the npm packages.",
"translation": "打开命令行窗口并安装这些*npm*包",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "### Polyfills",
"translation": "### Polyfills 腻子脚本",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "You'll need polyfills to run an Angular application in most browsers as explained\nin the [Browser Support](guide/browser-support) guide.",
"translation": "我们在[_浏览器支持_](guide/browser-support)章节里解释过Angular应用要能在大多数的浏览器里运行它还需要一些polyfills。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "### Common configuration",
"translation": "### 通用配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Gather the common configuration in a file called `webpack.common.js`.",
"translation": "我们可以把这些通用的配置收归到一个文件,命名为`webpack.common.js`。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "### Inside _webpack.common.js_",
"translation": "### webpack.common.js解读",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "* [`entry`](guide/webpack#common-entries)&mdash;the entry-point files that define the bundles.",
"translation": "[`entries`](guide/webpack#common-entries) - 包体的入口文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [`resolve`](guide/webpack#common-resolves)&mdash;how to resolve file names when they lack extensions.",
"translation": "[`resolve`](guide/webpack#common-resolves) - 省略扩展名时如何解释文件名。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* [`module.rules`](guide/webpack#common-rules)&mdash; `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/content-3/guide/webpack.md"
},
{
"original": "* [`plugins`](guide/webpack#common-plugins)&mdash;creates instances of the plugins.",
"translation": "[`plugins`](guide/webpack#common-plugins) - 创建插件的实例。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "#### _entry_",
"translation": "#### _entry_ 入口",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "The first export is the `entry` object:",
"translation": "如上所述,第一个导出的对象是*entries*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "This `entry` object defines the three bundles:",
"translation": "`entry`对象定义了三个包:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* `polyfills`&mdash;the polyfills needed to run Angular applications in most modern browsers.",
"translation": "`polyfills` - 使得Angular应用能够运行在大多数的现代浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* `vendor`&mdash;the third-party dependencies such as Angular, lodash, and bootstrap.css.",
"translation": "`vendor` - 第三方依赖如Angular、lodash和bootstrap.css。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* `app`&mdash;the application code.",
"translation": "`app` - 应用代码。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "#### _resolve_ extension-less imports",
"translation": "#### _resolve_ 无扩展名的文件导入",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "#### _module.rules_",
"translation": "#### _module.rules_ 规则",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "Rules tell Webpack which loaders to use for each file, or module:",
"translation": "Rules用来告诉Webpack加载不同文件或模块时该用哪个加载器。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* `awesome-typescript-loader`&mdash;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/content-3/guide/webpack.md"
},
{
"original": "* `angular2-template-loader`&mdash;loads angular components' template and styles.",
"translation": "`angular2-template-loader` - 用于加载Angular组件的模板和样式",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* `html-loader`&mdash;for component templates.",
"translation": "`html-loader` - 为组件模板准备的加载器",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* images/fonts&mdash;Images and fonts are bundled as well.",
"translation": "`images/fonts` - 图片和字体文件也能被打包。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* CSS&mdash;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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Multiple loaders can be chained using the array notation.",
"translation": "多重加载器也能使用数组形式串联起来。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "#### _plugins_",
"translation": "#### _插件_",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "Finally, create instances of three plugins:",
"translation": "最后,创建三个插件实例:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "#### *CommonsChunkPlugin*",
"translation": "#### *CommonsChunkPlugin* 插件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "#### _HtmlWebpackPlugin_",
"translation": "#### _HtmlWebpackPlugin_ 插件",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "### Environment-specific configuration",
"translation": "### 环境相关的配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "These files tend to be short and simple.",
"translation": "这些文件越小越简单越好。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "### Development configuration",
"translation": "### 开发环境配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "Here is the `webpack.dev.js` development configuration file.",
"translation": "下面是开发环境的而配置文件`webpack.dev.js`",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "The development build relies on the Webpack development server, configured near the bottom of the file.",
"translation": "开发环境下的构建依赖于Webpack的开发服务器我们在靠近文件底部的地方配置了它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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`中插入适当的&lt;script&gt;和&lt;link&gt;标签。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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`插件就会转而把一个&lt;link&gt;标签写进`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/content-3/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "### Production configuration",
"translation": "### 产品环境配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "Configuration of a *production* build resembles *development* configuration with a few key changes.",
"translation": "*产品环境*下的配置和*开发环境*下的配置很相似……除了一些关键的改动。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Put the production output bundle files in the `dist` folder.",
"translation": "把产品环境的输出包放在`dist`目录下。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "There are additional plugins:",
"translation": "还有一些别的插件:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* *`NoEmitOnErrorsPlugin`&mdash; stops the build if there is an error.",
"translation": "*`NoEmitOnErrorsPlugin`* - 如果出错就停止构建。*",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "*`UglifyJsPlugin`&mdash; minifies the bundles.",
"translation": "`UglifyJsPlugin` - 最小化(minify)生成的包。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* *`ExtractTextPlugin`&mdash; extracts embedded css as external files, adding cache-busting hash to the filename.",
"translation": "*`ExtractTextPlugin`* - 把内嵌的css抽取成外部文件并为其文件名添加“缓存无效哈希”。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* *`DefinePlugin`&mdash; use to define environment variables that you can reference within the application.",
"translation": "*`DefinePlugin`* - 用来定义环境变量,以便我们在自己的程序中引用它。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* *`LoaderOptionsPlugins`&mdash; to override options of certain loaders.",
"translation": "*`LoaderOptionsPlugins`* - 为特定的加载器提供选项。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "### Test configuration",
"translation": "### 测试环境配置",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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": "我们不用预编译TypeScriptWebpack随时在内存中转译我们的TypeScript文件并且把产出的JS直接反馈给Karma。\n硬盘上没有任何临时文件。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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&mdash;and only&mdash;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/content-3/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "## Trying it out",
"translation": "## 试一试",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "Highlights",
"translation": "### 重点:",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "* There are no `<script>` or `<link>` tags in the `index.html`. \nThe `HtmlWebpackPlugin` inserts them dynamically at runtime.",
"translation": "在`index.html`中没有&lt;script&gt;或&lt;link&gt;标签。\n `HtmlWebpackPlugin`会在运行时动态插入它们。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"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/content-3/guide/webpack.md"
},
{
"original": "* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.\n The application imports these modules too; they'd be duplicated in the `app.js` bundle\n if 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/content-3/guide/webpack.md"
},
{
"original": "## Conclusion",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "You've learned just enough Webpack to configurate development, test and production builds \nfor a small Angular application.",
"translation": "我们学到了刚好够用来在开发、测试、产品环境下构建一个小型Angular应用的Webpack配置知识。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "_You could always do more_. Search the web for expert advice and expand your Webpack knowledge.",
"translation": "_但我们还能做得更多_。搜索互联网来获得专家的建议并扩展你对Webpack的认识。",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"original": "[Back to top](guide/webpack#top)",
"translation": "[回到顶部](guide/webpack#top)",
"sourceFile": "/Users/twer/private/GDE/content-3/guide/webpack.md"
},
{
"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/content-3/marketing/docs.md"
},
{
"original": "## Assumptions",
"translation": "## 基本假设",
"sourceFile": "/Users/twer/private/GDE/content-3/marketing/docs.md"
},
{
"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 \"学习 JavaScript\")和来自[最新标准](https://babeljs.io/learn-es2015/ \"Latest JavaScript standards\")的一些知识,比如 [类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes \"ES2015 类\") 和 [模块](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import \"ES2015 模块\")。\n下列代码范例都是用最新版本的JavaScript写的利用[类型](https://www.typescriptlang.org/docs/handbook/classes.html \"TypeScript 类型\")实现依赖注入,并使用[装饰器](https://www.typescriptlang.org/docs/handbook/decorators.html \"装饰器\")来提供元数据。",
"sourceFile": "/Users/twer/private/GDE/content-3/marketing/docs.md"
},
{
"original": "## Feedback",
"translation": "## 反馈",
"sourceFile": "/Users/twer/private/GDE/content-3/marketing/docs.md"
},
{
"original": "You can sit with us!",
"translation": "你也可以和我们一起做贡献!",
"sourceFile": "/Users/twer/private/GDE/content-3/marketing/docs.md"
},
{
"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/content-3/marketing/docs.md"
},
{
"original": "<h1 class=\"no-toc\">Tutorial: Tour of Heroes</h1",
"translation": "教程:英雄指南",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"original": "By the end of the tutorial you will be able to do the following:",
"translation": "在本教程的最后,我们将完成下列工作:",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "* Use built-in Angular directives to show and hide elements and display lists of hero data.",
"translation": "使用内置指令来显示 / 隐藏元素,并且显示英雄数据的列表。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "* Create Angular components to display hero details and show an array of heroes.",
"translation": "创建 Angular 组件以显示英雄的详情,并显示一个英雄数组。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "* Use one-way data binding for read-only data.",
"translation": "为只读数据使用单项数据绑定。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "* Add editable fields to update a model with two-way data binding.",
"translation": "添加可编辑字段,使用双向数据绑定来更新模型。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "* Bind component methods to user events, like keystrokes and clicks.",
"translation": "把组件中的方法绑定到用户事件上,比如按键和点击。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"original": "* Format data with pipes.",
"translation": "使用管道来格式化数据。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "* Create a shared service to assemble the heroes.",
"translation": "创建共享的服务来管理这些英雄。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "* Use routing to navigate among different views and their components.",
"translation": "使用路由在不同的视图及其组件之间导航。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"original": "## What you'll build",
"translation": "## 我们要构建出什么",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"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/content-3/tutorial/index.md"
},
{
"original": "The following diagram captures all of the navigation options.",
"translation": "下面这张图汇总了我们所有可能的导航路径。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "Here's the app in action:",
"translation": "下图演示了我们应用中的所有操作。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/index.md"
},
{
"original": "# The Hero Editor",
"translation": "# 英雄编辑器",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"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/content-3/tutorial/toh-pt1.md"
},
{
"original": "## Create the heroes component",
"translation": "## 创建英雄列表组件",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"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`属性的类型换成`Hero`。\n然后以`1`为 id、以 “Windstorm” 为名字,初始化它。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"original": "The revised `HeroesComponent` class file should look like this:",
"translation": "修改后的 `HeroesComponent` 类应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"original": "The browser refreshes and display's the hero's information.",
"translation": "浏览器自动刷新,并显示这位英雄的信息。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"original": "## Edit the hero",
"translation": "## 编辑英雄名字",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"original": "Users should be able to edit the hero name in an `<input>` textbox.",
"translation": "用户应该能在一个`<input>`输入框中编辑英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"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/content-3/tutorial/toh-pt1.md"
},
{
"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/content-3/tutorial/toh-pt1.md"
},
{
"original": "### Two-way binding",
"translation": "### 双向绑定",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"original": "Refactor the details area in the `HeroesComponent` template so it looks like this:",
"translation": "把模板中的英雄名字重构成这样:",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"original": "**[(ngModel)]** is Angular's two-way data binding syntax.",
"translation": "**[(ngModel)]** 是 Angular 的双向数据绑定语法。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"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/content-3/tutorial/toh-pt1.md"
},
{
"original": "### The missing _FormsModule_",
"translation": "### 缺少 `FormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"original": "Notice that the app stopped working when you added `[(ngModel)]`.",
"translation": "注意,当我们加上 `[(ngModel)]` 之后这个应用无法工作了。",
"sourceFile": "/Users/twer/private/GDE/content-3/tutorial/toh-pt1.md"
},
{
"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/content-3/tutorial/toh-pt1.md"
},
{
"original": "## Transpile",
"translation": "## 转译transpile)",
"sourceFile": "/Users/twer/private/GDE/content-2/_fragments/glossary-t2.md"
},
{
"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/content-2/_fragments/glossary-t2.md"
},
{
"original": "## TypeScript",
"translation": "## TypeScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-2/_fragments/glossary-t2.md"
},
{
"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/content-2/_fragments/glossary-t2.md"
},
{
"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/content-2/_fragments/glossary-t2.md"
},
{
"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/content-2/_fragments/glossary-t2.md"
},
{
"original": "Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).",
"translation": "更多信息,见[typescript.org](http://www.typescriptlang.org/)。",
"sourceFile": "/Users/twer/private/GDE/content-2/_fragments/glossary-t2.md"
},
{
"original": "# AngularJS to Angular Quick Reference",
"translation": "# 从 AngularJS 到 Angular 快速参考",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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 的 1.x 版本。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "## Template basics",
"translation": "## 模板基础",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Bindings/interpolation",
"translation": "### 绑定/插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Bindings/interpolation",
"translation": "### 绑定/插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Filters",
"translation": "### 过滤器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "To filter output in AngularJS templates, use the pipe character (|) and one or more filters.",
"translation": "要在AngularJS中过滤输出使用管道字符(|)以及一个或多个过滤器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "This example filters the `title` property to uppercase.",
"translation": "在这个例子中,我们把`title`属性过滤成了大写形式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Pipes",
"translation": "### 管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Filters/pipes](guide/ajs-quick-reference#filters-pipes) below.",
"translation": "请参见下面[过滤器/管道](guide/ajs-quick-reference#filters-pipes)了解更多信息。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Local variables",
"translation": "### 局部变量",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Here, `movie` is a user-defined local variable.",
"translation": "这里的`movie`是一个用户定义的局部变量",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Input variables",
"translation": "### 输入变量",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Angular has true template input variables that are explicitly defined using the `let` keyword.",
"translation": "在Angular中我们有了真正的模板输入变量它需要使用`let`关键字进行明确定义。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "## Template directives",
"translation": "## 模板指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "The application startup process is called **bootstrapping**.",
"translation": "应用的启动过程被称为**引导**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Bootstrapping",
"translation": "### 引导",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "You can specify multiple classes, as shown in the second example.",
"translation": "就像第二个例子中展示的可以指定多个CSS类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "You can specify multiple classes, as shown in the second example.",
"translation": "就像第二个例子中所展示的那样,可以同时指定多个类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `click` event",
"translation": "### 绑定到`click`事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Component decorator",
"translation": "### Component装饰器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Architecture Overview](guide/architecture#components).",
"translation": "要了解更多,请参见[架构概览](guide/architecture#components)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### ng-hide\n 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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `hidden` property",
"translation": "### 绑定`hidden`属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Routing is handled differently in Angular.",
"translation": "路由在Angular中的处理方式不同。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `href` property",
"translation": "### 绑定到`href`属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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中移除。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "For more information on two-way binding with `ngModel`, see the [NgModel&mdash;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&mdash;使用`[(ngModel)]`进行双向绑定](../guide/template-syntax.html#ngModel)部分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the table row (`<tr>`) element repeats for each movie object in the collection of movies.",
"translation": "在这个例子中,对`movies`集合中的每一个`movie`对象重复渲染了这个表格行元素(`<tr>`)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Structural Directives](guide/structural-directives).",
"translation": "要了解更多信息,参见[结构性指令](guide/structural-directives)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the `<div>` element is shown if the `favoriteHero` variable is truthy.",
"translation": "在这个例子中,如果`favoriteHero`变量为真,`<div>`元素就会显示出来。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `hidden` property",
"translation": "### 绑定到`hidden`属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the `<div>` element is hidden if the `favoriteHero` variable is not truthy.",
"translation": "在这个例子中,如果`favoriteHero`变量不是真值,`<div>`元素就会被隐藏。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `src` property",
"translation": "### 绑定到`src`属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "The (*) before `ngSwitchCase` and `ngSwitchDefault` is required in this example.",
"translation": "在这个例子中,`ngSwitchCase`和`ngSwitchDefault`前面的星号(*)是必须的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "## Filters/pipes",
"translation": "## 过滤器/管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Formats a number as currency.",
"translation": "把一个数字格式化成货币。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `currency` pipe is similar although some of the parameters have changed.",
"translation": "Angular的`currency`管道和1中很相似只是有些参数变化了。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Formats a date to a string based on the requested format.",
"translation": "基于要求的格式把日期格式化成字符串。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `date` pipe is similar.",
"translation": "Angular的`date`管道和它很相似。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Selects a subset of items from the defined collection, based on the filter criteria.",
"translation": "基于过滤条件从指定的集合中选取出一个子集。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Converts a JavaScript object into a JSON string. This is useful for debugging.",
"translation": "把一个JavaScript对象转换成一个JSON字符串。这对调试很有用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `json` pipe does the same thing.",
"translation": "Angular的`json`管道做完全相同的事。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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)个条目。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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中一样如果们改用组件中的代码实现此操作性能将会提升。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Converts the string to lowercase.",
"translation": "把该字符串转成小写形式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `lowercase` pipe does the same thing.",
"translation": "Angular的`lowercase`管道和1中的功能完全相同。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "Formats a number as text.",
"translation": "把数字格式化为文本。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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)百分比格式,如第三个范例所示。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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排序了。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "## Modules/controllers/components",
"translation": "## 模块/控制器/组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### none",
"translation": "### 没了",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Angular modules",
"translation": "### Angular模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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模块用来对控制器、服务和其它代码进行跟踪。第二个参数定义该模块依赖的其它模块列表。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "NgModules, defined with the `NgModule` decorator, serve the same purpose:",
"translation": "Angular的模块用`NgModule`装饰器进行定义,有如下用途:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "* `imports`: specifies the list of other modules that this module depends upon",
"translation": "`imports`: 指定当前模块依赖的其它模块列表",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "* `declaration`: keeps track of your components, pipes, and directives.",
"translation": "`declaration`: 用于记录组件、管道和指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "For more information on modules, see [NgModules](guide/ngmodule).",
"translation": "要了解关于模块的更多知识,参见[NgModules](guide/ngmodule)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Component decorator",
"translation": "### 组件装饰器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "This is how you associate a template with logic, which is defined in the component class.",
"translation": "这就是把模板关联到代码的方式,它定义在组件类中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Controller function",
"translation": "### 控制器函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "In AngularJS, you write the code for the model and methods in a controller function.",
"translation": "在Angular1中我们在控制器函数中写模型和方法的代码。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Component class",
"translation": "### 组件类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "In Angular, you create a component class.",
"translation": "在Angular中我们写组件类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Dependency injection",
"translation": "### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Dependency injection",
"translation": "### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "## Style sheets",
"translation": "## 样式表",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"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`标签来为应用程序定义样式。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "### Styles configuration",
"translation": "### 样式配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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": "在Angular2中我们可以继续在`index.html`中使用link标签来为应用程序定义样式。\n 但是也能在组件中封装样式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"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/content-2/guide/ajs-quick-reference.md"
},
{
"original": "This allows you to set appropriate styles for individual components that wont leak into\n other parts of the application.",
"translation": "这让我们可以为各个组件设置合适的样式,而不用担心它被泄漏到程序中的其它部分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ajs-quick-reference.md"
},
{
"original": "# Animations",
"translation": "# 动画",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "For other browsers, a polyfill is required. Uncomment the `web-animations-js` polyfill from the `polyfills.ts` file.",
"translation": "至于其它浏览器,就需要一个填充库(polyfill)了。你可以[从这里获取`web-animations.min.js`](https://github.com/web-animations/web-animations-js),并把它加入你的页面中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "The examples in this page are available as a <live-example></live-example>.",
"translation": "本章中引用的这个例子可以到<live-example></live-example>去体验。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "## Transitioning between two states",
"translation": "## 快速起步范例:在两个状态间转场",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "Animations can be defined inside `@Component` metadata.",
"translation": "动画会被定义在`@Component`元数据中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "## States and transitions",
"translation": "## 状态与转场",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "Angular animations are defined as logical **states** and **transitions**\nbetween states.",
"translation": "Angular动画是由**状态**和**状态之间的转场效果**所定义的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "We can define *styles* for each animation state:",
"translation": "我们可以为每个动画状态定义了*一组样式*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "### The wildcard state `*`",
"translation": "### `*`(通配符)状态",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "* The `active => *` transition applies when the element's state changes from `active` to anything else.",
"translation": "当该元素的状态从`active`变成任何其它状态时,`active => *`转场都会生效。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "* The `* => *` transition applies when *any* change between two states takes place.",
"translation": "当在*任意*两个状态之间切换时,`* => *`转场都会生效。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "### The `void` state",
"translation": "### `void`状态",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "The wildcard state `*` also matches `void`.",
"translation": "`*`通配符状态也能匹配`void`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "## Example: Entering and leaving",
"translation": "## 例子:进场与离场",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "* Enter: `void => *`",
"translation": "进场:`void => *`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "* Leave: `* => void`",
"translation": "离场:`* => void`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "These two common animations have their own aliases:",
"translation": "这两个常见的动画有自己的别名:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "## Example: Entering and leaving from different states",
"translation": "## 范例:从不同的状态下进场和离场",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "* Inactive hero enter: `void => inactive`",
"translation": "非激活英雄进场:`void => inactive`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "* Active hero enter: `void => active`",
"translation": "激活英雄进场:`void => active`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "* Inactive hero leave: `inactive => void`",
"translation": "非激活英雄离场:`inactive => void`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "* Active hero leave: `active => void`",
"translation": "激活英雄离场:`active => void`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "This gives you fine-grained control over each transition:",
"translation": "现在就对每一种转场都有了细粒度的控制:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "## Animatable properties and units",
"translation": "## 可动的(Animatable)属性与单位",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "If you don't provide a unit when specifying dimension, Angular assumes the default of `px`:",
"translation": "对大多数尺寸类属性而言,还能只定义一个数字,那就表示它使用的是像素(px)数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "* `50` is the same as saying `'50px'`",
"translation": "`50`相当于`'50px'`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "## Automatic property calculation",
"translation": "## 自动属性值计算",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "## Animation timing",
"translation": "## 动画时间线",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "### Duration",
"translation": "### 持续时间",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "* As a plain number, in milliseconds: `100`",
"translation": "作为一个普通数字,以毫秒为单位,如:`100`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "* In a string, as milliseconds: `'100ms'`",
"translation": "作为一个字符串,以毫秒为单位,如:`'100ms'`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "* In a string, as seconds: `'0.1s'`",
"translation": "作为一个字符串,以秒为单位,如:`'0.1s'`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "### Delay",
"translation": "### 延迟",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "* Wait for 100ms and then run for 200ms: `'0.2s 100ms'`",
"translation": "等待100毫秒然后运行200毫秒`'0.2s 100ms'`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "### Easing",
"translation": "### 缓动函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "* Run for 200ms, with easing: `'0.2s ease-in-out'`",
"translation": "运行200毫秒并且带缓动`'0.2s ease-in-out'`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "### Example",
"translation": "### 例子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "## Multi-step animations with keyframes",
"translation": "## 基于关键帧(Keyframes)的多阶段动画",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "This example adds some \"bounce\" to the enter and leave animations with\nkeyframes:",
"translation": "在这个例子中,我们使用关键帧来为进场和离场动画添加一些“反弹效果”:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "## Parallel animation groups",
"translation": "## 并行动画组(Group)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "One group animates the element transform and width; the other group animates the opacity.",
"translation": "其中一个动画组对元素的`transform`和`width`做动画,另一个组则对`opacity`做动画。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"original": "A callback is fired when an animation is started and also when it is done.",
"translation": "当动画开始和结束时,会触发一个回调。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"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/content-2/guide/animations.md"
},
{
"original": "Those callbacks will fire whether or not an animation is picked up.",
"translation": "无论动画是否实际执行过,那些回调都会触发。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/animations.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "This guide explains how to build with the AOT compiler and how to write Angular metadata that AOT can compile.",
"translation": "本章描述了如何使用 AOT 编译器,以及如何书写能被 AOT 编译的 Angular 元数据。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "<a href=\"https://www.youtube.com/watch?v=kW9cJsvcsGo\">Watch compiler author Tobias Bosch explain the Angular Compiler</a> at AngularConnect 2016.",
"translation": "观看 Angular 编译器的作者Tobias Bosch 在 AngularConnect 2016 上对编译器的解释。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "## Angular compilation",
"translation": "## 概览",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "<code-example language=\"sh\" class=\"code-shell\">\n ng build --aot\n ng serve --aot\n</code-example>",
"translation": "Angular应用主要包含组件和它们的HTML模板。\n在浏览器可以渲染应用之前组件和模板必须要被**Angular编译器**转换为可以执行的JavaScript。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "## Why compile with AOT?",
"translation": "## 为什么需要AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "*Faster rendering*",
"translation": "**渲染得更快**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "*Fewer asynchronous requests*",
"translation": "**需要的异步请求更少**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "*Smaller Angular framework download size*",
"translation": "**需要下载的Angular框架体积更小**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "*Detect template errors earlier*",
"translation": "**提早检测模板错误**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "*Better security*",
"translation": "**更安全**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "## Angular Metadata and AOT",
"translation": "## Angular 元数据与 AOT",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "## Metadata restrictions",
"translation": "## 元数据的限制",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "You write metadata in a _subset_ of TypeScript that must conform to the following general constraints:",
"translation": "我们只能使用 TypeScript 的一个**子集**书写元数据,它必须满足下列限制:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "1. Limit [expression syntax](#expression-syntax) to the supported subset of JavaScript.",
"translation": "[表达式语法](#expression-syntax)只支持 JavaScript 的一个有限的子集。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "2. Only reference exported symbols after [code folding](#folding).",
"translation": "只能引用[代码收缩](#folding)后导出的符号。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "3. Only call [functions supported](#supported-functions) by the compiler.",
"translation": "只能调用编译器[支持的那些函数](#supported-functions)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "4. Decorated and data-bound class members must be public.",
"translation": "被装饰和用于数据绑定的类成员必须是公共public的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "The next sections elaborate on these points.",
"translation": "我们将在下一节详细解释这些问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"original": "## How AOT works",
"translation": "## AOT 工作原理",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "## Phase 1: analysis",
"translation": "## 阶段1分析",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"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/content-2/guide/aot-compiler.md"
},
{
"original": "# Architecture Overview",
"translation": "# 架构概览",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "The framework consists of several libraries, some of them core and some optional.",
"translation": "该框架包括一系列库,有些是核心库,有些是可选库。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "The code referenced on this page is available as a <live-example></live-example>.",
"translation": "本章所引用的代码见<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "## Modules",
"translation": "## 模块",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "NgModules are a big deal.\nThis page introduces modules; the [NgModules](guide/ngmodule) page covers them in depth.",
"translation": "_Angular 模块_很重要。这里只是简单介绍在 [Angular 模块](guide/ngmodule)中会做深入讲解。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "* `providers` - creators of [services](guide/architecture#services) that this module contributes to\n the global collection of services; they become accessible in all parts of the app.",
"translation": "`providers` - [服务](guide/architecture#services)的创建者,并加入到全局服务列表中,可用于应用任何部分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* `bootstrap` - the main application view, called the _root component_,\n that hosts all other app views. Only the _root module_ should set this `bootstrap` property.",
"translation": "`bootstrap` - 指定应用的主视图称为_根组件_它是所有其它视图的宿主。只有_根模块_才能设置`bootstrap`属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "Here's a simple root module:",
"translation": "下面是一个简单的根模块:",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "### NgModules vs. JavaScript modules",
"translation": "### NgModules vs. JavaScript 模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "The NgModule &mdash; a class decorated with `@NgModule` &mdash; is a fundamental feature of Angular.",
"translation": "NgModule一个带`@NgModule`装饰器的类)是 Angular 的基础特性之一。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "### Angular libraries",
"translation": "### Angular 模块库",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Each Angular library name begins with the `@angular` prefix.",
"translation": "每个 Angular 库的名字都带有`@angular`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "You also import NgModules from Angular _libraries_ using JavaScript import statements:",
"translation": "还可以使用 JavaScript 的导入语句从 Angular _库_中导入 Angular _模块_",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "## Components",
"translation": "## 组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "A _component_ controls a patch of screen called a *view*.",
"translation": "_组件_负责控制屏幕上的一小块区域我们称之为*视图*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "For example, the following views are controlled by components:",
"translation": "例如,下列视图都是由组件控制的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* The app root with the navigation links.",
"translation": "带有导航链接的应用根组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* The list of heroes.",
"translation": "英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* The hero editor.",
"translation": "英雄编辑器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "You define a component's application logic&mdash;what it does to support the view&mdash;inside a class.\nThe class interacts with the view through an API of properties and methods.",
"translation": "我们在类中定义组件的应用逻辑,为视图提供支持。\n组件通过一些由属性和方法组成的 API 与视图交互。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "## Templates",
"translation": "## 模板",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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 `<hero-detail>` uses Angular's [template syntax](guide/template-syntax).",
"translation": "模板除了可以使用像`<h2>`和`<p>`这样的典型的 HTML 元素,还能使用其它元素。\n例如像`*ngFor`、`{{hero.name}}`、`(click)`、`[hero]`和`<hero-detail>`这样的代码使用了 Angular 的[模板语法](guide/template-syntax)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "In the last line of the template, the `<hero-detail>` tag is a custom element that represents a new component, `HeroDetailComponent`.",
"translation": "在模板的最后一行,`<hero-detail>`标签就是一个用来表示新组件`HeroDetailComponent`的自定义元素。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Notice how `<hero-detail>` rests comfortably among native HTML elements. Custom components mix seamlessly with native HTML in the same layouts.",
"translation": "注意到了吗?`<hero-detail>`舒适地躺在原生 HTML 元素之间。\n自定义组件和原生 HTML 在同一布局中融合得天衣无缝。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "## Metadata",
"translation": "## 元数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "Metadata tells Angular how to process a class.",
"translation": "<p style=\"padding-top:10px\">元数据告诉 Angular 如何处理一个类。</p>\n<br class=\"clear\">",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Here are a few of the most useful `@Component` configuration options:",
"translation": "`@Component`的配置项包括:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* `selector`: CSS selector that tells Angular to create and insert an instance of this component\nwhere it finds a `<hero-list>` tag in *parent* HTML.\nFor example, if an app's HTML contains `<hero-list></hero-list>`, then\nAngular inserts an instance of the `HeroListComponent` view between those tags.",
"translation": "`selector` CSS 选择器,它告诉 Angular 在*父级* HTML 中查找`<hero-list>`标签,创建并插入该组件。\n 例如,如果应用的 HTML 包含`<hero-list></hero-list>` Angular 就会把`HeroListComponent`的一个实例插入到这个标签中。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "The template, metadata, and component together describe a view.",
"translation": "模板、元数据和组件共同描绘出这个视图。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "## Data binding",
"translation": "## 数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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 如何把二者联系起来。As the diagram shows, there are four forms of data binding syntax. Each form has a direction &mdash; to the DOM, from the DOM, or in both directions.如图所示,数据绑定的语法有四种形式。每种形式都有一个方向 —— 绑定到 DOM 、绑定自 DOM 以及双向绑定。<br class=\"clear\">",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "The `HeroListComponent` [example](guide/architecture#templates) template has three forms:",
"translation": "`HeroListComponent`[示例](guide/architecture#templates)模板中有三种形式:",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Data binding plays an important role in communication between a template and its component.",
"translation": "数据绑定在模板与对应组件的交互中扮演了重要的角色。\n<br class=\"l-clear-both\">",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "Data binding is also important for communication between parent and child components.",
"translation": "数据绑定在父组件与子组件的通讯中也同样重要。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "## Directives",
"translation": "## 指令 (directive)",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Two *other* kinds of directives exist: _structural_ and _attribute_ directives.",
"translation": "还有两种*其它*类型的指令_结构型_指令和_属性 (attribute) 型_指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "**Structural** directives alter layout by adding, removing, and replacing elements in DOM.",
"translation": "**结构型**指令通过在 DOM 中添加、移除和替换元素来修改布局。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "## Services",
"translation": "## 服务",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Examples include:",
"translation": "例如:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* logging service",
"translation": "日志服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* data service",
"translation": "数据服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* message bus",
"translation": "消息总线",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* tax calculator",
"translation": "税款计算器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* application configuration",
"translation": "应用程序配置",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Here's an example of a service class that logs to the browser console:",
"translation": "下面是一个服务类的范例,用于把日志记录到浏览器的控制台:",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Services are everywhere.",
"translation": "服务无处不在。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "## Dependency injection",
"translation": "## 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-2/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 使用依赖注入来提供新组件以及组件所需的服务。<br class=\"clear\">",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "The process of `HeroService` injection looks a bit like this:",
"translation": "`HeroService`注入的过程差不多是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "You can register providers in modules or in components.",
"translation": "我们可以在模块中或组件中注册提供商。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "Points to remember about dependency injection:",
"translation": "需要记住的关于依赖注入的要点是:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* Dependency injection is wired into the Angular framework and used everywhere.",
"translation": "依赖注入渗透在整个 Angular 框架中,被到处使用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* The *injector* is the main mechanism.",
"translation": "**注入器 (injector)** 是本机制的核心。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* An injector maintains a *container* of service instances that it created.",
"translation": "注入器负责维护一个*容器*,用于存放它创建过的服务实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* An injector can create a new service instance from a *provider*.",
"translation": "注入器能使用*提供商*创建一个新的服务实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* A *provider* is a recipe for creating a service.",
"translation": "*提供商*是一个用于创建服务的配方。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* Register *providers* with injectors.",
"translation": "把*提供商*注册到注入器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "## Wrap up",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/architecture.md"
},
{
"original": "* [Modules](guide/architecture#modules)",
"translation": "[模块](guide/architecture#modules)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* [Components](guide/architecture#components)",
"translation": "[组件](guide/architecture#components)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* [Templates](guide/architecture#templates)",
"translation": "[模板](guide/architecture#templates)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* [Metadata](guide/architecture#metadata)",
"translation": "[元数据](guide/architecture#metadata)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* [Data binding](guide/architecture#data-binding)",
"translation": "[数据绑定](guide/architecture#data-binding)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* [Directives](guide/architecture#directives)",
"translation": "[指令](guide/architecture#directives)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* [Services](guide/architecture#services)",
"translation": "[服务](guide/architecture#services)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "* [Dependency injection](guide/architecture#dependency-injection)",
"translation": "[依赖注入](guide/architecture#dependency-injection)",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/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/content-2/guide/architecture.md"
},
{
"original": "> [**Pipes**](guide/pipes): Use pipes in your templates to improve the user experience by transforming values for display. Consider this `currency` pipe expression:",
"translation": "> [**管道**](guide/pipes):在模板中使用管道转换成用于显示的值,以增强用户体验。例如,`currency`管道表达式:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "> It displays a price of 42.33 as `$42.33`.",
"translation": "> 它把价格“42.33”显示为`$42.33`。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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 框架交互时进行单元测试。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/architecture.md"
},
{
"original": "# Attribute Directives",
"translation": "# 属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "An **Attribute** directive changes the appearance or behavior of a DOM element.",
"translation": "**属性**型指令用于改变一个 DOM 元素的外观或行为。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Try the <live-example title=\"Attribute Directive example\"></live-example>.",
"translation": "你可以到这里试试:<live-example title=\"Attribute Directive example\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "## Directives overview",
"translation": "## 指令概览",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "There are three kinds of directives in Angular:",
"translation": "在 Angular 中有三种类型的指令:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "1. Components&mdash;directives with a template.",
"translation": "组件 &mdash; 拥有模板的指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "1. Structural directives&mdash;change the DOM layout by adding and removing DOM elements.",
"translation": "结构型指令 &mdash; 通过添加和移除 DOM 元素改变 DOM 布局的指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "1. Attribute directives&mdash;change the appearance or behavior of an element, component, or another directive.",
"translation": "属性型指令 &mdash; 改变元素、组件或其它指令的外观和行为的指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "## Build a simple attribute directive",
"translation": "## 创建一个简单的属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "### Write the directive code",
"translation": "### 编写指令代码",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Create the directive class file in a terminal window with this CLI command.",
"translation": "在命令行窗口下用 CLI 命令创建指令类文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "_Directives_ must be declared in [Angular Modules](guide/ngmodule) in the same manner as _components_.",
"translation": "和**组件**一样,这些**指令**也必须在[Angular模块](guide/ngmodule)中进行声明。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "The generated `src/app/highlight.directive.ts` is as follows:",
"translation": "生成的`src/app/highlight.directive.ts`文件如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "The imported `Directive` symbol provides the Angular the `@Directive` decorator.",
"translation": "这里导入的`Directive`符号提供了 Angular 的 `@Directive` 装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "The _attribute selector_ pattern explains the name of this kind of directive.",
"translation": "正因如此,这类指令被称为 **属性选择器** 。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "#### Why not \"highlight\"?",
"translation": "#### 为什么不直接叫做 \"highlight\"",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "The `import` statement specifies an additional `ElementRef` symbol from the Angular `core` library:",
"translation": "`import`语句还从 Angular 的 `core` 库中导入了一个 `ElementRef` 符号。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "Now run the application to see the `HighlightDirective` in action.",
"translation": "运行这个应用以查看`HighlightDirective`的实际效果。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "## Respond to user-initiated events",
"translation": "## 响应用户引发的事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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": "当前,`myHighlight`只是简单的设置元素的颜色。\n这个指令应该在用户鼠标悬浮一个元素时设置它的颜色。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Begin by adding `HostListener` to the list of imported symbols.",
"translation": "先把`HostListener`加进导入列表中,同时再添加`Input`符号,因为我们很快就要用到它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "1. You have to write the listeners correctly.",
"translation": "必须正确的书写事件监听器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "1. The code must *detach* the listener when the directive is destroyed to avoid memory leaks.",
"translation": "当指令被销毁的时候,必须*拆卸*事件监听器,否则会导致内存泄露。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "1. Talking to DOM API directly isn't a best practice.",
"translation": "必须直接和 DOM API 打交道,应该避免这样做。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "The helper method, `highlight`, was extracted from the constructor.\nThe revised constructor simply declares the injected `el: ElementRef`.",
"translation": "这些处理器委托给了一个辅助方法它用于为DOM元素设置颜色`el`就是你在构造器中声明和初始化过的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Here's the updated directive in full:",
"translation": "下面是修改后的指令代码:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Run the app and confirm that the background color appears when the mouse hovers over the `p` and\ndisappears as it moves out.We run the app and confirm that the background color appears as we move the mouse over the `p` and\ndisappears as we move out.",
"translation": "运行本应用并确认:当把鼠标移到`p`上的时候,背景色就出现了,而移开的时候,它消失了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "## Pass values into the directive with an _@Input_ data binding",
"translation": "## 使用数据绑定向指令传递值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "Begin by adding `Input` to the list of symbols imported from `@angular/core`.\n<code-example path=\"attribute-directives/src/app/highlight.directive.3.ts\" linenums=\"false\" title=\"src/app/highlight.directive.ts (imports)\" region=\"imports\"></code-example>",
"translation": "我们先从`@angular/core`中导入`Input`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Add a `highlightColor` property to the directive class like this:",
"translation": "然后把`highlightColor`属性添加到指令类中,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "### Binding to an _@Input_ property",
"translation": "### 绑定到_@Input_属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "Try it by adding the following directive binding variations to the `AppComponent` template:",
"translation": "试试把下列指令绑定变量添加到`AppComponent`的模板中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Add a `color` property to the `AppComponent`.",
"translation": "把`color`属性添加到`AppComponent`中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Let it control the highlight color with a property binding.",
"translation": "让它通过属性绑定来控制高亮颜色。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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": "`[myHighlight]`属性同时做了两件事:把这个高亮指令应用到了`<p>`元素上,并且通过属性绑定设置了该指令的高亮颜色。\n我们复用了该指令的属性选择器`[myHighlight]`来同时完成它们。\n这是清爽、简约的语法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "This is disagreeable. The word, `appHighlight`, is a terrible property name and it doesn't convey the property's intent.",
"translation": "这可不好。因为`myHighlight`是一个糟糕的属性名,而且不能反映该属性的意图。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "### Bind to an _@Input_ alias",
"translation": "### 绑定到_@Input_别名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Fortunately you can name the directive property whatever you want _and_ **_alias it_** for binding purposes.",
"translation": "幸运的是,我们可以随意命名该指令的属性,并且**给它指定一个用于绑定的别名**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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`,在外部,当我们绑定到它时,它叫`myHighlight`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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如果有人忘了绑定到`highlightColor`,那就用红色进行高亮。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Here's the latest version of the directive class.",
"translation": "这是最终版本的指令类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "## Write a harness to try it",
"translation": "## 写个测试程序试验下",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "Update <code>app.component.html</code> as follows:",
"translation": "把`app.component.html`修改成这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Revise the `AppComponent.color` so that it has no initial value.",
"translation": "修改`AppComponent.color`,让它不再有初始值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Here are the harness and directive in action.",
"translation": "下面是测试程序和指令的动图。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "## Bind to a second property",
"translation": "## 绑定到第二个属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "This highlight directive has a single customizable property. In a real app, it may need more.",
"translation": "本例的指令只有一个可定制属性,真实的应用通常需要更多。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "At the moment, the default color&mdash;the color that prevails until\nthe user picks a highlight color&mdash;is hard-coded as \"red\".\nLet the template developer set the default color.",
"translation": "目前,默认颜色(它在用户选取了高亮颜色之前一直有效)被硬编码为红色。我们要让模板的开发者也可以设置默认颜色。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "Add a second **input** property to `HighlightDirective` called `defaultColor`:",
"translation": "把第二个名叫`defaultColor`的**输入**属性添加到`HighlightDirective`中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "How do you bind to a second property when you're already binding to the `appHighlight` attribute name?",
"translation": "当已经绑定过`myHighlight`属性时,要如何绑定到第二个属性呢?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "Here's how the harness should work when you're done coding.",
"translation": "当这些代码完成时,测试程序工作时的动图如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "This page covered how to:",
"translation": "本章介绍了如何:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "* [**Bind** values to the directive](guide/attribute-directives#bindings).",
"translation": "[把值**绑定**到指令中](guide/attribute-directives#bindings)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "The final source code follows:",
"translation": "最终的源码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "### Appendix: Why add _@Input_?",
"translation": "### 附录:为什么要加*@Input*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "You've seen it with an alias:",
"translation": "也见过用别名时的代码:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"original": "Now apply that reasoning to the following example:",
"translation": "试用此原理分析下列范例:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"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/content-2/guide/attribute-directives.md"
},
{
"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": "`myHighlight`属性位于左侧,它引用了`MyHighlightDirective`中一个*带别名的*属性,它不是模板所属组件的一部分,因此存在信任问题。\n所以该属性必须带`@Input`装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/attribute-directives.md"
},
{
"original": "# Bootstrapping",
"translation": "# 启动过程",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "An Angular Module (NgModule) class describes how the application parts fit together.\nEvery application has at least one Angular Module, the _root_ module \nthat you [bootstrap](#main) to launch the application.\nYou can call the class anything you want. The conventional name is `AppModule`.",
"translation": "Angular 模块类描述应用的部件是如何组合在一起的。\n每个应用都至少有一个 Angular 模块,也就是*根*模块,用来[引导](#main)并运行应用。\n你可以为它取任何名字。常规名字是`AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "After the `import` statements, you come to a class adorned with the\n**`@NgModule`** [_decorator_](guide/glossary#decorator '\"Decorator\" explained').",
"translation": "`import`语句之后,可以看到一个**`@NgModule`**[装饰器](guide/glossary#decorator '\"Decorator\" explained')修饰的类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"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`标记为 Angular 模块类(也叫`NgModule`类)。\n`@NgModule`接受一个_元数据_对象告诉 Angular 如何编译和启动应用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "The `@NgModule` properties for the minimal `AppModule` generated by the CLI are as follows:",
"translation": "在 CLI 生成的初始 `AppModule`中,`@NgModule` 包括下列属性:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "* **[_declarations_](#declarations)** &mdash; declares the application components. At the moment, there is only the `AppComponent`.",
"translation": "**[_declarations_](#declarations)** —— 声明该应用的组件,刚创建时只有一个`AppComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "* **[_imports_](#imports)** &mdash; the `BrowserModule`, which this and every application must import in order to run the app in a browser.",
"translation": "**[_imports_](#imports)** —— `BrowserModule`,每个应用都必须引入它,以便在浏览器中运行该应用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "* **[_providers_](#providers)** &mdash; there are none to start but you are likely to add some soon.",
"translation": "**[_providers_](#providers)** —— 开始时它是空的,不过你可能很快就会添加一个了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "* **[_bootstrap_](#bootstrap-array)** &mdash; the _root_ `AppComponent` that Angular creates and inserts into the `index.html` host web page.",
"translation": "**_bootstrap_** &mdash; _根_组件 `AppComponent`Angular 创建它并把它插入到`index.html`宿主页面。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "The [Angular Modules (NgModules)](guide/ngmodule) guide dives deeply into the details of `@NgModule`.\nAll you need to know at the moment is a few basics about these four properties.",
"translation": "[Angular 模块 (NgModules)](guide/ngmodule) 指南深入讲解了 Angular 模块。\n现在先初步了解这三个属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "### The _declarations_ array",
"translation": "### _declarations_ 数组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "You tell Angular which components belong to the `AppModule` by listing it in the module's `declarations` array.\nAs you create more components, you'll add them to `declarations`.",
"translation": "通过把组件添加到模块的 `declarations` 数组中,我们会告诉 Angular 哪些组件属于这个 `AppModule`。创建更多组件时,我们也要把它们添加到 `declarations` 中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "You must declare _every_ component in an Angular Module class.\nIf you use a component without declaring it, you'll see a clear error message in the browser console.",
"translation": "我们必须把 **每个** 组件都声明到某个 Angular 的模块类中,否则就会在浏览器的控制台中看到一个明确的错误信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "You'll learn to create two other kinds of classes &mdash;\n[directives](guide/attribute-directives) and [pipes](guide/pipes) &mdash;\nthat you must also add to the `declarations` array.",
"translation": "我们后面要学的另外两种类([指令](guide/attribute-directives)和[管道](guide/pipes))也同样必须添加到`declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "**Only _declarables_** &mdash; _components_, _directives_ and _pipes_ &mdash; belong in the `declarations` array.\nDo not put any other kind of class in `declarations`. Do _not_ declare `NgModule` classes. Do _not_ declare service classes. Do _not_ declare model classes.",
"translation": "**只有“可声明的类”(组件、指令和管道)能添加到`declarations`数组中。\n其它类型的类都不要往里放。**不要**添加`NgModule`。不要添加服务类。不要添加模型类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "### The _imports_ array",
"translation": "### _imports_ 数组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "Angular Modules are a way to consolidate features that belong together into discrete units.\nMany features of Angular itself are organized as Angular Modules.\nHTTP services are in the `HttpClientModule`. The router is in the `RouterModule`.\nEventually you may create your own modules.",
"translation": "Angular 模块把特性合并成离散单元的一种方式。\nAngular 自身的许多特性也是通过 Angular 模块组织的。\nHTTP 服务在`HttpClientModule`里。路由器在`RouterModule`中。\n最终我们还可能创建自己的模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "Add a module to the `imports` array when the application requires its features.",
"translation": "当应用需要模块的特性时,将其添加到`imports`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "_This_ application, like most applications, executes in a browser.\nEvery application that executes in a browser needs the `BrowserModule` from `@angular/platform-browser`.\nSo every such application includes the `BrowserModule` in its _root_ `AppModule`'s `imports` array.\nOther guide pages will tell you when you need to add additional modules to this array.",
"translation": "_这个_应用和大多数其他应用一样在浏览器中运行。\n每个浏览器中运行的应用都需要`@angular/platform-browser`里的`BrowserModule`。\n所以每个这样的应用都在其_根_`AppModule`的`imports`数组中包含`BrowserModule`。\n在需要添加额外模块到此数组时其他指南和烹饪宝典页面会告诉你。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "**Only `@NgModule` classes** go in the `imports` array. Do not put any other kind of class in `imports`.",
"translation": "`imports`数组中应该**只有`NgModule`类**。不要放置其它类型的类。\n</div>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "The `import` statements at the top of the file and the NgModule's `imports` array\nare unrelated and have completely different jobs.",
"translation": "不要将 Angular 模块的`imports`数组与文件顶部的`import`语句弄混淆了。它们的功能不同。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "The _JavaScript_ `import` statements give you access to symbols _exported_ by other files\nso you can reference them within _this_ file.\nYou add `import` statements to almost every application file.\nThey have nothing to do with Angular and Angular knows nothing about them.",
"translation": "_JavaScript_ 的`import`声明允许你访问在其他文件中_导出_的符号这样你可以在_当前_文件引用它们。\n我们会往几乎所有类型的应用中加入`import`语句。\n它们与 Angular 毫无关系Angular 对它们也一无所知。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "The _module's_ `imports` array appears _exclusively_ in the `@NgModule` metadata object.\nIt tells Angular about specific _other_ Angular Modules&mdash;all of them classes decorated\nwith `@NgModule`&mdash;that the application needs to function properly.",
"translation": "_模块_的`imports`数组是`@NgModule`元数据中*独有的*。它告诉 Angular 特定 Angular 模块的信息 &mdash; 用`@NgModule`装饰的类 &mdash; 应用需要它们来正常工作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "### The _providers_ array",
"translation": "### _providers_ 数组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "Angular apps rely on [_dependency injection (DI)_](guide/dependency-injection)\nto deliver services to various parts of the application.",
"translation": "Angular 应用靠 [_依赖注入DI_](guide/dependency-injection) 机制为应用中的各个部件提供服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "Before DI can inject a service, it must create that service with the help of a _provider_.\nYou can tell DI about a service's _provider_ in a number of ways.\nAmong the most popular ways is to register the service in the root `ngModule.providers` array, which will make that service available _everywhere_.",
"translation": "要想注入一个服务,就要先在**服务提供商provider**的帮助下创建这个服务。\n我们可以用多种方式告诉 DI 某个服务的提供商是谁。\n最常见的方式是在根模块的`ngModule.providers`数组中注册这个服务。这样一来,这个服务就**在哪里**都可以用了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "For example, a data service provided in the `AppModule`s _providers_ can be injected into any\ncomponent anywhere in the application.",
"translation": "比如,在根模块 `AppModule` 的 _providers_ 数组中提供的数据服务可以被注入到该应用中任意地方的任意组件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"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/content-2/guide/bootstrapping.md"
},
{
"original": "### The _bootstrap_ array",
"translation": "### _bootstrap_ 数组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "You launch the application by [_bootstrapping_](#main) the root `AppModule`.\nAmong other things, the _bootstrapping_ process creates the component(s) listed in the `bootstrap` array\nand inserts each one into the browser DOM.",
"translation": "通过[_引导_](#main)根`AppModule`来启动应用。\n在启动过程中其中一步是创建列在`bootstrap`数组的组件,\n并将它们每一个都插入到浏览器的DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "Each bootstrapped component is the base of its own tree of components.\nInserting a bootstrapped component usually triggers a cascade of component creations that fill out that tree.",
"translation": "每个被引导的组件都是它自己的组件树的根。\n插入一个被引导的组件通常触发一系列组件的创建并形成组件树。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "While you can put more than one component tree on a host web page, that's not typical.\nMost applications have only one component tree and they bootstrap a single _root_ component.",
"translation": "虽然你可以将多个组件树插入到宿主页面,但并不普遍。\n大多数应用只有一个组件树它们引导单一_根_组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "You can call the one _root_ component anything you want but most developers call it `AppComponent`.",
"translation": "你可以为这个_根_组件取任何名字但是大多数程序员将其取名为`AppComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "Which brings us to the _bootstrapping_ process itself.",
"translation": "下面让我们来看看*引导*过程本身。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "## Bootstrap in _main.ts_",
"translation": "## 在 _main.ts_ 中引导",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "While there are many ways to bootstrap an application, most applications do so in the `src/main.ts` that is generated by the Angular CLI.",
"translation": "虽然有很多方式来引导应用,不过大多数应用还是选择在 Angular CLI 生成的 `src/main.ts` 中进行引导。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "This code creates a browser platform for dynamic compilation and\nbootstraps the `AppModule` described above.",
"translation": "上面的代码为动态 (JiT) 编译创建浏览器平台,并引导上面提到的`AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "The _bootstrapping_ process sets up the execution environment,\ndigs the _root_ `AppComponent` out of the module's `bootstrap` array,\ncreates an instance of the component and inserts it within the element tag identified by the component's `selector`.",
"translation": "引导过程搭建运行环境,从模块的`bootstrap`数组中提出_根_`AppComponent` 创建该组件的实例,并将其插入到组件`selector`标识的元素标签中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "The `AppComponent` selector &mdash; here and in most documentation samples &mdash; is `app-root`\nso Angular looks for a `<app-root>` tag in the `index.html` like this one ...",
"translation": "`AppComponent`选择器 &mdash; 在这里以及文档大部分例子中 &mdash; 是`my-app`\n所以 Angular 在`index.html`中查找像这样的`<my-app>`标签...",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "... and displays the `AppComponent` there.",
"translation": "...然后在那儿显示`AppComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "The `main.ts` file is very stable. Once you've set it up, you may never change it again.",
"translation": "The `main.ts` 文件非常稳定,一旦配置好,可能永远都不会再修改它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "## More about Angular Modules",
"translation": "## 关于Angular模块的更多知识",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "Your initial app has only a single module, the _root_ module.\nAs your app grows, you'll consider subdividing it into multiple \"feature\" modules,\nsome of which can be loaded later (\"lazy loaded\") if and when the user chooses\nto visit those features.",
"translation": "你最初的应用只有一个单一的模块 —— *根*模块。\n当这个应用不断成长时你就要考虑把它们拆分到多个 \"特性\" 模块中了。\n这些特性模块中的一部分可以稍后加载即惰性加载它们只会在用户访问到这些特性时才会加载。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "When you're ready to explore these possibilities, visit the [Angular Modules](guide/ngmodule) guide.",
"translation": "如果你要了解这些知识,请访问[Angular 模块 (NgModule)](guide/ngmodule)页",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/bootstrapping.md"
},
{
"original": "# Browser support",
"translation": "# 浏览器支持",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Angular supports most recent browsers. This includes the following specific versions:",
"translation": "Angular 支持大多数常用浏览器,包括下列版本:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "latest",
"translation": "最新版",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "latest",
"translation": "最新版",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"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/content-2/guide/browser-support.md"
},
{
"original": "## Polyfills",
"translation": "## 填充库 (polyfill)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"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/content-2/guide/browser-support.md"
},
{
"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/content-2/guide/browser-support.md"
},
{
"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/content-2/guide/browser-support.md"
},
{
"original": "## Enabling polyfills",
"translation": "## 启用填充脚本",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"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/content-2/guide/browser-support.md"
},
{
"original": "This file incorporates the mandatory and many of the optional polyfills as JavaScript `import` statements.",
"translation": "这个文件把强制的和很多可选的填充脚本组织成 JavaScript 的 `import` 语句。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "The npm packages for the _mandatory_ polyfills (such as `zone.js`) were installed automatically for you when you created your project and \ntheir corresponding `import` statements are ready to go.\nYou probably won't touch these.",
"translation": "**强制性** 填充脚本(如`zone.js`的npm 包在创建工程时就已经自动安装了,相应的 `import` 语句也都加好了。我们一般不用动它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "But if you need an optional polyfill, you'll have to install its npm package with `npm` or `yarn`.\nFor example, [if you need the web animations polyfill](http://caniuse.com/#feat=web-animation),\nyou could install it with either of the following commands:",
"translation": "但是如果要用一个可选的填充库,就要通过 `npm` 或 `yarn` 来安装它们的 npm 包了。\n比如[如果你需要 web 动画的填充脚本](http://caniuse.com/#feat=web-animation),就要通过下列命令之一来安装它:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Then open the `polyfills.ts` file and un-comment the corresponding `import` statement\nas in the following example:",
"translation": "然后打开 `polyfills.ts` 文件,并反注释对应的 `import` 语句,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"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/content-2/guide/browser-support.md"
},
{
"original": "1. install the npm package",
"translation": "安装 npm 包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "1. `import` the file in `polyfills.ts`",
"translation": "在 `polyfills.ts` 中 `import` 这个文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Non-CLI users should follow the instructions [below](#non-cli).",
"translation": "不使用 CLI 的用户可以遵循[下列](#non-cli)步骤自行操作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "### Mandatory polyfills",
"translation": "### 强制性填充库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "These are the polyfills required to run an Angular application on each supported browser:",
"translation": "下表中的填充库是每个浏览器都要用到的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Browsers (Desktop & Mobile)",
"translation": "<p>\n 浏览器(桌面和移动)\n </p>\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Polyfills Required",
"translation": "需要的填充库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "### Optional browser features to polyfill",
"translation": "### 可选浏览器特性的填充库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Some features of Angular may require additional polyfills.",
"translation": "有些 Angular 特性可能需要额外的填充库。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "For example, the animations library relies on the standard web animation API, which is only available in Chrome and Firefox today.\nYou'll need a polyfill to use animations in other browsers.",
"translation": "例如,动画库依赖于标准的 web 动画 API目前它只在 Chrome 和 Firefox 上可用。你可能需要一个填充库来在其它浏览器上使用动画功能。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Here are the features which may require additional polyfills:",
"translation": "下列特性可能需要更多填充库:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "<th>\n Feature",
"translation": "特性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "<th>\n Polyfill",
"translation": "填充库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "<th style=\"width: 50%\">\n Browsers (Desktop & Mobile)",
"translation": "浏览器(桌面和移动)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "[JIT compilation](guide/aot-compiler). \n Required to reflect for metadata.",
"translation": "[JIT 编译](guide/aot-compiler) 需要 reflect 来提供元数据。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "<td>\n All current browsers.\n Enabled by default.\n Can remove If you always use AOT and only use Angular decorators.",
"translation": "默认对目前的所有浏览器都启用了。如果总是使用 AOT 模式,并且只使用 Angular 自带的装饰器,那么可以移除它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "[Animations](guide/animations)",
"translation": "[动画](guide/animations)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "[Web Animations](guide/browser-support#web-animations)",
"translation": "[Web 动画](guide/browser-support#web-animations)\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "All but Chrome and Firefox<br>Not supported in IE9",
"translation": "除 Chrome 和 Firefox 外的所有,但不支持 IE9",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "If you use the following deprecated i18n pipes: [date](api/common/DeprecatedDatePipe), [currency](api/common/DeprecatedCurrencyPipe), [decimal](api/common/DeprecatedDecimalPipe) and [percent](api/common/DeprecatedPercentPipe)",
"translation": "如果你使用下列已废弃的i18n管道\n [date](api/common/DeprecatedDatePipe)、[currency](api/common/DeprecatedCurrencyPipe)、[decimal](api/common/DeprecatedDecimalPipe) 和 [percent](api/common/DeprecatedPercentPipe)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "<td>\n <p>All but Chrome, Firefox, Edge, IE11 and Safari 10</p>",
"translation": "除了 Chrome、Firefox、Edge、IE11 和 Safari 10 外的所有浏览器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "[NgClass](api/common/NgClass) on SVG elements",
"translation": "<p>在 SVG 元素上应用 [NgClass](api/common/NgClass)</p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "[Http](guide/http) when sending and receiving binary data",
"translation": "用 [Http](guide/http) 发送和接收二进制数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "</table>",
"translation": "### Suggested polyfills ##\n### 建议的填充库 ##\nBelow are the polyfills which are used to test the framework itself. They are a good starting point for an application.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Polyfill",
"translation": "填充库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Licence",
"translation": "授权方式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Size*",
"translation": "大小*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "Public domain",
"translation": "公共域",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "{@a non-cli}\n## Polyfills for non-CLI users",
"translation": "## 不使用 CLI 的用户的填充库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/browser-support.md"
},
{
"original": "If you aren't 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/content-2/guide/browser-support.md"
},
{
"original": "# Change Log",
"translation": "# 变更记录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## All mention of moduleId removed. \"Component relative paths\" guide deleted (2017-03-13)",
"translation": "## 移除了所有的moduleId引用。移除了“组件相对路径” 的烹饪书。(2017-03-13)\nWe 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.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## NEW: Downloadable examples for each guide (2017-02-28)",
"translation": "## 新增:每篇指南都增加了可下载的范例程序 (2017-02-28)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## Template Syntax/Structural Directives: refreshed (2017-02-06)",
"translation": "## 模板语法/结构型指令:更新了 (2017-02-06)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## NEW: Samples re-structured with `src/` folder (2017-02-02)",
"translation": "## 新增:调整了范例程序的结构,移到了`src/`文件夹 (2017-02-02)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "Notably:",
"translation": "要点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "* `app/main.ts` moved to `src/main.ts`.",
"translation": "把`app/main.ts`移到`src/main.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "* `app/` moved to `src/app/`.",
"translation": "把`app/`移到`src/app/`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "* `index.html`, `styles.css` and `tsconfig.json` moved inside `src/`.",
"translation": "把`index.html`、`styles.css`和`tsconfig.json`移到`src/`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "* `systemjs.config.js` now imports `main.js` instead of `app`.",
"translation": "`systemjs.config.js`现在要导入`main.js`而不是`app`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "* Added `lite-server` configuration (`bs-config.json`) to serve `src/`.",
"translation": "新增了一个`lite-server`配置(`bs-config.json`)以便在`src/`下启动开发服务器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "## NEW: Reactive Forms guide (2017-01-31)",
"translation": "## 新增响应式Reactive表单指南 (2017-01-31)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## NEW: Deployment guide (2017-01-30)",
"translation": "## 新增:部署指南 (2017-01-30)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## Hierarchical Dependency Injection: refreshed (2017-01-13)",
"translation": "## 多级依赖注入:更新完毕 (2017-01-13)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## Miscellaneous (2017-01-05)",
"translation": "## 杂项 (2017-01-05)* [Setup](guide/setup) guide: \nadded (optional) instructions on how to remove _non-essential_ files. [环境搭建](guide/setup)指南:\n 添加了(可选的)步骤说明,告诉你如何移除*非核心*文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "* All samples prepend template/style URLs with `./` as a best practice.",
"translation": "所有范例都在模板/样式的URL之前添加`./`前缀 …… 而且你在实际开发中也应该这么做。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "* [Style Guide](guide/styleguide): copy edits and revised rules.",
"translation": "[风格指南](guide/styleguide):复制了编辑过的和修改过的规则。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "## Router: more detail (2016-12-21)",
"translation": "## 路由:更详细 (2016-12-21)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "Added section on how to set default request headers (and other request options) to\nHTTP guide.",
"translation": "添加了一节“如何设置默认的请求头(以及其它配置项)”",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "## Testing: added component test plunkers (2016-12-02)",
"translation": "## 测试添加了组件测试的plunker范例 (2016-12-02)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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](guide/testing#live-examples) and [Setup anatomy](guide/setup-systemjs-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并在[测试](guide/testing#live-examples)和[环境设置剖析](guide/setup-systemjs-anatomy)中链接到它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "## Internationalization: pluralization and _select_ (2016-11-30)",
"translation": "## 国际化:单复数和`select` (2016-11-30)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## Testing: karma file updates (2016-11-30)",
"translation": "## 测试更新了karma文件 (2016-11-30)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "* Displays Jasmine Runner output in the karma-launched browser.",
"translation": "在启动了karma的浏览器中显示Jasmine的输出。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "## QuickStart Rewrite (2016-11-18)",
"translation": "## 全新《快速上手》 (2016-11-18)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## ES6 described in \"TypeScript to JavaScript\" (2016-11-14)",
"translation": "## 在“从TypeScript到JavaScript”增加ES6的描述 (2016-11-14)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "The updated TypeScript to JavaScript guide (removed August 2017, PR #18694)\nexplains how to write apps in ES6/7",
"translation": "更新了“[从TypeScript到JavaScript](guide/ts-to-js)”烹饪宝典解释如何使用ES6/7编写应用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "by translating the common idioms in the TypeScript documentation examples\n(and elsewhere on the web) to ES6/7 and ES5.",
"translation": "将TypeScript文档示例中以及网站其它地方的习惯用法翻译成ES6/7和ES5。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## npm _@types_ packages replace _typings_ (2016-10-20)",
"translation": "## 使用npm的_@types_包替换_typings_ (2016-10-20)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## \"Template Syntax\" explains two-way data binding syntax (2016-10-20)",
"translation": "## \"模板语法\"添加了双向数据绑定语法的解释(2016-10-20)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## \"Router\" _preload_ syntax and _:enter_/_:leave_ animations (2016-10-19)",
"translation": "## \"路由器\"_预加载_语法和_:enter_/_:leave_动画(2016-10-19)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "New `:enter` and `:leave` aliases make animation more natural.",
"translation": "新`:enter`和`:leave`语法,让动画更加自然。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## NEW \"Ahead of time (AOT) Compilation\" guide (2016-10-11)",
"translation": "## 添加了新的“预编译(AoT)\"烹饪书(2016-10-11)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## \"Routing and Navigation\" guide with the _Router Module_ (2016-10-5)",
"translation": "## 在“路由和导航”向导中添加**路由模块** (2016-10-5)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "[Routing and Navigation](guide/router)",
"translation": "[路由与导航](guide/router)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "All guided samples with routing use the _Routing Module_ and prose content has been updated,\nmost conspicuously in the\n[NgModule](guide/ngmodule) guide and [NgModule FAQ](guide/ngmodule-faq) guide.",
"translation": "所有使用路由的例子都使用**路由模块**,相关内容也被更新。更新最多的是[Angular模块NgModule](guide/ngmodule)章和[Angular模块常见问题](guide/ngmodule-faq)烹饪书。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "## New \"Internationalization\" guide (2016-09-30)",
"translation": "## 全新“国际化”烹饪书(2016-09-30)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## \"Style Guide\" with _NgModules_ (2016-09-27)",
"translation": "## “风格指南”中添加了_NgModules_(2016-09-27)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "[StyleGuide](guide/styleguide) explains recommended conventions for NgModules.",
"translation": "[StyleGuide](guide/styleguide)解释了我们为Angular模块NgModule而推荐的约定。\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.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"original": "## _moduleId: module.id_ everywhere (2016-09-25)",
"translation": "## moduleId到处添加module.id(2016-09-25)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "## \"Lifecycle Hooks\" guide simplified (2016-09-24)",
"translation": "## 简化了“生命周期钩子”章(2016-09-24)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/change-log.md"
},
{
"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/content-2/guide/change-log.md"
},
{
"original": "<h1 class=\"no-toc\">Cheat Sheet</h1",
"translation": "速查表",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/cheatsheet.md"
},
{
"original": "# Component Interaction",
"translation": "# 组件之间的交互",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "This cookbook contains recipes for common component communication scenarios\nin which two or more components share information.",
"translation": "本烹饪宝典包含了常见的组件通讯场景,也就是让两个或多个组件之间共享信息的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "For an in-depth look at each fundamental concepts in component communication, we can find detailed description and\nsamples in the [Component Communication]() document.",
"translation": "要深入了解组件通讯的各个基本概念,在[组件通讯]()文档中可以找到详细的描述和例子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "# Contents",
"translation": "# 目录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "* [Parent and children communicate via a service](guide/component-interaction#bidirectional-service)",
"translation": "[通过服务进行父子通讯](guide/component-interaction#bidirectional-service)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "**See the <live-example name=\"component-interaction\"></live-example>**.",
"translation": "**参见<live-example name=\"cb-component-interaction\"></live-example>**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "## Pass data from parent to child with input binding",
"translation": "## 通过输入型绑定把数据从父组件传到子组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "The second `@Input` aliases the child component property name `masterName` as `'master'`.",
"translation": "第二个`@Input`为子组件的属性名`masterName`指定一个别名`master`(译者注:不推荐为起别名,请参见风格指南).",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "The `HeroParentComponent` nests the child `HeroChildComponent` inside an `*ngFor` repeater, \nbinding its `master` string property to the child's `master` alias, and each iteration's `hero` instance to the child's `hero` property.",
"translation": "父组件`HeroParentComponent`把子组件的`HeroChildComponent`放到`*ngFor`循环器中,把自己的`master`字符串属性绑定到子组件的`master`别名上,并把每个循环的`hero`实例绑定到子组件的`hero`属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "The running application displays three heroes:",
"translation": "运行应用程序会显示三个英雄:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "E2E test that all children were instantiated and displayed as expected:",
"translation": "端到端测试,用于确保所有的子组件都像所期待的那样被初始化并显示出来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "## Intercept input property changes with a setter",
"translation": "## 通过setter截听输入属性值的变化",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "Use an input property setter to intercept and act upon a value from the parent.",
"translation": "使用一个输入属性的setter以拦截父组件中值的变化并采取行动。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "Here's the `NameParentComponent` demonstrating name variations including a name with all spaces:",
"translation": "下面的`NameParentComponent`展示了各种名字的处理方式,包括一个全是空格的名字。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "E2E tests of input property setter with empty and non-empty names:",
"translation": "端到端测试输入属性的setter分别使用空名字和非空名字。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "## Intercept input property changes with *ngOnChanges()*",
"translation": "## 通过*ngOnChanges()*来截听输入属性值的变化",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "You may prefer this approach to the property setter when watching multiple, interacting input properties.",
"translation": "当需要监视多个、交互式输入属性的时候本方法比用属性的setter更合适。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "Learn about `ngOnChanges()` in the [LifeCycle Hooks](guide/lifecycle-hooks) chapter.",
"translation": "学习关于`ngOnChanges()`的更多知识,参见[生命周期钩子](guide/lifecycle-hooks)一章。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "Here's the output of a button-pushing sequence:",
"translation": "下面是点击按钮的结果。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "## Parent listens for child event",
"translation": "## 父组件监听子组件的事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "Clicking a button triggers emission of a `true` or `false` ,the boolean *payload*.",
"translation": "点击按钮会触发`true`或`false`(布尔型*有效载荷*)的事件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "The framework passes the event argument &mdash; represented by `$event` &mdash; to the handler method, \nand the method processes it:",
"translation": "框架(Angular)把事件参数(用`$event`表示)传给事件处理方法,这个方法会处理:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "Test that clicking the *Agree* and *Disagree* buttons update the appropriate counters:",
"translation": "测试确保点击*Agree*和*Disagree*按钮时,计数器被正确更新。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "## Parent interacts with child via *local variable*",
"translation": "## 父组件与子组件通过*本地变量*互动",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "{@a countdown-timer-example} \nThe following is a child `CountdownTimerComponent` that repeatedly counts down to zero and launches a rocket. It has `start` and `stop` methods that control the clock and it displays a countdown status message in its own template.",
"translation": "子组件`CountdownTimerComponent`进行倒计时,归零时发射一个导弹。`start`和`stop`方法负责控制时钟并在模板里显示倒计时的状态信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "The `CountdownLocalVarParentComponent` that hosts the timer componentis as follows:",
"translation": "让我们来看看计时器组件的宿主组件`CountdownLocalVarParentComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "Here we see the parent and child working together.",
"translation": "下面是父组件和子组件一起工作时的效果。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "## Parent calls an _@ViewChild()_",
"translation": "## 父组件调用*@ViewChild()*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "Here is the parent, `CountdownViewChildParentComponent`:",
"translation": "下面是父组件`CountdownViewChildParentComponent`:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "It takes a bit more work to get the child view into the parent component *class*.",
"translation": "把子组件的视图插入到父组件类需要做一点额外的工作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "First, you have to import references to the `ViewChild` decorator and the `AfterViewInit` lifecycle hook.",
"translation": "首先,你要使用`ViewChild`装饰器导入这个引用,并挂上`AfterViewInit`生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "These methods access the injected timer component directly.",
"translation": "这些方法可以直接访问被注入的计时器组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "测试一下!",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "## Parent and children communicate via a service",
"translation": "## 父组件和子组件通过服务来通讯",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "A parent component and its children share a service whose interface enables bi-directional communication *within the family*.",
"translation": "父组件和它的子组件共享同一个服务,利用该服务*在家庭内部*实现双向通讯。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "This `MissionService` connects the `MissionControlComponent` to multiple `AstronautComponent` children.",
"translation": "这个`MissionService`把`MissionControlComponent`和多个`AstronautComponent`子组件连接起来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"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/content-2/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-interaction.md"
},
{
"original": "# Component Styles",
"translation": "# 组件样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "Additionally, Angular can bundle *component styles*\nwith components, enabling a more modular design than regular stylesheets.",
"translation": "另外Angular 还能把*组件样式*捆绑在我们的组件上,以实现比标准样式表更加模块化的设计。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "This page describes how to load and apply these component styles.",
"translation": "在本章中,我们将学到如何加载和使用这些*组件样式*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "You can run the <live-example></live-example> in Plunker and download the code from there.",
"translation": "你可以在Plunker上运行本章这些代码的<live-example></live-example>并下载这些代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "## Using component styles",
"translation": "## 使用组件样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "## Style scope",
"translation": "## 范围化的样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "The styles specified in `@Component` metadata _apply only within the template of that component_.",
"translation": "在 `@Component` 的元数据中指定的样式只会对该组件的模板生效。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "This scoping restriction is a ***styling modularity feature***.",
"translation": "这种范围限制就是所谓的***样式模块化***特性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "* Changes to styles elsewhere in the application don't affect the component's styles.",
"translation": "我们组件的样式*不会*因为别的地方修改了样式而被意外改变。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "## Special selectors",
"translation": "## 特殊的选择器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "### :host",
"translation": "### :host 选择器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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": "这是我们能以宿主元素为目标的*唯一*方式。除此之外,我们将没办法指定它,\n因为宿主不是组件自身模板的一部分而是父组件模板的一部分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "### :host-context",
"translation": "### :host-context 选择器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "### (deprecated) `/deep/`, `>>>`, and `::ng-deep`",
"translation": "### 已废弃 `/deep/`、`>>>`和`::ng-deep`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "Component styles normally apply only to the HTML in the component's own template.",
"translation": "组件样式通常只会作用于组件自身的 HTML 上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "The `/deep/` combinator also has the aliases `>>>`, and `::ng-deep`.",
"translation": "`/deep/` 组合器还有两个别名:`>>>`和`::ng-deep`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "## Loading component styles",
"translation": "## 把样式加载进组件中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "There are several ways to add styles to a component:",
"translation": "有几种方式把样式加入组件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "* By setting `styles` or `styleUrls` metadata.",
"translation": "设置`styles`或`styleUrls`元数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "* Inline in the template HTML.",
"translation": "内联在模板的 HTML 中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "* With CSS imports.",
"translation": "通过 CSS 文件导入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "The scoping rules outlined earlier apply to each of these loading patterns.",
"translation": "上述作用域规则对所有这些加载模式都适用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "### Styles in component metadata",
"translation": "### 元数据中的样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "You can add a `styles` array property to the `@Component` decorator.",
"translation": "我们可以给`@Component`装饰器添加一个`styles`数组型属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "Each string in the array defines some CSS for this component.",
"translation": "这个数组中的每一个字符串(通常也只有一个)定义一份 CSS。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "### Style files in component metadata",
"translation": "### 组件元数据中的样式文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "### Template inline styles",
"translation": "### 模板内联样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "You can also write `<link>` tags into the component's HTML template.",
"translation": "我们也可以在组件的 HTML 模板中写`<link>`标签。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "### CSS @imports",
"translation": "### CSS @imports 语法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "## View encapsulation",
"translation": "## 控制视图的封装模式:原生 (Native)、仿真 (Emulated) 和无 (None)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "To set the components encapsulation mode, use the `encapsulation` property in the component metadata:",
"translation": "通过组件元数据中的`encapsulation`属性来设置组件封装模式:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "## Inspecting generated CSS",
"translation": "## 附录 1查看仿真 (Emulated) 模式下生成的 CSS",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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 元素都被加上了一些额外的属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"original": "There are two kinds of generated attributes:",
"translation": "我们看到了两种被生成的属性:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"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/content-2/guide/component-styles.md"
},
{
"original": "# Dependency Injection",
"translation": "# 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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依赖注入的许多特性。\n{@a toc}",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Application-wide dependencies",
"translation": "## 应用程序全局依赖",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Register providers for dependencies used throughout the application in the root application component, `AppComponent`.",
"translation": "在应用程序根组件`AppComponent`中注册那些被应用程序全局使用的依赖提供商。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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#injector-providers)一章可以学到关于提供商的更多知识。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## External module configuration",
"translation": "## 外部模块配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Generally, register providers in the `NgModule` rather than in the root application component.",
"translation": "我们通常会在`NgModule`中注册提供商,而不是在应用程序根组件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## _@Injectable()_ and nested service dependencies",
"translation": "## *@Injectable*和嵌套服务依赖",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The following example shows injecting both the `LoggerService` and the `UserContext` in the `AppComponent`.",
"translation": "在下列例子中,我们往`AppComponent`里注入的`LoggerService`和`UserContext`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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 justuse `new` to instantiateone .",
"translation": "当Angular新建`AppComponent`时,依赖注入框架先创建一个`LoggerService`的实例,然后创建`UserContextService`实例。\n`UserContextService`需要框架已经创建好的`LoggerService`实例和尚未创建的`UserService`实例。\n`UserService`没有其它依赖,所以依赖注入框架可以直接`new`一个实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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`) and the framework does the rest.",
"translation": "依赖注入最帅的地方在于,`AppComponent`的作者不需要在乎这一切。作者只是在(`LoggerService`和`UserContextService`的)构造函数里面简单的声明一下,框架就完成了剩下的工作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Once all the dependencies are in place, the `AppComponent` displays the user information:",
"translation": "一旦所有依赖都准备好了,`AppComponent`就会显示用户信息:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### *@Injectable()*",
"translation": "### *@Injectable()* 注解",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Notice the `@Injectable()`decorator on the `UserContextService` class.",
"translation": "注意在`UserContextService`类里面的`@Injectable()`装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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 of consistency and to avoid future pain.",
"translation": "但是在给它添加依赖的那一瞬间,该服务就会停止工作,要想修复它,就必须要添加`@Injectable()`。\n为了保持一致性和防止将来的麻烦推荐从一开始就加上`@Injectable()`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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&mdash;*any* decorator&mdash;is sufficient to identify dependency types.",
"translation": "`AppComponent`类有两个依赖,但它没有`@Injectable()`。\n它不需要`@Injectable()`,这是因为组件类有`@Component`装饰器。\n在用TypeScript的Angular应用里有一个*单独的*装饰器 &mdash; *任何*装饰器 &mdash; 来标识依赖的类型就够了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Limit service scope to a component subtree",
"translation": "## 把服务作用域限制到一个组件支树",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### Take a break!",
"translation": "### 休息一下!",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Multiple service instances (sandboxing)",
"translation": "## 多个服务实例(sandboxing)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Sometimes you want multiple instances of a service at *the same level of the component hierarchy*.",
"translation": "在*同一个级别的组件树*里,有时需要一个服务的多个实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Imagine a `HeroBiosComponent` that presents three instances of the `HeroBioComponent`.",
"translation": "想象一下,一个`HeroBiosComponent`组件显示三个`HeroBioComponent`的实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Qualify dependency lookup with _@Optional()_ and `@Host()`",
"translation": "## 使用*@Optional()*和`@Host()`装饰器来限定依赖查找方式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "As you now know, dependencies can be registered at any level in the component hierarchy.",
"translation": "我们知道,依赖可以被注入到任何组件级别。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The `@Host` decorator stops the upward search at the *host component*.",
"translation": "`@Host`装饰器将把往上搜索的行为截止在*宿主组件*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### Demonstration",
"translation": "### 示范",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Focus on the template:",
"translation": "注意看模板:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Here's the `HeroContactComponent` which demonstrates the qualifying decorators:",
"translation": "下面的`HeroContactComponent`,示范了限定型装饰器(@Optional和@Host)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Focus on the constructor parameters:",
"translation": "注意看构造函数的参数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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 in the component tree happens to have it.",
"translation": "`@Host()`函数是`heroCache`属性的装饰器,确保从其父组件`HeroBioComponent`得到一个缓存服务。如果该父组件不存在这个服务Angular就会抛出错误即使组件树里的再上级有某个组件拥有这个服务Angular也会抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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`的装饰器,我们知道在应用程序中,只有一个`LoggerService`实例,也就是在`AppComponent`级提供的服务。\n该宿主`HeroBioComponent`没有自己的`LoggerService`提供商。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Here's the `HeroBiosAndContactsComponent` in action.",
"translation": "下面是`HeroBiosAndContactsComponent`的执行结果:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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)`\n{@a component-element}",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Inject the component's DOM element",
"translation": "## 注入组件的DOM元素",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Define dependencies with providers",
"translation": "## 使用提供商来定义依赖",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "This section demonstrates how to write providers that deliver dependent services.",
"translation": "在这个部分,我们将演示如何编写提供商来提供被依赖的服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Get a service from a dependency injector by giving it a ***token***.",
"translation": "我们给依赖注入器提供***令牌***来获取服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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&mdash;unless the request was [optional](guide/dependency-injection-in-action#optional).",
"translation": "如果注入器无法根据令牌在自己内部找到对应的提供商,它便将请求移交给它的父级注入器,这个过程不断重复,直到没有更多注入器为止。\n如果没找到注入器就抛出一个错误...除非这个请求是[可选的](guide/dependency-injection-in-action#optional)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### Defining providers",
"translation": "### 定义提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The code behind it gives you plenty to think about.",
"translation": "这段代码的背后有很多值得深入思考的地方。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "#### The *provide* object literal",
"translation": "#### *provide*对象",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "#### useValue &mdash; the *value provider*",
"translation": "#### useValue - *值-提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The other providers create their values *lazily* when they're needed for injection.",
"translation": "其它提供商只在需要注入它们的时候才创建并*惰性加载*它们的值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "#### useClass &mdash; the *class provider*",
"translation": "#### useClass - *类-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The `useClass` provider creates and returns new instance of the specified class.",
"translation": "`userClass`提供商创建并返回一个指定类的新实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Here are two examples in the `HeroOfTheMonthComponent`:",
"translation": "请看下面`HeroOfTheMonthComponent`里的两个例子:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The `DateLoggerService` inherits from `LoggerService`; it appends the current date/time to each message:",
"translation": "`DateLoggerService`从`LoggerService`继承;它把当前的日期/时间附加到每条信息上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "#### _useExisting_&mdash;the *alias provider*",
"translation": "#### useExisting - *别名-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Now put it to use in a simplified version of the `HeroOfTheMonthComponent`.",
"translation": "现在,在一个简化版的`HeroOfTheMonthComponent`中使用它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Behind the scenes,Angular actually sets the `logger` parameter to the full service registered under the `LoggingService` token \nwhich 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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The following image, which displays the logging date, confirms the point:",
"translation": "在下面的图片中,显示了日志日期,可以确认这一点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "#### _useFactory_&mdash; the *factory provider*",
"translation": "#### useFactory - *工厂-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The `useFactory` provider creates a dependency object by calling a factory function\nas in this example.",
"translation": "`useFactory` 提供商通过调用工厂函数来新建一个依赖对象,如下例所示。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "That returned function takes a winning `Hero` and a `HeroService` as arguments.",
"translation": "这个返回的函数需要一个`Hero`和一个`HeroService`参数。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Provider token alternatives: the *class-interface* and *InjectionToken*",
"translation": "## 备选提供商令牌:*类-接口*和*InjectionToken*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Angular dependency injection is easiest when the provider *token* is a class\nthat is also the type of the returned dependency object , orwhat you usually call the *service*.",
"translation": "Angular依赖注入当*令牌*是类的时候是最简单的,该类同时也是返回的依赖对象的类型(通常直接称之为*服务*)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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": "但令牌不一定都是类,就算它是一个类,它也不一定都返回类型相同的对象。这是下一节的主题。\n{@a class-interface}",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### class-interface",
"translation": "### 类-接口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The `MinimalLogger` is an abstract class.",
"translation": "该`MinimalLogger`是一个抽象类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "You usually inherit from an abstract class.\nBut *no class* in this application inherits from `MinimalLogger`.",
"translation": "我们通常从一个抽象类继承。但这个应用中并没有类会继承`MinimalLogger`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "#### Why *MinimalLogger* is a class and not a TypeScript interface",
"translation": "#### 为什么*MinimalLogger*是一个类而不是一个TypeScript接口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### _InjectionToken_",
"translation": "### _InjectionToken_ 值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "You created the `TITLE` token like this:",
"translation": "这样创建`TITLE`令牌:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Inject into a derived class",
"translation": "## 注入到派生类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "In this contrived example, `SortedHeroesComponent` inherits from `HeroesBaseComponent` \nto display a *sorted* list of heroes.",
"translation": "在这个刻意生成的例子里,`SortedHeroesComponent`继承自`HeroesBaseComponent`,显示一个*被排序*的英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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这就是为什么我们要在`ngOnInit`里面调用`HeroService`,而不是在构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Overriding the base class's `afterGetHeroes()` method solves the problem.",
"translation": "覆盖基类的`afterGetHeroes()`方法可以解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "These complications argue for *avoiding component inheritance*.",
"translation": "分析上面的这些复杂性是为了强调*避免使用组件继承*这一点。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Find a parent component by injection",
"translation": "## 通过注入来找到一个父组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "This section describes some techniques for doing that.",
"translation": "本章节描述了这项技术。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### Find a parent component of known type",
"translation": "### 找到已知类型的父组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "You use standard class injection to acquire a parent component whose type you know.",
"translation": "我们使用标准的类注入来获取已知类型的父组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "In the following example, the parent `AlexComponent` has several children including a `CathyComponent`:",
"translation": "在下面的例子中,父组件`AlexComponent`有几个子组件,包括`CathyComponent`:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### Cannot find a parent by its base class",
"translation": "### 无法通过它的基类找到一个父级",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "What if you *don't* know the concrete parent component class?",
"translation": "如果*不*知道具体的父组件类名怎么办?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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]{#alex},我们看到`Alex`组件*扩展*(*派生*)自一个叫`Base`的类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### Find a parent by its class-interface",
"translation": "### 通过类-接口找到父组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Write an [*alias provider*](guide/dependency-injection-in-action#useexisting)&mdash;a `provide` object literal with a `useExisting`\ndefinition&mdash;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`函数 &mdash;\n它新建一个*备选的*方式来注入同一个组件实例,并把这个提供商添加到`AlexComponent`的`@Component`元数据里的`providers`数组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Alex* and family in action:",
"translation": "下面是*Alex*和其家庭的运行结果:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### Find the parent in a tree of parentswith _@SkipSelf()_",
"translation": "### 通过父级树找到父组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Imagine one branch of a component hierarchy: *Alice* -> *Barry* -> *Carol*. \nBoth *Alice* and *Barry* implement the `Parent` *class-interface*.",
"translation": "想象组件树中的一个分支为:*Alice* -> *Barry* -> *Carol*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Barry*:",
"translation": "下面是*Barry*的代码:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "For now, focus on *Barry*'s constructor:",
"translation": "眼下,请注意*Barry*的构造函数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "It's identical to *Carol*'s constructor except for the additional `@SkipSelf` decorator.",
"translation": "除额外添加了一个的`@SkipSelf`外,它和*Carol*的构造函数一样。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "`@SkipSelf` is essential for two reasons:",
"translation": "添加`@SkipSelf`主要是出于两个原因:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "2. Angular throws a cyclic dependency error if you omit the `@SkipSelf` decorator.",
"translation": "如果没写`@SkipSelf`装饰器的话Angular就会抛出一个循环依赖错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "`Cannot instantiate cyclic dependency! (BethComponent -> Parent -> BethComponent)`",
"translation": "`不能创建循环依赖实例!(BethComponent -> Parent -> BethComponent)`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Alice*, *Barry* and family in action:",
"translation": "这里是*Alice**Barry*和该家庭的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### The *Parent* class-interface",
"translation": "### *Parent*类-接口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The example defines a `Parent` *class-interface*.",
"translation": "我们的例子定义了一个`Parent`*类-接口*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### A _provideParent()_ helper function",
"translation": "### *provideParent()*助手函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "You can extract that logic into a helper function like this:",
"translation": "可以像这样把该逻辑抽取到一个助手函数里:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Now you can add a simpler, more meaningful parent provider to your components:",
"translation": "现在就可以为组件添加一个更简单、直观的父级提供商了:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "And here's how you could use it with a different parent type:",
"translation": "下面的代码演示了如何使它添加一个不同类型的父级:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "## Break circularities with a forward class reference (*forwardRef*)",
"translation": "## 使用一个前向引用(*forwardRef*)来打破循环",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The Angular `forwardRef()` function creates an *indirect* reference that Angular can resolve later.",
"translation": "Angular的`forwardRef()`函数建立一个*间接地*引用Angular可以随后解析。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "The *Parent Finder* sample is full of circular class references that are impossible to break.",
"translation": "*Parent Finder*是一个充满了无法解决的循环引用的例子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"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/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "Break the circularity with `forwardRef`:",
"translation": "我们使用`forwardRef`来打破这种循环:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection-in-action.md"
},
{
"original": "### _@Component_ providers",
"translation": "### 在组件中注册提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "Here's a revised `HeroesComponent` that registers the `HeroService` in its `providers` array.",
"translation": "下面是修改过的`HerosComponent`,把`HeroService`注册到了它的`providers`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "{@a testing-the-component}",
"translation": "## Testing the component\n## 测试组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "Learn more in the [Testing](guide/testing) guide.",
"translation": "要学习更多知识,参见[测试](guide/testing)一章。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "## When the service needs a service",
"translation": "## 当服务需要别的服务时",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "The `HeroService` is very simple. It doesn't have any dependencies of its own.",
"translation": "这个`HeroService`非常简单。它本身不需要任何依赖。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "## Providers",
"translation": "## 服务提供商们",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "But it's not the only way.",
"translation": "但它不是唯一的途径。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "### The _provide_ object literal",
"translation": "### *provide* 对象字面量",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "### Alternative class providers",
"translation": "### 备选的类提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "### Class provider with dependencies",
"translation": "### 带依赖的类提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "Configure it like `BetterLogger`.",
"translation": "就像之前在`BetterLogger`中那样配置它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "### Aliased class providers",
"translation": "### 别名类提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "The solution: alias with the `useExisting` option.",
"translation": "解决方案:使用`useExisting`选项指定别名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "### Value providers",
"translation": "### 值提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "### Factory providers",
"translation": "### 工厂提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "Suppose also that the injectable service has no independent access to the source of this information.",
"translation": "还假设这个可注入的服务没法通过独立的源访问此信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "This situation calls for a **factory provider**.",
"translation": "这种情况下,请调用**工厂提供商**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "Instead, the `HeroService` constructor takes a boolean flag to control display of secret heroes.",
"translation": "让`HeroService`的构造函数带上一个布尔型的标志,来控制是否显示隐藏的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "A factory provider needs a factory function:",
"translation": "工厂提供商需要一个工厂方法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "Although the `HeroService` has no access to the `UserService`, the factory function does.",
"translation": "虽然`HeroService`不能访问`UserService`,但是工厂方法可以。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "## Dependency injection tokens",
"translation": "## 依赖注入令牌",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "This is especially convenient when you consider that most dependency values are provided by classes.",
"translation": "这是一个特殊的规约,因为大多数依赖值都是以类的形式提供的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "### Non-class dependencies",
"translation": "### 非类依赖",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "### TypeScript interfaces aren't valid tokens",
"translation": "### TypeScript 接口不是一个有效的令牌",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "The `HERO_DI_CONFIG` constant conforms to the `AppConfig` interface. \nUnfortunately, you cannot use a TypeScript interface as a token:",
"translation": "`CONFIG`常量有一个接口:`AppConfig`。不幸的是,不能把 TypeScript 接口用作令牌:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "### _InjectionToken_",
"translation": "### _InjectionToken_ 值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "{@a optional}",
"translation": "## Optional dependencies\n## 可选依赖",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "## Appendix: Working with injectors directly",
"translation": "## 附录:直接使用注入器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "Developers rarely work directly with an injector, but\nhere's an `InjectorComponent` that does.",
"translation": "这里的`InjectorComponent`直接使用了注入器,\n但我们很少直接使用它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "An `Injector` is itself an injectable service.",
"translation": "`Injector`本身是可注入的服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "Framework developers may take this approach when they\nmust acquire services generically and dynamically.",
"translation": "框架开发人员必须采用通用的或者动态的方式获取服务时,可能采用这个方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "## Appendix: one class per file",
"translation": "## 附录:为什么建议每个文件只放一个类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"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/content-2/guide/dependency-injection.md"
},
{
"original": "But it's best to avoid the problem altogether by defining components and services in separate files.",
"translation": "在`forwardRef()`方法的帮助下,实际上也可以先定义组件,\n具体说明见这篇[博客](http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html)。\n但是为什么要先给自己找麻烦呢\n还是通过在独立的文件中定义组件和服务完全避免此问题吧。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dependency-injection.md"
},
{
"original": "# Deployment",
"translation": "# 部署",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "This page describes techniques for deploying your Angular application to a remote server.",
"translation": "本章会描述在远程服务器上部署Angular应用的工具与技术。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "## Simplest deployment possible",
"translation": "## 最简化的部署方式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "For the simplest deployment, build for development and copy the output directory to a web server.",
"translation": "最简化的部署方式就是为开发环境构建,并把其输出复制到 Web 服务器上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "1. Start with the development build",
"translation": "使用开发环境进行构建",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "2. Copy _everything_ within the output folder (`dist/` by default) to a folder on the server.",
"translation": "把输出目录(默认为`dist/`)下的*每个文件*都复制到到服务器上的某个目录下。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "* [Production mode](#enable-prod-mode): deploys the production environment which enables _production mode_.",
"translation": "[生产模式](#enable-prod-mode):启用生产模式部署到生产环境。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "* Bundling: concatenates your many application and library files into a few bundles.",
"translation": "打捆Bundle把这些模块串接成一个单独的捆文件bundle。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "* Minification: removes excess whitespace, comments, and optional tokens.",
"translation": "最小化移除不必要的空格、注释和可选令牌Token。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "* Uglification: rewrites code to use short, cryptic variable and function names.",
"translation": "混淆:使用短的、无意义的变量名和函数名来重写代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "* Dead code elimination: removes unreferenced modules and much unused code.",
"translation": "消除死代码:移除未引用过的模块和未使用过的代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "The remaining [copy deployment steps](#copy-files) are the same as before.",
"translation": "剩下的 [拷贝部署步骤](#copy-files) 和以前的方式是一样的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"original": "### Enable production mode",
"translation": "### 启用生产模式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "### Lazy loading",
"translation": "### 惰性加载",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "#### Don't eagerly import something from a lazy loaded module",
"translation": "#### 不要立即导入惰性加载模块中的任何东西",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "## Server configuration",
"translation": "## 服务端配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "### Routed apps must fallback to `index.html`",
"translation": "### 带路由的应用必须以`index.html`作为后备页面",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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 &mdash;\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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "#### Fallback configuration examples",
"translation": "#### 后备页面配置范例",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "#### Development servers",
"translation": "#### 开发服务器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "#### Production servers",
"translation": "#### 生产服务器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "### Requesting services from a different server (CORS)",
"translation": "### 请求来自另一个服务器的服务CORS",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"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/content-2/guide/deployment.md"
},
{
"original": "# Displaying Data",
"translation": "# 显示数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "The final UI looks like this:",
"translation": "最终的用户界面是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "## Showing component properties with interpolation",
"translation": "## 使用插值表达式显示组件属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "Follow the [quickstart](guide/quickstart) instructions for creating a new project\nnamed <code>displaying-data</code>.",
"translation": "按照[开发环境](guide/setup)的说明,创建一个新项目,名为<code>displaying-data</code>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "When you're done, it should look like this:",
"translation": "修改完之后,它应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "You added two properties to the formerly empty component: `title` and `myHero`.",
"translation": "再把两个属性`title`和`myHero`添加到之前空白的组件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "The template displays the two component properties using double curly brace\ninterpolation:",
"translation": "修改完的模板会使用双花括号形式的插值表达式来显示这两个模板属性:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "The template is a multi-line string within ECMAScript 2015 backticks (<code>\\`</code>).\nThe backtick (<code>\\`</code>)&mdash;which is *not* the same character as a single\nquote (`'`)&mdash;allows you to compose a string over several lines, which makes the\nHTML more readable.",
"translation": "模板是包在 ECMAScript 2015 反引号 (<code>\\`</code>) 中的一个多行字符串。\n反引号 (<code>\\`</code>) &mdash; 注意,不是单引号 (') &mdash; 允许把一个字符串写在多行上,\n使 HTML 模板更容易阅读。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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`中查找一个`<my-app>`元素,\n然后实例化一个`AppComponent`,并将其渲染到`<my-app>`标签中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "Now run the app. It should display the title and hero name:",
"translation": "运行应用。它应该显示出标题和英雄名:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "The next few sections review some of the coding choices in the app.",
"translation": "回顾一下前面所做的决定,看看还有哪些其它选择。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "## Template inline or template file?",
"translation": "## 内联 (inline) 模板还是模板文件?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "In either style, the template data bindings have the same access to the component's properties.",
"translation": "无论用哪种风格,模板数据绑定在访问组件属性方面都是完全一样的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "## Constructor or variable initialization?",
"translation": "## 使用构造函数还是变量初始化?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "This app uses more terse \"variable assignment\" style simply for brevity.",
"translation": "为了让本应用更加简短,它采用了更简单的“变量赋值”风格。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "## Showing an array property with ***ngFor**",
"translation": "## 使用***ngFor***显示数组属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "Now the heroes appear in an unordered list.",
"translation": "现在,英雄们出现在了一个无序列表中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "## Creating a class for the data",
"translation": "## 为数据创建一个类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "With the following code:",
"translation": "代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "You've defined a class with a constructor and two properties: `id` and `name`.",
"translation": "你定义了一个类,具有一个构造函数和两个属性:`id`和`name`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "It might not look like the class has properties, but it does.\n The declaration of the constructor parameters takes advantage of a TypeScript shortcut.",
"translation": "它可能看上去不像是有属性的类,但它确实有,利用的是 TypeScript 提供的简写形式 —— 用构造函数的参数直接定义属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "Consider the first parameter:",
"translation": "来看第一个参数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "That brief syntax does a lot:",
"translation": "这个简写语法做了很多:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "* Declares a constructor parameter and its type",
"translation": "声明了一个构造函数参数及其类型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "* Declares a public property of the same name",
"translation": "声明了一个同名的公共属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "* Initializes that property with the corresponding argument when we \"new\" an instance of the class",
"translation": "当我们`new`出该类的一个实例时,把该属性初始化为相应的参数值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "### Using the Hero class",
"translation": "### 使用 Hero 类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "Our display looks the same, but now we know much better what a hero really is.",
"translation": "从显示上看还是一样,但现在我们知道了更多英雄信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "## Conditional display with NgIf",
"translation": "## 通过 NgIf 进行条件显示",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "Let's change the example to display a message if there are more than three heroes.",
"translation": "让我们来修改这个例子,如果多于三位英雄,显示一条消息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "Now you know how to use:",
"translation": "现在你知道了如何使用:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "* **Interpolation** with double curly braces to display a component property.",
"translation": "带有双花括号的**插值表达式 (interpolation) **来显示一个组件属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "* **ngFor** to display an array of items.",
"translation": "用 **ngFor** 显示数组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"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/content-2/guide/displaying-data.md"
},
{
"original": "* **ngIf** to conditionally display a chunk of HTML based on a boolean expression.",
"translation": "用 **ngIf** 根据一个布尔表达式有条件地显示一段 HTML。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "Here's the final code:",
"translation": "下面是最终的代码:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/displaying-data.md"
},
{
"original": "# Dynamic Component Loader",
"translation": "# 动态组件加载器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "Component templates are not always fixed. An application may need to load new components at runtime.",
"translation": "组件的模板不会永远是固定的。应用可能会需要在运行期间加载一些新的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "This cookbook shows you how to use `ComponentFactoryResolver` to add components dynamically.",
"translation": "这本烹饪书为你展示如何使用`ComponentFactoryResolver`来动态添加组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "See the <live-example name=\"dynamic-component-loader\"></live-example>\nof the code in this cookbook.",
"translation": "到<live-example name=\"cb-dynamic-component-loader\"></live-example>查看本烹饪书的源码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "## Dynamic component loading",
"translation": "## 动态组件加载",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "The following example shows how to build a dynamic ad banner.",
"translation": "下面的例子展示了如何构建动态广告条。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"original": "Angular comes with its own API for loading components dynamically.",
"translation": "Angular 自带的API就能支持动态加载组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "## The anchor directive",
"translation": "## 指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"original": "## Loading components",
"translation": "## 加载组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"original": "## Resolving components",
"translation": "## 解析组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "Take a closer look at the methods in `ad-banner.component.ts`.",
"translation": "深入看看`ad-banner.component.ts`中的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"original": "**How _loadComponent()_ chooses an ad**",
"translation": "**`loadComponent()`如何选择广告**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "The `loadComponent()` method chooses an ad using some math.",
"translation": "`loadComponent()`方法使用某种算法选择了一个广告。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"original": "To add the component to the template, you call `createComponent()` on `ViewContainerRef`.",
"translation": "要把这个组件添加到模板中,我们可以调用`ViewContainerRef`的`createComponent()`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"original": "#### Selector references",
"translation": "#### 对选择器的引用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"original": "## The _AdComponent_ interface",
"translation": "## 公共的`AdComponent`接口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"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/content-2/guide/dynamic-component-loader.md"
},
{
"original": "Here are two sample components and the `AdComponent` interface for reference:",
"translation": "下面就是两个范例组件及其`AdComponent`接口:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "## Final ad banner",
"translation": "## 最终的广告栏",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "The final ad banner looks like this:",
"translation": "最终的广告栏是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "See the <live-example name=\"dynamic-component-loader\"></live-example>.",
"translation": "参见<live-example name=\"cb-dynamic-component-loader\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-component-loader.md"
},
{
"original": "# Dynamic Forms",
"translation": "# 动态表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "Building handcrafted forms canbe 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/content-2/guide/dynamic-form.md"
},
{
"original": "It may be more economical to create the forms dynamically, based on metadata that describes the business object model.",
"translation": "基于业务对象模型的元数据,动态创建表单可能会更划算。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"original": "See the <live-example name=\"dynamic-form\"></live-example>.",
"translation": "参见<live-example name=\"dynamic-form\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "## Bootstrap",
"translation": "## 程序启动",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "Start by creating an `NgModule` called `AppModule`.",
"translation": "让我们从创建一个名叫`AppModule`的`NgModule`开始。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "This cookbook uses [reactive forms](guide/reactive-forms).",
"translation": "这个烹饪书使用[响应式表单](guide/reactive-forms)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"original": "Bootstrap the `AppModule` in `main.ts`.",
"translation": "我们在`main.ts`中启动`AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "## Question model",
"translation": "## 问卷问题模型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"original": "The following `QuestionBase` is a fundamental question class.",
"translation": "下面是我们建立的最基础的问卷问题基类,名叫`QuestionBase`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"original": "`DropdownQuestion` presents a list of choices in a select box.",
"translation": "`DropdownQuestion`表示一个带可选项列表的选择框。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"original": "## Question form components",
"translation": "## 问卷表单组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"original": "`DynamicFormComponent` is the entry point and the main container for the form.",
"translation": "`DynamicFormComponent`是表单的主要容器和入口点。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "It presents a list of questions, each bound to a `<df-question>` component element.\nThe `<df-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": "它代表了问卷问题列表,每个问题都被绑定到一个`<df-question>`组件元素。\n`<df-question>`标签匹配到的是组件`DynamicFormQuestionComponent`,该组件的职责是根据各个问卷问题对象的值来动态渲染表单控件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"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`。\n{@a questionnaire-data}",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "## Questionnaire data",
"translation": "## 问卷数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"original": "Finally, display an instance of the form in the `AppComponent` shell.",
"translation": "最后,在`AppComponent`里显示出表单。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "## Dynamic Template",
"translation": "## 动态模板",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"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/content-2/guide/dynamic-form.md"
},
{
"original": "The final form looks like this:",
"translation": "完整的表单是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "[Back to top](guide/dynamic-form#top)",
"translation": "[回到顶部](guide/dynamic-form#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/dynamic-form.md"
},
{
"original": "# Form Validation",
"translation": "# 表单验证",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"original": "Improve overall data quality by validating user input for accuracy and completeness.",
"translation": "我们可以通过验证用户输入的准确性和完整性,来增强整体数据质量。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "## Template-driven validation",
"translation": "## 模板驱动验证",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "Note the following:",
"translation": "请注意以下几点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "#### Why check _dirty_ and _touched_?",
"translation": "#### 为何检查**dirty**和**touched**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "## Reactive form validation",
"translation": "## 响应式表单的验证",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "### Validator functions",
"translation": "### 验证器函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"original": "There are two types of validator functions: sync validators and async validators.",
"translation": "有两种验证器函数:同步验证器和异步验证器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "### Built-in validators",
"translation": "### 内置验证器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "To update the hero form to be a reactive form, you can use some of the same \nbuilt-in validators&mdash;this time, in function form. See below:",
"translation": "要想把这个英雄表单改造成一个响应式表单,我们还是用那些内置验证器,但这次改为用它们的函数形态。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"original": "Note that:",
"translation": "注意",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"original": "* The name control sets up two built-in validators&mdash;`Validators.required` and `Validators.minLength(4)`&mdash;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/content-2/guide/form-validation.md"
},
{
"original": "* As these validators are all sync validators, you pass them in as the second argument.",
"translation": "由于这些验证器都是同步验证器,因此我们要把它们作为第二个参数传进去。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"original": "* Support multiple validators by passing the functions in as an array.",
"translation": "可以通过把这些函数放进一个数组后传进去,可以支持多重验证器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "Key takeaways:",
"translation": "关键改动是:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "## Custom validators",
"translation": "## 自定义验证器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "### Adding to reactive forms",
"translation": "### 添加响应式表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "### Adding to template-driven forms",
"translation": "### 添加到模板驱动表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "The corresponding `ForbiddenValidatorDirective` serves as a wrapper around the `forbiddenNameValidator`.",
"translation": "`ForbiddenValidatorDirective`指令相当于`forbiddenNameValidator`的包装器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "Once the `ForbiddenValidatorDirective` is ready, you can simply add its selector, `forbiddenName`, to any input element to activate it. For example:",
"translation": "一旦 `ForbiddenValidatorDirective` 写好了,我们只要把`forbiddenName`选择器添加到输入框上就可以激活这个验证器了。比如:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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`&mdash;the instance in the form with\nits `forbiddenName` property bound to “bob\". If you were to replace\n`useExisting` with `useClass`, then youd be registering a new class instance, one that\ndoesnt have a `forbiddenName`.",
"translation": "你可能注意到了自定义验证器指令是用`useExisting`而不是`useClass`来实例化的。注册的验证器必须是这个 `ForbiddenValidatorDirective` 实例本身,也就是表单中 `forbiddenName` 属性被绑定到了\"bob\"的那个。如果用`useClass`来代替`useExisting`,就会注册一个新的类实例,而它是没有`forbiddenName`的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"original": "## Control status CSS classes",
"translation": "## 表示控件状态的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"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/content-2/guide/form-validation.md"
},
{
"original": "# Forms",
"translation": "# 表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "* Build an Angular form with a component and template.",
"translation": "用组件和模板构建 Angular 表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* Use `ngModel` to create two-way data bindings for reading and writing input-control values.",
"translation": "用`ngModel`创建双向数据绑定,以读取和写入输入控件的值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* Track state changes and the validity of form controls.",
"translation": "跟踪状态的变化,并验证表单控件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* Provide visual feedback using special CSS classes that track the state of the controls.",
"translation": "使用特殊的CSS类来跟踪控件的状态并给出视觉反馈",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* Display validation errors to users and enable/disable form controls.",
"translation": "向用户显示验证错误提示,以及启用/禁用表单控件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* Share information across HTML elements using template reference variables.",
"translation": "使用模板引用变量在 HTML 元素之间共享信息",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "You can run the <live-example></live-example> in Plunker and download the code from there.",
"translation": "你可以在Plunker中运行<live-example></live-example>,并且从那里下载代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Template-driven forms",
"translation": "## 模板驱动的表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "You can build almost any form with an Angular template&mdash;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 模板,可以构建几乎所有表单 &mdash; 登录表单、联系人表单…… 以及任何的商务表单。\n 可以创造性的摆放各种控件、把它们绑定到数据、指定校验规则、显示校验错误、有条件的禁用或\n 启用特定的控件、触发内置的视觉反馈等等,不胜枚举。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "You'll learn to build a template-driven form that looks like this:",
"translation": "我们将学习构建如下的“模板驱动”表单:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "If you delete the hero name, the form displays a validation error in an attention-grabbing style:",
"translation": "如果删除了英雄的名字,表单就会用醒目的样式把验证错误显示出来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "You can customize the colors and location of the \"required\" bar with standard CSS.",
"translation": "稍后,会使用标准 CSS 来定制“必填”条的颜色和位置。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "You'll build this form in small steps:",
"translation": "我们将一点点构建出此表单:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Create the `Hero` model class.",
"translation": "创建`Hero`模型类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Create the component that controls the form.",
"translation": "创建控制此表单的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Create a template with the initial form layout.",
"translation": "创建具有初始表单布局的模板。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Bind data properties to each form control using the `ngModel` two-way data-binding syntax.",
"translation": "使用`ngModel`双向数据绑定语法把数据属性绑定到每个表单输入控件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Add a `name` attribute to each form-input control.",
"translation": "往每个表单输入控件上添加`name`属性 (attribute)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Add custom CSS to provide visual feedback.",
"translation": "添加自定义 CSS 来提供视觉反馈。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Show and hide validation-error messages.",
"translation": "显示和隐藏有效性验证的错误信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Handle form submission with *ngSubmit*.",
"translation": "使用 **ngSubmit** 处理表单提交。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Disable the forms *Submit* button until the form is valid.",
"translation": "禁用此表单的提交按钮,直到表单变为有效。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Setup",
"translation": "## 搭建",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Create a new project named <code>angular-forms</code>:",
"translation": "创建一个名为 <code>angular-forms</code> 的新项目:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Create the Hero model class",
"translation": "## 创建 Hero 模型类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "Using the Angular CLI, generate a new class named `Hero`:",
"translation": "使用 Angular CLI 生成一个名叫`Hero`的新类:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "With this content:",
"translation": "内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "It's an anemic model with few requirements and no behavior. Perfect for the demo.",
"translation": "这是一个少量需求和零行为的贫血模型。对演示来说很完美。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "The TypeScript compiler generates a public field for each `public` constructor parameter and\nautomatically assigns the parameters value to that field when you create heroes.",
"translation": "TypeScript 编译器为每个`public`构造函数参数生成一个公共字段,在创建新的英雄实例时,自动把参数值赋给这些公共字段。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "## Create a form component",
"translation": "## 创建表单组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "Using the Angular CLI, generate a new component named `HeroForm`:",
"translation": "使用 Angular CLI 生成一个名叫 `HeroForm` 的新组件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "With this content:",
"translation": "内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Theres 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/content-2/guide/forms.md"
},
{
"original": "Understanding this component requires only the Angular concepts covered in previous pages.",
"translation": "只需要前面章节中学过的概念,就可以完全理解这个组件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* The code imports the Angular core library and the `Hero` model you just created.",
"translation": "这段代码导入了Angular核心库以及我们刚刚创建的`Hero`模型。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "* The `templateUrl` property points to a separate file for the template HTML.",
"translation": "`moduleId: module.id`属性设置了基地址,用于从相对模块路径加载`templateUrl`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* You defined dummy data for `model` and `powers`, as befits a demo.",
"translation": "`templateUrl`属性指向一个独立的 HTML 模板文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "## Revise *app.module.ts*",
"translation": "## 修改 *app.module.ts*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "Update it with the following:",
"translation": "对它做如下修改:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "There are two changes:",
"translation": "有三处更改",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. You import `FormsModule`.",
"translation": "导入`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. You add the `FormsModule` to the list of `imports` defined in the `@NgModule` decorator. This gives the application\naccess to all of the template-driven forms features, including `ngModel`.",
"translation": "把`FormsModule`添加到`ngModule`装饰器的`imports`列表中,这样应用就能访问模板驱动表单的所有特性,包括`ngModel`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "## Revise *app.component.html*",
"translation": "## 修改 *app.component.ts*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "`AppComponent` is the application's root component. It will host the new `HeroFormComponent`.",
"translation": "`AppComponent`是应用的根组件,`HeroFormComponent`将被放在其中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "## Create an initial HTML form template",
"translation": "## 创建初始 HTML 表单模板",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Create the template file with the following contents:",
"translation": "创建模板文件,内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "You added a *Submit* button at the bottom with some classes on it for styling.",
"translation": "在底部添加个 *Submit* 按钮,它还带一些 CSS 样式类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "*You're not using Angular yet*. There are no bindings or extra directives, just layout.",
"translation": "**我们还没有真正用到Angular**。没有绑定,没有额外的指令,只有布局。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/)。纯粹是装饰。\n我们使用 Bootstrap 来美化表单。嘿,一点样式都没有的表单算个啥!",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Angular forms don't require a style library",
"translation": "Angular 表单不需要任何样式库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "## Add powers with _*ngFor_",
"translation": "## 用 ***ngFor*** 添加超能力",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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模板输入变量`p`在每个迭代指向不同的超能力,使用双花括号插值表达式语法来显示它的名称。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Two-way data binding with _ngModel_",
"translation": "## 使用 *ngModel* 进行双向数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Running the app right now would be disappointing.",
"translation": "如果立即运行此应用,你将会失望。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "Now you need to display, listen, and extract at the same time.",
"translation": "现在,需要同时进行显示、监听和提取。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "Focus on the binding syntax: `[(ngModel)]=\"...\"`.",
"translation": "聚焦到绑定语法`[(ngModel)]=\"...\"`上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "### The _NgForm_ directive",
"translation": "### `NgForm`指令What `NgForm` directive?\nYou didn't add an [NgForm](api/forms/NgForm) directive.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "*Delete* the `{{diagnostic}}` binding at the top as it has served its purpose.",
"translation": "表单顶部的`{{diagnostic}}`绑定已经完成了它的使命,**删除**它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Track control state and validity with _ngModel_",
"translation": "## 通过 **ngModel** 跟踪修改状态与有效性验证",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "State",
"translation": "状态",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Class if true",
"translation": "为真时的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Class if false",
"translation": "为假时的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "The control has been visited.",
"translation": "控件被访问过。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "The control's value has changed.",
"translation": "控件的值变化了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "The control's value is valid.",
"translation": "控件的值有效。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Now run the app and look at the _Name_ input box.\nFollow these steps *precisely*:",
"translation": "现在,运行本应用,并让*姓名*输入框获得焦点。\n然后严格按照下面四个步骤来做",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Look but don't touch.",
"translation": "查看输入框,但别碰它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Click inside the name box, then click outside it.",
"translation": "点击输入框,然后点击输入框外面。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Add slashes to the end of the name.",
"translation": "在名字的末尾添加些斜杠。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Erase the name.",
"translation": "删除名字。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "The actions and effects are as follows:",
"translation": "动作和它对应的效果如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "You should see the following transitions and class names:",
"translation": "我们会看到下列转换及其类名:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "*Delete* the `#spy` template reference variable and the `TODO` as they have served their purpose.",
"translation": "**删除**模板引用变量`#spy`和`TODO`,因为它们已经完成了使命。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Add custom CSS for visual feedback",
"translation": "## 添加用于视觉反馈的自定义 CSS",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "Update the `<head>` of `index.html` to include this style sheet:",
"translation": "更新`index.html`中的`<head>`,以包含这个样式表:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Show and hide validation error messages",
"translation": "## 显示和隐藏验证错误信息",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "When the user deletes the name, the form should look like this:",
"translation": "当用户删除姓名时,应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "To achieve this effect, extend the `<input>` tag with the following:",
"translation": "要达到这个效果,在`<input>`标签中添加:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* A [template reference variable](guide/template-syntax#ref-vars).",
"translation": "[模板引用变量](guide/template-syntax#ref-vars)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "The hero *Alter Ego* is optional so you can leave that be.",
"translation": "英雄的*第二人格*是可选项,所以不用改它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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 *did not restore the pristine state* of the form controls.",
"translation": "使用浏览器工具审查这个元素就会发现,这个 *name* 输入框并不是全新的。\n表单记得我们在点击 *New Hero* 前输入的名字。\n更换了英雄*并不会重置控件的“全新”状态*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Now clicking \"New Hero\" resets both the form and its control flags.",
"translation": "现在点击“New Hero”重设表单和它的控制标记。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Submit the form with _ngSubmit_",
"translation": "## 使用 *ngSubmit* 提交该表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "If you run the application now, you find that the button is enabled&mdash;although\nit doesn't do anything useful yet.",
"translation": "重新运行应用。表单打开时,状态是有效的,按钮是可用的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "For you, it was as simple as this:",
"translation": "有了 Angular它就是这么简单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "1. Define a template reference variable on the (enhanced) form element.",
"translation": "定义模板引用变量放在强化过的form 元素上",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "2. Refer to that variable in a button many lines away.",
"translation": "从很多行之外的按钮上引用这个变量。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Toggle two form regions (extra credit)",
"translation": "## 切换两个表单区域(额外的奖励)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Submitting the form isn't terribly dramatic at the moment.",
"translation": "提交表单还是不够激动人心。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "For a more strikingly visual effect,\nhide the data entry area and display something else.",
"translation": "来实现一些更炫的视觉效果吧。\n 隐藏掉数据输入框,显示一些其它东西。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "When you click the *Edit* button, this block disappears and the editable form reappears.",
"translation": "当点*Edit*按钮时,这个只读块消失了,可编辑的表单重新出现了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"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/content-2/guide/forms.md"
},
{
"original": "* An Angular HTML form template.",
"translation": "Angular HTML 表单模板。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* A form component class with a `@Component` decorator.",
"translation": "带有`@Component`装饰器的表单组件类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* Handling form submission by binding to the `NgForm.ngSubmit` event property.",
"translation": "通过绑定到`NgForm.ngSubmit`事件属性来处理表单提交。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* Template-reference variables such as `#heroForm` and `#name`.",
"translation": "模板引用变量,例如`#heroForm`和`#name`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* `[(ngModel)]` syntax for two-way data binding.",
"translation": "`[(ngModel)]`语法用来实现双向数据绑定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* The use of `name` attributes for validation and form-element change tracking.",
"translation": "`name`属性的用途是有效性验证和对表单元素的变更进行追踪。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* The reference variables `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/content-2/guide/forms.md"
},
{
"original": "* Controlling the *Submit* button's enabled state by binding to `NgForm` validity.",
"translation": "通过绑定到`NgForm`的有效性状态,控制*Submit*按钮的禁用状态。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "* Custom CSS classes that provide visual feedback to users about invalid controls.",
"translation": "定制 CSS 类来给用户提供无效控件的视觉反馈。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "Heres the code for the final version of the application:",
"translation": "下面是该应用最终版本的代码:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/forms.md"
},
{
"original": "# Angular Glossary",
"translation": "# Angular 词汇表",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Ahead-of-time (AOT) compilation",
"translation": "## 预 (ahead-of-time, AoT) 编译",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "You can compile Angular applications at build time.\nBy compiling your application using the compiler-cli, `ngc`, you can bootstrap directly\nto 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/content-2/guide/glossary.md"
},
{
"original": "## Annotation",
"translation": "## 注解",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "In practice, a synonym for [Decoration](guide/glossary#decorator).",
"translation": "实际上,是[装饰 (decoration)](guide/glossary#decorator) 的同义词。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Attribute directives",
"translation": "## 属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "For example, you can use the `ngClass` directive to add and remove CSS class names.",
"translation": "例如,`ngClass`指令就是典型的属性型指令。它可以添加或移除 CSS 类名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Learn about them in the [_Attribute Directives_](guide/attribute-directives) guide.",
"translation": "要了解更多信息,请参见[_属性型指令_](guide/attribute-directives)页。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Barrel",
"translation": "## 封装桶",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "For example, imagine three ES2015 modules in a `heroes` folder:",
"translation": "例如,设想在`heroes`目录下有三个 ES2015 模块:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Without a barrel, a consumer needs three import statements:",
"translation": "如果没有封装桶,消费者需要三条导入语句:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Now a consumer can import what it needs from the barrel.",
"translation": "现在,消费者就就可以从这个封装桶中导入它需要的东西了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "You can often achieve the same result using [NgModules](guide/glossary#ngmodule) instead.",
"translation": "注意,你可以利用 [Angular 模块](guide/glossary#ngmodule)达到同样的目的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Binding",
"translation": "## 绑定 (binding)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Sometimes refers to a [dependency-injection](guide/glossary#dependency-injection) binding\nbetween a \"token\"&mdash;also referred to as a \"key\"&mdash;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/content-2/guide/glossary.md"
},
{
"original": "## Bootstrap",
"translation": "## 启动/引导 (bootstrap)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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": "通过应用程序根 Angular 模块来启动 Angular 应用程序。\n 启动过程标识应用的顶级“根”[组件 (component)](guide/glossary#component),也就是应用加载的第一个组件。\n 更多信息,见[设置](guide/setup)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## camelCase",
"translation": "## 驼峰式命名法 (camelCase)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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)。\n在文档中提到“驼峰式命名法 (camelCase) ”的时候,我们所指的都是小驼峰命名法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Component",
"translation": "## 组件 (component)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "An Angular class responsible for exposing data to a [view](guide/glossary#view) and handling most of the views display and user-interaction logic.",
"translation": "组件是一个 Angular 类,用于把数据展示到[视图 (view)](guide/glossary#view),并处理几乎所有的视图显示和交互逻辑。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## dash-case",
"translation": "## 中线命名法 (dash-case)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Data binding",
"translation": "## 数据绑定 (data binding)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "* [Interpolation](guide/template-syntax#interpolation)",
"translation": "[插值表达式 (interpolation)](guide/template-syntax#interpolation)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* [Property binding](guide/template-syntax#property-binding)",
"translation": "[property 绑定 (property binding)](guide/template-syntax#property-binding)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* [Event binding](guide/template-syntax#event-binding)",
"translation": "[事件绑定 (event binding)](guide/template-syntax#event-binding)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* [Attribute binding](guide/template-syntax#attribute-binding)",
"translation": "[attribute 绑定 (attribute binding)](guide/template-syntax#attribute-binding)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* [Class binding](guide/template-syntax#class-binding)",
"translation": "[CSS 类绑定 (class binding)](guide/template-syntax#class-binding)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* [Style binding](guide/template-syntax#style-binding)",
"translation": "[样式绑定 (style binding)](guide/template-syntax#style-binding)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Decorator | decoration",
"translation": "## 装饰器decorator | decoration",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "A *function* that adds metadata to a class, its members (properties, methods) and function arguments.",
"translation": "装饰器是一个**函数**,它将元数据添加到类、类成员(属性、方法)和函数参数。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "To apply a decorator, position it immediately above or to the left of the item it decorates.",
"translation": "要想应用装饰器,把它放到被装饰对象的上面或左边。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Always include parentheses `()` when applying a decorator.",
"translation": "永远别忘了在装饰器后面加括号`()`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Dependency injection",
"translation": "## 依赖注入dependency injection",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Read more in the [Dependency Injection](guide/dependency-injection) page.",
"translation": "更多信息,参见[依赖注入 (dependency injection)](guide/dependency-injection)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Directive",
"translation": "## 指令 (directive)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "A directive is usually associated with an HTML element or attribute.\nThis element or attribute is often referred to as the directive itself.\nWhen 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": "指令几乎总与 HTML 元素或属性 (attribute) 相关。\n我们通常把这些关联到的 HTML 元素或者属性 (attribute) 当做指令本身。\n当 Angular 在 HTML 模板中遇到一个指令的时候,\n它会创建匹配的指令类的实例并把浏览器中这部分 DOM 的控制权交给它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Directives fall into one of the following categories:",
"translation": "指令分为三类:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## ECMAScript",
"translation": "## ECMAScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Angular developers can write in ES5 directly.",
"translation": "Angular 的开发人员也可以选择直接使用 ES5 编程。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## ES2015",
"translation": "## ES2015 语言",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.",
"translation": "[ECMAScript](guide/glossary#ecmascript) 2015 的缩写。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## ES5",
"translation": "## ES5 语言",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## ES6",
"translation": "## ES6 语言",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.",
"translation": "[ECMAScript](guide/glossary#ecmascript) 2015 的简写。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Injector",
"translation": "## 注入器 (injector)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Input",
"translation": "## 输入属性 (input)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Interpolation",
"translation": "## 插值表达式 (interpolation)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Just-in-time (JIT) compilation",
"translation": "## 即时 (just-in-time, JiT) 编译",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## kebab-case",
"translation": "## 烤串命名法 (kebab-case)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "See [dash-case](guide/glossary#dash-case).",
"translation": "见[中线命名法 (dash-case)](guide/glossary#dash-case)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Lifecycle hooks",
"translation": "## 生命周期钩子 (lifecycle hook)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Angular calls these hook methods in the following order:",
"translation": "Angular 会按以下顺序调用钩子方法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "* `ngOnInit`: after the first `ngOnChanges`.",
"translation": "`ngOnInit` - 在第一次`ngOnChanges`完成后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* `ngDoCheck`: developer's custom change detection.",
"translation": "`ngDoCheck` - 开发者自定义变更检测。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* `ngAfterContentInit`: after component content initialized.",
"translation": "`ngAfterContentInit` - 在组件内容初始化后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* `ngAfterContentChecked`: after every check of component content.",
"translation": "`ngAfterContentChecked` - 在组件内容每次检查后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* `ngAfterViewInit`: after a component's views are initialized.",
"translation": "`ngAfterViewInit` - 在组件视图初始化后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* `ngAfterViewChecked`: after every check of a component's views.",
"translation": "`ngAfterViewChecked` - 在组件视图每次检查后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* `ngOnDestroy`: just before the directive is destroyed.",
"translation": "`ngOnDestroy` - 在指令销毁前调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Read more in the [Lifecycle Hooks](guide/lifecycle-hooks) page.",
"translation": "更多信息,见[生命周期钩子 (lifecycle hook)](guide/lifecycle-hooks)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Module",
"translation": "## 模块 (module)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Angular has the following types of modules:",
"translation": "Angular有下列模块类型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* [NgModules](guide/glossary#ngmodule).\nFor details and examples, see the [NgModules](guide/ngmodule) page.",
"translation": "[Angular 模块](guide/glossary#ngmodule),见[Angular 模块](guide/ngmodule)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* ES2015 modules, as described in this section.",
"translation": "本节描述的 ES2015 模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "A cohesive block of code dedicated to a single purpose.",
"translation": "模块是一个内聚的代码块,具有单一用途。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Angular apps are modular.",
"translation": "Angular 应用程序是模块化的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## NgModule",
"translation": "## 可观察对象 (observable)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Observable",
"translation": "## Observable 对象",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "To use observables, Angular uses a third-party library called Reactive Extensions (RxJS).\nObservables are a proposed feature for ES 2016, the next version of JavaScript.",
"translation": "为了使用`Observable` Angular 采用了名为 Reactive Extensions (RxJS) 的第三方包。\n在下个版本的 JavaScript - ES 2016 中,`Observable`是建议的特性之一。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Output",
"translation": "## 输出属性 (output)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## PascalCase",
"translation": "## Pascal 命名法 (PascalCase)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Pipe",
"translation": "## 管道 (pipe)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Provider",
"translation": "## 提供商 (provider)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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&mdash;sometimes called a \"recipe\"&mdash;that can create a dependency value.",
"translation": "依赖注入系统依靠提供商来创建依赖的实例。\n它把一个查找令牌和代码有时也叫“配方”关联到一起以便创建依赖值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Reactive forms",
"translation": "## 响应式表单 (reactive forms)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "When building reactive forms:",
"translation": "构建响应式表单时:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "* The \"source of truth\" is the component. The validation is defined using code in the component.",
"translation": "组件是“真理之源”。表单验证在组件代码中定义。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "* The template input elements do *not* use `ngModel`.",
"translation": "模板中的`input`元素**不**使用`ngModel`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Router",
"translation": "## 路由器 (router)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "A [routing component's](guide/glossary#routing-component) template has a `RouterOutlet` element\n where it can display views produced by the router.",
"translation": "[路由组件](guide/glossary#routing-component)的模板中带有一个`RouterOutlet`元素,那是显示路由器生成的视图的地方。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Other views in the application likely have anchor tags or buttons with `RouterLink`\n directives that users can click to navigate.",
"translation": "应用中的其它视图中某些锚标签或按钮上带有`RouterLink`指令,用户可以点击它们进行导航。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Router module",
"translation": "## 路由器模块 (router module)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Routing component",
"translation": "## 路由组件 (routing component)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Scoped package",
"translation": "## 范围化包 (scoped package)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Service",
"translation": "## 服务 (service)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Applications often require services such as a hero data service or a logging service.",
"translation": "应用程序经常需要服务,例如英雄数据服务或者日志服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Applications often require services such as a data service or a logging service.",
"translation": "应用通常都需要服务,比如数据服务或者日志服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## snake_case",
"translation": "## 蛇形命名法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Structural directives",
"translation": "## 结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Read more in the [Structural Directives](guide/structural-directives) page.",
"translation": "更多信息,见[结构型指令](guide/structural-directives)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Template",
"translation": "## 模板 (template)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Template-driven forms",
"translation": "## 模板驱动表单 (template-driven forms)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "When building template-driven forms:",
"translation": "当构建模板驱动表单时:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Read about how to build template-driven forms\nin the [Forms](guide/forms) page.",
"translation": "要了解如何构建模板驱动表单的更多信息,参见[表单](guide/forms)页。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## Template expression",
"translation": "## 模板表达式 (template expression)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Transpile",
"translation": "## 转译transpile)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## TypeScript",
"translation": "## TypeScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).",
"translation": "更多信息,见[typescript.org](http://www.typescriptlang.org/)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "## View",
"translation": "## 视图 (view)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "## Zone",
"translation": "## 区域 (zone)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "A mechanism for encapsulating and intercepting\na JavaScript application's asynchronous activity.",
"translation": "区域是一种用来封装和截听 JavaScript 应用程序异步活动的机制。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "The browser DOM and JavaScript have a limited number\n of 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)\n calls 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/content-2/guide/glossary.md"
},
{
"original": "Zones intercept all of these activities and give a \"zone client\" the opportunity\n to take action before and after the async activity finishes.",
"translation": "区域能截听所有这些活动,并让“区域的客户”有机会在异步活动完成之前和之后采取行动。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"original": "Angular runs your application in a zone where it can respond to\n asynchronous events by checking for data changes and updating\n the information it displays via [data bindings](guide/glossary#data-binding).",
"translation": "Angular 会在一个 Zone 区域中运行应用程序,在这个区域中,它可以对异步事件做出反应,可以通过检查数据变更、利用[数据绑定 (data bindings)](guide/glossary#data-binding) 来更新信息显示。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/glossary.md"
},
{
"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/content-2/guide/glossary.md"
},
{
"original": "# Hierarchical Dependency Injectors",
"translation": "# 多级依赖注入器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "This guide explores this system and how to use it to your advantage.",
"translation": "在本章中,我们将浏览这个体系,并告诉你如何善用它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "Try the <live-example></live-example>.",
"translation": "试试<live-example></live-example>.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "## The injector tree",
"translation": "## 注入器树",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Injector bubbling",
"translation": "### 注入器冒泡",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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.\n This is a topic for another day.",
"translation": "我们还可以“盖住”这次冒泡。一个中层的组件可以声称自己是“宿主”组件。\n向上查找提供商的过程会截止于这个“宿主”组件。\n我们先保留这个问题等改天再讨论这个选项。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Re-providing a service at different levels",
"translation": "### 在不同层级再次提供同一个服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "## Component injectors",
"translation": "## 组件注入器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "The ability to configure one or more providers at different levels opens up interesting and useful possibilities.",
"translation": "在不同层次上重新配置一个或多个提供商的能力,开启了一些既有趣又有用的可能性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: service isolation",
"translation": "### 场景:服务隔离",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "Instead, provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:",
"translation": "我们可以换一种方案:在`VillainsListComponent`元数据的`providers`中提供`VillainsService`,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: multiple edit sessions",
"translation": "### 场景:多重编辑会话",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "Each tax return component has the following characteristics:",
"translation": "每个报税单组件都有下列特征:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Is its own tax return editing session.",
"translation": "属于它自己的报税单会话。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Can change a tax return without affecting a return in another component.",
"translation": "可以修改一个报税单,而不会影响另一个组件中的申报单。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Has the ability to save the changes to its tax return or cancel them.",
"translation": "能把所做的修改保存到它的报税单中,或者放弃它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "Here is the `HeroTaxReturnComponent` that makes use of it.",
"translation": "下面是正在使用它的`HeroTaxReturnComponent`组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "Look closely at the metadata for the `HeroTaxReturnComponent`. Notice the `providers` property.",
"translation": "但仔细看`HeroTaxReturnComponent`的元数据,注意`providers`属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: specialized providers",
"translation": "### 场景:专门的提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "You create a car component (A) that displays a car constructed from these three generic services.",
"translation": "我们创建了一个车辆组件A它显示一个从另外三个通用服务构造出的车辆。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"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/content-2/guide/hierarchical-dependency-injection.md"
},
{
"original": "# HttpClient",
"translation": "# HttpClient 库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"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/content-2/guide/http.md"
},
{
"original": "With `HttpClient`, `@angular/common/http` provides a simplified API for HTTP functionality for use with Angular applications, building on top of the `XMLHttpRequest` interface exposed by browsers.\nAdditional benefits of `HttpClient` include testability support, strong typing of request and response objects, request and response interceptor support, and better error handling via apis based on Observables.",
"translation": "`@angular/common/http`中的`HttpClient`类Angular 为应用程序提供了一个简化的 API 来实现 HTTP 功能。它基于浏览器提供的`XMLHttpRequest`接口。\n`HttpClient`带来的其它优点包括可测试性、强类型的请求和响应对象、发起请求与接收响应时的拦截器支持以及更好的、基于可观察Observable对象的错误处理机制。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "## Setup: installing the module",
"translation": "## 初始设置:安装本模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Before you can use the `HttpClient`, you need to install the `HttpClientModule` which provides it. This can be done in your application module, and is only necessary once.",
"translation": "在使用`HttpClient`之前,要先安装`HttpClientModule`以提供它。这可以在应用模块中做,而且只需要做一次。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Once you import `HttpClientModule` into your app module, you can inject `HttpClient`\ninto your components and services.",
"translation": "一旦把`HttpClientModule`引入了应用模块中,我们就可以把`HttpClient`注入到组件和服务中去了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "## Making a request for JSON data",
"translation": "## 发起一个请求来获取 JSON 数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "The most common type of request applications make to a backend is to request JSON data. For example, suppose you have an API endpoint that lists items, `/api/items`, which returns a JSON object of the form:",
"translation": "在应用发给服务器的请求中最常见的就是获取一个JSON数据。比如假设我们有一个用来获取条目列表的 API 端点 `/api/items`,它会返回一个如下格式的 JSON 对象:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "The `get()` method on `HttpClient` makes accessing this data straightforward.",
"translation": "`HttpClient`的`get()`方法可以让访问此数据的代码非常直白:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Typechecking the response",
"translation": "### 响应体的类型检查",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "In the above example, the `data['results']` field access stands out because you use bracket notation to access the results field. If you tried to write `data.results`, TypeScript would correctly complain that the `Object` coming back from HTTP does not have a `results` property. That's because while `HttpClient` parsed the JSON response into an `Object`, it doesn't know what shape that object is.",
"translation": "在上面的例子中,访问`data['results']`是用方括号语法来取得results字段的。如果写成`data.results`TypeScript 就会抱怨说来自HTTP的`Object`没有一个名叫`results`的属性。\n那是因为`HttpClient`把 JSON 格式的响应体解析成了一个`Object`,它并不知道这个对象的形态应该是什么。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "You can, however, tell `HttpClient` what type the response will be, which is recommended.\nTo do so, first you define an interface with the correct shape:",
"translation": "然而,我们其实可以告诉`HttpClient`这个响应体应该是什么类型的,而且这是推荐的做法。\n要这样做首先我们要定义一个接口来描述这个类型的正确形态",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Then, when you make the `HttpClient.get` call, pass a type parameter:",
"translation": "然后,当我们发起 `HttpClient.get` 调用时,传入一个类型参数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Reading the full response",
"translation": "### 读取完整的响应体",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"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, and inspecting those can be necessary. To do this, you can tell `HttpClient` you want the full response instead of just the body with the `observe` option:",
"translation": "响应体可能并不包含我们需要的全部信息。有时候服务器会返回一个特殊的响应头或状态码,以标记出特定的条件,因此读取它们可能是必要的。要这样做,我们就要通过`observe`选项来告诉`HttpClient`,你想要完整的响应信息,而不是只有响应体:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "As you can see, the resulting object has a `body` property of the correct type.",
"translation": "如你所见,这个结果对象具有一个带正确类型的`body`属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Error handling",
"translation": "### 错误处理",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"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_ instead of a successful response.",
"translation": "如果这个请求导致了服务器错误怎么办?甚至,在烂网络下请求都没到服务器该怎么办?`HttpClient`就会返回一个错误error而不再是成功的响应。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "To handle it, add an error handler to your `.subscribe()` call:",
"translation": "要处理它,可以在`.subscribe()`调用中添加一个错误处理器:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### Getting error details",
"translation": "#### 获取错误详情",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Detecting that an error occurred is one thing, but it's more useful to know what error actually occurred. The `err` parameter to the callback above is of type `HttpErrorResponse`, and contains useful information on what went wrong.",
"translation": "检测错误的发生是第一步,不过如果知道具体发生了什么错误才会更有用。上面例子中传给回调函数的`err`参数的类型是`HttpErrorResponse`,它包含了这个错误中一些很有用的信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "There are two types of errors that can occur. If the backend returns an unsuccessful response code (404, 500, etc.), it gets returned as an error. Also, if something goes wrong client-side, such as an exception gets thrown in an RxJS operator, or if a network error prevents the request from completing successfully, an actual `Error` will be thrown.",
"translation": "可能发生的错误分为两种。如果后端返回了一个失败的返回码如404、500等它会返回一个错误。同样的如果在客户端这边出了错误比如在RxJS操作符中抛出的异常或某些阻碍完成这个请求的网络错误就会抛出一个`Error`类型的异常。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "In both cases, you can look at the `HttpErrorResponse` to figure out what happened.",
"translation": "这两种情况下,我们可以查看`HttpErrorResponse`来判断到底发生了什么。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### `.retry()`",
"translation": "#### `.retry()` 操作符",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "One way to deal with errors is to simply retry the request. This strategy can be useful when the errors are transient and unlikely to repeat.",
"translation": "解决问题的方式之一,就是简单的重试这次请求。这种策略对于那些临时性的而且不大可能重复发生的错误会很有用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "RxJS has a useful operator called `.retry()`, which automatically resubscribes to an Observable, thus reissuing the request, upon encountering an error.",
"translation": "RxJS有一个名叫`.retry()`的很有用的操作符,它会在遇到错误时自动重新订阅这个可观察对象,也就会导致再次发送这个请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "First, import it:",
"translation": "首先,导入它:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Then, you can use it with HTTP Observables like this:",
"translation": "然后,你可以把它用在 HTTP 的可观察对象上,比如这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Requesting non-JSON data",
"translation": "### 请求非 JSON 数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Not all APIs return JSON data. Suppose you want to read a text file on the server. You have to tell `HttpClient` that you expect a textual response:",
"translation": "并非所有的 API 都会返回 JSON 数据。假如我们要从服务器上读取一个文本文件,那就要告诉 `HttpClient` 我们期望获得的是文本格式的响应:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "## Sending data to the server",
"translation": "## 把数据发送到服务器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "In addition to fetching data from the server, `HttpClient` supports mutating requests, that is, sending data to the server in various forms.",
"translation": "除了从服务器获取数据之外,`HttpClient` 还支持 \"修改\" 型请求,也就是说,使用各种格式把数据发送给服务器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Making a POST request",
"translation": "### 发起一个 POST 请求",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "One common operation is to POST data to a server; for example when submitting a form. The code for\nsending a POST request is very similar to the code for GET:",
"translation": "常用的操作之一就是把数据 POST 到服务器,比如提交表单。下面这段发送 POST 请求的代码和发送 GET 请求的非常像:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "*Note the `subscribe()` method.* All Observables returned from `HttpClient` are _cold_, which is to say that they are _blueprints_ for making requests. Nothing will happen until you call `subscribe()`, and every such call will make a separate request. For example, this code sends a POST request with the same data twice:",
"translation": "*注意这个`subscribe()`方法*。 所有从`HttpClient`返回的可观察对象都是*冷的cold*,也就是说,它们只是发起请求的*蓝图*而已。在我们调用`subscribe()`之前,什么都不会发生,而当我们每次调用`subscribe()`时,就会独立发起一次请求。\n比如下列代码会使用同样的数据发送两次同样的 POST 请求:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Configuring other parts of the request",
"translation": "### 配置请求中的其它部分",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Besides the URL and a possible request body, there are other aspects of an outgoing request which you may wish to configure. All of these are available via an options object, which you pass to the request.",
"translation": "除了 URL 和可能的请求体之外,要发送的请求中你可能还希望配置一些别的东西。所有这些都可以通过给这次请求传一个额外的`options`(选项)对象来解决。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### Headers",
"translation": "#### 头",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "One common task is adding an `Authorization` header to outgoing requests. Here's how you do that:",
"translation": "最常见的就是往发出的请求中添加一个`Authorization`头,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "The `HttpHeaders` class is immutable, so every `set()` returns a new instance and applies the changes.",
"translation": "`HttpHeaders`类是不可变对象immutable所以每个`set()`都会返回一个新实例,并且应用上这些修改。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### URL Parameters",
"translation": "#### URL 参数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Adding URL parameters works in the same way. To send a request with the `id` parameter set to `3`, you would do:",
"translation": "添加 URL 参数的方法也一样。比如要发送一个请求,并把`id`参数设置为`3`,就要这样写:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "In this way, you send the POST request to the URL `/api/items/add?id=3`.",
"translation": "这种情况下,我们会往 URL `/api/items/add?id=3` 上发送一个 POST 请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "## Advanced usage",
"translation": "## 高级用法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "The above sections detail how to use the basic HTTP functionality in `@angular/common/http`, but sometimes you need to do more than just make requests and get data back.",
"translation": "上一节详细讲解了如何在`@angular/common/http`中使用基本的 HTTP 功能,但是有时候除了发起请求和获取数据之外,我们还要做更多。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Intercepting all requests or responses",
"translation": "### 拦截所有的请求和响应。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "A major feature of `@angular/common/http` is _interception_, the ability to declare interceptors which sit in between your application and the backend. When your application makes a request, interceptors transform it\nbefore sending it to the server, and the interceptors can transform the response on its way back before your application sees it. This is useful for everything from authentication to logging.",
"translation": "`@angular/common/http`的主要特性之一是*拦截器*,它能声明一些拦截器,拦在应用和后端之间。当应用程序发起一个请求时,拦截器可以在请求被发往服务器之前先转换这个请求。并且在应用看到服务器发回来的响应之前,转换这个响应。这对于处理包括认证和记录日志在内的一系列工作都非常有用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### Writing an interceptor",
"translation": "#### 写一个拦截器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "To implement an interceptor, you declare a class that implements `HttpInterceptor`, which\nhas a single `intercept()` method. Here is a simple interceptor which does nothing but forward the request through without altering it:",
"translation": "要实现一个拦截器,就要声明一个实现了`HttpInterceptor`接口的类,它只有一个`intercept()`方法。下面是一个最简单的拦截器,它什么也不做,只是简单的转发请求而不做任何修改:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "`intercept` is a method which transforms a request into an Observable that eventually returns the response. In this sense, each interceptor is entirely responsible for handling the request by itself.",
"translation": "`intercept`是一个方法它把一个请求对象转换成一个返回这个响应的可观察对象Observable。从这个意义上说每个拦截器都要完全自己处理这个请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Most of the time, though, interceptors will make some minor change to the request and forward it to the rest of the chain. That's where the `next` parameter comes in. `next` is an `HttpHandler`, an interface that, similar to `intercept`, transforms a request into an Observable for the response. In an interceptor, `next` always represents the next interceptor in the chain, if any, or the final backend if there are no more interceptors. So most interceptors will end by calling `next` on the request they transformed.",
"translation": "当然,大多数时候,拦截器会对请求做一些小的修改,然后才把它转给拦截器链中的其它部分,也就是所传进来的`next`参数。`next`是一个`HttpHandler`,是一个类似于`intercept`的接口,它会把一个请求对象转换成一个可观察的响应对象。在拦截器中,`next`总是代表位于拦截器链中的下一个拦截器(如果有的话),如果没有更多拦截器了,它就会是最终的后端。所以,大多数拦截器的最后一句都会以它们转换后请求对象为参数调用`next.handle`函数。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Our do-nothing handler simply calls `next.handle` on the original request, forwarding it without mutating it at all.",
"translation": "我们这个什么也不做的处理器只是简单地在原始请求上调用`next.handle`,什么也不改动就转发出去。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "This pattern is similar to those in middleware frameworks such as Express.js.",
"translation": "这种工作模式类似于一些框架如Express.js中的中间件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "##### Providing your interceptor",
"translation": "##### 提供你自己的拦截器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Simply declaring the `NoopInterceptor` above doesn't cause your app to use it. You need to wire it up in your app module by providing it as an interceptor, as follows:",
"translation": "像上面这样简单地声明`NoopInterceptor`并不会让我们的应用实际使用它。还要通过把它作为拦截器提供给我们的应用模块才会生效,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Note the `multi: true` option. This is required and tells Angular that `HTTP_INTERCEPTORS` is an array of values, rather than a single value.",
"translation": "注意`multi: true`选项。这是必须的,因为它会告诉 Angular 这个 `HTTP_INTERCEPTORS` 表示的是一个数组,而不是单个的值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "##### Events",
"translation": "##### 事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "You may have also noticed that the Observable returned by `intercept` and `HttpHandler.handle` is not an `Observable<HttpResponse<any>>` but an `Observable<HttpEvent<any>>`. That's because interceptors work at a lower level than the `HttpClient` interface. A single request can generate multiple events, including upload and download progress events. The `HttpResponse` class is actually an event itself, with a `type` of `HttpEventType.HttpResponseEvent`.",
"translation": "注意,`intercept`和`HttpHandler.handle`返回的可观察对象并不是`Observable<HttpResponse<any>>`,而是`Observable<HttpEvent<any>>`。\n这是因为拦截器所工作的层级要低于 `HttpClient` 接口。单个请求会生成多个事件,比如表示上传和下载过程的事件。`HttpResponse`类实际上本身也是一个事件,只是它的`type`是`HttpEventType.HttpResponseEvent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "An interceptor must pass through all events that it does not understand or intend to modify. It must not filter out events it didn't expect to process. Many interceptors are only concerned with the outgoing request, though, and will simply return the event stream from `next` without modifying it.",
"translation": "拦截器必须透传所有它不理解或不打算修改的事件。它不能过滤掉自己不准备处理的事件。很多拦截器只关心要发出的请求,而只简单的返回`next`所返回的事件流,而不修改它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "##### Ordering",
"translation": "##### 顺序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "When you provide multiple interceptors in an application, Angular applies them in the order that you\nprovided them.",
"translation": "当我们在一个应用中提供了多个拦截器时Angular 会按照你提供时的顺序应用它们(译注:即模块的`providers`数组中列出的顺序)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "##### Immutability",
"translation": "##### 不可变性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Interceptors exist to examine and mutate outgoing requests and incoming responses. However, it may be surprising to learn that the `HttpRequest` and `HttpResponse` classes are largely immutable.",
"translation": "拦截器要检查和修改准备发出的请求和接收进来的响应。但是,你可能会惊奇的发现`HttpRequest`和`HttpResponse`类在很大程度上却是不可变的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "This is for a reason: because the app may retry requests, the interceptor chain may process an individual request multiple times. If requests were mutable, a retried request would be different than the original request. Immutability ensures the interceptors see the same request for each try.",
"translation": "这是有原因的:因为应用可能会重发请求,而拦截器链可能会多次处理同一个请求。如果请求是可变的,每次重试时的请求都可能和原始的请求不一样。而不可变对象可以确保拦截器每次重试时处理的都是同一个请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "There is one case where type safety cannot protect you when writing interceptors&mdash;the request body. It is invalid to mutate a request body within an interceptor, but this is not checked by the type system.",
"translation": "在一种情况下类型安全体系无法在写拦截器时提供保护 —— 请求体body。在拦截器中修改请求体本应是无效的但类型检查系统无法发现它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "If you have a need to mutate the request body, you need to copy the request body, mutate the copy, and then use `clone()` to copy the request and set the new body.",
"translation": "如果确实需要修改请求体,我们就得自己复制它,修改这个复本,然后使用`clone()`来复制这个请求,并使用这个新的请求体。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Since requests are immutable, they cannot be modified directly. To mutate them, use `clone()`:",
"translation": "由于请求都是不可变的,所以不能直接修改它们。要想修改,就使用`clone()`函数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "As you can see, the hash accepted by `clone()` allows you to mutate specific properties of the request while copying the others.",
"translation": "如你所见,传给`clone()`函数的这个哈希对象可以让我们在复制时修改请求中的特定属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### Setting new headers",
"translation": "#### 设置新的头",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "A common use of interceptors is to set default headers on outgoing responses. For example, assuming you have an injectable `AuthService` which can provide an authentication token, here is how you would write an interceptor which adds it to all outgoing requests:",
"translation": "拦截器的常见用途之一是为所发出的请求设置默认的请求头。比如,假设我们有一个可注入的`AuthService`,它可以提供一个认证令牌,而我们希望写一个拦截器,它负责把这个令牌添加到所有要发出的请求中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "The practice of cloning a request to set new headers is so common that there's actually a shortcut for it:",
"translation": "这种克隆一个请求并设置一组新的请求头的操作非常常见,因此有了一种快捷写法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "An interceptor that alters headers can be used for a number of different operations, including:",
"translation": "这种可以修改头的拦截器可以用于很多不同的操作,比如:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "* Authentication/authorization",
"translation": "认证 / 授权",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "* Caching behavior; for example, If-Modified-Since",
"translation": "控制缓存行为。比如`If-Modified-Since`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "* XSRF protection",
"translation": "XSRF 防护",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### Logging",
"translation": "#### 记日志",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Because interceptors can process the request and response _together_, they can do things like log or time requests. Consider this interceptor which uses `console.log` to show how long each request takes:",
"translation": "由于拦截器可以同时处理请求和响应,因此可以用来记日志或请求计时等。考虑下面这个拦截器,它使用`console.log`来显示每个请求花了多久:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n \tconst started = Date.now();\n return next\n .handle(req)\n .do(event => {\n if (event instanceof HttpResponse) {\n const elapsed = Date.now() - started;\n console.log(`Request for ${req.urlWithParams} took ${elapsed} ms.`);\n }\n });\n }\n}\n```\nNotice the RxJS `do()` operator&mdash;it adds a side effect to an Observable without affecting the values on the stream. Here, it detects the `HttpResponse` event and logs the time the request took.",
"translation": "注意 RxJS 的 `do()`操作符 —— 它为可观察对象添加一个副作用,而不会影响到流中的值。这里,它会检测`HttpResponse`的事件,并且记录这个请求花费的时间。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### Caching",
"translation": "#### 缓存",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "You can also use interceptors to implement caching. For this example, assume that you've written an HTTP cache with a simple interface:",
"translation": "我们也可以使用拦截器来实现缓存。比如,假设我们已经写了一个 HTTP 缓存,它具有如下的简单接口:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "An interceptor can apply this cache to outgoing requests.",
"translation": "拦截器可以把这个缓存应用到所发出的请求上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Obviously this example glosses over request matching, cache invalidation, etc., but it's easy to see that interceptors have a lot of power beyond just transforming requests. If desired, they can be used to completely take over the request flow.",
"translation": "显然,这个例子忽略了请求匹配、缓存失效等问题,但是很容易看出除了转换请求外,拦截器还有很强力的功能。如果需要,它们可以完全接管请求流程。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "To really demonstrate their flexibility, you can change the above example to return _two_ response events if the request exists in cache&mdash;the cached response first, and an updated network response later.",
"translation": "为了实际演示它们的灵活性,我们可以把上面的例子改为:如果请求已经存在于缓存中了,就返回*两个*响应事件,第一个是缓存的响应,第二个是从网络上更新过来的响应。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Now anyone doing `http.get(url)` will receive _two_ responses if that URL has been cached before.",
"translation": "现在,如果 URL 被缓存过,那么任何人调用`http.get(url)`时都会收到*两次*响应。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Listening to progress events",
"translation": "### 监听进度事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Sometimes applications need to transfer large amounts of data, and those transfers can take time. It's a good user experience practice to provide feedback on the progress of such transfers; for example, uploading files&mdash;and `@angular/common/http` supports this.",
"translation": "有时候应用需要传输一大堆数据,这时传输就需要花一些时间。在这种传输过程中(比如上传文件)给用户一些关于进度的反馈能带来更好的用户体验,而`@angular/common/http`支持它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "To make a request with progress events enabled, first create an instance of `HttpRequest` with the special `reportProgress` option set:",
"translation": "要发起一个支持进度事件的请求,首先要创建一个设置过`reportProgress`选项的`HttpRequest`实例:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "This option enables tracking of progress events. Remember, every progress event triggers\nchange detection, so only turn them on if you intend to actually update the UI on each event.",
"translation": "该选项让我们可以跟踪进度事件。记住,每个进度事件都会触发变更检测,所以应该只有在你真的打算在每个事件中更新 UI 时才打开它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Next, make the request through the `request()` method of `HttpClient`. The result will be an Observable of events, just like with interceptors:",
"translation": "接下来,通过`HttpClient`上的`request()`方法发起这个请求。其结果应该是一个关于事件的可观察对象,就像拦截器中看到的那样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "## Security: XSRF Protection",
"translation": "## 安全XSRF 防护",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"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/content-2/guide/http.md"
},
{
"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/content-2/guide/http.md"
},
{
"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/content-2/guide/http.md"
},
{
"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/content-2/guide/http.md"
},
{
"original": "### Configuring custom cookie/header names",
"translation": "### 配置自定义 cookie/header 名称",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "If your backend service uses different names for the XSRF token cookie or header, use `HttpClientXsrfModule.withOptions()` to override the defaults.",
"translation": "如果我们的后端服务中对 XSRF 令牌的 cookie 或 头使用了不一样的名字,就要使用 `HttpClientXsrfModule.withConfig()` 来覆盖掉默认值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "## Testing HTTP requests",
"translation": "## 测试 HTTP 请求",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Like any external dependency, the HTTP backend needs to be mocked as part of good testing practice. `@angular/common/http` provides a testing library `@angular/common/http/testing` that makes setting up such mocking straightforward.",
"translation": "如同所有的外部依赖一样HTTP 后端也需要在良好的测试实践中被 Mock 掉。`@angular/common/http` 提供了一个测试库 `@angular/common/http/testing`,它让我们可以直截了当的进行这种 Mock 。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Mocking philosophy",
"translation": "### Mock 方法论",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Angular's HTTP testing library is designed for a pattern of testing where the app executes code and makes requests first. After that, tests expect that certain requests have or have not been made, perform assertions against those requests, and finally provide responses by \"flushing\" each expected request, which may trigger more new requests, etc. At the end, tests can optionally verify that the app has made no unexpected requests.",
"translation": "Angular 的 HTTP 测试库是为这种模式的测试而设计的应用执行代码并首先发起请求之后测试代码会期待expect特定的请求发起过或没发起然后对那些请求进行断言最终通过刷新flushing每个被期待的请求来提供响应此后还可能会触发更多新的请求。最后测试代码还可以根据需要去验证应用不曾发起过预期之外的请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Setup",
"translation": "### 初始设置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "To begin testing requests made through `HttpClient`, import `HttpClientTestingModule` and add it to your `TestBed` setup, like so:",
"translation": "要开始测试那些通过`HttpClient`发起的请求,就要导入`HttpClientTestingModule`模块,并把它加到你的`TestBed` 设置里去,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "That's it. Now requests made in the course of your tests will hit the testing backend instead of the normal backend.",
"translation": "这样就可以了。现在,在测试代码中发起的请求将会抵达后端的测试替身,而不是标准后端(真实服务器)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "### Expecting and answering requests",
"translation": "### 期待并回复请求",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "With the mock installed via the module, you can write a test that expects a GET Request to occur and provides a mock response. The following example does this by injecting both the `HttpClient` into the test and a class called `HttpTestingController`",
"translation": "在通过本模块安装了 Mock 之后,我们可以就写一个测试来期待发生一个 GET 请求,并给出一个 Mock 版的响应。\n下列例子通过把 `HttpClient` 同时注入到测试代码和一个名叫`HttpTestingController`的类中来做到这一点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"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/content-2/guide/http.md"
},
{
"original": "#### Custom request expectations",
"translation": "#### 自定义请求的预期",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "If matching by URL isn't sufficient, it's possible to implement your own matching function. For example, you could look for an outgoing request that has an Authorization header:",
"translation": "如果根据 URL 匹配还不满足要求也可以实现我们自己的匹配函数。比如我们可以查找一个具有特定认证Authorization头的对外请求",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "Just as with the `expectOne()` by URL in the test above, if 0 or 2+ requests match this expectation, it will throw.",
"translation": "和前面根据 URL 进行测试时一样,如果零或两个以上的请求匹配上了这个期待,它就会抛出异常。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "#### Handling more than one request",
"translation": "#### 处理一个以上的请求",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"original": "If you need to respond to duplicate requests in your test, use the `match()` API instead of `expectOne()`, which takes the same arguments but returns an array of matching requests. Once returned, these requests are removed from future matching and are your responsibility to verify and flush.",
"translation": "如果我们需要在测试中对重复的请求进行响应,可以使用`match()` API 来代替 `expectOne()`它的参数不变但会返回一个与这些请求相匹配的数组。一旦返回这些请求就会从将来要匹配的列表中移除而验证和刷新flush是我们自己的职责。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/http.md"
},
{
"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 name=\"i18n\">i18n 例子</live-example>作为一个简单的例子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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": "**国际化**工作者通常将一个可翻译的文本叫作“信息”。\n本章使用了“文本”和“信息”它们可以互换也可以组合“文本信息”。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "To mark the greeting for translation, add the `i18n` attribute to the `<h1>` tag.",
"translation": "添加`i18n`属性到该标签上,把它标记为需要翻译的文本。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"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": "在描述的前面,我们为指定的字符串添加一些上下文含义,用`|`将其与描述文字隔开(`<意图>|<描述>`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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": "如果所有地方出现的文本具有**相同**含义时,它们应该有**相同**的翻译,\n但是如果在某些地方它具有**不同含义**,那么它应该有不同的翻译。\nAngular的提取工具在翻译源文件中保留**含义**和**描述**,以支持符合特定上下文的翻译。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a custom-id}\n### Set a custom id for persistence and maintenance",
"translation": "### 设置一个自定义的`id`来提升可搜索性和可维护性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "When you specify a custom id, the extractor tool and compiler generate a translation unit with that\ncustom id.",
"translation": "现在,提取工具和编译器就会用*你的自定义id`生成一个翻译单元,而不会再改变它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "You also can add a meaning, as shown in this example:",
"translation": "下面这个例子带有*含义*和*描述*,最后是`id`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "{@a no-element}\n### Translate text without creating an element",
"translation": "### 翻译文本,而不必创建元素",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "{@a translate-attributes}\n## Add i18n translation attributes",
"translation": "## 添加 *i18n* 翻译属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "This `title` attribute needs to be translated.",
"translation": "这个 `title` 属性也需要翻译。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "{@a plural-ICU}\n## Translate singular and plural",
"translation": "## 处理单数与复数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "Different languages have different pluralization rules.",
"translation": "不同的语言有不同的单复数规则。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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": "假设应用中需要谈论一些狼。\n在英语中根据狼的数量可能要显示为\"no wolves\"、\"one wolf\"、\"two wolves\"或\"a wolf pack\"。\n而在其它语言中则可能会有不同的**基数**规则。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* The first parameter is the key. It is bound to the component property (`minutes`), which determines the number of minutes.",
"translation": "第一个参数是key。它绑定到了组件中表示狼的数量的`wolves`属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* The second parameter identifies this as a `plural` translation type.",
"translation": "第二个参数表示这是一个`plural`(复数)翻译类型。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* The third parameter defines a pluralization pattern consisting of pluralization categories and their matching values.",
"translation": "第三个参数定义了一组复数表示模式,这个模式由复数类别和它们所匹配的值组成。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "Pluralization categories include (depending on the language):",
"translation": "复数类别包括(取决于语言):",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* =0 (or any other number)",
"translation": "=0 (或其它数字)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* zero",
"translation": "zero",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* one",
"translation": "one一个)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* two",
"translation": "two两个",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* few",
"translation": "few少数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* many",
"translation": "many很多",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "After the pluralization category, put the default English text in braces (`{}`).",
"translation": "把默认的*英语*翻译结果放在复数类别之后的括号(`{}`)中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a select-ICU}\n## Select among alternative text messages",
"translation": "## 在候选文本中选择",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "{@a nesting-ICUS}\n## Nesting plural and select ICU expressions",
"translation": "## 把\"复数\"与\"选择\"表达式嵌套在一起",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "You can also nest different ICU expressions together, as shown in this example:",
"translation": "我们也可以把不同的 ICU 表达式嵌套在一起,比如:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a ng-xi18n}\n## Create a translation source file with _ng xi18n_",
"translation": "## 使用_ng-xi18n_工具创建翻译源文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "Use the `ng xi18n` command provided by the CLI to extract the text messages marked with`i18n`into\n a translation source file .",
"translation": "使用`ng-xi18n`提取工具来将带`i18n`标记的文本提取到一个翻译源文件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "{@a other-formats}\n### Other translation formats",
"translation": "### 其它翻译格式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "{@a ng-xi18n-options}\n### Other options",
"translation": "### 其它选项",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "You can specify the output path used by the CLI to extract your translation source file with\nthe parameter `--outputPath`:",
"translation": "我们还可能需要指定其它选项。\n比如如果TypeScript的配置文件`tsconfig.json`位于其它地方而不是根目录,我们就要通过`-p`选项来明确指出它的路径。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a translate}\n## Translate text messages",
"translation": "## 翻译文本信息",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "The `ng xi18n` command generates a translation source file\nnamed `messages.xlf`in the project `src` folder .",
"translation": "`ng xi18n`命令在项目根目录生成一个名为`messages.xlf`的翻译源文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "{@a localization-folder}\n### Create a localization folder",
"translation": "### 新建一个本土化目录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "{@a translate-text-nodes}\n### Translate text nodes",
"translation": "### 翻译文本节点",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "In a large translation project, you wouldsend the `messages.fr.xlf` file to a French translator who would enter the translations\nusing an XLIFF file editor.",
"translation": "在现实世界中,`messages.es.xlf`文件会被发给西班牙语翻译,他们使用<a href=\"https://en.wikipedia.org/wiki/XLIFF#Editors\" target=\"_blank\">这些XLIFF文件编辑器</a>中的一种来翻译它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "This sample file is easy to translate without a special editor or knowledge of French.",
"translation": "我们不需要任何编辑器或者法语知识就可以轻易的翻译本例子文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "To translate a `plural`, translate its ICU format match values:",
"translation": "要翻译一个复数就要翻译它的ICU格式中匹配的值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a translate-select}\n### Translate _select_",
"translation": "### 翻译*选择*select",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "The extraction tool broke that into two translation units because ICU expressions are extracted\nseparately.",
"translation": "提取工具会把它拆成*两个*翻译单元,因为 ICU 表达式是分别提取的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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翻译这段文本并把占位符放在那里。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "Here they are together, after translation:",
"translation": "在翻译之后,它们会放在一起:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a translate-nested}\n### Translate a nested expression",
"translation": "### 翻译嵌套的表达式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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": "嵌套的表达式和前一节没有什么不同。就像上一个例子中那样,我们有*两个*翻译单元。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "The second unit contains the complete nested expression:",
"translation": "第二个包含完整的嵌套表达式:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "And both together:",
"translation": "放在一起时:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a app-pre-translation}\n### The app and its translation file",
"translation": "### 应用及其翻译文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "The sample app and its translation file are now as follows:",
"translation": "下面是例子应用及其翻译文件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a merge}\n## Merge the completed translation file into the app",
"translation": "## 合并已经翻译的文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* The translation file.",
"translation": "翻译文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* The translation file format.",
"translation": "翻译文件的格式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "{@a merge-jit}\n### Merge with the JIT compiler",
"translation": "### 用JiT编译器合并",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "1. Importing the appropriate language translation file as a string constant.",
"translation": "把合适的语言翻译文件导入成一个字符串常量",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "2. Creating corresponding translation providers for the JIT compiler.",
"translation": "为JiT编译器创建相应的翻译提供商。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "3. Bootstrapping the app with those providers.",
"translation": "使用这些提供商来启动应用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "* `TRANSLATIONS` is a string containing the content of the translation file.",
"translation": "`TRANSLATIONS`是含有翻译文件内容的字符串。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlf2`, or `xtb`.",
"translation": "`TRANSLATIONS_FORMAT`是文件的格式: `xlf`、`xlif`或`xtb`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"original": "* `LOCALE_ID` is the locale of the target language.",
"translation": "`LOCALE_ID`是目标语言的语言环境。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/i18n.md"
},
{
"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/content-2/guide/i18n.md"
},
{
"original": "# Angular Language Service",
"translation": "# Angular 语言服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "## Autocompletion",
"translation": "## 自动完成",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "## Error checking",
"translation": "## 错误检查",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "## Navigation",
"translation": "## 导航",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "## Angular Language Service in your editor",
"translation": "## 编辑器中的 Angular 语言服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "### Visual Studio Code",
"translation": "### Visual Studio Code 中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "Then click the install button to install the Angular Language Service.",
"translation": "然后点击安装按钮来安装 Angular 语言服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"original": "### WebStorm",
"translation": "### WebStorm 中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "Here's the dev dependency \nyou need to have in `package.json`:",
"translation": "下面这个开发依赖需要添加到`package.json`中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "*OR*",
"translation": "*或*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"original": "*OR*",
"translation": "*或*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"original": "### Sublime Text",
"translation": "### Sublime Text 编辑器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "Then install the Angular Language Service in the same location:",
"translation": "然后把 Angular 语言服务安装到同一位置:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "Next, in your user preferences (`Cmd+,` or `Ctrl+,`), add:",
"translation": "接下来,在你的用户首选项中(按`Cmd+,`或`Ctrl+,`)添加:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"original": "## Installing in your project",
"translation": "## 安装到工程中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"original": "You can also install Angular Language Service in your project with the \nfollowing `npm` command:",
"translation": "我们还可以使用下列`npm`命令来把 Angular 语言服务安装到工程中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"original": "```sh\nnpm install --save-dev @angular/language-service\n```\nAdditionally, add the following to the `\"compilerOptions\"` section of \nyour project's `tsconfig.json`.",
"translation": "另外,还要在工程的`tsconfig.json`中添加下列`\"compilerOptions\"`区域:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"original": "```json\n \"plugins\": [\n {\"name\": \"@angular/language-service\"}\n ]\n```\nNote 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/content-2/guide/language-service.md"
},
{
"original": "## How the Language Service works",
"translation": "## 语言服务的工作原理",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "## More on Information",
"translation": "## 更多信息",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/language-service.md"
},
{
"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/content-2/guide/language-service.md"
},
{
"original": "# Lifecycle Hooks",
"translation": "# 生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "A component has a lifecycle managed by Angular .",
"translation": "每个组件都有一个被Angular管理的生命周期。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "A directive has the same set of lifecycle hooks, minus the hooks that are specific to component content and views.",
"translation": "除了那些组件内容和视图相关的钩子外,指令有相同生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## Component lifecycle hooks overview",
"translation": "## 组件生命周期钩子概览",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "No directive or component will implement all of the lifecycle hooks and some of the hooks only make sense for components.\nAngular only calls a directive/component hook method *if it is defined*.",
"translation": "没有指令或者组件会实现所有这些接口,并且有些钩子只对组件有意义。只有在指令/组件中*定义过的*那些钩子方法才会被Angular调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## Lifecycle sequence",
"translation": "## 生命周期的顺序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Hook\n </p>",
"translation": "钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Purpose and Timing\n </p>",
"translation": "<p>\n 目的和时机\n </p></th>\n </tr>\n <tr style='vertical-align:top'>\n <td>\n <code>ngOnChanges()</code>\n </td>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Called before `ngOnInit()` and whenever one or more data-bound input properties change.",
"translation": "当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在`ngOnInit()`之前。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_, after the _first_ `ngOnChanges()`.",
"translation": "在第一轮`ngOnChanges()`完成之后调用,只调用**一次**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Detect and act upon changes that Angular can't or won't detect on its own.",
"translation": "检测并在发生Angular无法或不愿意自己检测的变化时作出反应。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Called during every change detection run, immediately after `ngOnChanges()` and `ngOnInit()`.",
"translation": "在每个Angular变更检测周期中调用`ngOnChanges()`和`ngOnInit()`之后。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular projects external content into the component's view.",
"translation": "当把内容投影进组件之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_ after the first `ngDoCheck()`.",
"translation": "第一次`ngDoCheck()`之后调用,只调用一次。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "_A component-only hook_.",
"translation": "**只适用于组件**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular checks the content projected into the component.",
"translation": "每次完成被投影组件内容的变更检测之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Called after the `ngAfterContentInit()` and every subsequent `ngDoCheck()`.",
"translation": "`ngAfterContentInit()`和每次`ngDoCheck()`之后调用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "_A component-only hook_.",
"translation": "**只适合组件**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular initializes the component's views and child views.",
"translation": "初始化完组件视图及其子视图之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_ after the first `ngAfterContentChecked()`.",
"translation": "第一次`ngAfterContentChecked()`之后调用,只调用一次。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "_A component-only hook_.",
"translation": "**只适合组件**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular checks the component's views and child views.",
"translation": "每次做完组件视图和子视图的变更检测之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Called after the `ngAfterViewInit` and every subsequent `ngAfterContentChecked()`.",
"translation": "`ngAfterViewInit()`和每次`ngAfterContentChecked()`之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "_A component-only hook_.",
"translation": "**只适合组件**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Called _just before_ Angular destroys the directive/component.",
"translation": "在Angular销毁指令/组件之前调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## Interfaces are optional (technically)",
"translation": "## 接口是可选的(理论上)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Fortunately, they aren't necessary.",
"translation": "幸运的是,它们并不是必须的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "You don't have to add the lifecycle hook interfaces to directives and components to benefit from the hooks themselves.",
"translation": "我们并不需要在指令和组件上添加生命周期钩子接口就能获得钩子带来的好处。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## Other Angular lifecycle hooks",
"translation": "## 其它生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Other Angular sub-systems may have their own lifecycle hooks apart from these component hooks.",
"translation": "Angular的其它子系统除了有这些组件钩子外还可能有它们自己的生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## Lifecycle examples",
"translation": "## 生命周期练习",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Here's a brief description of each exercise:",
"translation": "下面是每个练习简短的描述:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Component\n </p>",
"translation": "组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Description\n </p>",
"translation": "<p>\n 描述\n </p></th>\n </tr>\n <tr style='vertical-align:top'>\n <td>\n <a href=\"#peek-a-boo\">Peek-a-boo</a>\n </td>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Demonstrates every lifecycle hook.\n Each hook method writes to the on-screen log.",
"translation": "展示每个生命周期钩子,每个钩子方法都会在屏幕上显示一条日志。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Counter",
"translation": "计数器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Demonstrates a combination of a component and a directive\n each with its own hooks.",
"translation": "演示了组件和指令的组合,它们各自有自己的钩子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The remainder of this page discusses selected exercises in further detail.",
"translation": "接下来,我们将详细讨论这些练习。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## Peek-a-boo: all hooks",
"translation": "## Peek-a-boo全部钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The `PeekABooComponent` demonstrates all of the hooks in one component.",
"translation": "`PeekABooComponent`组件演示了组件中所有可能存在的钩子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The sequence of log messages follows the prescribed hook calling order:\n`OnChanges`, `OnInit`, `DoCheck`&nbsp;(3x), `AfterContentInit`, `AfterContentChecked`&nbsp;(3x),\n`AfterViewInit`, `AfterViewChecked`&nbsp;(3x), and `OnDestroy`.",
"translation": "日志信息的日志和所规定的钩子调用顺序是一致的:\n`OnChanges`、`OnInit`、`DoCheck`&nbsp;(3x)、`AfterContentInit`、`AfterContentChecked`&nbsp;(3x)、\n`AfterViewInit`、`AfterViewChecked`&nbsp;(3x)和`OnDestroy`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The next examples focus on hook details.",
"translation": "下一个例子就聚焦于这些钩子的细节上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## Spying *OnInit* and *OnDestroy*",
"translation": "## 窥探*OnInit*和*OnDestroy*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Go undercover with these two spy hooks to discover when an element is initialized or destroyed.",
"translation": "潜入这两个spy钩子来发现一个元素是什么时候被初始化或者销毁的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Kidding aside, pay attention to two key points:",
"translation": "不开玩笑了,注意下面两个关键点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "1. Angular calls hook methods for *directives* as well as components.<br><br>",
"translation": "就像对组件一样Angular也会对*指令*调用这些钩子方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "2. A spy directive can provide insight into a DOM object that you cannot change directly.\nObviously you can't touch the implementation of a native `<div>`.\nYou can't modify a third party component either.\nBut you can watch both with a directive.",
"translation": "一个侦探(spy)指令可以让我们在无法直接修改DOM对象实现代码的情况下透视其内部细节。\n显然你不能修改一个原生`<div>`元素的实现代码。\n你同样不能修改第三方组件。\n但我们用一个指令就能监视它们了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The `ngOnInit()` and `ngOnDestroy()` methods have more vital roles to play in real applications.",
"translation": "在真实的应用程序中,`ngOnInit()`和`ngOnDestroy()`方法扮演着更重要的角色。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "### _OnInit()_",
"translation": "### _OnInit()钩子_",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Use `ngOnInit()` for two main reasons:",
"translation": "使用`ngOnInit()`有两个原因:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "1. To perform complex initializations shortly after construction.",
"translation": "在构造函数之后马上执行复杂的初始化逻辑",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "1. To set up the component after Angular sets the input properties.",
"translation": "在Angular设置完输入属性之后对该组件进行准备。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Experienced developers agree that components should be cheap and safe to construct.",
"translation": "有经验的开发者会认同组件的构建应该很便宜和安全。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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 HeveryAngular项目的头在[这里解释](http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/)了你为什么应该避免复杂的构造函数逻辑。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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) guideshows how.",
"translation": "`ngOnInit()`是组件获取初始数据的好地方。[指南](tutorial/toh-pt4#oninit)中讲解了如何这样做。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "### _OnDestroy()_",
"translation": "### _OnDestroy()钩子_",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Put cleanup logic in `ngOnDestroy()`, the logic that *must* run before Angular destroys the directive.",
"translation": "一些清理逻辑*必须*在Angular销毁指令之前运行把它们放在`ngOnDestroy()`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "This is the time to notify another part of the application that the component is going away.",
"translation": "这是在该组件消失之前,可用来通知应用程序中其它部分的最后一个时间点。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## _OnChanges()_",
"translation": "## _OnChanges()_ 钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive).",
"translation": "一旦检测到该组件(或指令)的***输入属性***发生了变化Angular就会调用它的`ngOnChanges()`方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "This example monitors the `OnChanges` hook.",
"translation": "本例监控`OnChanges`钩子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The example component, `OnChangesComponent`, has two input properties: `hero` and `power`.",
"translation": "这个例子中的`OnChangesComponent`组件有两个输入属性:`hero`和`power`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The host `OnChangesParentComponent` binds to them like this:",
"translation": "宿主`OnChangesParentComponent`绑定了它们,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Here's the sample in action as the user makes changes.",
"translation": "下面是此例子中的当用户做出更改时的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## _DoCheck()_",
"translation": "## _DoCheck()_ 钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Use this method to detect a change that Angular overlooked.",
"translation": "用这个方法来检测那些被Angular忽略的更改。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck()` hook:",
"translation": "*DoCheck*范例通过下面的`ngDoCheck()`实现扩展了*OnChanges*范例:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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&mdash;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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## AfterView",
"translation": "## AfterView 钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Here's a child view that displays a hero's name in an `<input>`:",
"translation": "下面是一个子视图,它用来把英雄的名字显示在一个`<input>`中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The `AfterViewComponent` displays this child view *within its template*:",
"translation": "`AfterViewComponent`把这个子视图显示*在它的模板中*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "### Abide by the unidirectional data flow rule",
"translation": "### 遵循单向数据流规则",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The `doSomething()` method updates the screen when the hero name exceeds 10 characters.",
"translation": "当英雄的名字超过10个字符时`doSomething()`方法就会更新屏幕。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Why does the `doSomething()` method wait a tick before updating `comment`?",
"translation": "为什么在更新`comment`属性之前,`doSomething()`方法要等上一拍(tick)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Here's *AfterView* in action:",
"translation": "这里是*AfterView*的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "## AfterContent",
"translation": "## AfterContent 钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "### Content projection",
"translation": "### 内容投影",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "AngularJS developers know this technique as *transclusion*.",
"translation": "AngularJS的开发者大概知道一项叫做*transclusion*的技术,对,这就是它的马甲。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "Now look at the component's template:",
"translation": "现在来看下`<after-content>`组件的模板:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "The telltale signs of *content projection* are twofold:",
"translation": "下列迹象表明存在着*内容投影*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "* HTML between component element tags.",
"translation": "在组件的元素标签中有HTML",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "* The presence of `<ng-content>` tags in the component's template.",
"translation": "组件的模板中出现了`<ng-content>`标签",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"original": "### AfterContent hooks",
"translation": "### AfterContent钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "* The *AfterContent* hooks concern `ContentChildren`, the child components that Angular\nprojected into the component.",
"translation": "*AfterContent*钩子所关心的是`ContentChildren`这些子组件被Angular投影进该组件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "### No unidirectional flow worries with _AfterContent_",
"translation": "### 使用**AfterContent**时,无需担心单向数据流规则",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"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/content-2/guide/lifecycle-hooks.md"
},
{
"original": "# NgModule FAQs",
"translation": "# Angular 模块常见问题",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "**NgModules** help organize an application into cohesive blocks of functionality.",
"translation": "**Angular模块**可以帮我们把应用组织成一些紧密相关的代码块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The [NgModules](guide/ngmodule) guide takes you step-by-step\nfrom the most elementary `@NgModule` class to a multi-faceted sample with lazy-loaded modules.",
"translation": "[Angular模块](guide/ngmodule)章涵盖了此概念,并带你从最基本的`@NgModule`学到惰性加载模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "This page answers the questions many developers ask about NgModule design and implementation.",
"translation": "*这里*回答的是开发者常问起的关于Angular模块的设计与实现问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "These FAQs assume that you have read the [NgModules](guide/ngmodule) guide.",
"translation": "本《Angular模块常见问题》假设你已经读完了[Angular模块](guide/ngmodule)章。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What classes should I add to _declarations_?",
"translation": "## 我应该把哪些类加到*declarations*中?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Add [declarable](guide/ngmodule-faq#q-declarable) classes&mdash;components, directives, and pipes&mdash;to a `declarations` list.",
"translation": "把[可声明](guide/ngmodule-faq#q-declarable)的类(组件、指令和管道)添加到`declarations`列表中。Declare these classes in _exactly one_ NgModule.\nDeclare them in _this_ NgModule if they _belong_ to this module.\n这些类只能在应用程序的*一个并且只有一个*模块中声明。\n只有当它们*从属于*某个模块时,才能把在*此*模块中声明它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What is a _declarable_?",
"translation": "## 什么是*可声明的*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Declarables are the class types&mdash;components, directives, and pipes&mdash;that\nyou can add to an NgModule's `declarations` list.\nThey're the _only_ classes that you can add to `declarations`.",
"translation": "*可声明的*就是组件、指令和管道等可以被加到模块的`declarations`列表中的类。它们也是*所有*能被加到`declarations`中的类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What classes should I _not_ add to _declarations_?",
"translation": "## 哪些类*不*应该加到`declarations`中?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Add only [declarable](guide/ngmodule-faq#q-declarable) classes to an NgModule's `declarations` list.",
"translation": "只有[可声明的](guide/ngmodule-faq#q-declarable)类才能加到模块的`declarations`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Do *not* declare the following:",
"translation": "*不要*声明:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* A class that's already declared in another NgModule.",
"translation": "已经在其它模块中声明过的类。无论它来自应用自己的模块(@NgModule还是第三方模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* An array of directives imported from another NgModule.\nFor example, don't declare FORMS_DIRECTIVES from `@angular/forms`.",
"translation": "从其它模块中导入的指令。例如,不要声明来自`@angular/forms`的FORMS_DIRECTIVES。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* NgModule classes.",
"translation": "模块类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Service classes.",
"translation": "服务类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Why list the same component in multiple _@NgModule_ properties?",
"translation": "## 为什么要把同一个组件声明在不同的*NgModule*属性中?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "`AppComponent` is often listed in both `declarations` and `bootstrap`.\nYou might see `HeroComponent` listed in `declarations`, `exports`, and `entryComponents`.",
"translation": "我们经常看到`AppComponent`被同时列在`declarations`和`bootstrap`中。\n 我们还可能看到`HeroComponent`被同时列在`declarations`、`exports`和`entryComponent`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "* `AppComponent` could be declared in this module but not bootstrapped.",
"translation": "`AppComponent`可能被声明在此模块中,但可能不是引导组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* `AppComponent` could be bootstrapped in this module but declared in a different feature module.",
"translation": "`AppComponent`可能在此模块中引导,但可能是由另一个特性模块声明的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* `HeroComponent` could be imported from another application module (so you can't declare it) and re-exported by this module.",
"translation": "`HeroComponent`可能是从另一个应用模块中导入的(所以我们没法声明它)并且被当前模块重新导出。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* `HeroComponent` 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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "You also get this error if \"x\" really isn't a property or if \"x\" is a private component property (i.e., lacks the `@Input` or `@Output` decorator).",
"translation": "如果“x”其实不是属性或者是组件的私有属性比如它不带 `@Input` 或 `@Output` 装饰器),那么你也同样会遇到这个错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "For example, if \"x\" is `ngModel`, you may not have imported the `FormsModule` from `@angular/forms`.",
"translation": "比如如果这个“x”是`ngModel`,你可能忘了从`@angular/forms`中导入`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Perhaps you declared \"x\" in an application feature module but forgot to export it?\nThe \"x\" class isn't visible to other components of other NgModules until you add it to the `exports` list.",
"translation": "也可能你在该应用的特性模块中声明了“x”但是忘了从那个模块导出它。\n除非你把这个“x”类加入了`exports`列表中,否则它对其它模块将是不可见的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What should I import?",
"translation": "## 我应该导入什么?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Import NgModules whose public (exported) [declarable classes](guide/ngmodule-faq#q-declarable)\nyou need to reference in this module's component templates.",
"translation": "一句话:导入你需要在当前模块的组件模板中使用的那些公开的(被导出的)[可声明类](guide/ngmodule-faq#q-declarable)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Import _shared_ and _feature_ modules when this module's components incorporate their\ncomponents, directives, and pipes.",
"translation": "如果当前模块中的组件包含了*共享*模块和*特性*模块中的组件、指令和管道,就导入这些模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Should I import _BrowserModule_ or _CommonModule_?",
"translation": "## 我应该导入*BrowserModule*还是*CommonModule*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "`BrowserModule` provides services that are essential to launch and run a browser app.",
"translation": "`BrowserModule`提供了启动和运行浏览器应用的那些基本的服务提供商。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "_Do not import_ `BrowserModule` in any other NgModule.\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/content-2/guide/ngmodule-faq.md"
},
{
"original": "`BrowserModule` throws an error if you try to lazy load a module that imports it.",
"translation": "如果你在惰性加载模块中导入`BrowserModule`Angular就会抛出一个错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Importing `CommonModule` also frees feature modules for use on _any_ target platform, not just browsers.",
"translation": "特性模块中导入`CommonModule`可以让它能用在任何目标平台上,不仅是浏览器。那些跨平台库的作者应该喜欢这种方式的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What if I import the same NgModule twice?",
"translation": "## 如果我两次导入同一个模块会怎么样?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "That's not a problem. When three NgModules 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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What should I export?",
"translation": "## 我应该导出什么?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Export [declarable](guide/ngmodule-faq#q-declarable) classes that components in _other_ NgModules\nare able to reference in their templates. These are your _public_ classes.\nIf you don't export a class, it stays _private_, visible only to other component\ndeclared in this NgModule.",
"translation": "导出那些*其它模块*希望在自己的模板中引用的[可声明类](guide/ngmodule-faq#q-declarable)。这些也是你的*公开*类。\n如果你不导出某个类它就是*私有的*,只对当前模块中声明的其它组件可见。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "You _can_ export any declarable class&mdash;components, directives, and pipes&mdash;whether\nit's declared in this NgModule or in an imported NgModule.",
"translation": "你*可以*导出任何可声明类组件、指令和管道而不用管它是声明在当前模块中还是某个导入的模块中。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.\n你*可以*重新导出整个导入过的模块,这将导致重新导出它们导出的所有类。模块甚至还可以导出它未曾导入过的模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What should I *not* export?",
"translation": "## 我*不应该*导出什么?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Don't export the following:",
"translation": "*不要*导出:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Non-declarable objects such as services, functions, configurations, and entity models.",
"translation": "不可声明的对象,比如服务、函数、配置、实体模型等。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Pure service modules that don't have public (exported) declarations.\nFor example, there's no point in re-exporting `HttpModule` because it doesn't export anything.\nIt's only purpose is to add http service providers to the application as a whole.",
"translation": "纯服务模块没有公开(导出)的声明。\n 例如,没必要重新导出`HttpModule`,因为它不导出任何东西。\n 它唯一的用途是一起把http的那些服务提供商添加到应用中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Can I re-export classes and NgModules?",
"translation": "## 我可以重新导出类和模块吗?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Absolutely.",
"translation": "毫无疑问!",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "An NgModule can export a combination of its own declarations, selected imported classes, and imported NgModules.",
"translation": "模块还能导出一个组合,它可以包含自己的声明、某些导入的类以及导入的模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Don't bother re-exporting pure service modules.\nPure service modules don't export [declarable](guide/ngmodule-faq#q-declarable) classes that another NgModule could use.\nFor example, there's no point in re-exporting `HttpModule` because it doesn't export anything.\nIt's only purpose is to add http service providers to the application as a whole.",
"translation": "不要费心去导出纯服务类。\n纯服务类的模块不会导出任何可供其它模块使用的[可声明类](guide/ngmodule-faq#q-declarable)。\n例如不用重新导出`HttpModule`,因为它没有导出任何东西。\n它唯一的用途是把那些http服务提供商一起添加到应用中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What is the _forRoot_ method?",
"translation": "## *forRoot*方法是什么?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Only call and import a `.forRoot` result in the root application NgModule, `AppModule`.\nImporting it in any other NgModule, particularly in a lazy-loaded NgModule,\nis contrary to the intent and will likely produce a runtime error.",
"translation": "只能在应用的根模块`AppModule`中调用并导入`.forRoot`的结果。\n在其它模块中导入它特别是惰性加载模块中是违反设计目标的并会导致一个运行时错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "`RouterModule` also offers a `forChild` static method for configuring the routes of lazy-loaded modules.",
"translation": "`RouterModule`也提供了静态方法`forChild`,用于配置惰性加载模块的路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Why is a service provided in a feature module visible everywhere?",
"translation": "## 为什么服务提供商在特性模块中的任何地方都是可见的?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "This makes the provider visible to every class in the application that knows the provider's lookup token.",
"translation": "这会让该提供商对应用中所有知道该提供商令牌token的类都可见。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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 `HttpModule` once, every application component can make http requests.",
"translation": "Angular就是如此设计的。\n通过模块导入来实现可扩展性是Angular模块系统的主要设计目标。\n把模块的提供商并入应用程序的注入器可以让库模块使用新的服务来强化应用程序变得更容易。\n只要添加一次`HttpModule`那么应用中的每个组件就都可以发起Http请求了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Why is a service provided in a _lazy-loaded_ NgModule visible only to that module?",
"translation": "## 为什么在惰性加载模块中声明的服务提供商只对该模块自身可见?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Unlike providers of the NgModules loaded at launch,\nproviders of lazy-loaded modules are *module-scoped*.",
"translation": "和启动时就加载的模块中的提供商不同,惰性加载模块中的提供商是*局限于模块*的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What if two NgModules provide the same service?",
"translation": "## 如果两个模块提供了*同一个*服务会怎么样?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "When two imported NgModules, 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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## How do I restrict service scope to an NgModule?",
"translation": "## 我们应该如何把服务的范围限制到模块中?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "When an NgModule 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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "As a general rule, import NgModules 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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Suppose an NgModule requires a customized `HttpBackend` that adds a special header for all Http requests.\nIf another NgModule elsewhere in the application also customizes `HttpBackend`\nor merely imports the `HttpModule`, 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`或仅仅导入了`HttpModule`,它就会改写当前模块的`HttpBackend`提供商,丢掉了这个特别的请求头。\n 这样服务器就会拒绝来自该模块的请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "To avoid this problem, import the `HttpModule` only in the `AppModule`, the application _root module_.",
"translation": "要消除这个问题,就只能在应用的根模块`AppModule`中导入`HttpModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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 NgModules do to `HttpBackend`.",
"translation": "当该组件的子组件*想要*一个`HttpBackend`服务时Angular会提供一个局部的`HttpBackend`服务,而不是应用的根注入器创建的那个。\n子组件将正确发起http请求而不管其它模块对`HttpBackend`做了什么。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Be sure to create module components as children of this module's top component.",
"translation": "确保把模块中的组件都创建成这个顶级组件的子组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Should I add application-wide providers to the root _AppModule_ or the root _AppComponent_?",
"translation": "## 我应该把全应用级提供商添加到根模块`AppModule`中还是根组件`AppComponent`中?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Register application-wide providers in the root `AppModule`, not in the `AppComponent`.",
"translation": "在根模块`AppModule`中注册全应用级提供商,而不是`AppComponent`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Discussion",
"translation": "讨论",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Angular registers all startup NgModule providers with the application root injector.\nThe services created from root injector providers are available to the entire application.\nThey are _application-scoped_.",
"translation": "Angular把所有启动期模块的提供商都注册进了应用的根注入器中。\n这些服务是由根注入器中的提供商创建的并且在整个应用中都可用。\n它们具有*应用级作用域*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Certain services (such as the `Router`) only work when registered in the application root injector.",
"translation": "某些服务(比如`Router`)只有当注册进应用的根注入器时才能正常工作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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 are _component-scoped_.",
"translation": "相反Angular使用`AppComponent`自己的注入器注册了`AppComponent`的提供商。\n`AppComponent`服务只在该组件及其子组件树中才能使用。\n它们具有*组件级作用域*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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 for routed applications, \"almost\" isn't good enough.",
"translation": "`AppComponent`的注入器是根注入器的*子级*,注入器层次中的下一级。\n这对于没有路由器的应用来说*几乎是*整个应用了。\n但这个“几乎”对于带路由的应用仍然是不够的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "`AppComponent` services don't exist at the root level where routing operates.\nLazy-loaded modules can't reach them.\nIn the [_NgModules_ sample application](guide/ngmodule), if you had registered `UserService` in the `AppComponent`,\nthe `HeroComponent` couldn't inject it.\nThe application would fail the moment a user navigated to \"Heroes\".",
"translation": "当有路由时,`AppComponent`服务并不在根部。\n惰性加载的模块就不能用它们。\n在“Angular模块”章的范例应用中如果我们在`AppComponent`中注册`UserService`,那么`HeroComponent`就不能注入它。\n一旦用户导航到“Heroes”特性区该应用就会失败。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "{@a q-component-or-module}",
"translation": "## Should I add other providers to an NgModule or a component?## 我应该把其它提供商注册到模块中还是组件中?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "In general, prefer registering feature-specific providers in NgModules (`@NgModule.providers`)\nto registering in components (`@Component.providers`).",
"translation": "通常,优先把模块中具体特性的提供商注册到模块中(`@NgModule.providers`),而不是组件中(`@Component.providers`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "For example, a hero editing component that needs a private copy of a caching hero service should register\nthe `HeroService` with the `HeroEditorComponent`.\nThen each new instance of the `HeroEditorComponent` gets its own cached service instance.\nThe changes that editor makes to heroes in its service don't touch the hero instances elsewhere in the application.",
"translation": "例如,如果英雄编辑组件需要自己私有的缓存英雄服务实例,那么我们应该把`HeroService`注册进`HeroEditorComponent`中。\n这样每个新的`HeroEditorComponent`的实例都会得到一份自己的缓存服务实例。\n编辑器的改动只会作用于它自己的服务而不会影响到应用中其它地方的英雄实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Why is it bad if _SharedModule_ provides a service to a lazy-loaded NgModule?",
"translation": "## 为什么*SharedModule*为惰性加载模块提供服务是个馊主意?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "This question is addressed in the [Why UserService isn't shared](guide/ngmodule#no-shared-module-providers)\nsection of the [NgModules](guide/ngmodule) guide,\nwhich discusses the importance of keeping providers out of the `SharedModule`.",
"translation": "这个问题在[Angular模块](guide/ngmodule)一章的[为何UserService不是共享的](guide/ngmodule#no-shared-module-providers)部分出现过,\n那时我们在讨论不要把提供商放进`SharedModule`的重要性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Suppose the `UserService` was listed in the NgModule's `providers` (which it isn't).\nSuppose every NgModule imports this `SharedModule` (which they all do).",
"translation": "假设把`UserService`列在了模块的`providers`中(我们没有这么做)。\n假设每个模块都导入了这个`SharedModule`(我们是这么做的)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "When the app starts, Angular eagerly loads the `AppModule` and the `ContactModule`.",
"translation": "当应用启动时Angular主动加载了`AppModule`和`ContactModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Both instances of the imported `SharedModule` would provide the `UserService`.\nAngular registers one of them in the root app injector (see [What if I import the same NgModule twice?](guide/ngmodule-faq#q-reimport)).\nThen some component injects `UserService`, Angular finds it in the app root injector,\nand delivers the app-wide singleton `UserService`. No problem.",
"translation": "导入的`SharedModule`的每个实例都会提供`UserService`。\nAngular把它们中的一个注册进了应用的根注入器中参见[如果同一个模块被导入两次会怎么样?](guide/ngmodule-faq#q-reimport))。\n然后某些组件要求注入`UserService`Angular就会在应用的根注入器中查找它并交付一个全应用级的单例对象`UserService`。这没问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Now consider the `HeroModule` _which is lazy-loaded_.",
"translation": "现在,该考虑`HeroModule`了,*它是惰性加载的!*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "When the router lazy loads the `HeroModule`, 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/content-2/guide/ngmodule-faq.md"
},
{
"original": "When Angular creates a lazy `HeroComponent`, it must inject a `UserService`.\nThis time it 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/content-2/guide/ngmodule-faq.md"
},
{
"original": "That's almost certainly a mistake.",
"translation": "这绝对是一个错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "To demonstrate, run the <live-example name=\"ngmodule\">live example</live-example>.\nModify the `SharedModule` so that it provides the `UserService` rather than the `CoreModule`.\nThen toggle between the \"Contact\" and \"Heroes\" links a few times.\nThe username flashes irregularly as the Angular creates a new `UserService` instance each time.",
"translation": "自己验证一下吧。\n运行这个<live-example name=\"ngmodule\">在线例子</live-example>。\n修改`SharedModule`,由它来提供`UserService`而不再由`CoreModule`。\n然后在“Contact”和“Heroes”链接之间切换几次。\n由于Angular每次都创建一个新的`UserService`实例,所以用户名变得不正常了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Why does lazy loading create a child injector?",
"translation": "## 为什么惰性加载模块会创建一个子注入器?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## How can I tell if an NgModule or service was previously loaded?",
"translation": "## 我要如何知道一个模块或服务是否已经加载过了?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Certain NgModules (such as `BrowserModule`) implement such a guard,\nsuch as this `CoreModule` constructor.",
"translation": "某些Angular模块例如`BrowserModule`)就实现了一个像 Angular 模块那一章的`CoreModule`构造函数那样的守卫。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What is an _entry component_?",
"translation": "## 什么是*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "An entry component is any component that Angular loads _imperatively_ by type.",
"translation": "Angular根据其类型*不可避免地*加载的组件是*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A component loaded _declaratively_ via its selector is _not_ an entry component.",
"translation": "而通过组件选择器*声明式*加载的组件则*不是*入口组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Most application components are loaded declaratively.\nAngular uses the component's selector to locate the element in the template.\nIt then creates the HTML representation of the component and inserts it into the DOM at the selected element.\nThese aren't entry components.",
"translation": "大多数应用组件都是声明式加载的。\nAngular使用该组件的选择器在模板中定位元素然后创建表现该组件的HTML并把它插入DOM中所选元素的内部。它们不是入口组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A few components are only loaded dynamically and are _never_ referenced in a component template.",
"translation": "也有少量组件只会被动态加载,并且*永远不会*被组件的模板所引用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Angular loads `AppComponent` dynamically because it's either listed _by type_ in `@NgModule.bootstrap`\nor bootstrapped imperatively with the NgModule's `ngDoBootstrap` method.",
"translation": "Angular总是会动态加载`AppComponent` —— 无论把它的*类型*列在了`@NgModule.bootstrap`函数中,还是命令式的调用该模块的`ngDoBootstrap`方法来引导它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "The compiler can't discover these _entry components_ by looking for them in other component templates.\nYou must tell it about them by adding them to the `entryComponents` list.",
"translation": "编译器无法通过在其它组件的模板中查找来发现这些*入口组件*。\n 我们必须通过把它们加入`entryComponents`列表中来让编译器知道它们的存在。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Angular automatically adds the following types of components to the NgModule's `entryComponents`:",
"translation": "Angular会自动把下列类型的组件添加到模块的`entryComponents`中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* The component in the `@NgModule.bootstrap` list.",
"translation": "那些出现在`@NgModule.bootstrap`列表中的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Components referenced in router configuration.",
"translation": "那些被路由定义引用的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "You don't have to mention these components explicitly, although doing so is harmless.",
"translation": "我们并不需要显式的引用这些组件 —— 虽然引用了也没坏处。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What's the difference between a _bootstrap_ component and an _entry component_?",
"translation": "### *引导组件*和*入口组件*有什么不同?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A bootstrapped component _is_ an [entry component](guide/ngmodule-faq#q-entry-component-defined)\nthat Angular loads into the DOM during the bootstrap (application launch) process.\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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "There's no need to list a component in both the `bootstrap` and `entryComponent` lists,\nalthough doing so is harmless.",
"translation": "不需要把组件同时列在`bootstrap`和`entryComponent`列表中 —— 虽然这样做也没坏处。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## When do I add components to _entryComponents_?",
"translation": "## 什么时候我应该把组件加到`entryComponents`中?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Most application developers won't need to add components to the `entryComponents`.",
"translation": "大多数应用开发者都不需要把组件添加到`entryComponents`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## Why does Angular need _entryComponents_?",
"translation": "## 为什么Angular需要*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "_Entry components_ are also declared.\nWhy doesn't the Angular compiler generate code for every component in `@NgModule.declarations`?\nThen you wouldn't need entry components.",
"translation": "*入口组件*也是被声明的。\n为什么Angular编译器不为`@NgModule.declarations`中的每个组件都生成一份代码呢?那样就不需要入口组件了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The reason is _tree shaking_. For production apps you want to load the smallest, fastest code possible.\nThe 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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "If the [Angular compiler](guide/ngmodule-faq#q-angular-compiler) generated code for every declared component,\nit would defeat the purpose of the tree shaker.",
"translation": "如果[Angular编译器](guide/ngmodule-faq#q-angular-compiler)为每个声明的组件都生成了代码,那么摇树优化器的作用就没有了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Instead, the compiler adopts a recursive strategy that generates code only for the components you use.",
"translation": "所以,编译器转而采用一种递归策略,它只为我们用到的那些组件生成代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What kinds of NgModules should I have and how should I use them?",
"translation": "## 有哪些类型的模块?我应该如何使用它们?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Every app is different. Developers have various levels of experience and comfort with the available choices.\nThe following suggestions and guidelines have wide appeal.",
"translation": "每个应用都不一样。根据不同程度的经验,开发者会做出不同的选择。下列建议和指导原则广受欢迎。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Create a `SharedModule` with the components, directives, and pipes that you use\neverywhere in your app. This NgModule should consist entirely of `declarations`,\nmost of them exported.",
"translation": "为那些可能会在应用中到处使用的组件、指令和管道创建`SharedModule`。\n 这种模块应该只包含`declarations`,并且应该导出几乎所有`declarations`里面的声明。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The `SharedModule` may re-export other [widget modules](guide/ngmodule-faq#widget-feature-module), such as `CommonModule`,\n`FormsModule`, and NgModules with the UI controls that you use most widely.",
"translation": "`SharedModule`可以重新导出其它[小部件模块](guide/ngmodule-faq#widget-feature-module),比如`CommonModule`、`FormsModule`和提供你广泛使用的UI控件的那些模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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 NgModules have `providers`.\nIf you deviate from this guideline, know what you're doing and why.",
"translation": "`SharedModule`***不应该***带有`providers`,原因[在前面解释过了](guide/ngmodule-faq#q-why-bad)。\n它的导入或重新导出的模块中也不应该有`providers`。\n如果你要违背这条指导原则请务必想清楚你在做什么并要有充分的理由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Create a `CoreModule` with `providers` for the singleton services you load when the application starts.",
"translation": "为你要在应用启动时加载的那些服务创建一个带`providers`的`CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Consider making `CoreModule` a [pure services module](guide/ngmodule-faq#service-feature-module) with no `declarations`.",
"translation": "考虑把`CoreModule`做成一个没有`declarations`的[纯服务模块](guide/ngmodule-faq#service-feature-module)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "This page sample departs from that advice by declaring and exporting two components that are\nonly used within the root `AppComponent` declared by `AppModule`.\nSomeone following this guideline strictly would have declared these components in the `AppModule` instead.",
"translation": "这里的范例违背了此建议,它声明和导出了两个只用在`AppModule`模块的`AppComponent`组件中的组件。\n如果你想严格遵循这条指南应该把这两个组件改为声明在`AppModule`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "### Feature Modules",
"translation": "### 特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Create feature modules around specific application business domains, user workflows, and utility collections.",
"translation": "围绕特定的业务领域、工作流和工具集来为应用创建*特性模块*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Feature modules tend to fall into one of the following groups:",
"translation": "特性模块一般可分成下面这几种:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* [Domain feature modules](guide/ngmodule-faq#domain-feature-module).",
"translation": "[领域特性模块](guide/ngmodule-faq#domain-feature-module)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* [Routed feature modules](guide/ngmodule-faq#routed-feature-module)",
"translation": "[带路由的特性模块](guide/ngmodule-faq#routed-feature-module)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* [Routing modules](guide/ngmodule-faq#routing-module)",
"translation": "[路由模块](guide/ngmodule-faq#routing-module)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* [Service feature modules](guide/ngmodule-faq#service-feature-module)",
"translation": "[服务特性模块](guide/ngmodule-faq#service-feature-module)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* [Widget feature modules](guide/ngmodule-faq#widget-feature-module).",
"translation": "[窗口部件特性模块](guide/ngmodule-faq#widget-feature-module)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Real-world NgModules are often hybrids that purposefully deviate from the following guidelines.\nThese guidelines are not laws;\nfollow them unless you have a good reason to do otherwise.",
"translation": "真实世界中的模块通常会偏离这些指导原则,而混杂多种不同的类型。\n这些只是指导原则不是硬性要求。\n但除非你有充分的理由不这么做最好还是遵循它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Feature Module",
"translation": "特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Guidelines",
"translation": "指导原则",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a domain-feature-module}\n <p>\n Domain\n </p>",
"translation": "领域",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Domain feature modules deliver a user experience *dedicated to a particular application domain*\n like editing a customer or placing an order.",
"translation": "领域特性模块**专注于一个特定的应用领域**来提供用户体验,比如编辑消费者信息或下订单。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "They typically have a top component that acts as the feature root.\n Private, supporting sub-components descend from it.",
"translation": "它们通常有一个顶级组件,并作为该特性的根组件。\n 内部则是它的一些子组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Domain feature modules consist mostly of _declarations_.\n Only the top component is exported.",
"translation": "领域特性模块几乎总是由`declarations`构成。只有顶级组件会被导出。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Domain feature modules rarely have _providers_.\n When they do, the lifetime of the provided services\n should be the same as the lifetime of the module.",
"translation": "领域特性模块很少会有`providers`。\n 如果要这么做,那它们所提供服务的生命周期就应该与该模块的生命周期相同。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Don't provide application-wide singleton services in a domain feature module.",
"translation": "不要在领域特性模块中提供全应用级的单例服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Domain feature modules are typically imported _exactly once_ by a larger feature module.",
"translation": "领域特性模块的典型用法是*只被*更大的特性模块*导入一次*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "They might be imported by the root `AppModule` of a small application that lacks routing.",
"translation": "对于缺少路由的小型应用,它们可能只会被根模块`AppModule`导入一次。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "For an example, see the [Feature Modules](guide/ngmodule#contact-module-v1)\n section of the [NgModules](guide/ngmodule) guide, before routing is introduced.",
"translation": "比如[Angular模块](guide/ngmodule)章的[_ContactModule_](guide/ngmodule#contact-module-v1)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a routed-feature-module}\n <p>\n Routed\n </p>",
"translation": "路由特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "_Routed feature modules_ are _domain feature modules_\n whose top components are the *targets of router navigation routes*.",
"translation": "*路由特性模块*属于*领域特性模块*的一种,它的顶层组件是**路由器导航时的路由目标**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "All lazy-loaded modules are routed feature modules by definition.",
"translation": "根据这个定义,所有惰性加载的模块都是路由特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "This page's `ContactModule`, `HeroModule`, and `CrisisModule` are routed feature modules.",
"translation": "这里的`ContactModule`、`HeroModule`和`CrisisModule`都是路由特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Routed feature modules _shouldn't export anything_.\n They don't have to because their components never appear in the template of an external component.",
"translation": "路由特性模块*不应该导出任何东西*,这是因为它们中的任何组件都不可能出现在外部组件的模板中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A lazy-loaded routed feature module should _not be imported_ by any NgModule.\n Doing so would trigger an eager load, defeating the purpose of lazy loading.\n `HeroModule` and `CrisisModule` are lazy-loaded. They aren't mentioned among the `AppModule` imports.",
"translation": "惰性加载的路由特性模块也不应该被任何模块*导出*。\n 那么做会触发一次主动加载,破坏了我们惰性加载的目的。\n `HeroModule`和`CrisisModule`是惰性加载的。它们没有出现在`AppModule`的`imports`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "But an eagerly loaded, routed feature module must be imported by another NgModule\n so that the compiler learns about its components.\n `ContactModule` is eager loaded and therefore listed among the `AppModule` imports.",
"translation": "而主动加载的路由特性模块必须被其它模块导入,以便编译器了解它有哪些组件。\n `ContactModule`就是主动加载的,因此它也被列在了`AppModule`的`imports`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Routed Feature Modules rarely have _providers_ for reasons [explained earlier](guide/ngmodule-faq#q-why-bad).\n When they do, the lifetime of the provided services\n should be the same as the lifetime of the NgModule.",
"translation": "路由特性模块很少会有`providers`,理由[前面解释过](guide/ngmodule-faq#q-why-bad)。\n 如果要那么做,它所提供的服务就应该与模块具有相同的生命周期。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Don't provide application-wide singleton services in a routed feature module\n or in an NgModule that the routed module imports.",
"translation": "不要在路由特性模块及其导入的模块中提供*全应用级*的单例服务。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a routing-module}\n <p>\n Routing\n </p>",
"translation": "路由模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A [routing module](guide/router#routing-module) *provides routing configuration* for another NgModule.",
"translation": "[路由模块](guide/router#routing-module)为其它模块**提供路由配置**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A routing module separates routing concerns from its companion module.",
"translation": "路由模块将路由配置从它的关联模块分离开来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A routing module typically does the following:",
"translation": "路由模块通常会做这些:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Defines routes.",
"translation": "定义路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Adds router configuration to the module's `imports`.",
"translation": "添加路由配置到模块的`imports`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Re-exports `RouterModule`.",
"translation": "重新导出`RouterModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Adds guard and resolver service providers to the module's `providers`.",
"translation": "添加守卫和解析器服务提供商到模块的`providers`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The name of the routing module should parallel the name of its companion module, using the suffix \"Routing\".\n For example, `FooModule` in `foo.module.ts` has a routing module named `FooRoutingModule`\n in `foo-routing.module.ts`",
"translation": "路由模块的名字应该和它的关联模块平行比如使用“Routing”前缀\n `foo.module.ts`中的`FooModule`有名为`FooRoutingModule`的路由模块,所属文件名为`foo-routing.module.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "If the companion module is the _root_ `AppModule`, \n the `AppRoutingModule` adds router configuration to its `imports` with `RouterModule.forRoot(routes)`. \n All other routing modules are children that import `RouterModule.forChild(routes)`.",
"translation": "如果关联模块是**根**`AppModule`,那么在`AppRoutingModule`的`imports`中,添加`RouterModule.forRoot(routes)`来配置路由。\n 所有其它路由模块都是子级,导入`RouterModule.forChild(routes)`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A routing module re-exports the `RouterModule` as a convenience\n so that components of the companion module have access to\n router directives such as `RouterLink` and `RouterOutlet`.",
"translation": "路由模块顺便重新导出`RouterModule`,这样关联模块的组件可以访问路由指令,比如`RouterLink`和`RouterOutlet`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A routing module *should not have its own `declarations`*. \n Components, directives, and pipes are the *responsibility of the feature module*,\n not the _routing_ module.",
"translation": "路由模块**不应该有自己的`declarations`**。组件、指令和管道是**特性模块的责任**,不属于路由模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A routing module should _only_ be imported by its companion module.",
"translation": "路由模块应该**只**被它的关联模块导入。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The `AppRoutingModule`, `ContactRoutingModule`, and `HeroRoutingModule` are good examples.",
"translation": "`AppRoutingModule`、`ContactRoutingModule`和`HeroRoutingModule是很好的例子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "See also [Do you need a _Routing Module_?](guide/router#why-routing-module) on the\n [Routing & Navigation](guide/router) page.",
"translation": "参见[路由与导航](guide/router)一章的“[你需要**路由模块**吗?](guide/router#why-routing-module)”部分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a service-feature-module}\n <p>\n Service\n </p>",
"translation": "服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Service modules *provide utility services* such as data access and messaging.",
"translation": "*服务模块*用于**提供工具类服务**,比如数据访问和消息等。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Ideally, they consist entirely of _providers_ and have no _declarations_.\n The `CoreModule` and Angular's `HttpModule` are good examples.",
"translation": "理想情况下,它们应该完全由`providers`组成,不应该包括`declarations`。\n `CoreModule`和Angular的`HttpModule`就是很好的例子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Service Modules should _only_ be imported by the root `AppModule`.",
"translation": "服务模块应该*只被*根模块`AppModule`导入。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Do *not* import service modules in other feature modules.\n If you deviate from this guideline, know what you're doing and why.",
"translation": "*不要*在任何特性模块中导入它们。\n 如果你要违背这条指导原则,请务必想清楚你在做什么,并要有充分的理由。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a widget-feature-module}\n <p>\n Widget\n </p>",
"translation": "窗口部件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A widget module makes *components, directives, and pipes* available to external NgModules.",
"translation": "*窗口部件*模块导出能用供外部模块使用的**组件、指令和管道**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "`CommonModule` and `SharedModule` are widget modules.\n Many third-party UI component libraries are widget modules.",
"translation": "`CommonModule`和`SharedModule`都是窗口部件模块。\n 很多第三方UI组件库都是窗口部件模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A widget module should consist entirely of _declarations_, most of them exported.",
"translation": "部件模块应该只有`declarations`,并导出里面的绝大多数声明。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A widget module should rarely have _providers_.\n If you deviate from this guideline, know what you're doing and why.",
"translation": "窗口部件模块很少会有`providers`。\n 如果你要违背这条指导原则,请务必想清楚你在做什么,并要有充分的理由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Import widget modules in any module whose component templates need the widgets.",
"translation": "如果任何模块的组件模板中需要用到这些窗口部件,就请导入相应的窗口部件模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The following table summarizes the key characteristics of each _feature module_ group.",
"translation": "下表是对各种*特性模块*的关键特征汇总。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Real-world NgModules are often hybrids that knowingly deviate from these guidelines.",
"translation": "真实世界中的模块可能会违背这些分类法,混杂使用它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Feature Module",
"translation": "特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Declarations",
"translation": "声明`declarations`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Providers",
"translation": "提供商`providers`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Exports",
"translation": "导出什么",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Imported By",
"translation": "被谁导入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Examples",
"translation": "范例",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Domain",
"translation": "领域",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Rare",
"translation": "罕见",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Top component",
"translation": "顶级组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Feature, <code>AppModule</code>",
"translation": "特性模块和<code>AppModule</code>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "<code>ContactModule</code> (before routing)",
"translation": "<code>ContactModule</code>(路由之前的那个例子)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Routed",
"translation": "路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Rare",
"translation": "罕见",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Nobody",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "ContactModule</code>, <code>HeroModule</code>, <code>CrisisModule",
"translation": "ContactModule</code>、<code>HeroModule</code>、<code>CrisisModule",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Routing",
"translation": "路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "HttpModule</code>, <code>CoreModule",
"translation": "HttpModule</code>、<code>CoreModule",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Service",
"translation": "服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "HttpModule</code>, <code>CoreModule",
"translation": "HttpModule</code>、<code>CoreModule",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Widget",
"translation": "窗口部件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Rare",
"translation": "罕见",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Feature",
"translation": "特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "CommonModule</code>, <code>SharedModule",
"translation": "CommonModule</code>、<code>SharedModule",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What's the difference between Angular NgModules and JavaScript Modules?",
"translation": "## Angular模块和JavaScript模块有什么区别",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Angular and JavaScript are different yet complementary module systems.",
"translation": "Angular和JavaScript是两种不同但互补的模块体系。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "Then you `import` a part in another module:",
"translation": "然后,我们可以在其它模块中`import`那部分:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "This kind of modularity is a feature of the _JavaScript language_.",
"translation": "这种模块化方式是*JavaScript*语言中的特性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "An _NgModule_ is a feature of _Angular_ itself.",
"translation": "而*Angular模块*是*Angular本身*的特性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Angular's `@NgModule` metadata also have `imports` and `exports` and they serve a similar purpose.",
"translation": "Angular的`NgModule`也有自己的`imports`和`exports`来达到类似的目的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "The NgModule classes differ from JavaScript module class in the following key ways:",
"translation": "Angular的模块类与JavaScript的模块类有三个主要的不同点",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Instead of defining all member classes in one giant file (as in a JavaScript module),\n you list the NgModule's classes in the `@NgModule.declarations` list.",
"translation": "JavaScript模块把所有成员类都定义在一个巨型文件Angular模块则把自己的类都列在`@NgModule.declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* An NgModule can only export the [declarable classes](guide/ngmodule-faq#q-declarable)\nit owns or imports from other NgModules.\nIt doesn't declare or export any other kind of class.",
"translation": "Angular模块只能导出[_可声明的类_](guide/ngmodule-faq#q-declarable)。这可能是它自己拥有的也可能是从其它模块中导入的。它不会声明或导出任何其它类型的类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The NgModule is also special in another way.\nUnlike JavaScript modules, an NgModule can extend the _entire_ application with services\nby adding providers to the `@NgModule.providers` list.\n<!-- CF: Should this sentence be a bullet point in the list above? -->",
"translation": "Angular模块还有些别的特殊之处。\n不同于JavaScript模块Angular模块可以通过把服务提供商添加到`@NgModule.providers`数组中来扩展*整个*应用提供的服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The provided services don't belong to the NgModule nor are they scoped to the declared classes.\nThey are available _everywhere_.",
"translation": "这些提供的服务不仅仅从属于当前模块,其作用范围也不局限于模块中声明的类。它们*在哪里*都能用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Here's an _@NgModule_ class with imports, exports, and declarations.",
"translation": "这里是一个带有`imports`、`exports`和`declarations`的*@NgModule*类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Of course you use _JavaScript_ modules to write NgModules as seen in the complete `contact.module.ts` file:",
"translation": "当然,我们同样得用*JavaScript*模块来写*Angular模块*,就像在最终版`contact.module.ts`文件中所见到的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "The Angular compiler finds a component or directive in a template when it can match the *selector* of that\ncomponent or directive to some HTML in that template.",
"translation": "Angular编译器通过在一个模板的HTML中匹配组件或指令的**选择器selector**,来查找组件或指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The compiler finds a pipe if the pipe's *name* appears within the pipe syntax of the template HTML.",
"translation": "编译器通过分析模板HTML中的管道语法中是否出现了特定的管道名来查找对应的管道。Angular only matches selectors and pipe names for classes that are declared by this NgModule\nor exported by an NgModule that this one imports.\nAngular只查询两种组件、指令或管道1那些在当前模块中声明过的以及2那些被当前模块导入的模块所导出的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "## What is the Angular compiler?",
"translation": "## 什么是Angular编译器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The Angular compiler converts the application code you write into highly performant JavaScript code.\nThe `@NgModule` metadata play an important role in guiding the compilation process.",
"translation": "*Angular编译器*会把我们所写的应用代码转换成高性能的JavaScript代码。\n在编译过程中`@NgModule`的元数据扮演了很重要的角色。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The code you write isn't immediately executable.\nConsider *components*.\nComponents 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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "`@NgModule` metadata tells the Angular compiler what components to compile for this module and\nhow to link this module with other NgModules.",
"translation": "`@NgModule`元数据告诉*Angular编译器*要为当前模块编译哪些组件,以及如何把当前模块和其它模块链接起来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "The following table summarizes the `@NgModule` metadata properties.",
"translation": "下面是`@NgModule`元数据中属性的汇总表:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Property",
"translation": "属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A list of [declarable](guide/ngmodule-faq#q-declarable) classes,\n the *component*, *directive*, and *pipe* classes that _belong to this NgModule_.",
"translation": "[可声明类](guide/ngmodule-faq#q-declarable)的列表,也就是属于当前模块的**组件**、**指令**和**管道**类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "These declared classes are visible within the NgModule but invisible to\n components in a different NgModule unless they are _exported_ from this NgModule and\n the other NgModule _imports_ this one.",
"translation": "这些声明的类对组件内部可见,但是对其它模块不可见,除非 (a) 这些类从当前模块中*导出过*,并且 (b) 其它模块导入了当前模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Components, directives, and pipes must belong to _exactly_ one NgModule.\n The compiler emits an error if you try to declare the same class in more than one NgModule.",
"translation": "组件、指令和管道*只能*属于一个模块。\n 如果尝试把同一个类声明在多个模块中,编译器就会报告一个错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "*Do not re-declare a class imported from another NgModule.*",
"translation": "**不要重新声明从其它模块中导入的类。**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A list of dependency-injection providers.",
"translation": "依赖注入提供商的列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Angular registers these providers with the root injector of the NgModule's execution context.\n That's the application's root injector for all NgModules loaded when the application starts.",
"translation": "Angular会在当前模块执行环境的根注入器中注册这些提供商。\n 那是应用程序在启动时为其加载的所有模块提供的根注入器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Angular can inject one of these provider services into any component in the application.\n If this NgModule or any NgModule loaded at launch provides the `HeroService`,\n Angular can inject the same `HeroService` intance into any app component.",
"translation": "Angular可以把这些提供商提供的服务注入到应用中的任何组件中。\n 如果该模块提供了`HeroService`或启动时被加载的任何模块提供了`HeroService`那么Angular就会把同一个`HeroService`实例注入到应用中的任何组件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A lazy-loaded NgModule has its own sub-root injector which typically\n is a direct child of the application root injector.",
"translation": "惰性加载模块有自己的子注入器,通常它是应用的根注入器的直接子级。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Lazy-loaded services are scoped to the lazy module's injector.\n If a lazy-loaded NgModule also provides the `HeroService`,\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 如果惰性加载的模块也提供了`HeroService`,那么在该模块的环境中创建的任何组件(比如通过路由器导航),都会得到该服务的一个局部实例,而不是来自应用程序根注入器的那个全局实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Components in external NgModules continue to receive the instance created for the application root.",
"translation": "外部模块中的组件仍然会取得由应用的根注入器创建的那个实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A list of supporting NgModules.",
"translation": "支撑模块的列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Specifically, the list of NgModules whose exported components, directives, or pipes\n are referenced by the component templates declared in this NgModule.",
"translation": "特别是包含当前模块中的组件模板引用过的组件、指令或管道的那些模块的列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A component template can [reference](guide/ngmodule-faq#q-template-reference) another component, directive, or pipe\n when the referenced class is declared in this module\n or the class was imported from another module.",
"translation": "在两种情况下组件模板可以[引用](guide/ngmodule-faq#q-template-reference)其它组件、指令或管道:或者所引用的类是声明在当前模块中的,或者那个类已经从其它模块中导入进来了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A component can use the `NgIf` and `NgFor` directives only because its declaring NgModule\n imported the Angular `CommonModule` (perhaps indirectly by importing `BrowserModule`).",
"translation": "组件可以使用`NgIf`和`NgFor`指令只是因为它所在的模块导入了Angular的`CommonModule`(也可能是通过导入`BrowserModule`而间接导入的)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "You can import many standard directives with the `CommonModule`\n but some familiar directives belong to other NgModules.\n A component template can bind with `[(ngModel)]` only after importing the Angular `FormsModule`.",
"translation": "通过`CommonModule`,我们可以导入很多标准指令。\n 但是也有一些熟悉的指令是属于其它模块的。\n 比如组件只有导入了Angular的`FormsModule`才能在组件模板中用`[(ngModel)]`进行绑定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A list of declarations&mdash;*component*, *directive*, and *pipe* classes&mdash;that\n an importing NgModule can use.",
"translation": "可供导入了自己的模块使用的可声明对象(**组件**、**指令**、**管道类**)的列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Exported declarations are the module's _public API_.\n A component in another NgModule can [reference](guide/ngmodule-faq#q-template-reference) _this_ NgModule's `HeroComponent`\n if it imports this module and this module exports `HeroComponent`.",
"translation": "这些导出的可声明对象就是模块的*公开API*。\n 如果 (a) 其它模块导入了当前模块,并且 (b) 当前模块导出了`HeroComponent`\n 那么其它模块中的组件就可以[引用](guide/ngmodule-faq#q-template-reference)来自当前模块的`HeroComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Declarations are private by default.\n If this NgModule does _not_ export `HeroComponent`, no other NgModule can see it.",
"translation": "可声明对象默认情况下是私有的。\n 如果当前模块*没有*导出`HeroComponent`,那么没有任何其它模块能看到它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Importing an NgModule does _not_ automatically re-export the imported NgModule's imports.\n NgModule 'B' can't use `ngIf` just because it imported NgModule `A` which imported `CommonModule`.\n NgModule 'B' must import `CommonModule` itself.",
"translation": "导入一个模块*并不会*自动重新导出这个模块导出的东西。\n 模块'B'即使导入了模块`A`,而模块`A`中导入过`CommonModule`,它也没法使用`NgIf`。模块`B`必须自己导入`CommonModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "An NgModule can list another NgModule among its `exports`, in which case\n all of that NgModule's public components, directives, and pipes are exported.",
"translation": "一个模块可以把另一个模块加入自己的`exports`列表中,这时,另一个模块的所有公开组件、指令和管道都会被导出。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "[Re-export](guide/ngmodule-faq#q-re-export) makes NgModule transitivity explicit.\n If NgModule 'A' re-exports `CommonModule` and NgModule 'B' imports NgModule 'A',\n NgModule 'B' components can use `ngIf` even though 'B' itself didn't import `CommonModule`.",
"translation": "[重新导出](guide/ngmodule-faq#q-re-export)可以让模块的传递性更加明确。\n 如果模块`A`重新导出了`CommonModule`,然后模块`B`导入了模块`A`,那么模块`B`中的组件就能使用`NgIf`了,虽然模块`B`本身并没有导入过`CommonModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A list of components that can be bootstrapped.",
"translation": "能被引导的组件列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Usually there's only one component in this list, the _root component_ of the application.",
"translation": "通常,在这个列表中只有一个组件,也就是应用的*根组件*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"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/content-2/guide/ngmodule-faq.md"
},
{
"original": "A bootstrap component is automatically an `entryComponent`.",
"translation": "引导组件会自动成为`entryComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "A list of components that are _not_ [referenced](guide/ngmodule-faq#q-template-reference) in a reachable component template.",
"translation": "那些*没有*在任何可访问的组件的模板中[引用过](guide/ngmodule-faq#q-template-reference)的组件列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Most developers never set this property.\n The [Angular compiler](guide/ngmodule-faq#q-angular-compiler) must know about every component actually used in the application.\n The compiler can discover most components by walking the tree of references\n from one component template to another.",
"translation": "大多数开发人员从来没有设置过该属性。[_Angular编译器_](guide/ngmodule-faq#q-angular-compiler)必须知道在应用中实际用过的每一个组件。\n 通过遍历组件模板中的引用树,编译器可以自动找出大多数的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "But there's always at least one component that's not referenced in any template:\n the root component, `AppComponent`, that you bootstrap to launch the app.\n That's why it's called an _entry component_.",
"translation": "但是至少有一个组件不会被任何模板引用:根组件`AppComponent`,因为我们就是用它来引导本应用程序的。\n 这也就是为什么它被称为*入口组件*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Routed components are also _entry components_ because they aren't referenced in a template either.\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/content-2/guide/ngmodule-faq.md"
},
{
"original": "While the bootstrapped and routed components are _entry components_,\n you usually don't have to add them to a module's `entryComponents` list.",
"translation": "*引导组件*和*路由组件*都是*入口组件*,我们一般不用再把它们添加到模块的`entryComponents`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Angular automatically adds components in the module's `bootstrap` list to the `entryComponents` list.\n The `RouterModule` adds routed components to that list.",
"translation": "Angular会自动把模块的`bootstrap`列表中的组件添加到`entryComponents`列表中。\n `RouterModule`同样会把路由组件添加到`entryComponents`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "That leaves only the following sources of undiscoverable components:",
"translation": "这样,那些无法自动发现的组件就只剩下这些来源了:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Components bootstrapped using one of the imperative techniques.",
"translation": "使用某种命令式技巧引导的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "* Components dynamically loaded into the DOM by some means other than the router.",
"translation": "使用路由器之外的手段动态加载到DOM中的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "Both are advanced techniques that few developers ever employ.\n If you are one of those few, you must add these components to the\n `entryComponents` list yourself, either programmatically or by hand.",
"translation": "所有这些高级技巧是只有极少数开发人员才会去用的。\n 如果你是其中的一位,那么你就不得不自行把这些组件添加到`entryComponents`列表中 —— 无论是用程序添加还是手动添加。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule-faq.md"
},
{
"original": "# NgModules",
"translation": "# Angular模块 (NgModule)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "**NgModules** help organize an application into cohesive blocks of functionality.\n<!-- CF: \"app\" and \"application\" are used interchangeably throughout this page.\nI'm not sure what's appropriate, so I left them as is for now. --",
"translation": "**Angular 模块**能帮你把应用组织成多个内聚的功能块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "#### Live examples",
"translation": "#### 在线例子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "This page explains NgModules through a progression of improvements to a sample with a \"Heroes\" theme. Here's an index to live examples at key moments in the evolution of the sample:",
"translation": "本章通过一个基于《英雄指南》的渐进式例子解释了 Angular 的模块。这里是例子演化过程中一些关键节点的在线例子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* <live-example plnkr=\"minimal.0\">The initial app</live-example>",
"translation": "<live-example plnkr=\"minimal.0\">最小的 NgModule 应用</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* <live-example plnkr=\"contact.1b\">The first contact module</live-example>",
"translation": "<live-example plnkr=\"contact.1b\">第一个联系人模块</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* <live-example plnkr=\"contact.2\">The revised contact module</live-example>",
"translation": "<live-example plnkr=\"contact.2\">修改过的联系人模块</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* <live-example plnkr=\"pre-shared.3\">Just before adding SharedModule</live-example>",
"translation": "<live-example plnkr=\"pre-shared.3\">添加 _SharedModule_ 之前</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* <live-example>The final version</live-example>",
"translation": "<live-example>最终版</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "#### Frequently asked questions (FAQs)",
"translation": "### 常见问题",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "This page covers NgModule concepts in a tutorial fashion.",
"translation": "本章涵盖了英雄指南下的 Angular 模块概念。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The companion [NgModule FAQs](guide/ngmodule-faq \"NgModule FAQs\") guide\noffers answers to specific design and implementation questions.\nRead this page before reading those FAQs.",
"translation": "烹饪宝典中的 [Angular 模块常见问题](guide/ngmodule-faq \"Angular 模块常见问题\")为一些与设计和实现有关的问题提供了答案。\n不过在阅读常见问题之前要先阅读本章。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "## Angular modularity",
"translation": "## Angular 模块化",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "NgModules are a great way to organize an application and extend it with capabilities from external libraries.",
"translation": "模块是组织应用和使用外部库扩展应用的最佳途径。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Many Angular libraries are NgModules (such as `FormsModule`, `HttpModule`, 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>,\n<a href=\"https://github.com/angular/angularfire2\">AngularFire2</a>).",
"translation": "很多 Angular 库都是模块,例如:`FormsModule`、`HttpModule`、`RouterModule`。\n 很多第三方库也封装成了 Angular 模块,例如:<a href=\"https://material.angular.io/\" target=\"_blank\">Material Design</a>、\n <a href=\"http://ionicframework.com/\" target=\"_blank\">Ionic</a>、\n <a href=\"https://github.com/angular/angularfire2\" target=\"_blank\">AngularFire2</a>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"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/content-2/guide/ngmodule.md"
},
{
"original": "NgModules can also add services to the application.\nSuch services might be internally developed, such as the application logger.\nServices can come from outside sources, such as the Angular router and Http client.",
"translation": "模块还能用来把服务加到应用程序中。这些服务可能是内部研发的,例如应用日志服务;\n也可能是外部资源例如 Angular 路由和 Http 客户端。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "NgModules can be loaded eagerly when the application starts.\nThey can also be _lazy-loaded_ asynchronously by the router.",
"translation": "模块可能在应用启动时主动加载,也可能由路由器进行异步*惰性加载*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "An NgModule is a class decorated with `@NgModule` metadata. \nBy setting metadata properties you tell Angular how your application parts fit together.\nFor example, you can do the following:",
"translation": "Angular 模块是一个带有`@NgModule`元数据的类。\n通过设置元数据的属性我们可以告诉 Angular 应用的这些部件如何协同工作。比如,我们可以:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* _Declare_ which components, directives, and pipes belong to the NgModule.",
"translation": "声明哪些组件、指令、管道_属于_该模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* _Export_ some of those classes so that other component templates can use them.",
"translation": "*导出*某些类,以便其它的组件模板可以使用它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* _Import_ other NgModules with the components, directives, and pipes needed by the components in _this_ NgModule.",
"translation": "*导入*其它模块,从其它模块中获得*本*模块所需的组件、指令和管道。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* _Provide_ services at the application level that any application component can use.",
"translation": "在应用程序级*提供*服务,以便应用中的任何组件都能使用它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* _Bootstrap_ the app with one or more top-level, _root_ components.",
"translation": "使用一个或多个顶级*根*组件*启动*本应用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "## The root _AppModule_",
"translation": "## _AppModule_ - 应用的根模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Every Angular app has at least one NgModule class, the _root module_.\nYou bootstrap _that_ NgModule to launch the application.",
"translation": "每个 Angular 应用都有一个**根模块**类。\n按照约定它的类名叫做`AppModule`,被放在`app.module.ts`文件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "By convention, the *root module* class is called `AppModule` and it exists in a file named `app.module.ts`.\nThe [**Angular CLI**](https://cli.angular.io/) generates the initial `AppModule` for you when you create a project.",
"translation": "通常,*根模块*类叫做 `AppModule` 并且位于一个名叫 `app.module.ts` 的文件中。\n当创建项目时[**Angular CLI**](https://cli.angular.io/) 会生成最初的 `AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The root `AppModule` is all you need in a simple application with a few components.",
"translation": "在组件不多的简单应用中,一个根模块 `AppModule` 就够了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The `@NgModule` metadata `imports` a single helper module, `BrowserModule`, which every browser app must import.\n`BrowserModule` registers critical application service providers.\nIt also includes common directives like `NgIf` and `NgFor`, which become immediately visible and usable\nin any of this NgModule's component templates.",
"translation": "这个 `@NgModule` 元数据只导入了一个辅助模块(`BrowserModule`),每个运行在浏览器中的应用都必须导入它。\n`BrowserModule`注册了一些关键的应用服务提供商。\n它还包括了一些通用的指令例如`NgIf`和`NgFor`,所以这些指令在该模块的任何组件模板中都是可用的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Lastly, the `bootstrap` list identifies the `AppComponent` as the _bootstrap component_.\nWhen Angular launches the app, it renders the `AppComponent`\ninside the `<app-root>` element tag of the `index.html`.",
"translation": "最后,`bootstrap`列表中指定这个`AppComponent`作为*引导 (bootstrap) 组件*。\n当 Angular 引导应用时,它会在 DOM 中渲染`AppComponent`,并把结果放进`index.html`的`<app-root>`元素标记内。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Learn about that in the [bootstrapping](guide/bootstrapping) guide.",
"translation": "要了解更多,参见 [引导](guide/bootstrapping) 一章。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Rewrite `AppComponent` to display the new `TitleComponent` in the `<app-title>` element and get rid of the `title` property.",
"translation": "我们重写了`AppComponent`来把这个新的`TitleComponent`显示到`<app-title>`元素中,并使用一个输入型绑定来设置`subtitle`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "## Service providers",
"translation": "## 服务提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Many applications capture information about the currently logged-in user and make that information\naccessible through a user service.",
"translation": "很多应用都需要获取当前登录的用户的信息,并且通过一个用户服务来访问它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Update the `TitleComponent` class with a constructor that injects the `UserService`\nand sets the component's `user` property from the service.",
"translation": "更新`TitleComponent`,为它加入一个构造函数,注入`UserService`类,并把组件的`user`属性设置为它的实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "## NgModule imports",
"translation": "## 导入支持性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "In the revised `TitleComponent`, an `*ngIf` directive guards the message.\nThere is no message if there is no user.",
"translation": "在修改过的`TitleComponent`中,有一个`*ngIf`指令在“守卫着”该消息。如果没有当前用户,就没有任何消息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Although `AppModule` doesn't declare the `NgIf` directive, the application still compiles and runs.\nHow can that be? The Angular compiler should either ignore or complain about unrecognized HTML.",
"translation": "虽然`AppModule`没有声明过`NgIf`指令但该应用仍然能正常编译和运行。为什么这样没问题呢Angular 的编译器遇到不认识的 HTML 时应该不是忽略就是报错才对。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "### Importing _BrowserModule_",
"translation": "### 导入 *BrowserModule*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Angular does recognize `NgIf` because the `AppModule` imports it indirectly\nwhen it imports `BrowserModule`.",
"translation": "Angular 之所以能识别 `NgIf` 指令,是因为 `AppModule` 在导入 `BrowserModule` 时间接导入了它。。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Importing `BrowserModule` made all of its public components, directives, and pipes visible\nto the templates of components declared in `AppModule`, which include `TitleComponent`.",
"translation": "导入`BrowserModule`会让该模块公开的所有组件、指令和管道在`AppModule`下的任何组件模板中可用,也包括 `TitleComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The `NgIf` directive isn't declared in `BrowserModule`.\nIt's declared in `CommonModule` from `@angular/common`.",
"translation": "`NgIf` 指令并不是在 `BrowserModule` 中声明的。而是在 `@angular/common` 的 `CommonModule` 中声明的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "`CommonModule` contributes many of the common directives that applications need, including `ngIf` and `ngFor`.",
"translation": "`CommonModule`提供了很多应用程序中常用的指令,包括`NgIf`和`NgFor`等。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Many familiar Angular directives don't belong to `CommonModule`.\nFor example, `NgModel` and `RouterLink` belong to Angular's `FormsModule` and `RouterModule` respectively.\nYou must import those NgModules before you can use their directives.",
"translation": "很多熟悉的 Angular 指令并不属于`CommonModule`。\n例如`NgModel`和`RouterLink`分别属于 Angular 的`FormsModule`模块和`RouterModule`模块。\n在使用那些指令之前我们也必须*导入*那些模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Imagine that you added the following _contact editor_ files \nto the project by hand _without the help of the CLI_.",
"translation": "如果*不借助CLI的帮助*,就要自己把下列*联系人编辑器*文件添加到项目中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Run the app",
"translation": "运行该应用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Everything is in place to run the application with its contact editor.",
"translation": "一切就绪,可以运行该应用及其联系人编辑器了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Try the example:",
"translation": "试试这个例子:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "## Feature modules",
"translation": "## 特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "This tiny app is already experiencing structural issues.",
"translation": "该应用还不大,但是已经在受结构方面的问题困扰了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* The root `AppModule` grows larger with each new application class.",
"translation": "随着一个个类被加入应用中,根模块`AppModule`变大了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* There are conflicting directives.\nThe `ContactHighlightDirective` in the contact re-colors the work done by the `HighlightDirective` declared in `AppModule`and colors the application title text when it should color only the `ContactComponent`.",
"translation": "我们遇到了指令冲突。\n 联系人模块的`HighlightDirective`在`AppModule`中声明的`HighlightDirective`的基础上进行了二次上色。\n 并且,它染了应用标题文字的颜色,而不仅仅是`ContactComponent`中的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* The app lacks clear boundaries between contact functionality and other application features.\nThat lack of clarity makes it harder to assign development responsibilities to different teams.",
"translation": "该应用在联系人和其它特性区之间缺乏清晰的边界。这种缺失,导致难以在不同的开发组之间分配职责。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "These two module types have the following significant technical differences:",
"translation": "这两种模块在技术上有两个显著的不同点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* You _boot_ the root module to _launch_ the app;\nyou _import_ a feature module to _extend_ the app.",
"translation": "我们*引导*根模块来*启动*应用,但*导入*特性模块来*扩展*应用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* A feature module can expose or hide its [declarables](#declarables) from other NgModules.",
"translation": "特性模块可以对其它模块暴露或隐藏自己的实现。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Otherwise, a feature module is distinguished primarily by its intent.",
"translation": "此外,特性模块主要还是从它的设计意图上来区分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "A feature module delivers a cohesive set of functionality\nfocused on an application business domain, user workflow, facility (forms, http, routing),\nor collection of related utilities.\nFeature modules help you partition the app into areas of specific interest and purpose.",
"translation": "特性模块用来提供了内聚的功能集合。\n聚焦于应用的某个业务领域、用户工作流、某个基础设施表单、HTTP、路由或一组相关的工具集合。\n特性模块可以帮助我们把应用划分成多个具有特定用途的功能区。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "A feature module collaborates with the root module and with other NgModules\nthrough the services it provides and\nthe components, directives, and pipes that it shares.",
"translation": "特性模块通过自己提供的服务和它决定对外共享的那些组件、指令、管道来与根模块等其它模块协同工作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Create the `ContactModule` feature module in its own folder.",
"translation": "在自己的目录下创建特性模块`ContactModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Copy the _contact editor_ declarations and providers from `AppModule` to `ContactModule`.",
"translation": "把*联系人编辑器*的声明和服务提供商从 `AppModule` 复制到 `ContactModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Export the `ContactComponent`.",
"translation": "导出 `ContactComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Import the `ContactModule` into the `AppModule`.",
"translation": "在`AppModule`中导入`ContactModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Cleanup the `AppModule`.",
"translation": "清理 `AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "You will learn that services provided in [_lazy-loaded_ modules](#lazy-loaded-modules) \nhave their own scope.",
"translation": "当前模块不会继承其它模块中对组件、指令或管道的访问权。\n`AppModule`中的 imports 与`ContatModule`的 imports 互不相干。\n如果`ContactComponent`要绑定到`[(ngModel)]`,它所在的`ContactModule`必需导入`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "{@a refactor-appmodule}\n### Refactor the _AppModule_",
"translation": "### 重构 *AppModule*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Return to the `AppModule` and remove everything specific to the _contact editor_ feature set.\nLeave only the classes required at the application root level.",
"translation": "返回`AppModule`并移除专属于联系人特性下的任何东西。只保留应用的顶级所需的类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* Delete the _contact editor_ import statements.",
"translation": "删除属于联系人编辑器的`import`语句。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* Delete the _contact editor_ declarations and providers.",
"translation": "删除属于联系人编辑器的`declarations`和`providers`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* Delete the `FormsModule` from the `imports` list (the `AppComponent` doesn't need it).",
"translation": "从`imports`列表中移除`FormsModule``AppComponent`并不需要它)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* Import the `ContactModule` so the app can continue to display the exported `ContactComponent`.",
"translation": "导入`ContactModule`,以便应用能够继续显示导出的`ContactComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Here's the refactored `AppModule`, presented side-by-side with the previous version.",
"translation": "下面是`AppModule`重构完的版本与之前版本的对比。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "### Improvements",
"translation": "### 改进之处",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "There's a lot to like in the revised `AppModule`.",
"translation": "修改后的`AppModule`有一些很棒的特性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* It does not change as the _Contact_ domain grows.",
"translation": "它不会再随着_联系人_的领域扩张而修改。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* It only changes when you add new NgModules.",
"translation": "只有当添加新模块时才需要修改它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* It's simpler:",
"translation": "它也变得简单了:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* Fewer import statements.",
"translation": "更少的`import`语句",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* No `FormsModule` import.",
"translation": "不再导入`FormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* No _contact editor_ declarations.",
"translation": "没有与联系人有关的声明",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* No `ContactService` provider.",
"translation": "没有`ContactService`提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* No _highlight directive_ conflicts.",
"translation": "没有`HighlightDirective`冲突",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Try this `ContactModule` version of the sample.",
"translation": "试试范例的`ContactModule`版。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* The `ContactComponent` is the default destination when the app starts.",
"translation": "`ContactComponent`组件是应用启动时的默认页。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* The `ContactModule` continues to be _eagerly loaded_ when the application starts.",
"translation": "`ContactModule`仍然会在应用启动时被主动加载。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "You can examine the complete source for this version of the app in\nthe <live-example plnkr=\"pre-shared.3\" img=\"guide/ngmodule/v3-plunker.png\">live example.</live-example>",
"translation": "`HeroModule`和`CrisisModule`会被惰性加载。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The revised `AppComponent` template has\na title, three links, and a `<router-outlet>`.",
"translation": "我们从这个`AppComponent`新模板的顶部看起:标题、三个链接和`<router-outlet>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The `AppModule` is slimmer now.",
"translation": "这下 `AppModule` 苗条多了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The significant change from version 2 is the addition of the *AppRoutingModule* to the NgModule `imports`.\nThe `AppRoutingModule` is a [routing module](guide/router#routing-module)\nthat handles the app's routing concerns.",
"translation": "与第二版相比,最值得注意的修改是`imports`中那个额外的***AppRoutingModule***模块。\n`AppRoutingModule`是一个[**路由模块**](guide/router#routing-module)\n用来处理应用的路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Here is this app's `AppRoutingModule`, followed by a discussion.",
"translation": "### 应用路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The first route redirects the empty URL (such as `http://host.com/`)\nto another route whose path is `contact` (such as `http://host.com/contact`).",
"translation": "第一个路由把空白 URL例如`http://host.com/`)重定向到了另一个路径为`contact`的路由(例如`http://host.com/contact`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The `contact` route isn't defined within the `AppRoutingModule`.\nIt's defined in the _Contact_ feature's _own_ routing module, `ContactRoutingModule`.",
"translation": "`contact`路由并不是在`AppRoutingModule`中定义的,而是定义在*联系人*特性区自己的路由模块`ContactRoutingModule`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "It's standard practice for feature modules with routing components to define their own routes.\nYou'll get to [`ContactRoutingModule`](#contact-routing-module) in a moment.",
"translation": "对于带有路由组件的特性模块,标准做法就是让它们定义自己的路由。\n稍后我们就会在 [`ContactRoutingModule`](#contact-routing-module) 中看到这些。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The remaining two routes use lazy loading syntax to tell the router where to find the modules for the hero and crisis features:",
"translation": "另外两个路由使用惰性加载语法来告诉路由器要到哪里去找英雄特性模块和危机特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "A lazy-loaded NgModule location is a _string_, not a _type_.\nIn this app, the string identifies both the NgModule _file_ and the NgModule _class_,\nthe latter separated from the former by a `#`.",
"translation": "惰性加载模块的位置是*字符串*而不是*类型*。\n在本应用中该字符串同时标记出了模块*文件*和模块*类*,两者用`#`分隔开。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Never call `RouterModule.forRoot` in a feature's _routing module_.",
"translation": "永远不要在特性路由模块中调用`RouterModule.forRoot`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "### Routing to a feature module",
"translation": "### 路由到特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Always call `RouterModule.forChild` in a feature-routing module.\nNever call `RouterModule.forRoot`.",
"translation": "总是在特性路由模块中调用`RouterModule.forChild`。\n永远不要调用`RouterModule.forRoot`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Here is the latest version, side-by-side with the previous version.",
"translation": "`ContactModule`已经做了两个微小但重要的细节改动:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Try this routed version of the sample.",
"translation": "<live-example embedded plnkr=\"pre-shared.3\" img=\"guide/ngmodule/v3-plunker.png\">试试在线例子。</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "## Shared modules",
"translation": "## 共享模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The app is shaping up.\nBut there are a few annoying problems.\nThere are three unnecessarily different _highlight directives_\nand the many files cluttering the app folder level could be better organized.",
"translation": "本应用在继续演进中。\n 让我们感到不爽的是:这里有`HighlightDirective`的三个不同版本。\n 还有一大堆其它乱七八糟的东西堆在 app 目录这一级,我们得把它们清出去。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "- Move the `AwesomePipe` from `src/app/contact` to `src/app/shared`.",
"translation": "把 `AwesomePipe` 和 `HighlightDirective` 从 `src/app/contact` 移到 `src/app/shared` 中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "- Move the `HighlightDirective` from `src/app/hero` to `src/app/shared`.",
"translation": "把 `HighlightDirective` 从 `src/app/hero` 移到 `src/app/shared` 中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "- Delete the _highlight directive_ classes from `src/app/` and `src/app/contact`.",
"translation": "从 `src/app/` 和 `src/app/contact` 删除*高亮指令*类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "- Update the `SharedModule` as follows:",
"translation": "把 `SharedModule` 改成这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Note the following:",
"translation": "值得注意的有:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* It declares and exports the shared pipe and directive.",
"translation": "它导入了`CommonModule`,这是因为它的组件需要这些公共指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Normally, they'd have to import `CommonModule` and `FormsModule` as well as `SharedModule`.",
"translation": "正如我们所期待的,它声明并导出了工具性的管道、指令和组件类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "### Why _TitleComponent_ isn't shared",
"translation": "### 为什么 *TitleComponent* 没有被共享",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "`SharedModule` exists to make commonly used components, directives, and pipes available\nfor use in the templates of components in many other NgModules.",
"translation": "设计`SharedModule`的目的在于让常用的组件、指令和管道可以被用在*很多*其它模块的组件模板中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The `TitleComponent` is used only once by the `AppComponent`.\nThere's no point in sharing it.",
"translation": "而`TitleComponent`*只被*`AppComponent`用了一次,因此没必要共享它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "### Why _UserService_ isn't shared",
"translation": "### 为什么 *UserService* 没有被共享",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "While many components share the same service instances,\nthey rely on Angular dependency injection to do this kind of sharing, not the NgModule system.",
"translation": "虽然很多组件都共享着同一个服务*实例*,但它们是靠 Angular 的依赖注入体系实现的,而不是模块体系。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Several components of the sample inject the `UserService`.\nThere should be only one instance of the `UserService` in the entire application\nand only one provider of it.",
"translation": "例子中的很多组件都注入了`UserService`。\n在整个应用程序中*只应该有一个*`UserService`的实例,并且它*只应该有一个*提供商。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "`UserService` is an application-wide singleton.\nYou don't want each NgModule to have its own separate instance.\nYet there is [a real danger](guide/ngmodule-faq#q-why-bad) of that happening\nif the `SharedModule` provides the `UserService`.",
"translation": "`UserService`是全应用级单例。\n我们不希望每个模块都各自有它的实例。\n而如果由`SharedModule`提供`UserService`,就会导致[铁板钉钉的危险](guide/ngmodule-faq#q-why-bad)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Do *not* specify app-wide singleton `providers` in a shared module.\nA lazy-loaded NgModule that imports that shared module makes its own copy of the service.",
"translation": "**不要**在共享模块中把应用级单例添加到`providers`中。\n否则如果一个惰性加载模块导入了此共享模块就会导致它自己也生成一份此服务的实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "## The Core module",
"translation": "## 核心 (Core) 模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "At the moment, the root folder is cluttered with the `UserService`\nand `TitleComponent` that only appear in the root `AppComponent`.\nYou didn't include them in the `SharedModule` for reasons just explained.",
"translation": "现在,我们的根目录下只剩下`UserService`和`TitleComponent`这两个被根组件`AppComponent`用到的类没有清理了。\n但正如我们已经解释过的它们无法被包含在`SharedModule`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Instead, gather them in a single `CoreModule` that you import once when the app starts\nand never import anywhere else.",
"translation": "不过,我们可以把它们收集到单独的`CoreModule`中,并且**只在应用启动时导入它*一次*****而不会在其它地方导入它**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Create a `CoreModule` class in an `src/app/core` folder.",
"translation": "在 `src/app/core` 目录下创建 `CoreModule` 类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Move the `TitleComponent` and `UserService` from `src/app/` to `src/app/core`.",
"translation": "把 `TitleComponent` 和 `UserService` 从 `src/app/` 移到 `src/app/core`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Declare and export the `TitleComponent`.",
"translation": "声明并导出 `TitleComponent` 。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Provide the `UserService`.",
"translation": "提供 `UserService`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "1. Update the root `AppModule` to import `CoreModule`.",
"translation": "修改 `AppModule` 根模块,使其导入 `CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Most of this work is familiar. The interesting part is the `CoreModule`.",
"translation": "这些都是一些熟悉的普通任务。令人感兴趣的是`CoreModule`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "You're importing some extra symbols from the Angular core library that you're not using yet.\nThey'll become relevant later in this page.",
"translation": "我们正在从 Angular 核心库中导入一些从未用到的符号,稍后我们会接触它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The `@NgModule` metadata should be familiar.\nYou declare the `TitleComponent` because this NgModule owns it. \nYou export it because `AppComponent` (which is in `AppModule`) displays the title in its template.\n`TitleComponent` needs the Angular `NgIf` directive that you import from `CommonModule`.",
"translation": "我们对`@NgModule`的元数据应该很熟悉。\n由于该模块_拥有_`TitleComponent`,所以我们声明了它。由于`AppComponent`(位于`AppModule`模块)在模板中显示了这个标题,所以我们导出了它。\n由于`TitleComponent`需要用到 Angular 的`NgIf`指令,所以我们导入了`CommonModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "`CoreModule` provides the `UserService`. Angular registers that provider with the app root injector,\nmaking a singleton instance of the `UserService` available to any component that needs it,\nwhether that component is eagerly or lazily loaded.",
"translation": "`CoreModule`_提供_了`UserService`。Angular 在该应用的根注入器中注册了它的提供商,\n导致这份`UserService`的实例在每个需要它的组件中都是可用的,无论那个组件时主动加载的还是惰性加载的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Why bother?",
"translation": "没必要?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "This scenario is clearly contrived.\nThe app is too small to worry about a single service file and a tiny, one-time component.",
"translation": "这个场景设计的是有点生硬。\n该应用太小了所以其实并不需要拆分出单独的服务文件和小型的、一次性的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "A `TitleComponent` sitting in the root folder isn't bothering anyone.\nThe root `AppModule` can register the `UserService` itself,\nas it does currently, even if you decide to relocate the `UserService` file to the `src/app/core` folder.",
"translation": "把`TitleComponent`放在根目录中其实也无所谓。\n即使我们决定把`UserService`文件挪到`app/core`目录中,根`AppModule`也仍然可以自己注册`UserService`(就像现在这样)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Real-world apps have more to worry about.\nThey can have several single-use components (such as spinners, message toasts, and modal dialogs)\nthat appear only in the `AppComponent` template.\nYou don't import them elsewhere so they're not shared in that sense.\nYet they're too big and messy to leave loose in the root folder.",
"translation": "但真实的应用要考虑很多。\n它们有一些只用于`AppComponent`的模板的一次性的组件(例如:加载动画、消息浮层和模态对话框等)。\n我们不用在其它地方导入它们因此没必要*共享*它们。\n然而如果把它们留在根目录还是显得太大、太乱了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Apps often have many singleton services like this sample's `UserService`.\nEach must be registered exactly once, in the app root injector, when the application starts.",
"translation": "应用通常还有很多像这里的`UserService`这样的单例服务。\n当程序启动时每个服务都只能在应用的“根注入器”中*注册一次*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "While many components inject such services in their constructors&mdash;and\ntherefore require JavaScript `import` statements to import their symbols&mdash;no\nother component or NgModule should define or re-create the services themselves.\nTheir _providers_ aren't shared.",
"translation": "当很多组件在它们的构造函数中注入这些服务时 &mdash;\n因此也需要用 JavaScript 的`import`语句来导入它们的符号 &mdash;\n任何组件或模块自身都不应该定义或重新创建这些服务。\n因为它们的*提供商*不是共享的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "We recommend collecting such single-use classes and hiding their details inside a `CoreModule`.\nA simplified root `AppModule` imports `CoreModule` in its capacity as orchestrator of the application as a whole.",
"translation": "因此我们建议把这些一次性的类收集到`CoreModule`中,并且隐藏它们的实现细节。\n简化之后的根模块`AppModule`导入`CoreModule`来获取其能力。记住,根模块是整个应用的总指挥,不应该插手过多细节。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "#### A trimmer _AppModule_",
"translation": "#### 清理 *AppModule*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Here is the updated `AppModule` paired with version 3 for comparison:",
"translation": "这里是更新后的`AppModule`与其第三版本的对比:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "`AppModule` now has the following qualities:",
"translation": "`AppModule`现在变得:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* A little smaller because many `src/app/root` classes have moved to other NgModules.",
"translation": "更小了。因为很多`src/app/root`下的类被移到了其它模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* Stable because you'll add future components and providers to other NgModules, not this one.",
"translation": "更稳定了。因为我们以后会在其它模块中添加组件和服务提供商,而不是这里。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* Delegated to imported NgModules rather than doing work.",
"translation": "导入其它模块并把任务委托给它们,而不是亲力亲为。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* Focused on its main task, orchestrating the app as a whole.",
"translation": "聚焦于自己的主要任务:总指挥整个应用程序。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "### Configure core services with _CoreModule.forRoot_",
"translation": "### 用 *CoreModule.forRoot* 配置核心服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "An NgModule that adds providers to the application can offer a facility for configuring those providers as well.",
"translation": "为应用添加服务提供商的模块也可以同时提供配置那些提供商的功能。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "By convention, the `forRoot` static method both provides and configures services at the same time.\nIt takes a service configuration object and returns a\n[ModuleWithProviders](api/core/ModuleWithProviders), which is\na simple object with the following properties:",
"translation": "按照惯例,模块的静态方法***forRoot***可以同时提供并配置服务。\n它接收一个服务配置对象并返回一个[ModuleWithProviders](api/core/ModuleWithProviders)。这个简单对象具有两个属性:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* `ngModule`: the `CoreModule` class",
"translation": "`ngModule` - `CoreModule`类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "* `providers`: the configured providers",
"translation": "`providers` - 配置好的服务提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The root `AppModule` imports the `CoreModule` and adds the `providers` to the `AppModule` providers.",
"translation": "根模块`AppModule`会导入`CoreModule`类并把它的`providers`添加到`AppModule`的服务提供商中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "More precisely, Angular accumulates all imported providers before appending the items listed in `@NgModule.providers`.\nThis sequence ensures that whatever you add explicitly to the `AppModule` providers takes precedence\nover the providers of imported NgModules.",
"translation": "更精确的说法是Angular 会先累加所有导入的提供商,*然后才*把它们追加到`@NgModule.providers`中。\n这样可以确保我们显式添加到`AppModule`中的那些提供商总是优先于从其它模块中导入的提供商。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Add a `CoreModule.forRoot` method that configures the core `UserService`.",
"translation": "现在添加`CoreModule.forRoot`方法,以便配置核心中的`UserService`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "You've extended the core `UserService` with an optional, injected `UserServiceConfig`.\nIf a `UserServiceConfig` exists, the `UserService` sets the user name from that config.",
"translation": "我们曾经用一个可选的、被注入的`UserServiceConfig`服务扩展过核心的`UserService`服务。\n如果有`UserServiceConfig``UserService`就会据此设置用户名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Here's `CoreModule.forRoot` that takes a `UserServiceConfig` object:",
"translation": "这里的`CoreModule.forRoot`接收`UserServiceConfig`对象:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Lastly, call it within the `imports` list of the `AppModule`.",
"translation": "最后,我们在`AppModule`的`imports`*列表*中调用它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"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/content-2/guide/ngmodule.md"
},
{
"original": "Call `forRoot` only in the root module, `AppModule`.\nCalling it in any other NgModule, particularly in a lazy-loaded NgModule,\nis contrary to the intent and can produce a runtime error.",
"translation": "只在应用的根模块`AppModule`中调用`forRoot`。\n如果在其它模块特别是惰性加载模块中调用它则违反了设计意图并会导致运行时错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Remember to _import_ the result; don't add it to any other `@NgModule` list.",
"translation": "别忘了_导入_其返回结果而且不要把它添加到`@NgModule`的其它任何列表中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "### Prevent reimport of the _CoreModule_",
"translation": "## 禁止多次导入*CoreModule*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Only the root `AppModule` should import the `CoreModule`.\n[Bad things happen](guide/ngmodule-faq#q-why-bad) if a lazy-loaded NgModule imports it.",
"translation": "只有根模块`AppModule`才能导入`CoreModule`。\n 如果惰性加载模块导入了它,就会[出问题](guide/ngmodule-faq#q-why-bad)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "You could hope that no developer makes that mistake.\nOr you can guard against it and fail fast by adding the following `CoreModule` constructor.",
"translation": "我们可以*祈祷*任何开发人员都不会犯错。\n 但是最好还是对它进行一些保护,以便让它“尽快出错”。只要把下列代码添加到`CoreModule`的构造函数中就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The constructor tells Angular to inject the `CoreModule` into itself.\nThat seems dangerously circular.",
"translation": "这个构造函数会要求 Angular 把`CoreModule`注入自身。这看起来像一个危险的循环注入。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "The injection would be circular if Angular looked for `CoreModule` in the _current_ injector.\nThe `@SkipSelf` decorator means \"look for `CoreModule` in an ancestor injector, above me in the injector hierarchy.\"",
"translation": "确实,如果 Angular 在*当前*注入器中查阅`CoreModule`,这确实会是一个循环引用。\n不过`@SkipSelf`装饰器意味着“在当前注入器的所有祖先注入器中寻找`CoreModule`。”",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "If the constructor executes as intended in the `AppModule`,\nthere is no ancestor injector that could provide an instance of `CoreModule`.\nThe injector should give up.",
"translation": "如果该构造函数在我们所期望的`AppModule`中运行,就没有任何祖先注入器能够提供`CoreModule`的实例,于是注入器会放弃查找。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "By default, the injector throws an error when it can't find 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/content-2/guide/ngmodule.md"
},
{
"original": "It's a different story if you improperly import `CoreModule` into a lazy-loaded NgModule such as `HeroModule` (try it).",
"translation": "如果我们错误的把`CoreModule`导入了一个惰性加载模块(例如`HeroModule`)中,那就不一样了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Angular creates a lazy-loaded NgModule with its own injector, a _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/content-2/guide/ngmodule.md"
},
{
"original": "## Conclusion",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "You made it! You can examine and download the complete source for this final version from the live example.",
"translation": "完工!你可以到下面的在线例子中试验它,并下载最终版本的全部源码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "## Frequently asked questions",
"translation": "## 常见问题 (FAQ)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "Now that you understand NgModules, you may be interested\nin the companion [NgModule FAQs](guide/ngmodule-faq \"NgModule FAQs\") page\nwith its ready answers to specific design and implementation questions.",
"translation": "现在,你已经理解了 Angular 的模块。可能你还会对烹饪宝典中的\n[Angular 模块常见问题](guide/ngmodule-faq \"Angular 模块常见问题\")感兴趣,\n它解答了很多关于设计和实现方面的问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/ngmodule.md"
},
{
"original": "# Npm Packages",
"translation": "# Npm 包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "This guide focuses on the most important packages in the starter set.",
"translation": "本指南中会集中讲解这些初始包中的重点部分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"original": "#### *dependencies* and *devDependencies*",
"translation": "#### *dependencies* 和 *devDependencies*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "The `dependencies` section of `package.json` contains:",
"translation": "应用程序的`package.json`文件中,`dependencies`下包括:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"original": "* **Angular packages **: Angular core and optional modules; their package names begin `@angular/`.",
"translation": "**Angular 包**Angular 的核心和可选模块,它们的包名以`@angular/`开头。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"original": "* **Support packages**: 3rd party libraries that must be present for Angular apps to run.",
"translation": "**支持包**那些Angular 应用运行时必需的第三方库。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"original": "* **Polyfill packages**: Polyfills plug gaps in a browser's JavaScript implementation.",
"translation": "**填充库**:填充库负责抹平不同浏览器的 JavaScript 实现之间的差异。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"original": "### Angular Packages",
"translation": "### Angular 包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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 dont 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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "**@angular/http**: Angular's old, soon-to-be-deprecated, HTTP client.",
"translation": "**@angular/http**Angular 的老的、很快就会废弃的 HTTP 客户端库。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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)和[bootstrap](guide/ngmodule#bootstrap)方法,以便在客户端编译模板。不要用于离线编译。\n我们使用这个包在开发期间引导应用以及引导plunker中的范例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "**@angular/upgrade**: Set of utilities for upgrading AngularJS applications to Angular.",
"translation": "**@angular/upgrade**: 一组用来把 AngularJS 应用升级到 Angular 的工具。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"original": "### Polyfill packages",
"translation": "### 填充包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "### Support packages",
"translation": "### 支持包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "You don't deploy them with the production application although there is no harm in doing so.",
"translation": "我们不必在生产环境的应用中部署它们,当然,就算部署了也没什么坏处。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "**@types/... **: TypeScript definition files for 3rd party libraries such as Jasmine and node.",
"translation": "**@types/... **:第三方库(比如 Jasmine 和 node的 TypeScript 类型定义文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "## So many packages! So many files!",
"translation": "## 那么多包!那么多文件!",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"original": "The default `package.json` installs more packages than you'll need for your project.",
"translation": "默认的 `package.json` 所安装的包比项目实际需要的多。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"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/content-2/guide/npm-packages.md"
},
{
"original": "See the [Deployment](guide/deployment) to learn more.",
"translation": "参见[部署](guide/deployment)一章了解详情。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/npm-packages.md"
},
{
"original": "# Pipes",
"translation": "# 管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "You can run the <live-example></live-example> in Plunker and download the code from there.",
"translation": "试试<live-example>在线例子</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "## Using pipes",
"translation": "## 使用管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "Focus on the component's template.",
"translation": "重点看下组件的模板。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "## Built-in pipes",
"translation": "## 内置的管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "## Parameterizing a pipe",
"translation": "## 对管道进行参数化",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "</div>",
"translation": "## Chaining pipes\n## 链式管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "This example&mdash;which displays **<samp>FRIDAY, APRIL 15, 1988</samp>**&mdash;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/content-2/guide/pipes.md"
},
{
"original": "## Custom pipes",
"translation": "## 自定义管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "This pipe definition reveals the following key points:",
"translation": "在这个管道的定义中体现了几个关键点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "* A pipe is a class decorated with pipe metadata.",
"translation": "管道是一个带有“管道元数据(pipe metadata)”装饰器的类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "## The *PipeTransform* interface",
"translation": "### *PipeTransform*接口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "Now you need a component to demonstrate the pipe.",
"translation": "现在,我们需要一个组件来演示这个管道。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "Note the following:",
"translation": "要注意的有两点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "* You use your custom pipe the same way you use built-in pipes.",
"translation": "我们使用自定义管道的方式和内置管道完全相同。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "* You must include your pipe in the `declarations` array of the `AppModule`.",
"translation": "我们必须在`AppModule`的`declarations`数组中包含这个管道。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "Remember the declarations array",
"translation": "别忘了`declarations`数组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "## Power Boost Calculator",
"translation": "## 能力倍增计算器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "## Pipes and change detection",
"translation": "## 管道与变更检测",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "No pipe",
"translation": "无管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "The companion component class provides heroes, adds heroes into the array, and can reset the array.",
"translation": "和模板相伴的组件类可以提供英雄数组,能把新的英雄添加到数组中,还能重置英雄数组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "FlyingHeroesPipe",
"translation": "“会飞的英雄”管道FlyingHeroesPipe",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "Here's the `FlyingHeroesPipe` implementation, which follows the pattern for custom pipes described earlier.",
"translation": "下面是`FlyingHeroesPipe`的实现,它遵循了我们以前见过的那些写自定义管道的模式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "Notice how a hero is added:",
"translation": "来看看我们是如何添加新英雄的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "For filtering flying heroes, consider an *impure pipe*.",
"translation": "为了过滤会飞的英雄,我们要使用*非纯(impure)管道*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "## Pure and impure pipes",
"translation": "## 纯(pure)管道与非纯(impure)管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "Before doing that, understand the difference between pure and impure, starting with a pure pipe.",
"translation": "在继续往下走之前,我们先理解一下*纯*和*非纯*之间的区别,从*纯*管道开始。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "Pure pipes",
"translation": "纯管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "This may seem restrictive but it's also fast.\nAn object reference check is fast&mdash;much faster than a deep check for\ndifferences&mdash;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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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 laterin this page.",
"translation": "或者我们也可以完全不用管道。\n有时候使用组件的属性能比用管道更好的达到目的这一点我们等后面会再提起。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "Impure pipes",
"translation": "### 非纯管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "An impure <i>FlyingHeroesPipe</i>",
"translation": "### 非纯版本的*FlyingHeroesPipe*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`.",
"translation": "我们可以从`FlyingHeroesComponent`派生出一个`FlyingHeroesImpureComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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>中确认,当我们输入新的英雄甚至修改#[code heroes]数组时,这个#[i 会飞的英雄]的显示也跟着更新了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "{@a async-pipe}\n<h3 class=\"no-toc\">The impure <i>AsyncPipe</i></h3>",
"translation": "非纯 <i>AsyncPipe</i>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "An impure caching pipe",
"translation": "一个非纯而且带缓存的管道",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "Write one more impure pipe, a pipe that makes an HTTP request.",
"translation": "我们来写更多的非纯管道一个向服务器发起HTTP请求的管道。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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</span>:",
"translation": "我们确实得小心点。\n这个管道只有当所请求的URL发生变化时才会向服务器发起请求。它会缓存服务器的响应。\n代码如下它使用[Angular http](guide/http)客户端来接收数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "The component renders as the following:",
"translation": "组件渲染起来是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "A breakpoint on the pipe's request for data shows the following:",
"translation": "这个管道上的断点请求数据的过程显示:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "* Each binding gets its own pipe instance.",
"translation": "每个绑定都有它自己的管道实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "* Each pipe instance caches its own URL and data.",
"translation": "每个管道实例都缓存了它自己的URL和数据。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"original": "* Each pipe instance only calls the server once.",
"translation": "每个管道实例都只调用一次服务器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "Debugging with the json pipe",
"translation": "借助json管道进行调试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "Pure pipes and pure functions",
"translation": "### 纯管道与纯函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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`&mdash;an impure pipe with a pure function.",
"translation": "我们在本章前面见过的管道都是用纯函数实现的。\n内置的`DatePipe`就是一个用纯函数实现的纯管道。\n`ExponentialStrengthPipe`是如此,\n`FlyingHeroesComponent`也是如此。\n不久前我们刚看过的`FlyingHeroesImpurePipe`,是一个*用纯函数实现的非纯管道*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "## Next steps",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "## Appendix: No *FilterPipe* or *OrderByPipe*",
"translation": "## 附录:没有*FilterPipe*或者*OrderByPipe*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"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/content-2/guide/pipes.md"
},
{
"original": "# QuickStart",
"translation": "# 快速上手",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "Good tools make application development quicker and easier to maintain than\nif you did everything by hand.",
"translation": "好的工具能让开发更加简单快捷。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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": "在这一章CLI快速起步中我们的目标是构建并运行一个超级简单的Angular应用。我们会使用Angular-CLI来让每个Angular应用从[风格指南](guide/styleguide)中获益。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "Step 1. Set up the Development Environment",
"translation": "步骤1. 设置开发环境",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "You need to set up your development environment before you can do anything.",
"translation": "在开始工作之前,我们必须设置好开发环境。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "Step 2. Create a new project",
"translation": "步骤2. 创建新项目",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "Open a terminal window.",
"translation": "打开终端窗口。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "Generate a new project and skeleton application by running the following commands:",
"translation": "运行下列命令来生成一个新项目以及应用的骨架代码:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "Step 3: Serve the application",
"translation": "步骤3. 启动开发服务器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "Go to the project directory and launch the server.",
"translation": "进入项目目录,并启动服务器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "Your app greets you with a message:",
"translation": "本应用会用一条消息来跟你打招呼:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "Step 4: Edit your first Angular component",
"translation": "步骤4. 编辑我们的第一个Angular组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/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!!_ ",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "The browser reloads automatically with the revised title. That's nice, but it could look better.",
"translation": "浏览器会自动刷新,而我们会看到修改之后的标题。不错,不过它还可以更好看一点。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "Open `src/app/app.component.css` and give the component some style.",
"translation": "打开 `src/app/app.component.css` 并给这个组件设置一些样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "Looking good!",
"translation": "漂亮!",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "## What's next?",
"translation": "## 接下来呢?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "That's about all you'd expect to do in a \"Hello, World\" app.",
"translation": "如你所愿我们完成了这个“Hello, World”应用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "## Project file review",
"translation": "## 项目文件概览",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "An Angular CLI project is the foundation for both quick experiments and enterprise solutions.",
"translation": "Angular CLI项目是做快速试验和开发企业解决方案的基础。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "Some of the generated files might be unfamiliar to you.",
"translation": "有些生成的文件你可能觉得陌生。接下来我们就讲讲它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "### The `src` folder",
"translation": "### `src`文件夹",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "<table width=\"100%\">\n <col width=\"20%\">\n </col>\n <col width=\"80%\">\n </col>\n <tr>\n <th>\n File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "</th>\n <th>\n Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "A folder where you can put images and anything else to be copied wholesale\n when you build your application.",
"translation": "这个文件夹下你可以放图片等任何东西,在构建应用时,它们全都会拷贝到发布包中。\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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都替你考虑到了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "Every site wants to look good on the bookmark bar.\n Get started with your very own Angular icon.",
"translation": "每个网站都希望自己在书签栏中能好看一点。\n 请把它换成你自己的图标。\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "### The root folder",
"translation": "### 根目录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "<table width=\"100%\">\n <col width=\"20%\">\n </col>\n <col width=\"80%\">\n </col>\n <tr>\n <th>\n File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"original": "</th>\n <th>\n Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "Git configuration to make sure autogenerated files are not commited to source control.",
"translation": "一个Git的配置文件用来确保某些自动生成的文件不会被提交到源码控制系统中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "TypeScript compiler configuration for your IDE to pick up and give you helpful tooling.",
"translation": "TypeScript编译器的配置你的IDE会借助它来给你提供更好的帮助。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "### Next Step",
"translation": "### 下一步",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/quickstart.md"
},
{
"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/content-2/guide/quickstart.md"
},
{
"original": "# Reactive Forms",
"translation": "# 响应式表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "Try the <live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\">Reactive Forms live-example</live-example>.",
"translation": "试试<live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\">响应式表单的在线例子</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "You can also run the <live-example title=\"Reactive Forms Demo in Plunker\">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 Plunker\">响应式表单的演示程序</live-example>,并从顶部选取一个中间步骤。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Introduction to Reactive Forms",
"translation": "## 响应式表单简介",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### _Reactive_ forms",
"translation": "### *响应式*表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### _Template-driven_ forms",
"translation": "### *模板驱动*表单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "_Template-driven_ forms, introduced in the [Template guide](guide/forms), take a completely different approach.",
"translation": "在[模板](guide/forms)一章我们介绍过的*模板驱动*表单,是一种完全不同的方式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "For this reason, the `ngModel` directive is not part of the ReactiveFormsModule.",
"translation": "因此,`ngModel`并不是`ReactiveFormsModule`模块的一部分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### Async vs. sync",
"translation": "### 异步 vs. 同步",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Reactive forms are synchronous. Template-driven forms are asynchronous. It's a difference that matters.",
"translation": "响应式表单是同步的。模板驱动表单是异步的。这个不同点很重要。",
"sourceFile": "/Users/twer/private/GDE/content-2/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.",
"translation": "使用响应式表单,我们会在代码中创建整个表单控件树。\n我们可以立即更新一个值或者深入到表单中的任意节点因为所有的控件都始终是可用的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### Which is better, reactive or template-driven?",
"translation": "### 哪一个更好?响应式还是模板驱动?",
"sourceFile": "/Users/twer/private/GDE/content-2/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请自行选择更合适的方法甚至可以在同一个应用中同时使用它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/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": "在这章*响应式表单*中,我们只专注于*响应式*范式以及响应式表单技术的详情。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "## Setup",
"translation": "## 准备工作",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Create a new project named <code>angular-reactive-forms</code>:",
"translation": "创建一个名叫<code>angular-reactive-forms</code>的新项目:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Create a data model",
"translation": "## 创建数据模型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "Using the CLI, generate a new class named `data-model`:",
"translation": "使用 CLI 创建一个名叫 `data-model` 的新类:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "And copy the content below:",
"translation": "并复制下列内容:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "## Create a _reactive forms_ component",
"translation": "## 创建*响应式表单*组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Generate a new component named `HeroDetail`:",
"translation": "生成一个名叫 `HeroDetail` 的新组件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "And import:",
"translation": "并导入:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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`框,表示英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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/content-2/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)一章。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Create the template",
"translation": "## 创建模板",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Now update the component's template, with the following markup.",
"translation": "现在,在创建组件的模板文件`src/app/hero-detail.component.html`,内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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.",
"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/content-2/guide/reactive-forms.md"
},
{
"original": "## Import the _ReactiveFormsModule_",
"translation": "## 导入`ReactiveFormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "The HeroDetailComponent template uses `formControlName`\ndirective from the `ReactiveFormsModule`.",
"translation": "`HeroDetailComponent`的模板中使用了来自`ReactiveFormsModule`的`formControlName`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Do the following two things in `app.module.ts`:",
"translation": "在 `app.module.ts` 中做了下面两件事:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "1. Use a JavaScript `import` statement to access\nthe `ReactiveFormsModule`.",
"translation": "使用JavaScript的`import`语句访问`ReactiveFormsModule`和`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "1. Add `ReactiveFormsModule` to the `AppModule`'s `imports` list.",
"translation": "把`ReactiveFormsModule`添加到`AppModule`的`imports`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Display the _HeroDetailComponent_",
"translation": "## 显示`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Revise the `AppComponent` template so it displays the `HeroDetailComponent`.",
"translation": "修改`AppComponent`的模板,以便显示`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### Essential form classes",
"translation": "### 基础的表单类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "It may be helpful to read a brief description of the core form classes.",
"translation": "阅读一下这些核心表单类的简短描述也许会有用。",
"sourceFile": "/Users/twer/private/GDE/content-2/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*。",
"sourceFile": "/Users/twer/private/GDE/content-2/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表单控件比如输入框和下拉框。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`实例组成的有序数组的值和有效性状态。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "You'll learn more about these classes as you work through this guide.",
"translation": "随着本章的深入,我们将学到关于这三个类的更多知识。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### Style the app",
"translation": "### 为应用添加样式",
"sourceFile": "/Users/twer/private/GDE/content-2/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`区。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Now that everything is wired up, the browser should display something like this:",
"translation": "这些做好之后,浏览器中应该显示成这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Add a FormGroup",
"translation": "## 添加FormGroup",
"sourceFile": "/Users/twer/private/GDE/content-2/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`区就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "In the class, wrap the `FormControl` in a `FormGroup` called `heroForm` as follows:",
"translation": "在这个类中,把`FormControl`包裹进了一个名叫`heroForm`的`FormGroup`中,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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中的表单验证器。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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当用户输入名字时它的值去了哪里",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Taking a look at the form model",
"translation": "## 表单模型概览",
"sourceFile": "/Users/twer/private/GDE/content-2/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`标签紧后面添加如下代码:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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/content-2/guide/reactive-forms.md"
},
{
"original": "Great! You have the basics of a form.",
"translation": "真棒!我们有了一个基本版表单。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "## Introduction to _FormBuilder_",
"translation": "## `FormBuilder`简介",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "The `FormBuilder` class helps reduce repetition and\nclutter by handling details of control creation for you.",
"translation": "`FormBuilder`类能通过处理控件创建的细节问题来帮我们减少重复劳动。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "To use `FormBuilder`, you need to import it into `hero-detail.component.ts`:",
"translation": "要使用`FormBuilder`,我们就要先把它导入到`hero-detail.component.ts`中:",
"sourceFile": "/Users/twer/private/GDE/content-2/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`重构得更加容易读写。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "* Inject a `FormBuilder` into the constructor.",
"translation": "把`FormBuilder`注入到构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "* Call `createForm` in the constructor.",
"translation": "在构造函数中调用`createForm`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "The revised `HeroDetailComponent` looks like this:",
"translation": "修改过的`HeroDetailComponent`代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "`FormBuilder.group` is a factory method that creates a `FormGroup`. &nbsp;\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/content-2/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/content-2/guide/reactive-forms.md"
},
{
"original": "### Validators.required",
"translation": "### Validators.required 验证器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "First, import the `Validators` symbol.",
"translation": "首先,导入`Validators`符号。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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.",
"translation": "响应式验证器是一些简单、可组合的函数。\n在模板驱动表单中配置验证器有些困难因为我们必须把验证器包装进指令中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Update the diagnostic message at the bottom of the template to display the form's validity status.",
"translation": "修改模板底部的诊断信息,以显示表单的有效性状态。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "The browser displays the following:",
"translation": "浏览器会显示下列内容:",
"sourceFile": "/Users/twer/private/GDE/content-2/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`.",
"translation": "`Validators.required`生效了,但状态还是`INVALID`,因为输入框中还没有值。\n在输入框中输入就会看到这个状态从`INVALID`变成了`VALID`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "In a real app, you'd replace the diagnosic message with a user-friendly experience.",
"translation": "在真实的应用中,我们要把这些诊断信息替换成用户友好的信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### More FormControls",
"translation": "### 更多的表单控件FormControl",
"sourceFile": "/Users/twer/private/GDE/content-2/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": "每个英雄可以有多个名字,还有一个住址、一项超能力,有时还会有一个副手。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`(州列表)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Declare the `states` property and add some address `FormControls` to the `heroForm` as follows.",
"translation": "声明`states`属性并往`heroForm`中添加一些表示住址的`FormControl`,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Then add corresponding markup in `hero-detail.component.html`\nwithin the `form` element.",
"translation": "然后在`hero-detail.component.html`文件中把对应的脚本添加到`form`元素中。",
"sourceFile": "/Users/twer/private/GDE/content-2/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 `formGroupName` 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/content-2/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`.",
"translation": "修改过的模板包含更多文本输入框,一个`state`选择框,`power`(超能力)的单选按钮和一个`sidekick`检查框。",
"sourceFile": "/Users/twer/private/GDE/content-2/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如果不绑定这个值这个选择框就会显示来自数据模型中的第一个选项。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### Nested FormGroups",
"translation": "### 多级`FormGroup`",
"sourceFile": "/Users/twer/private/GDE/content-2/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": "这个表单变得越来越大、越来越笨重。我们可以把一些相关的`FormControl`组织到多级`FormGroup`中。\n`street`、`city`、`state`和`zip`属性就可以作为一个名叫`address`的`FormGroup`。\n用这种方式多级表单组和控件可以让我们轻松地映射多层结构的数据模型以便帮助我们跟踪这组相关控件的有效性和状态。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`.",
"translation": "我们用`FormBuilder`在这个名叫`heroForm`的组件中创建一个`FormGroup`,并把它用作父`FormGroup`。\n再次使用`FormBuilder`创建一个子级`FormGroup`,其中包括这些住址控件。把结果赋值给父`FormGroup`中新的`address`属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Youve changed 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/content-2/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`。",
"sourceFile": "/Users/twer/private/GDE/content-2/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如下",
"sourceFile": "/Users/twer/private/GDE/content-2/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`的住址。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Great! Youve made a group and you can see that the template\nand the form model are talking to one another.",
"translation": "真棒!我们制作了一个控件组,并且可以看到模板和表单模型已经能彼此通讯了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Inspect _FormControl_ Properties",
"translation": "## 查看`FormControl`的属性",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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:",
"translation": "我们可以使用`.get()`方法来提取表单中一个单独`FormControl`的状态。\n我们可以在组件类中这么做或者通过往模板中添加下列代码来把它显示在页面中就添加在`{{form.value | json}}`插值表达式的紧后面:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "To get the state of a `FormControl` thats inside a `FormGroup`, use dot notation to path to the control.",
"translation": "要点取得`FormGroup`中的`FormControl`的状态,使用点语法来指定到控件的路径。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`的*任意*属性,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Property",
"translation": "属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Description",
"translation": "说明",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "the value of a `FormControl`.",
"translation": "`FormControl`的值。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "the validity of a `FormControl`. Possible values: `VALID`,\n `INVALID`, `PENDING`, or `DISABLED`.",
"translation": "`FormControl`的有效性。可能的值有`VALID`、`INVALID`、`PENDING`或`DISABLED`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "`true` if the user has _not_ changed the value in the UI.\n Its opposite is `myControl.dirty`.",
"translation": "如果用户*尚未*改变过这个控件的值,则为`true`。它总是与`myControl.dirty`相反。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Learn 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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "## The _data model_ and the _form model_",
"translation": "## *数据模型*与*表单模型*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "In this app, the `HeroDetailComponent` gets its hero from a parent `HeroListComponent`",
"translation": "在这个应用中,`HeroDetailComponent`从它的父组件`HeroListComponent`中取得一个英雄。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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": "组件必须把*数据模型*中的英雄值复制到*表单模型*中。这里隐含着两个非常重要的点。",
"sourceFile": "/Users/twer/private/GDE/content-2/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": "开发人员必须理解*数据模型*是如何映射到*表单模型*中的属性的。",
"sourceFile": "/Users/twer/private/GDE/content-2/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元素流向*表单模型*的,而不是*数据模型*。表单控件永远不会修改*数据模型*。",
"sourceFile": "/Users/twer/private/GDE/content-2/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但是*表单模型*的形态越接近*数据模型*,事情就会越简单。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "In this `HeroDetailComponent`, the two models are quite close.",
"translation": "在`HeroDetailComponent`中,这两个模型是非常接近的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Recall the definition of `Hero` in `data-model.ts`:",
"translation": "回忆一下`data-model.ts`中的`Hero`定义:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Here, again, is the component's `FormGroup` definition.",
"translation": "这里又是组件的`FormGroup`定义。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "There are two significant differences between these models:",
"translation": "在这些模型中有两点显著的差异:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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\")则可以表示多个。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`方法来把*数据模型*拷贝到*表单模型*中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Take a moment to refactor the _address_ `FormGroup` definition for brevity and clarity as follows:",
"translation": "花一点时间来重构一下`address`这个`FormGroup`定义,来让它更简洁清晰,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "## Populate the form model with _setValue_ and _patchValue_",
"translation": "## 使用`setValue`和`patchValue`来操纵表单模型",
"sourceFile": "/Users/twer/private/GDE/content-2/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`来初始化或重置这些值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### _setValue_",
"translation": "### _setValue_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/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`**,我们可以*立即*设置*每个*表单控件的值,只要把与*表单模型*的属性精确匹配的数据模型传进去就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "The `setValue` method checks the data object thoroughly before assigning any form control values.",
"translation": "`setValue`方法会在赋值给任何表单控件之前先检查数据对象的值。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`会默默地失败。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "On the other hand,`setValue` will catch\nthe error and report it clearly.",
"translation": "而`setValue`会捕获错误,并清晰的报告它。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`结构是非常像的。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/guide/reactive-forms.md"
},
{
"original": "### _patchValue_",
"translation": "### _patchValue_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/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`中的指定控件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "This example sets only the form's `name` control.",
"translation": "这个例子只会设置表单的`name`控件。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`不会检查缺失的控件值,并且不会抛出有用的错误信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### When to set form model values (_ngOnChanges_)",
"translation": "### 什么时候设置表单的模型值(`ngOnChanges`",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/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/content-2/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/content-2/guide/reactive-forms.md"
},
{
"original": "Add the `hero` input property.",
"translation": "添加输入属性`hero`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Add the `ngOnChanges` method to the class as follows:",
"translation": "向该类中添加`ngOnChanges`方法,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### _reset_ the form flags",
"translation": "### *重置*表单的标识。",
"sourceFile": "/Users/twer/private/GDE/content-2/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/content-2/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/content-2/guide/reactive-forms.md"
},
{
"original": "### Create the _HeroListComponent_ and _HeroService_",
"translation": "### 创建`HeroListComponent`和`HeroService`",
"sourceFile": "/Users/twer/private/GDE/content-2/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:",
"translation": "`HeroDetalComponent`是一个嵌套在`HeroListComponent`的*主从*视图中的子组件。如果把它们放在一起就是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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`检测到英雄的变化,并使用当前英雄的值重置此表单。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "A \"Refresh\" button clears the hero list and the current selected hero before refetching the heroes.",
"translation": "\"刷新\"按钮清除英雄列表和当前选中的英雄,然后重新获取英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/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\")。",
"sourceFile": "/Users/twer/private/GDE/content-2/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接下来我们回到正轨继续学习*表单数组*属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Use _FormArray_ to present an array of _FormGroups_",
"translation": "## 使用`FormArray`来表示`FormGroup`数组",
"sourceFile": "/Users/twer/private/GDE/content-2/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`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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`的数组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "To _work_ with a `FormArray` you do the following:",
"translation": "要想使用`FormArray`,我们要这么做:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "1. Define the items (`FormControls` or `FormGroups`) in the array.",
"translation": "在数组中定义条目(`FormControl`或`FormGroup`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "1. Initialize the array with items created from data in the _data model_.",
"translation": "把这个数组初始化微一组从*数据模型*中的数据创建的条目。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "1. Add and remove items as the user requires.",
"translation": "根据用户的需求添加或移除这些条目。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`,并且让用户添加或修改这些住址(移除住址功能请课后自行实现)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Youll 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`显示第一个英雄住址。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### From _address_ to _secret lairs_",
"translation": "### 从*住址*到*秘密小屋*Secret Lair",
"sourceFile": "/Users/twer/private/GDE/content-2/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`定义:",
"sourceFile": "/Users/twer/private/GDE/content-2/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`让我们遇到了一个重要问题:*表单模型*与*数据模型*不再匹配了。",
"sourceFile": "/Users/twer/private/GDE/content-2/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.",
"translation": "显然,必须在两者之间建立关联。但它在应用领域中的意义不限于此,它可以用于任何东西。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### Initialize the \"secretLairs\" _FormArray_",
"translation": "### 初始化`FormArray`型的`secretLairs`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "The default form displays a nameless hero with no addresses.",
"translation": "默认的表单显示一个无地址的无名英雄。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`来进行初始化。",
"sourceFile": "/Users/twer/private/GDE/content-2/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我们所要替换的是*控件*,而不是控件的*值*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Notice also that the _secretLairs_ `FormArray` contains **`FormGroups`**, not `Addresses`.",
"translation": "还要注意,`secretLairs`数组中包含的是**`FormGroup`,而不是`Address`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### Get the _FormArray_",
"translation": "### 获取`FormArray`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "The `HeroDetailComponent` should be able to display, add, and remove items from the _secretLairs_ `FormArray`.",
"translation": "`HeroDetailComponent`应该能从`secretLairs`中显示、添加和删除条目。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`的便捷属性中来让它更清晰,并供复用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### Display the _FormArray_",
"translation": "### 显示`FormArray`",
"sourceFile": "/Users/twer/private/GDE/content-2/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`.",
"translation": "当前HTML模板显示单个的地址`FormGroup`。\n我们要把它修改成能显示0、1或更多个表示英雄地址的`FormGroup`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "The trick lies in knowing how to write the `*ngFor`. There are three key points:",
"translation": "诀窍在于要知道如何编写`*ngFor`。主要有三点:",
"sourceFile": "/Users/twer/private/GDE/content-2/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.",
"translation": "在`*ngFor`的`<div>`之外套上另一个包装`<div>`,并且把它的`formArrayName`指令设为`\"secretLairs\"`。\n 这一步为内部的表单控件建立了一个`FormArray`型的`secretLairs`作为上下文以便重复渲染HTML模板。",
"sourceFile": "/Users/twer/private/GDE/content-2/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.",
"translation": "这些重复条目的数据源是`FormArray.controls`而不是`FormArray`本身。\n 每个控件都是一个`FormGroup`型的地址对象与以前的模板HTML所期望的格式完全一样。",
"sourceFile": "/Users/twer/private/GDE/content-2/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.",
"translation": "每个被重复渲染的`FormGroup`都需要一个独一无二的`formGroupName`,它必须是`FormGroup`在这个`FormArray`中的索引。\n 我们将复用这个索引,以便为每个地址组合出一个独一无二的标签。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Here's the skeleton for the _secret lairs_ section of the HTML template:",
"translation": "下面是HTML模板中*秘密小屋*部分的代码骨架:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Here's the complete template for the _secret lairs_ section:",
"translation": "这里是*秘密小屋*部分的完整模板:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### Add a new lair to the _FormArray_",
"translation": "### 把新的小屋添加到`FormArray`中",
"sourceFile": "/Users/twer/private/GDE/content-2/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`添加到其中。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/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”按钮时就保存一次。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### Try it!",
"translation": "### 试试看!",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### Remove a lair",
"translation": "### 移除一个小屋",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "## Observe control changes",
"translation": "## 监视控件的变化",
"sourceFile": "/Users/twer/private/GDE/content-2/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`。",
"sourceFile": "/Users/twer/private/GDE/content-2/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幸运的是我们可以通过订阅表单控件的属性之一来了解这些变化此属性会发出变更通知。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "Add the following method to log changes to the value of the _name_ `FormControl`.",
"translation": "添加下列方法,以监听姓名这个`FormControl`中值的变化。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Call it in the constructor, after creating the form.",
"translation": "在构造函数中调用它,就在创建表单的代码之后:",
"sourceFile": "/Users/twer/private/GDE/content-2/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`绑定在组件模板的底部显示这个数组:",
"sourceFile": "/Users/twer/private/GDE/content-2/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我们会看到每次按键都会记录一个新名字。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### When to use it",
"translation": "### 什么时候用它",
"sourceFile": "/Users/twer/private/GDE/content-2/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*在组件类中*订阅表单控件属性变化的可观察对象以触发应用逻辑则是比较难的方式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Save form data",
"translation": "## 保存表单数据",
"sourceFile": "/Users/twer/private/GDE/content-2/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:",
"translation": "`HeroDetailComponent`捕获了用户输入,但没有用它做任何事。\n在真实的应用中我们可能要保存这些英雄的变化。\n在真实的应用中我们还要能丢弃未保存的变更然后继续编辑。\n在实现完本节的这些特性之后表单是这样的",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### Save",
"translation": "### 保存",
"sourceFile": "/Users/twer/private/GDE/content-2/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`的一个方法来进行保存。",
"sourceFile": "/Users/twer/private/GDE/content-2/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`助手来深层复制变化后的模型值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "**Address deep copy**",
"translation": "**地址的深层复制**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "### Revert (cancel changes)",
"translation": "### 丢弃(撤销修改)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/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`数据模型来构建出*表单模型*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "### Buttons",
"translation": "### 按钮",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "Add the \"Save\" and \"Revert\" buttons near the top of the component's template:",
"translation": "把“Save”和“Revert”按钮添加到组件模板的顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"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/content-2/guide/reactive-forms.md"
},
{
"original": "This is the final step in the demo.\nTry the <live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\"></live-example>.",
"translation": "这是本演示的最后一步。\n去试试<live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\"></live-example>吧。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "* How to create a reactive form component and its corresponding template.",
"translation": "如何创建一个响应式表单控件及其对应的模板。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "* How to use `FormBuilder` to simplify coding a reactive form.",
"translation": "如何使用`FormBuilder`来简化响应式表单的编码工作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "* Grouping `FormControls`.",
"translation": "分组`FormControl`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "* Inspecting `FormControl` properties.",
"translation": "审查`FormControl`的属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "* Setting data with `patchValue` and `setValue`.",
"translation": "使用`patchValue`和`setValue`设置数据。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "* Adding groups dynamically with `FormArray`.",
"translation": "使用`FormArray`动态添加控件组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "* Observing changes to the value of a `FormControl`.",
"translation": "监听`FormControl`中值的变化。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "* Saving form changes.",
"translation": "保存表单中的更改。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "The key files of the final version are as follows:",
"translation": "最终版中的核心文件如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "You can download the complete source for all steps in this guide\nfrom the <live-example title=\"Reactive Forms Demo in Plunker\">Reactive Forms Demo</live-example> live example.",
"translation": "你可以到<live-example title=\"Reactive Forms Demo in Plunker\">响应式表单在线例子</live-example>中下载本章所有步骤的完整代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/reactive-forms.md"
},
{
"original": "# Routing & Navigation",
"translation": "# 路由与导航",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "## Overview",
"translation": "## 概览",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The browser is a familiar model of application navigation:",
"translation": "浏览器具有我们熟悉的导航模式:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Enter a URL in the address bar and the browser navigates to a corresponding page.",
"translation": "在地址栏输入URL浏览器就会导航到相应的页面。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Click links on the page and the browser navigates to a new page.",
"translation": "在页面中点击链接,浏览器就会导航到一个新页面。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "## The Basics",
"translation": "## 基础知识",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "An introduction to a few core router concepts will help orient you to the details that follow.",
"translation": "在接触细节之前,我们先来介绍关于路由的一些核心概念。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### *&lt;base href>*",
"translation": "### *&lt;base href>* 元素",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Router imports",
"translation": "### 从路由库中导入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Configuration",
"translation": "### 配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Router outlet",
"translation": "### 路由出口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Router links",
"translation": "### 路由器链接",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Consider the following template:",
"translation": "考虑下列模板:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Router state",
"translation": "### 路由器状态",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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": "路由器状态为我们提供了从任意激活路由开始向上或向下遍历路由树的一种方式,以获得关于父、子、兄弟路由的信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Activated route",
"translation": "### 激活的路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Property",
"translation": "属性\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述\n </th>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "An `Observable` of the route path(s), represented as an array of strings for each part of the route path.",
"translation": "路由路径的`Observable`对象,是一个由路由路径中的各个部分组成的字符串数组。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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)解析而来的值。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The name of the `RouterOutlet` used to render the route. For an unnamed outlet, the outlet name is _primary_.",
"translation": "要把该路由渲染到的`RouterOutlet`的名字。对于无名路由,它的路由名是`primary`,而不是空串。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The route configuration used for the route that contains the origin path.",
"translation": "用于该路由的路由配置信息,其中包含原始路径。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The route's parent `ActivatedRoute` when this route is a [child route](#child-routing-component).",
"translation": "当该路由是一个[子路由](#child-routing-component)时,表示该路由的父级`ActivatedRoute`。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Contains the first `ActivatedRoute` in the list of this route's child routes.",
"translation": "包含该路由的子路由列表中的第一个`ActivatedRoute`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Contains all the [child routes](#child-routing-component) activated under the current route.",
"translation": "包含当前路由下所有已激活的[子路由](#child-routing-component)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "**`params`** &mdash; 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/content-2/guide/router.md"
},
{
"original": "**`queryParams`** &mdash; 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/content-2/guide/router.md"
},
{
"original": "### Router events",
"translation": "### 路由事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Router Event",
"translation": "路由器事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "An [event](api/router/NavigationStart) triggered when navigation starts.",
"translation": "本[事件](api/router/NavigationStart)会在导航开始时触发。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "An [event](api/router/RouteConfigLoadEnd) triggered after a route has been lazy loaded.",
"translation": "本[事件](api/router/RouteConfigLoadEnd)会在路由被惰性加载之后触发。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "An [event](api/router/NavigationEnd) triggered when navigation ends successfully.",
"translation": "本[事件](api/router/NavigationEnd)会在导航成功结束之后触发。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "An [event](api/router/NavigationError) triggered when navigation fails due to an unexpected error.",
"translation": "这个[事件](api/router/NavigationError)会在导航由于意料之外的错误而失败时触发。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Summary",
"translation": "### 总结一下",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Here are the key `Router` terms and their meanings:",
"translation": "下面是一些*路由器*中的关键词汇及其含义:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Router Part",
"translation": "路由器部件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Meaning",
"translation": "含义",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Router",
"translation": "<code>Router</code>(路由器)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "RouterModule",
"translation": "<code>RouterModule</code>(路由器模块)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "A separate NgModule that provides the necessary service providers\n and directives for navigating through application views.",
"translation": "<p>\n 一个独立的Angular模块用于提供所需的服务提供商以及用来在应用视图之间进行导航的指令。\n </p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Routes",
"translation": "<code>Routes</code>(路由数组)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Defines an array of Routes, each mapping a URL path to a component.",
"translation": "定义了一个路由数组每一个都会把一个URL路径映射到一个组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Route",
"translation": "<code>Route</code>(路由)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "RouterOutlet",
"translation": "<code>RouterOutlet</code>(路由出口)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The directive (<code>&lt;router-outlet></code>) that marks where the router displays a view.",
"translation": "该指令(<code>&lt;router-outlet></code>)用来标记出路由器该在哪里显示视图。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "RouterLink",
"translation": "<code>RouterLink</code>(路由链接)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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>link parameters array</i> triggers a navigation.",
"translation": "该指令用来把一个可点击的HTML元素绑定到路由。\n 点击带有绑定到<i>字符串</i>或<i>链接参数数组</i>的<code>routerLink</code>指令的元素就会触发一次导航。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "RouterLinkActive",
"translation": "<code>RouterLinkActive</code>(活动路由链接)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "ActivatedRoute",
"translation": "<code>ActivatedRoute</code>(激活的路由)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "RouterState",
"translation": "<code>RouterState</code>(路由器状态)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "<i>Link parameters array</i>",
"translation": "链接参数数组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "An array that the router interprets as a routing instruction.\n You can bind that array toa <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/content-2/guide/router.md"
},
{
"original": "<i>Routing component</i>",
"translation": "<i>路由组件</i>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "<td>\n<p> An Angular component with a <code>RouterOutlet</code> that displays views based on router navigations.\n</p>",
"translation": "<p>\n 一个带有<code>RouterOutlet</code>的Angular组件它根据路由器的导航来显示相应的视图。\n </p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "## The sample application",
"translation": "## 范例应用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* Organizing the application features into modules.",
"translation": "把应用的各个特性组织成模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Navigating to a component (*Heroes* link to \"Heroes List\").",
"translation": "导航到组件(*Heroes*链接到“英雄列表”组件)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Including a route parameter (passing the Hero `id` while routing to the \"Hero Detail\").",
"translation": "包含一个路由参数(当路由到“英雄详情”时,把该英雄的`id`传进去)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Child routes (the *Crisis Center* has its own routes).",
"translation": "子路由(*危机中心*特性有一组自己的路由)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The `CanActivate` guard (checking route access).",
"translation": "`CanActivate`守卫(检查路由的访问权限)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The `CanActivateChild` guard (checking child route access).",
"translation": "`CanActivateChild`守卫(检查子路由的访问权限)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The `CanDeactivate` guard (ask permission to discard unsaved changes).",
"translation": "`CanDeactivate`守卫(询问是否丢弃未保存的更改)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The `Resolve` guard (pre-fetching route data).",
"translation": "`Resolve`守卫(预先获取路由数据)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Lazy loading feature modules.",
"translation": "惰性加载特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The `CanLoad` guard (check before loading feature module assets).",
"translation": "`CanLoad`守卫(在加载特性模块之前进行检查)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### The sample application in action",
"translation": "### 范例程序的动图",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The application has three main feature areas:",
"translation": "本应用具有三个主要的特性区:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. A *Crisis Center* for maintaining the list of crises for assignment to heroes.",
"translation": "*危机中心*用于维护要指派给英雄的危机列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. A *Heroes* area for maintaining the list of heroes employed by the agency.",
"translation": "*英雄*区用于维护管理局雇佣的英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. An *Admin* area to manage the list of crises and heroes.",
"translation": "*管理*区会管理危机和英雄的列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Try it by clicking on this <live-example title=\"Hero Employment Agency Live Example\">live example link</live-example>.",
"translation": "点击<live-example title=\"Hero Employment Agency Live Example\"></live-example>试用一下。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Select one hero and the app takes you to a hero editing screen.",
"translation": "选择其中之一,该应用就会把我们带到此英雄的编辑页面。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Now click the *Crisis Center* link for a list of ongoing crises.",
"translation": "现在,点击*危机中心*链接,前往*危机*列表页。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Up pops a dialog box.",
"translation": "我们会看到弹出了一个对话框。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You can say \"OK\" and lose your changes or click \"Cancel\" and continue editing.",
"translation": "我们可以回答“确定”以放弃这些更改,或者回答“取消”来继续编辑。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Proceed to the first application milestone.",
"translation": "我们这就开始本应用的第一个里程碑。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "## Milestone 1: Getting started with the router",
"translation": "## 里程碑1从路由器开始",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Begin with a simple version of the app that navigates between two empty views.",
"translation": "开始本应用的一个简版,它在两个空路由之间导航。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Set the *&lt;base href>*",
"translation": "### 设置*&lt;base href>*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "You must **add a\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base\" title=\"base href\">&lt;base href&gt; 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\">&lt;base href&gt; 元素</a>**,这样`pushState`才能正常工作。\n当引用CSS文件、脚本和图片时浏览器会用`<base href>`的值作为*相对*URL的前缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "A live coding environment like Plunker 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": "像Plunker这样的在线编程环境会动态设置应用的基地址base href因此我们没办法指定固定的地址。\n这就是为什么我们要用一个脚本动态写入`<base>`标签,而不是直接写`<base href...>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You only need this trick for the live example, not production code.",
"translation": "我们只应该在在线例子这种情况下使用这种小花招,不要把它用到产品的正式代码中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Importing from the router library",
"translation": "### 从路由库中导入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "You teach the router how to navigate by configuring it with routes.",
"translation": "通过一些路由来配置路由器,我们可以教它如何进行导航。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### Define routes",
"translation": "#### 定义路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "A router must be configured with a list of route definitions.",
"translation": "路由器必须用“路由定义”的列表进行配置。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "In simpler terms, you might say this of the first route:",
"translation": "直白的说,我们可以这样解释第一个路由:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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随着应用的成长我们将需要将路由配置重构到单独的文件并创建**[路由模块](guide/router#routing-module)** - 一种特别的、专门为特性模块的路由器服务的**服务模块**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Providing the `RouterModule` in the `AppModule` makes the Router available everywhere in the application.",
"translation": "在`AppModule`中提供`RouterModule`,让该路由器在应用的任何地方都能被使用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### The *AppComponent* shell",
"translation": "### *AppComponent*外壳组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The corresponding component template looks like this:",
"translation": "该组件所对应的模板是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### *RouterOutlet*",
"translation": "### *RouterOutlet* 指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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>`。\n但路由器可以支持多个*命名的*出口outlet将来我们会涉及到这部分特性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### *RouterLink* binding",
"translation": "### `routerLink` 绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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=\"...\"`。我们从路由库中导入了`RouterLink`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### *RouterLinkActive* binding",
"translation": "### `routerLinkActive`绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### *Router directives*",
"translation": "### *路由器指令集*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The current state of `app.component.ts` looks like this:",
"translation": "`app.component.ts`目前是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Wildcard route",
"translation": "### 通配符路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Create the `PageNotFoundComponent` to display when users visit invalid URLs.",
"translation": "创建`PageNotFoundComponent`,以便在用户访问无效网址时显示它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "As with the other components, add the `PageNotFoundComponent` to the `AppModule` declarations.",
"translation": "像其它组件一样,把`PageNotFoundComponent`添加到`AppModule`的声明中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### The _default_ route to heroes",
"translation": "### 把*默认*路由设置为英雄列表",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "When the application launches, the initial URL in the browser bar is something like:",
"translation": "应用启动时浏览器地址栏中的初始URL是这样的",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Redirecting routes",
"translation": "### 重定向路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Basics wrap up",
"translation": "### “起步阶段”总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "You've learned how to do the following:",
"translation": "我们已经学会了如何:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Load the router library.",
"translation": "加载路由库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* Add a `router-outlet` to the shell template where views will be displayed.",
"translation": "往壳组件的模板中添加一个`router-outlet`指令,视图将会被显示在那里",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Configure the router module with `RouterModule.forRoot`.",
"translation": "用`RouterModule.forRoot`配置路由器模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Set the router to compose HTML5 browser URLs.",
"translation": "设置路由器使其合成HTML5模式的浏览器URL。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* handle invalid routes with a `wildcard` route.",
"translation": "使用通配符路由来处理无效路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* navigate to the default route when the app launches with an empty path.",
"translation": "当应用在空路径下启动时,导航到默认路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The starter app's structure looks like this:",
"translation": "这个初学者应用的结构是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Here are the files discussed in this milestone.",
"translation": "下面是当前里程碑中讨论过的文件列表:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "## Milestone 2: *Routing module*",
"translation": "## 里程碑 #2**路由模块**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The **Routing Module** has several characteristics:",
"translation": "**路由模块**有一系列特性:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Separates routing concerns from other application concerns.",
"translation": "把路由这个关注点从其它应用类关注点中分离出去",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Provides a module to replace or remove when testing the application.",
"translation": "测试特性模块时,可以替换或移除路由模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Provides a well-known location for routing service providers including guards and resolvers.",
"translation": "为路由服务提供商(包括守卫和解析器等)提供一个共同的地方",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Does **not** [declare components](guide/ngmodule-faq#routing-module).",
"translation": "**不要**[声明组件](guide/ngmodule-faq#routing-module)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Refactor the routing configuration into a _routing module_",
"translation": "### 将路由配置重构为*路由模块*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "After these steps, the file should look like this.",
"translation": "做完这些之后,该文件变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Do you need a _Routing Module_?",
"translation": "### 你需要**路由模块**吗?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Choose one pattern or the other and follow that pattern consistently.",
"translation": "我们建议你选择其中一种模式,并坚持模式的一致性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Most developers should always implement a Routing Module for the sake of consistency.",
"translation": "大多数开发者应该采用路由模块,以保持一致性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "It 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开发者可以很自然的从路由模块中查找和扩展路由配置。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "## Milestone 3: Heroes feature",
"translation": "## 里程碑 #2 英雄特征区",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You've seen how to navigate using the `RouterLink` directive.\nNow you'll learn the following:",
"translation": "我们刚刚学习了如何用`RouterLink`指令进行导航。接下来我们将到:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Organize the app and routes into *feature areas* using modules.",
"translation": "用模块把应用和路由组织为一些*特性区*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Navigate imperatively from one component to another.",
"translation": "命令式地从一个组件导航到另一个组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Pass required and optional information in route parameters.",
"translation": "通过路由传递必要信息和可选信息",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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=\"Tour of Heroes: Services example code\"></live-example>中赋值大部分代码过来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Here's how the user will experience this version of the app:",
"translation": "下面是用户将看到的版本:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "A typical application has multiple *feature areas*,\neach dedicated to a particular business purpose.",
"translation": "典型的应用具有多个*特性区*,每个特性区都专注于特定的业务用途。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Add heroes functionality",
"translation": "### 添加英雄管理功能",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Follow these steps:",
"translation": "按照下列步骤:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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=\"Tour of Heroes: Services example code\">教程中的“服务”部分</live-example>的代码复制到`app.component.ts`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Make a few minor but necessary changes:",
"translation": "做一些微小但必要的修改:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Delete the `selector` (routed components don't need them).",
"translation": "删除`selector`(路由组件不需要它们)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Delete the `<h1>`.",
"translation": "删除`<h1>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Relabel the `<h2>` to `<h2>HEROES</h2>`.",
"translation": "给`<h2>`加文字,改成`<h2>HEROES</h2>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Delete the `<hero-detail>` at the bottom of the template.",
"translation": "删除模板底部的`<hero-detail>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Rename the `AppComponent` class to `HeroListComponent`.",
"translation": "把`AppComponent`类改名为`HeroListComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "When you're done, you'll have these *hero management* files:",
"translation": "安排完这些,我们就有了四个*英雄管理*特性区的文件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### *Hero* feature routing requirements",
"translation": "### *英雄*特性区的路由需求",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### *Hero* feature route configuration",
"translation": "### *英雄*特性区的路由配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Add the routing module to the _HeroesModule_",
"translation": "### 把路由模块添加到`HeroesModule`中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Add the `HeroRoutingModule` to the `HeroModule`\njust as you added `AppRoutingModule` to the `AppModule`.",
"translation": "我们在`Heroes`模块中从`heroes-routing.module.ts`中导入`HeroRoutingModule`,并注册其路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Remove duplicate hero routes",
"translation": "### 移除重复的“英雄管理”路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Import hero module into AppModule",
"translation": "### 把“英雄管理”模块导入到AppModule",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "After these steps, the `AppModule` should look like this:",
"translation": "经过这些步骤,`AppModule`变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Module import order matters",
"translation": "### 导入模块的顺序很重要",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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 &mdash; which matches _every_ URL &mdash;\nwill intercept the attempt to navigate to a hero route.",
"translation": "每个路由模块都会根据*导入的顺序*把自己的路由配置追加进去。\n如果我们先列出了`AppRoutingModule`,那么通配符路由就会被注册在“英雄管理”路由*之前*。\n通配符路由它匹配*任意*URL将会拦截住每一个到“英雄管理”路由的导航因此事实上屏蔽了所有“英雄管理”路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Route definition with a parameter",
"translation": "### 带参数的路由定义",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Setting the route parameters in the list view",
"translation": "### 在列表视图中设置路由参数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### _Activated Route_ in action",
"translation": "#### _Activated Route_ 实战",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Import the `Router`, `ActivatedRoute`, and `ParamMap` tokens from the router package.",
"translation": "我们要从路由器(`router`)包中导入`Router`、`ActivatedRoute`和`Params`类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Import the `switchMap` operator because you need it later to process the `Observable` route parameters.",
"translation": "这里导入`switchMap`操作符是因为我们稍后将会处理路由参数的可观察对象`Observable`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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": "由于参数是作为`Observable`提供的,所以我们得用`switchMap`操作符来根据名字取得`id`参数,并告诉`HeroService`来获取带有那个`id`的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "#### _ParamMap_ API",
"translation": "#### _ParamMap_ 参数 API",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Member",
"translation": "成员\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述\n </th>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Returns `true` if the parameter name is in the map of parameters.",
"translation": "如果参数名位于参数列表中,就返回 `true` 。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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`。如果参数值实际上是一个数组,就返回它的*第一个*元素。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Returns a `string array` of all parameter names in the map.",
"translation": "返回这个map中的所有参数名组成的字符串数组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### Observable <i>paramMap</i> and component reuse",
"translation": "#### <i>参数</i>的可观察对象Observable与组件复用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Feel free to unsubscribe anyway. It is harmless and never a bad practice.",
"translation": "不过,我们仍然可以随意取消订阅,这不会造成任何损害,而且也不是一项坏的实践。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### _Snapshot_: the _no-observable_ alternative",
"translation": "#### *Snapshot*快照当不需要Observable时的替代品",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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如果有可能连续多次导航到此组件那么就该用`params`可观察对象的方式。\n我们在这里选择使用`params`可观察对象策略,以防万一。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Navigating back to the list component",
"translation": "### 导航回列表组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "{@a optional-route-parameters}",
"translation": "### Route Parameters: Required or optional?\n### 路由参数:必须还是可选?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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`返回时在URL中带上英雄Magneta的`id`,不就可以了吗?接下来我们就尝试实现这个场景。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Optional information takes other forms. Search criteria are often loosely structured, e.g., `name='wind*'`.\nMultiple values are common&mdash;`after='12/31/2015' & before='1/1/2017'`&mdash;in no\nparticular order&mdash;`before='1/1/2017' & after='12/31/2015'`&mdash; in a\nvariety of formats&mdash;`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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Heroes list: optionally selecting a hero",
"translation": "### 英雄列表:选定一个英雄(也可不选)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The application still works. Clicking \"back\" returns to the hero list view.",
"translation": "该应用仍然能工作。点击“back”按钮返回英雄列表视图。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Look at the browser address bar.",
"translation": "注意浏览器的地址栏。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "It should look something like this, depending on where you run it:",
"translation": "它应该是这样的,不过也取决于你在哪里运行它:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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 &mdash; something you may not have seen before.",
"translation": "可选的路由参数没有使用“?”和“&”符号分隔因为它们将用在URL查询字符串中。\n它们是**用“;”分隔的**。\n这是*矩阵URL*标记法 —— 我们以前可能从未见过。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Route parameters in the *ActivatedRoute* service",
"translation": "### *ActivatedRoute*服务中的路由参数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The list of heroes is unchanged. No hero row is highlighted.",
"translation": "英雄列表仍没有改变,没有哪个英雄列被加亮显示。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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`中。我们把该服务注入到了`HeroDetailComponent`的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "First you extend the router import statement to include the `ActivatedRoute` service symbol:",
"translation": "首先,我们扩展该路由的导入语句,以包含进`ActivatedRoute`服务的类;",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Import the `switchMap` operator to perform an operation on the `Observable` of route parameter map.",
"translation": "我们将导入`switchMap`操作符,在路由参数的`Observable`对象上执行操作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Then you inject the `ActivatedRoute` in the `HeroListComponent` constructor.",
"translation": "接着,我们注入`ActivatedRoute`到`HeroListComponent`的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The optional `foo` route parameter is harmless and continues to be ignored.",
"translation": "这儿可选的`foo`路由参数人畜无害,并继续被忽略。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Adding animations to the routed component",
"translation": "### 为路由组件添加动画",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The heroes feature module is almost complete, but what is a feature without some smooth transitions?",
"translation": "这个“英雄”特性模块就要完成了,但这个特性还没有平滑的转场效果。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "This section shows you how to add some [animations](guide/animations)\nto the `HeroDetailComponent`.",
"translation": "在这一节,我们将为*英雄详情*组件添加一些[动画](guide/animations)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "First import `BrowserAnimationsModule`:",
"translation": "首先导入`BrowserAnimationsModule`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "This file does the following:",
"translation": "该文件做了如下工作:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Imports the animation symbols that build the animation triggers, control state, and manage transitions between states.",
"translation": "导入动画符号以构建动画触发器、控制状态并管理状态之间的过渡。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* Specifies the _wildcard state_ , `*`, that matches any animation state that the route component is in.",
"translation": "指定了一个*通配符状态* —— `*`,它匹配该路由组件存在时的任何动画状态。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Add an `animations` array to the `@Component` metadata's that contains the `slideInDownAnimation`.",
"translation": "把一个包含`slideInDownAnimation`的`animations`数组添加到`@Component`的元数据中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The other two `@HostBinding` properties style the display and position of the component.",
"translation": "另外两个`@HostBinding`属性指定组件的外观和位置。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Milestone 3 wrap up",
"translation": "### 里程碑#3的总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You've learned how to do the following:",
"translation": "我们学到了如何:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Organize the app into *feature areas*.",
"translation": "把应用组织成*特性区*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Navigate imperatively from one component to another.",
"translation": "命令式的从一个组件导航到另一个",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Pass information along in route parameters and subscribe to them in the component.",
"translation": "通过路由参数传递信息,并在组件中订阅它们",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Import the feature area NgModule into the `AppModule`.",
"translation": "把这个特性分区模块导入根模块`AppModule`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Apply animations to the route component.",
"translation": "把动画应用到路由组件上",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "After these changes, the folder structure looks like this:",
"translation": "做完这些修改之后,目录结构是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Here are the relevant files for this version of the sample application.",
"translation": "这里是当前版本的范例程序相关文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "## Milestone 4: Crisis center feature",
"translation": "## 里程碑#4危机中心",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "It's time to add real features to the app's current placeholder crisis center.",
"translation": "是时候往该应用的危机中心(现在是占位符)中添加一些真实的特性了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Begin by imitating the heroes feature:",
"translation": "我们先从模仿“英雄管理”中的特性开始:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Delete the placeholder crisis center file.",
"translation": "删除危机中心的占位文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Create an `app/crisis-center` folder.",
"translation": "创建`app/crisis-center`文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Copy the files from `app/heroes` into the new crisis center folder.",
"translation": "把`app/heroes`中的文件复制到新的危机中心文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "You'll turn the `CrisisService` into a purveyor of mock crises instead of mock heroes:",
"translation": "我们将会把`CrisisService`转换成模拟的危机列表,而不再是模拟的英雄列表:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The resulting crisis center is a foundation for introducing a new concept&mdash;**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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### A crisis center with child routes",
"translation": "### 带有子路由的危机中心",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "This section shows you how to organize the crisis center\nto conform to the following recommended pattern for Angular applications:",
"translation": "本节会展示如何组织危机中心来满足Angular应用所推荐的模式* Each feature area resides in its own folder. 把每个特性放在自己的目录中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Each feature has its own Angular feature module.",
"translation": "每个特性都有自己的Angular特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Each area has its own area root component.",
"translation": "每个特性区都有自己的根组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Each area root component has its own router outlet and child routes.",
"translation": "每个特性区的根组件中都有自己的路由出口及其子路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Feature area routes rarely (if ever) cross with routes of other features.",
"translation": "特性区的路由很少(或完全不)与其它特性区的路由交叉。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "If your app had many feature areas, the app component trees might look like this:",
"translation": "如果我们有更多特性区,它们的组件树是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Child routing component",
"translation": "### 子路由组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The `CrisisCenterComponent` has the following in common with the `AppComponent`:",
"translation": "`CrisisCenterComponent`和`AppComponent`有下列共同点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Child route configuration",
"translation": "### 子路由配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "These two routes navigate to the crisis center child components,\n`CrisisCenterHomeComponent` and `CrisisDetailComponent`, respectively.",
"translation": "这两个路由导航到了*危机中心*的两个子组件:`CrisisCenterHomeComponent`和`CrisisDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "There are *important differences* in the way the router treats these _child routes_.",
"translation": "对这些路由的处理中有一些*重要的不同*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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.",
"translation": "`Crisis Detail`路由是`Crisis List`的子路由。由于路由器默认会[复用组件](guide/router#reuse),因此当我们选择了另一个危机时,`CrisisDetailComponent`会被复用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "In contrast, back in the `Hero Detail` route, the component was recreated each time you selected a different hero.",
"translation": "作为对比,回到`Hero Detail`路由时,每当我们选择了不同的英雄时,该组件都会被重新创建。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The absolute URL for the latter example, including the `localhost` origin, is",
"translation": "本例子中包含站点部分的绝对URL就是",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Here's the complete `crisis-center-routing.module.ts` file with its imports.",
"translation": "这里是完整的`crisis-center.routing.ts`及其导入语句。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Import crisis center module into the *AppModule* routes",
"translation": "### 把危机中心模块导入到`AppModule`的路由中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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`中移除了危机中心的初始路由。我们的路由现在是由`HeroesModule`和`CrisisCenter`特性模块提供的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The `app-routing.module.ts` file retains the top-level application routes such as the default and wildcard routes.",
"translation": "我们将保持`app.routing.ts`文件中只有通用路由,本章稍后会讲解它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Relative navigation",
"translation": "### 相对导航",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The router matches such _absolute_ paths to routes starting from the top of the route configuration.",
"translation": "路由器会从路由配置的顶层来匹配像这样的*绝对路径*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Here's an example:",
"translation": "例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The router supports directory-like syntax in a _link parameters list_ to help guide route name lookup:",
"translation": "在*链接参数数组*中,路由器支持“目录式”语法来指导我们如何查询路由名:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "`./` or `no leading slash` is relative to the current level.",
"translation": "`./`或`无前导斜线`形式是相对于当前级别的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "`../` to go up one level in the route path.",
"translation": "`../`会回到当前路由路径的上一级。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "**Always** specify the complete _absolute_ path when calling router's `navigateByUrl` method.",
"translation": "当调用路由器的`navigateByUrl`时,**总是**要指定完整的*绝对路径*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Navigate to crisis list with a relative URL",
"translation": "把*危机列表*的`onSelect`方法改成使用相对导航,以便我们不用每次都从路由配置的顶层开始。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You've already injected the `ActivatedRoute` that you need to compose the relative navigation path.",
"translation": "我们已经注入过了`ActivatedRoute`,我们需要它来和相对导航路径组合在一起。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Displaying multiple routes in named outlets",
"translation": "### 用命名出口outlet显示多重路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Add an outlet named \"popup\" in the `AppComponent`, directly below the unnamed outlet.",
"translation": "在`AppComponent`中添加一个名叫“popup”的出口就在无名出口的下方。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "#### Secondary routes",
"translation": "#### 第二路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Named outlets are the targets of _secondary routes_.",
"translation": "命名出口是*第二路由*的目标。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* They are displayed in named outlets.",
"translation": "它们显示在命名出口中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Here's the component and its template:",
"translation": "下面是该组件及其模板:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "#### Add a secondary route",
"translation": "#### 添加第二路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Open the `AppRoutingModule` and add a new `compose` route to the `appRoutes`.",
"translation": "打开`AppRoutingModule`,并把一个新的`compose`路由添加到`appRoutes`中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "#### Secondary route navigation: merging routes during navigation",
"translation": "#### 第二路由导航:在导航期间合并路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The interesting part of the URL follows the `...`:",
"translation": "这个URL中有意思的部分是`...`后面的这些:* The `crisis-center` is the primary navigation. `crisis-center`是主导航。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Parentheses surround the secondary route.",
"translation": "圆括号包裹的部分是第二路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Click the _Heroes_ link and look at the URL again.",
"translation": "点击*Heroes*链接并再次查看URL",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The primary navigation part has changed; the secondary route is the same.",
"translation": "主导航的部分变化了,而第二路由没有变。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Experiment with these possibilities at your leisure.",
"translation": "有空的时候你可以自行试验这些可能性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### Clearing secondary routes",
"translation": "#### 清除第二路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "## Milestone 5: Route guards",
"translation": "## 里程碑5路由守卫",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* Perhaps the user is not authorized to navigate to the target component.",
"translation": "该用户可能无权导航到目标组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Maybe the user must login (*authenticate*) first.",
"translation": "可能用户得先登录(认证)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Maybe you should fetch some data before you display the target component.",
"translation": "在显示目标组件前,我们可能得先获取某些数据。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* You might want to save pending changes before leaving a component.",
"translation": "在离开组件前,我们可能要先保存修改。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* You might ask the user if it's OK to discard pending changes rather than save them.",
"translation": "我们可能要询问用户:你是否要放弃本次更改,而不用保存它们?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You can add _guards_ to the route configuration to handle these scenarios.",
"translation": "我们可以往路由配置中添加***守卫***,来处理这些场景。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "A guard's return value controls the router's behavior:",
"translation": "守卫返回一个值,以控制路由器的行为:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* If it returns `true`, the navigation process continues.",
"translation": "如果它返回`true`,导航过程会继续",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* If it returns `false`, the navigation process stops and the user stays put.",
"translation": "如果它返回`false`,导航过程会终止,且用户会留在原地。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation.",
"translation": "守卫还可以告诉路由器导航到别处,这样也取消当前的导航。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* [`CanActivate`](api/router/CanActivate) to mediate navigation *to* a route.",
"translation": "用[`CanActivate`](api/router/CanActivate)来处理导航*到*某路由的情况。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* [`CanActivateChild`](api/router/CanActivateChild) to mediate navigation *to* a child route.",
"translation": "用[`CanActivateChild`](api/router/CanActivateChild)来处理导航*到*某子路由的情况。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* [`CanDeactivate`](api/router/CanDeactivate) to mediate navigation *away* from the current route.",
"translation": "用[`CanDeactivate`](api/router/CanDeactivate)来处理从当前路由*离开*的情况.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* [`Resolve`](api/router/Resolve) to perform route data retrieval *before* route activation.",
"translation": "用[`Resolve`](api/router/Resolve)在路由激活*之前*获取路由数据。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* [`CanLoad`](api/router/CanLoad) to mediate navigation *to* a feature module loaded _asynchronously_.",
"translation": "用[`CanLoad`](api/router/CanLoad)来处理*异步*导航到某特性模块的情况。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "There are several examples over the next few sections.",
"translation": "我们会在接下来的小节中看到一些例子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### _CanActivate_: requiring authentication",
"translation": "### *CanActivate*: 要求认证",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The `CanActivate` guard is the tool to manage these navigation business rules.",
"translation": "`CanActivate`守卫是一个管理这些导航类业务规则的工具。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### Add an admin feature module",
"translation": "#### 添加一个“管理”特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Create an `admin` folder with a feature module file, a routing configuration file, and supporting components.",
"translation": "创建一个`admin`目录,它带有一个特性模块文件、一个路由配置文件和一些支持性组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The admin feature file structure looks like this:",
"translation": "管理特性区的文件是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The initial admin routing configuration:",
"translation": "我们的初始管理路由配置如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Component-less route: grouping routes without a component",
"translation": "### 无组件路由: 不借助组件对路由进行分组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Add an \"Admin\" link to the `AppComponent` shell so that users can get to this feature.",
"translation": "然后我们往壳组件`AppComponent`中添加一个链接,让用户能点击它,以访问该特性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### Guard the admin feature",
"translation": "#### 守护“管理特性”区",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "This is a general purpose guard&mdash;you can imagine other features\nthat require authenticated users&mdash;so you create an\n`auth-guard.service.ts` in the application root folder.",
"translation": "这是一种具有通用性的守护目标(通常会有其它特性需要登录用户才能访问),所以我们在应用的根目录下创建一个`auth-guard.ts`文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The admin feature is now protected by the guard, albeit protected poorly.",
"translation": "我们的管理特性区现在受此守卫保护了,不过这样的保护还不够。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### Teach *AuthGuard* to authenticate",
"translation": "#### 教*AuthGuard*进行认证",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Make the `AuthGuard` at least pretend to authenticate.",
"translation": "我们先让`AuthGuard`至少能“假装”进行认证。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Revise the `AuthGuard` to call it.",
"translation": "我们这就修改`AuthGuard`来调用它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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&mdash;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/content-2/guide/router.md"
},
{
"original": "#### Add the *LoginComponent*",
"translation": "#### 添加*LoginComponent*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You need a `LoginComponent` for the user to log in to the app. After logging in, you'll redirect\n to the stored URL if available, or use the default URL.\n There 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/content-2/guide/router.md"
},
{
"original": "Register a `/login` route in the `login-routing.module.ts` and add the necessary providers to the `providers`\n array. In `app.module.ts`, import the `LoginComponent` and add it to the `AppModule` `declarations`.\n Import 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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### _CanActivateChild_: guarding child routes",
"translation": "### `CanAcitvateChild`:保护子路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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`守卫和`CanAcitvate`守卫很像。\n它们的区别在于`CanActivateChild`会在*任何子路由*被激活之前运行。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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": "接下来,实现`CanAcitvateChild`方法,它所接收的参数与`CanAcitvate`方法一样:一个`ActivatedRouteSnapshot`和一个`RouterStateSnapshot`。\n`CanAcitvateChild`方法可以返回`Observable<boolean>`或`Promise<boolean>`来支持异步检查,或`boolean`来支持同步检查。\n这里返回的是`boolean`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### _CanDeactivate_: handling unsaved changes",
"translation": "### *CanDeactivate*:处理未保存的更改",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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": "我们应该暂停,并让用户决定该怎么做。如果用户选择了取消,我们就留下来,并允许更多改动。如果用户选择了确认,那就进行保存。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "You can't block while waiting for the server&mdash;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/content-2/guide/router.md"
},
{
"original": "You need the `CanDeactivate` guard.",
"translation": "我们需要`CanDeactivate`守卫。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Cancel and save",
"translation": "### 取消与保存",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Both buttons navigate back to the crisis list after save or cancel.",
"translation": "这两个按钮都会在保存或取消之后导航回危机列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "You could wait for the user's answer with synchronous, blocking code.\nThe app will be more responsive&mdash;and can do other work&mdash;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/content-2/guide/router.md"
},
{
"original": "The `DialogService`, provided in the `AppModule` for app-wide use, does the asking.",
"translation": "`DialogService`(为了在应用级使用,已经注入到了`AppModule`)就可以做到这些。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Create a _guard_ that checks for the presence of a `canDeactivate()` method in a component&mdash;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`函数的工作现场,在这里,它就是`CrisisDetailComponent`。我们并不需要知道`CrisisDetailComponent`确认退出激活状态的详情。这让我们的守卫可以被复用,这是一次轻而易举的胜利。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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`守卫。在需要访问外部信息时,`canDeactivate()`方法为提供了组件、`ActivatedRoute`和`RouterStateSnapshot`的当前实例。如果只想为这个组件使用该守卫,并且需要使用该组件属性、或者需要路由器确认是否允许从该组件导航出去时,这个守卫就非常有用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Looking back at the `CrisisDetailComponent`, it implements the confirmation workflow for unsaved changes.",
"translation": "看看`CrisisDetailComponent`组件,我们已经实现了对未保存的更改进行确认的工作流。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Add the `Guard` to the crisis detail route in `crisis-center-routing.module.ts` using the `canDeactivate` array property.",
"translation": "我们往`crisis-center.routing.ts`的危机详情路由中用`canDeactivate`数组添加一个`Guard`(守卫)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Now you have given the user a safeguard against unsaved changes.",
"translation": "现在,我们已经给了用户一个能保护未保存更改的安全守卫。\n{@a Resolve}",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### _Resolve_: pre-fetching component data",
"translation": "### _Resolve_: 预先获取组件数据",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "In summary, you want to delay rendering the routed component until all necessary data have been fetched.",
"translation": "总之,你希望的是只有当所有必要数据都已经拿到之后,才渲染这个路由组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You need a *resolver*.",
"translation": "我们需要`Resolve`守卫。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Fetch data before navigating",
"translation": "### 导航前预先加载路由信息",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Be explicit. Implement the `Resolve` interface with a type of `Crisis`.",
"translation": "为了更明确一点,可以实现一个带有`Crisis`类型的`Resolve`接口。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Remember to add the `CrisisDetailResolver` service to the `CrisisCenterRoutingModule`'s `providers` array.",
"translation": "别忘了把`CrisisDetailResolver`服务添加到`CrisisCenterRoutingModule`的`providers`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "**Three critical points**",
"translation": "**两个关键点**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The relevant *Crisis Center* code for this milestone follows.",
"translation": "本里程碑中与*危机中心*有关的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Query parameters and fragments",
"translation": "### 查询参数及片段",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Add an `anchor` element so you can jump to a certain point on the page.",
"translation": "再添加一个锚点(`A`)元素,来让你能跳转到页面中的正确位置。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Add the `NavigationExtras` object to the `router.navigate` method that navigates you to the `/login` route.",
"translation": "我们还将为`router.nativate`方法传入一个`NavigationExtras`对象,用来导航到`/login`路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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 在更新过的*英雄管理*组件中,我们将直接把`Observable`传给模板,借助`AsyncPipe`在组件被销毁时自动_取消_对`Observable`的订阅。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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*按钮,它会带着我们提供的“查询参数”和“片段”跳转到登录页。\n 点击登录按钮,我们就会被带到`Crisis Admin`页,仍然带着上一步提供的“查询参数”和“片段”。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "## Milestone 6: Asynchronous routing",
"translation": "## 里程碑6异步路由",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "How do you combat this problem? With asynchronous routing, which loads feature modules _lazily_, on request.\nLazy loading has multiple benefits.",
"translation": "如何才能解决这个问题呢?我们引进了异步路由到应用程序中,并获得在请求时才**惰性**加载特性模块的能力。这样给我们带来了下列好处:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* You can load feature areas only when requested by the user.",
"translation": "我们可以只在用户请求时才加载某些特性区。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* You can speed up load time for users that only visit certain areas of the application.",
"translation": "对于那些只访问应用程序某些区域的用户,这样能加快加载速度。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* You can continue expanding lazy loaded feature areas without increasing the size of the initial load bundle.",
"translation": "我们可以持续扩充惰性加载特性区的功能,而不用增加初始加载的包体积。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You're already made part way there.\nBy organizing the application into modules&mdash;`AppModule`,\n`HeroesModule`, `AdminModule` and `CrisisCenterModule`&mdash;you\nhave natural candidates for lazy loading.",
"translation": "我们已经完成了一部分。通过把应用组织成一些模块:`AppModule`、`HeroesModule`、`AdminModule`和`CrisisCenterModule`\n我们已经有了可用于实现惰性加载的候选者。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Lazy Loading route configuration",
"translation": "### 惰性加载路由配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Open the `AppRoutingModule` and add a new `admin` route to its `appRoutes` array.",
"translation": "打开`AppRoutingModule`,并把一个新的`admin`路由添加到它的`appRoutes`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### _CanLoad_ Guard: guarding unauthorized loading of feature modules",
"translation": "### `CanLoad`守卫:保护对特性模块的未授权加载",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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": "我们已经使用`CanAcitvate`保护`AdminModule`了,它会阻止未授权用户访问管理特性区。如果用户未登录,它就会跳转到登录页。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Preloading: background loading of feature areas",
"translation": "### 预加载:特性区的后台加载",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You've learned how to load modules on-demand.\nYou can also load modules asynchronously with _preloading_.",
"translation": "我们已经学会了如何按需加载模块,接下来再看看如何使用*预加载*技术异步加载模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "That's _preloading_.",
"translation": "这就是*预加载*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### How preloading works",
"translation": "#### 预加载的工作原理",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The `Router` offers two preloading strategies out of the box:",
"translation": "`Router`内置了两种预加载策略:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* No preloading at all which is the default. Lazy loaded feature areas are still loaded on demand.",
"translation": "完全不预加载,这是默认值。惰性加载的特性区仍然会按需加载。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Preloading of all lazy loaded feature areas.",
"translation": "预加载所有惰性加载的特性区。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "#### Lazy load the _crisis center_",
"translation": "#### 惰性加载*危机中心*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "1. Change the `crisis-center` path in the `CrisisCenterRoutingModule` to an empty string.",
"translation": "把`CrisisCenterRoutingModule`中的路径从`crisis-center`改为空字符串。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. Add a `crisis-center` route to the `AppRoutingModule`.",
"translation": "往`AppRoutingModule`中添加一个`crisis-center`路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. Set the `loadChildren` string to load the `CrisisCenterModule`.",
"translation": "设置`loadChildren`字符串来加载`CrisisCenterModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. Remove all mention of the `CrisisCenterModule` from `app.module.ts`.",
"translation": "从`app.module.ts`中移除所有对`CrisisCenterModule`的引用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "Here are the updated modules _before enabling preload_:",
"translation": "下面是打开预加载之前的模块修改版:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Surprisingly, the `AdminModule` does _not_ preload. Something is blocking it.",
"translation": "意外的是,`AdminModule`*没有*预加载,有什么东西阻塞了它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "#### CanLoad blocks preload",
"translation": "#### CanLoad会阻塞预加载",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Custom Preloading Strategy",
"translation": "### 自定义预加载策略",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "You can control what and how the router preloads with a custom preloading strategy.",
"translation": "使用自定义预加载策略,我们可以控制路由器预加载哪些路由以及如何加载。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "`SelectivePreloadingStrategy` implements the `PreloadingStrategy`, which has one method, `preload`.",
"translation": "`SelectivePreloadingStrategy`实现了`PreloadingStrategy`,它只有一个方法`preload`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "The router calls the `preload` method with two arguments:",
"translation": "路由器会用两个参数调用调用`preload`方法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. The route to consider.",
"translation": "要加载的路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. A loader function that can load the routed module asynchronously.",
"translation": "一个加载器loader函数它能异步加载带路由的模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Shortly, you'll extend the `AdminDashboardComponent` to inject this service and display its `preloadedModules` array.",
"translation": "很快,我们就会扩展`AdminDashboardComponent`来注入该服务,并且显示它的`preloadedModules`数组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "But first, make a few changes to the `AppRoutingModule`.",
"translation": "但是首先,要对`AppRoutingModule`做少量修改。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Now edit the `AdminDashboardComponent` to display the log of preloaded routes.",
"translation": "现在,编辑`AdminDashboardComponent`以显示这些预加载路由的日志。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. Import the `SelectivePreloadingStrategy` (it's a service).",
"translation": "导入`SelectivePreloadingStrategy`(它是一个服务)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. Inject it into the dashboard's constructor.",
"translation": "把它注入到仪表盘的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. Update the template to display the strategy service's `preloadedModules` array.",
"translation": "修改模板来显示这个策略服务的`preloadedModules`数组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "When you're done it looks like this.",
"translation": "当完成时,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "## Migrating URLs with Redirects",
"translation": "## 使用重定向迁移 URL",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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": "我们已经设置好了路由,并且用命令式和声明式的方式导航到了很多不同的路由。但是,任何应用的需求都会随着时间而改变。我们把链接`/heroes`和`hero/:id`指向了`HeroListComponent`和`HeroDetailComponent`组件。如果有这样一个需求,要把链接`heroes`变成`superheroes`我们希望以前的URL仍然能正常导航。但我们也不想在应用中找到并修改每一个链接这时候重定向就可以省去这些琐碎的重构工作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Changing /heroes to /superheroes",
"translation": "### 把`/heroes`修改为`/superheros`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* When using relative redirects, the `Router` use the query params and the fragment from the source URL.",
"translation": "当使用相对地址重定向时,路由器将会使用源地址(跳转前的地址)中的查询参数和片段。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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`。这样*不行*,从设计上就不行。因为路由器在每一层的路由配置中只会处理一次重定向。这样可以防止出现无限循环的重定向。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "## Inspect the router's configuration",
"translation": "## 审查路由器配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "## Wrap up and final app",
"translation": "## 总结与最终的应用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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 Plunker\"></live-example>\nwhere you can download the final source code.",
"translation": "本章中涉及到了很多背景知识,而且本应用程序也太大了,所以没法在这里显示。请访问<live-example title=\"Router Sample in Plunker\"></live-example>,在那里你可以下载最终的源码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "## Appendices",
"translation": "## 附录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The appendix material isn't essential. Continued reading is for the curious.",
"translation": "该附件中的内容不是必须的,感兴趣的人才需要阅读它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "### Appendix: link parameters array",
"translation": "### 附录:链接参数数组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "A link parameters array holds the following ingredients for router navigation:",
"translation": "链接参数数组保存路由导航时所需的成分:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The *path* of the route to the destination component.",
"translation": "指向目标组件的那个路由的*路径path*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* Required and optional route parameters that go into the route URL.",
"translation": "必备路由参数和可选路由参数它们将进入该路由的URL",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You can bind the `RouterLink` directive to such an array like this:",
"translation": "我们可以把`RouterLink`指令绑定到一个数组,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You've written a two element array when specifying a route parameter like this:",
"translation": "在指定路由参数时,我们写过一个双元素的数组,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "You can provide optional route parameters in an object like this:",
"translation": "我们可以在对象中提供可选的路由参数,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Parse it out.",
"translation": "分解一下。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The first item in the array identifies the parent route (`/crisis-center`).",
"translation": "数组中的第一个条目标记出了父路由(`/crisis-center`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* There are no parameters for this parent route so you're done with it.",
"translation": "这个父路由没有参数,因此这步已经完成了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* There is no default for the child route so you need to pick one.",
"translation": "没有默认的子路由,因此我们得选取一个。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* Voilà! `['/crisis-center']`.",
"translation": "哇!`['/crisis-center']`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* The first item in the array identifies the parent route (`/crisis-center`).",
"translation": "数组中的第一个条目用来标记出父路由('/crisis-center')。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* There are no parameters for this parent route so you're done with it.",
"translation": "这个父路由没有参数,因此这步已经完成了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The second item identifies the child route details about a particular crisis (`/:id`).",
"translation": "数组中的第二个条目('/:id')用来标记出到指定危机的详情页的子路由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "* The details child route requires an `id` route parameter.",
"translation": "详细的子路由需要一个`id`路由参数。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "* The resulting path is `/crisis-center/1`.",
"translation": "最终生成的路径是`/crisis-center/1`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "If you wanted to, you could redefine the `AppComponent` template with *Crisis Center* routes exclusively:",
"translation": "只要想,我们也可以用*危机中心*路由单独重定义`AppComponent`的模板:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "### Appendix: *LocationStrategy* and browser URL styles",
"translation": "### 附录:*LocationStrategy*以及浏览器URL样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Here's the *Crisis Center* URL in this \"HTML5 pushState\" style:",
"translation": "下面是*危机中心*的URL在“HTML 5 pushState”风格下的样子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "The router supports both styles with two `LocationStrategy` providers:",
"translation": "路由器通过两种`LocationStrategy`提供商来支持所有这些风格:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. `PathLocationStrategy`&mdash;the default \"HTML5 pushState\" style.",
"translation": "`PathLocationStrategy` - 默认的策略支持“HTML 5 pushState”风格。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. `HashLocationStrategy`&mdash;the \"hash URL\" style.",
"translation": "`HashLocationStrategy` - 支持“hash URL”风格。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "#### Which strategy is best?",
"translation": "#### 哪种策略更好?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "#### HTML5 URLs and the *&lt;base href>*",
"translation": "#### HTML 5 URL与*&lt;base href>*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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\">&lt;base href&gt; element</a>\ntag in the `<head>` of the `index.html`.",
"translation": "配置该策略的首选方式是往`index.html`的`<head>`中添加一个[&lt;base href> element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)标签。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "Those developers may still use HTML5 URLs by taking two remedial steps:",
"translation": "它们仍然可以使用HTML 5格式的URL但要采取两个步骤进行补救",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"original": "1. Provide the router with an appropriate [APP_BASE_HREF][] value.",
"translation": "用适当的[APP_BASE_HREF][]值提供provide路由器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "#### *HashLocationStrategy*",
"translation": "#### *HashLocationStrategy* 策略",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/router.md"
},
{
"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/content-2/guide/router.md"
},
{
"original": "# Security",
"translation": "# 安全",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "You can run the <live-example></live-example> in Plunker and download the code from there.",
"translation": "运行<live-example></live-example>来试用本页的代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"original": "<h2 id='report-issues'>\nReporting vulnerabilities\n</h2",
"translation": "举报漏洞",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "Best practices",
"translation": "最佳实践",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "## Preventing cross-site scripting (XSS)",
"translation": "## 防范跨站脚本(XSS)攻击",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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&mdash;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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "### Sanitization and security contexts",
"translation": "### 无害化处理与安全环境",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "Angular defines the following security contexts:",
"translation": "Angular定义了四个安全环境 - HTML样式URL和资源URL",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "* **Style** is used when binding CSS into the `style` property.",
"translation": "**样式**值需要作为CSS绑定到`style`属性时使用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"original": "* **URL** is used for URL properties such as `<a href>`.",
"translation": "**URL**值需要被用作URL属性时使用比如`<a href>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "### Sanitization example",
"translation": "### 无害化示例",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "Interpolated content is always escaped&mdash;the HTML isn't interpreted and the browser displays\nangle brackets in the element's text content.",
"translation": "插值表达式的内容总会被编码 - 其中的HTML不会被解释所以浏览器会在元素的文本内容中显示尖括号。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "### Avoid direct use of the DOM APIs",
"translation": "### 避免直接使用DOM API",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "### Content security policy",
"translation": "### 内容安全策略",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "### Use the offline template compiler",
"translation": "### 使用离线模板编译器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "### Server-side XSS protection",
"translation": "### 服务器端XSS保护",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "Trusting safe values",
"translation": "信任安全值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "To mark a value as trusted, inject `DomSanitizer` and call one of the\nfollowing methods:",
"translation": "注入`DomSanitizer`服务,然后调用下面的方法之一,你就可以把一个值标记为可信任的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "HTTP-level vulnerabilities",
"translation": "HTTP级别的漏洞",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "Cross-site request forgery",
"translation": "跨站请求伪造XSRF",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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。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`.如果`example-bank.com`服务器缺乏XSRF保护就无法辨识请求是从应用程序发来的合法请求还是从`evil.com`来的假请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "Cross-site script inclusion (XSSI)",
"translation": "跨站脚本包含(XSSI)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "Auditing Angular applications",
"translation": "审计Angular应用程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/security.md"
},
{
"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/content-2/guide/security.md"
},
{
"original": "# Set the Document Title",
"translation": "# 设置文档标题",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"original": "To see the browser title bar change in the live example,\n open it again in the Plunker editor by clicking the icon in the upper right,\n then pop out the preview window by clicking the blue 'X' button in the upper right corner.",
"translation": "要在在线例子中看到浏览器标题的变化请点击右上角的图标在Plunker编辑器中打开它然后点击预览窗口右上角的蓝色'X'按钮,弹出窗口。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"original": "## The problem with *&lt;title&gt;*",
"translation": "## *&lt;title&gt;*的问题",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"original": "## Use the `Title` service",
"translation": "## 使用 `Title` 服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"original": "* `getTitle() : string`&mdash;Gets the title of the current HTML document.",
"translation": "`getTitle(): string` —— 获取当前HTML文档的标题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"original": "* `setTitle( newTitle : string )`&mdash;Sets the title of the current HTML document.",
"translation": "`setTitle( newTitle: string)` —— 设置当前HTML文档的标题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"original": "Bind that method to three anchor tags and voilà!",
"translation": "我们把这个方法绑定到三个A标签瞧瞧",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"original": "Here's the complete solution:",
"translation": "这里是完整的方案(代码)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"original": "## Why provide the `Title` service in `bootstrap`",
"translation": "## 为什么要在*bootstrap*里面提供这个*Title*服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"original": "Generally you want to provide application-wide services in the root application component, `AppComponent`.",
"translation": "我们通常会推荐在应用程序的根组件`AppComponent`中提供应用程序级的服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"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/content-2/guide/set-document-title.md"
},
{
"original": "# Anatomy of the Setup Project",
"translation": "# 搭建项目环境",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Application files _inside the_ **`src/`** and **`e2e/`** folders matter most to developers.",
"translation": "对程序员来讲最重要的是在 *`src/`* 和 *`e2e/`* 文件夹*之内*的应用文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "File",
"translation": "文件\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Purpose",
"translation": "用途\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Angular application files go here.",
"translation": "你的 Angular 应用文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Try the <live-example name=\"setup\">sample application</live-example> \n and the <live-example name=\"setup\" plnkr=\"quickstart-specs\">unit test</live-example>\n as _live examples_.",
"translation": "在live example中试试<live-example name=\"setup\">范例程序</live-example>和<live-example name=\"setup\" plnkr=\"quickstart-specs\">单元测试</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Initialized with an e2e test for the \"Hello Angular\" sample.",
"translation": "初始化后有个“Hello Angular” 的例子的端对端测试。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "The _npm_ packages installed with the `npm install` command.",
"translation": "用 `npm install` 命令安装的 *npm* 包。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Tooling configuration files and folders.",
"translation": "配置文件和文件夹的工具。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Ignore them until you have a compelling reason to do otherwise.",
"translation": "除非非常必要,否则可以忽略。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "The history of changes to the _QuickStart_ repository.",
"translation": "*快速上手*库的更新历史。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Delete or ignore.",
"translation": "删除或忽略。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "The application icon that appears in the browser tab.",
"translation": "出现在浏览器标签上的应用图标。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "The same `index.html` satisfies all documentation application samples.",
"translation": "同一个 `index.html`满足所有文档应用例子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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配置*\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "The open source MIT license to use this setup code in your application.",
"translation": "应用的搭建代码中用到的开源 MIT 许可证。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Identifies `npm `package dependencies for the project.",
"translation": "为项目指定`npm`依赖包。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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>阅读更多关于它们的说明。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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) 测试器运行器的配置。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Instruction for using this git repository in your project.\n Worth reading before deleting.",
"translation": "项目中使用这个 git 库的说明。\n 在删除前值得阅读。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Global styles for the application. Initialized with an `<h1>` style for the QuickStart demo.",
"translation": "应用的全局样式。初始化后,有个为《快速上手》演示准备的`<h1>`样式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "Don't touch this file unless you are fully versed in SystemJS configuration.",
"translation": "除非你完全理解 SystemJS 的配置,不要修改它。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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/content-2/guide/setup-systemjs-anatomy.md"
},
{
"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)与本文档站作者喜爱的语法检查规则。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup-systemjs-anatomy.md"
},
{
"original": "# Setup for local development",
"translation": "# 搭建本地开发环境",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"original": "## Clone",
"translation": "## 克隆",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "Perform the _clone-to-launch_ steps with these terminal commands.",
"translation": "运行下列命令来执行*克隆并启动*步骤。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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-04为止它还不支持访问网络上的服务器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "## Download",
"translation": "## 下载\n<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.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"original": "## Delete _non-essential_ files (optional)",
"translation": "## 删除*非必需*文件(可选)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"original": "Do this only in the beginning to avoid accidentally deleting your own tests and git setup!",
"translation": "请只在开始时执行此删除操作以防你自己的测试和git文件被意外删除",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "Open a terminal window in the project folder and enter the following commands for your environment:",
"translation": "在项目目录下打开一个终端窗口,并根据你的操作系统执行以下命令:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "### OS/X (bash)",
"translation": "### OS/X (bash) 命令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "### Windows",
"translation": "### Windows 命令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "## What's in the QuickStart seed?",
"translation": "## 《快速上手》种子库里都有什么?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"original": "Focus on the following three TypeScript (`.ts`) files in the **`/src`** folder.",
"translation": "注意**`/src`**目录中以下三个 TypeScript (`.ts`) 文件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"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除非明确指出否则教程中添加的 TypeScriptHTML和CSS文件都在`src/`目录下,\n大多数在`src/app`目录中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "The following are all in `src/`",
"translation": "`src/`目录文件详情如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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 不久,它将声明更多组件。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "Compiles the application with the [JIT compiler](guide/glossary#jit) and\n [bootstraps](guide/bootstrapping#main \"bootstrap the application\")\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 Plunker.\n You'll learn about alternative compiling and [deployment](guide/deployment) options later in the documentation.",
"translation": "使[即时 (JiT) 编译器](guide/glossary#jit)用编译应用并且在浏览器中[启动](guide/bootstrapping#main \"启动应用\")并运行应用。\n 对于大多数项目的开发,这都是合理的选择。而且它是在像 Plunker 这样的*在线编程*环境中运行例子的唯一选择。\n 你将在本文档中学习其他编译和开发选择。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "### Next Step",
"translation": "### 下一步",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"original": "## Appendix: node and npm",
"translation": "## 附录node 与 npm",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"original": "<a href=\"https://docs.npmjs.com/getting-started/installing-node\" target=\"_blank\" title=\"Installing Node.js and updating npm\">\n</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\">\n立刻安装它们</a>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"original": "## Appendix: Why develop locally",
"translation": "## 附录:为何在本地开发",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "<live-example title=\"QuickStart Seed in Plunker\">Live coding</live-example> in the browser is a great way to explore Angular.",
"translation": "在浏览器中<live-example title=\"QuickStart Seed in Plunker\">在线编程</live-example>是很好的探索 Angular 的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"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/content-2/guide/setup.md"
},
{
"original": "As much fun as this is ...",
"translation": "虽然有这么多的乐趣,但是...",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "* you can't ship your app in plunker",
"translation": "你不能在 plunker 里面发布你的应用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "* you aren't always online when writing code",
"translation": "编程时你不可能总是在线",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "* transpiling TypeScript in the browser is slow",
"translation": "在浏览器中编译 TypeScript 很慢",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "* the type support, refactoring, and code completion only work in your local IDE",
"translation": "只有本地 IDE 有类型支持、代码重构和代码自动完成",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "Use the <live-example title=\"QuickStart Seed in Plunker\">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 Plunker\">在线编程</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/content-2/guide/setup.md"
},
{
"original": "For real development, we strongly recommend [developing locally](guide/setup#develop-locally).",
"translation": "对于现实项目开发,我们强烈推荐在[本地开发](guide/setup#develop-locally)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/setup.md"
},
{
"original": "# Structural Directives",
"translation": "# 结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Try the <live-example></live-example>.",
"translation": "试试<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "## What are structural directives?",
"translation": "## 什么是结构型指令?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "No brackets. No parentheses. Just `*ngIf` set to a string.",
"translation": "没有方括号,没有圆括号,只是把`*ngIf`设置为一个字符串。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "You'll learn in this guide that the [asterisk (*) is a convenience notation](guide/structural-directives#asterisk)\nand the string isa [_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/content-2/guide/structural-directives.md"
},
{
"original": "Three of the common, built-in structural directives&mdash;[NgIf](guide/template-syntax#ngIf),\n[NgFor](guide/template-syntax#ngFor), and [NgSwitch...](guide/template-syntax#ngSwitch)&mdash;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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Directive spelling",
"translation": "指令的拼写形式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "There are two other kinds of Angular directives, described extensively elsewhere:\n(1)&nbsp;components and (2)&nbsp;attribute directives.",
"translation": "还有另外两种Angular指令在本开发指南的其它地方有讲解(1) 组件 (2) 属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## NgIf case study",
"translation": "## NgIf案例分析",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "### Why *remove* rather than *hide*?",
"translation": "### 为什么*移除*而不是*隐藏*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "A directive could hide the unwanted paragraph instead by setting its `display` style to `none`.",
"translation": "指令也可以通过把它的`display`风格设置为`none`而隐藏不需要的段落。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "While invisible, the element remains in the DOM.",
"translation": "当不可见时这个元素仍然留在DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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": "对于简单的段落,隐藏和移除之间的差异影响不大,但对于资源占用较多的组件是不一样的。当我们隐藏掉一个元素时,组件的行为还在继续 —— 它仍然附加在它所属的DOM元素上\n它也仍在监听事件。Angular会继续检查哪些能影响数据绑定的变更。\n组件原本要做的那些事情仍在继续。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "Although invisible, the component&mdash;and all of its descendant components&mdash;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/content-2/guide/structural-directives.md"
},
{
"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&mdash;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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## The asterisk (*) prefix",
"translation": "## 星号(*)前缀",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Here is `*ngIf` displaying the hero's name if `hero` exists.",
"translation": "这里的`*ngIf`会在`hero`存在时显示英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## Inside _*ngFor_",
"translation": "## `*ngFor`内幕",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Here's a full-featured application of `NgFor`, written both ways:",
"translation": "这里有一个`NgFor`的全特性应用,同时用了这三种写法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "### Microsyntax",
"translation": "### 微语法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "* The context property for `let-hero` wasn't specified.\nIt's 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`属性,`NgFor`会用当前迭代中的英雄初始化它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "### Template input variable",
"translation": "### 模板输入变量",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "### One structural directive per host element",
"translation": "### 每个宿主元素上只能有一个结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## Inside _NgSwitch_ directives",
"translation": "## `NgSwitch` 内幕",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Here's an example.",
"translation": "例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "*Design thought*: minimize initialization effort and consider caching state in a \ncompanion service.",
"translation": "*设计思路*:要最小化初始化的成本,并考虑把状态缓存在一个伴生的服务中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## Prefer the asterisk (*) syntax.",
"translation": "## 优先使用星号(`*`)语法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "The asterisk (*) syntax is more clear than the desugared form.\nUse [&lt;ng-container&gt;](guide/structural-directives#ng-container) when there's no single element\nto host the directive.",
"translation": "星号(`*`)语法比不带语法糖的形式更加清晰。\n如果找不到单一的元素来应用该指令可以使用[&lt;ng-container&gt;](guide/structural-directives#ng-container)作为该指令的容器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## The *&lt;ng-template&gt;*",
"translation": "## *&lt;ng-template&gt;*指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "The &lt;ng-template&gt; 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": "&lt;ng-template&gt;是一个 Angular 元素用来渲染HTML。\n它永远不会直接显示出来。\n事实上在渲染视图之前Angular 会把`<ng-template>`及其内容*替换为*一个注释。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Angular erases the middle \"Hip!\", leaving the cheer a bit less enthusiastic.",
"translation": "Angular 抹掉了中间的那个 \"Hip!\" ,让欢呼声显得不再那么热烈了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## Group sibling elements with &lt;ng-container&gt;",
"translation": "## 使用&lt;ng-container&gt;把一些兄弟元素归为一组",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Introducing another container element&mdash;typically a `<span>` or `<div>`&mdash;to\ngroup the elements under a single _root_ is usually harmless.\n_Usually_ ... but not _always_.",
"translation": "但引入另一个容器元素(通常是`<span>`或`<div>`)来把一些元素归到一个单一的*根元素*下,通常也会带来问题。注意,是\"通常\"而不是\"总会\"。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "The constructed paragraph renders strangely.",
"translation": "这样渲染出来的段落就会非常奇怪。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "The `p span` style, intended for use elsewhere, was inadvertently applied here.",
"translation": "本来为其它地方准备的`p span`样式,被意外的应用到了这里。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "When you try this,",
"translation": "如果这样做:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "the drop down is empty.",
"translation": "下拉列表就是空的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "The browser won't display an `<option>` within a `<span>`.",
"translation": "浏览器不会显示`<span>`中的`<option>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "### &lt;ng-container&gt; to the rescue",
"translation": "### &lt;ng-container&gt; 的救赎",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Here's the conditional paragraph again, this time using `<ng-container>`.",
"translation": "下面是重新实现的条件化段落,这次我们使用`<ng-container>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "It renders properly.",
"translation": "这次就渲染对了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "Now conditionally exclude a _select_ `<option>` with `<ng-container>`.",
"translation": "我们再用`<ng-container>`来根据条件排除选择框中的某个`<option>`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "The drop down works properly.",
"translation": "下拉框也工作正常。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## Write a structural directive",
"translation": "## 写一个结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Creating a directive is similar to creating a component.",
"translation": "创建指令很像创建组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "* Import the `Directive` decorator (instead of the `Component` decorator).",
"translation": "导入`Directive`装饰器(而不再是`Component`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "* Apply the decorator to the directive class.",
"translation": "给指令类添加装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Here's how you might begin:",
"translation": "这里是起点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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": "指令的*选择器*通常是把指令的属性名括在方括号中,如`[myUnless]`。\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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "### _TemplateRef_ and _ViewContainerRef_",
"translation": "### _TemplateRef_ 和 _ViewContainerRef_",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "You inject both in the directive constructor as private variables of the class.",
"translation": "我们可以把它们都注入到指令的构造函数中,作为该类的私有属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "### The _appUnless_ property",
"translation": "### *myUnless* 属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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条件绑定到`[myUnless]`属性上。\n也就是说该指令需要一个带有`@Input`的`myUnless`属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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 就会去设置 `myUnless` 属性这时候我们就需要为它定义一个设置器setter。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Nobody reads the `appUnless` property so it doesn't need a getter.",
"translation": "没有人会读取`myUnless`属性因此它不需要定义设置器getter。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "The completed directive code looks like this:",
"translation": "完整的指令代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "Add this directive to the `declarations` array of the AppModule.",
"translation": "把这个指令添加到AppModule的`declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "Then create some HTML to try it.",
"translation": "然后创建一些 HTML 来试用一下。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "Here is the source from the `src/app/` folder.",
"translation": "本章相关的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "You learned",
"translation": "我们学到了",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "* that structural directives manipulate HTML layout.",
"translation": "结构型指令可以操纵 HTML 的元素布局。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "* how that works for the `NgIf`, `NgFor` and `NgSwitch` built-in directives.",
"translation": "内置指令`NgIf`、`NgFor`和`NgSwitch`的工作原理。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"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/content-2/guide/structural-directives.md"
},
{
"original": "* to write a [custom structural directive](guide/structural-directives#unless), `UnlessDirective`.",
"translation": "写了一个[自定义结构型指令](guide/structural-directives#unless) —— `UnlessDirective`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/structural-directives.md"
},
{
"original": "# Style Guide",
"translation": "# 风格指南",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "## Style vocabulary",
"translation": "## 风格词汇",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Each guideline describes either a good or bad practice, and all have a consistent presentation.",
"translation": "每个指导原则都会描述好的或者坏的做法,所有指导原则风格一致。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "The wording of each guideline indicates how strong the recommendation is.",
"translation": "指导原则中使用的词汇表明推荐的程度。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Consider** guidelines should generally be followed.",
"translation": "**考虑**标志着通常应该遵循的指导原则。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "If you fully understand the meaning behind the guideline and have a good reason to deviate, then do so. Please strive to be consistent.",
"translation": "如果能完全理解指导原则背后的含义,并且很好的理由背离它,那就可以那么做。但是请保持一致。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Avoid** indicates something you should almost never do. Code examples to *avoid* have an unmistakeable red header.",
"translation": "**避免**标志着我们决不应该做的事。需要*避免*的代码范例会有明显的红色标题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** gives reasons for following the previous recommendations.",
"translation": "**为何?**会给出随后的建议的理由。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## File structure conventions",
"translation": "## 文件结构约定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "## Single responsibility",
"translation": "## 单一职责",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "### Rule of One",
"translation": "### 单一规则",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 01-01",
"translation": "#### 风格 01-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** define one thing, such as a service or component, per file.",
"translation": "**坚持**每个文件只定义一样东西(例如服务或组件)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** limiting files to 400 lines of code.",
"translation": "**考虑**把文件大小限制在 400 行代码以内。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "The key is to make the code more reusable, easier to read, and less mistake prone.",
"translation": "最关键的是,可以增强代码可重用性和阅读性,减少出错的可能性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "As the app grows, this rule becomes even more important.",
"translation": "随着应用程序的成长,本法则会变得越来越重要。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Small functions",
"translation": "### 小函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 01-02",
"translation": "#### 风格 01-02",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** define small functions",
"translation": "**坚持**定义简单函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** limiting to no more than 75 lines.",
"translation": "**考虑**限制在 75 行之内。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to test, especially when they do one thing and serve one purpose.",
"translation": "**为何?**简单函数更易于测试,特别是当它们只做一件事,只为一个目的服务时。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Small functions promote reuse.",
"translation": "**为何?**简单函数促进代码重用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to read.",
"translation": "**为何?**简单函数更易于阅读。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to maintain.",
"translation": "**为何?**简单函数更易于维护。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## Naming",
"translation": "## 命名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "### General Naming Guidelines",
"translation": "### 总体命名原则",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-01",
"translation": "#### 风格 02-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all symbols.",
"translation": "**坚持**所有符号使用一致的命名规则。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** The naming conventions should simply help find desired code faster and make it easier to understand.",
"translation": "**为何?**命名约定帮助我们更快得找到不在手头的代码,更容易理解它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Separate file names with dots and dashes",
"translation": "### 使用点和横杠来分隔文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-02",
"translation": "#### 风格 02-02",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use dashes to separate words in the descriptive name.",
"translation": "**坚持** 在描述性名字中,用横杠来分隔单词。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use dots to separate the descriptive name from the type.",
"translation": "**坚持**使用点来分隔描述性名字和类型。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Type names provide a consistent way to quickly identify what is in the file.",
"translation": "**为何?**类型名字提供一致的方式来快速的识别文件中有什么。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Type names provide pattern matching for any automated tasks.",
"translation": "**为何?**为自动化任务提供模式匹配。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Symbols and file names",
"translation": "### 符号名与文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-03",
"translation": "#### 风格 02-03",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all assets named after what they represent.",
"translation": "**坚持**为所有东西使用一致的命名约定,以它们所代表的东西命名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use upper camel case for class names.",
"translation": "**坚持**使用大写驼峰命名法来命名类。符号名匹配它所在的文件名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Consistent conventions make it easy to quickly identify\nand reference assets of different types.",
"translation": "**为何?**遵循一致的约定可以快速识别和引用不同类型的资产。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Service names",
"translation": "### 服务名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-04",
"translation": "#### 风格 02-04",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all services named after their feature.",
"translation": "**坚持**使用一致的规则命名服务,以它们的特性来命名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference services.",
"translation": "**为何?**提供一致的方式来快速识别和引用服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Clear service names such as `Logger` do not require a suffix.",
"translation": "**为何?**像`Logger`这样的清楚的服务名不需要后缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Bootstrapping",
"translation": "### 引导",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-05",
"translation": "#### 风格 02-05",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** put bootstrapping and platform logic for the app in a file named `main.ts`.",
"translation": "**坚持**把应用的引导程序和平台相关的逻辑放到名为`main.ts`的文件里。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** include error handling in the bootstrapping logic.",
"translation": "**坚持**在引导逻辑中包含错误处理代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Follows a consistent convention for the startup logic of an app.",
"translation": "**为何?**应用的启动逻辑遵循一致的约定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Follows a familiar convention from other technology platforms.",
"translation": "**为何?**这是从其它技术平台借鉴的常用约定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Directive selectors",
"translation": "### 指令选择器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-06",
"translation": "#### 风格 02-06",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** Use lower camel case for naming the selectors of directives.",
"translation": "**坚持**使用小驼峰命名法来命名指令的选择器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.",
"translation": "**为何?**Angular HTML 解析器是大小写敏感的,它识别小写驼峰写法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Custom prefix for components",
"translation": "### 为组件添加自定义前缀",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-07",
"translation": "#### 风格 02-07",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use a hyphenated, lowercase element selector value (e.g. `admin-users`).",
"translation": "**坚持**使用带连字符的小写元素选择器值(例如`admin-users`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Do** use a prefix that identifies the feature area or the app itself.",
"translation": "**坚持**使用前缀来识别特性区或者应用程序本身。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Prevents element name collisions with components in other apps and with native HTML elements.",
"translation": "**为何?**防止与其它应用中的组件和原生 HTML 元素发生命名冲突。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Makes it easier to promote and share the component in other apps.",
"translation": "**为何?**更容易在其它应用中推广和共享组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Components are easy to identify in the DOM.",
"translation": "**为何?**组件在 DOM 中更容易被区分出来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Custom prefix for directives",
"translation": "### 为指令添加自定义前缀",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-08",
"translation": "#### 风格 02-08",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Prevents name collisions.",
"translation": "**为何?**防止名字冲突。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Directives are easily identified.",
"translation": "**为何?**指令更加容易被识别。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Pipe names",
"translation": "### 管道名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-09",
"translation": "#### 风格 02-09",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all pipes, named after their feature.",
"translation": "**坚持**为所有管道使用一致的命名约定,用它们的特性来命名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference pipes.",
"translation": "**为何?**提供一致方式快速识别和引用管道。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Unit test file names",
"translation": "### 单元测试文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-10",
"translation": "#### 风格 02-10",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** name test specification files the same as the component they test.",
"translation": "**坚持**测试规格文件名与被测试组件文件名相同。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** name test specification files with a suffix of `.spec`.",
"translation": "**坚持**测试规格文件名添加`.spec`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify tests.",
"translation": "**为何?**提供一致的方式来快速识别测试。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "<th>\n Test Type",
"translation": "测试类型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "<th>\n File Names",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Components",
"translation": "组件\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Services",
"translation": "服务\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Pipes",
"translation": "管道\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### _End-to-End_ (E2E) test file names",
"translation": "### *端到端*E2E测试的文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-11",
"translation": "#### 风格 02-11",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify end-to-end tests.",
"translation": "**为何?**提供一致的方式快速识别端到端测试文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Provides pattern matching for test runners and build automation.",
"translation": "**为何?**提供一个与测试运行器和构建自动化匹配的模式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "<th>\n Test Type",
"translation": "测试类型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "<th>\n File Names",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "End-to-End Tests",
"translation": "端到端测试\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Angular _NgModule_ names",
"translation": "### Angular *NgModule* 命名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 02-12",
"translation": "#### 风格 02-12",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** append the symbol name with the suffix `Module`.",
"translation": "**坚持**为符号名添加`Module`后缀",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** give the file name the `.module.ts` extension.",
"translation": "**坚持**为文件名添加`.module.ts`扩展名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** name the module after the feature and folder it resides in.",
"translation": "**坚持**用特性名和所在目录命名模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference modules.",
"translation": "**为何?**提供一致的方式来快速标识和引用模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Upper camel case is conventional for identifying objects that can be instantiated using a constructor.",
"translation": "**为何?**大驼峰命名法是一种命名约定,用来标识可用构造函数实例化的对象。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Easily identifies the module as the root of the same named feature.",
"translation": "**为何?**很容易就能看出这个模块是同名特性的根模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** suffix a _RoutingModule_ class name with `RoutingModule`.",
"translation": "**坚持**为 *RoutingModule* 类名添加`RoutingModule`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** end the filename of a _RoutingModule_ with `-routing.module.ts`.",
"translation": "**坚持**为 *RoutingModule* 的文件名添加`-routing.module.ts`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## Coding conventions",
"translation": "## 编程约定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Have a consistent set of coding, naming, and whitespace conventions.",
"translation": "坚持一致的编程、命名和空格的约定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Classes",
"translation": "### 类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 03-01",
"translation": "#### 风格 03-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use upper camel case when naming classes.",
"translation": "**坚持**使用大写驼峰命名法来命名类。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Follows conventional thinking for class names.",
"translation": "**为何?**遵循类命名传统约定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Constants",
"translation": "### 常量",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 03-02",
"translation": "#### 风格 03-02",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** declare variables with `const` if their values should not change during the application lifetime.",
"translation": "**坚持**用`const`声明变量,除非它们的值在应用的生命周期内会发生变化。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Conveys to readers that the value is invariant.",
"translation": "**为何?**告诉读者这个值是不可变的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** TypeScript helps enforce that intent by requiring immediate initialization and by\npreventing subsequent re-assignment.",
"translation": "**为何?** TypeScript 会要求在声明时立即初始化,并阻止再次赋值,以确保达成我们的意图。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** spelling `const` variables in lower camel case.",
"translation": "**考虑** 把常量名拼写为小驼峰格式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Do** tolerate _existing_ `const` variables that are spelled in UPPER_SNAKE_CASE.",
"translation": "**坚持**容许_现存的_`const`常量沿用大写蛇形命名法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Interfaces",
"translation": "### 接口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 03-03",
"translation": "#### 风格 03-03",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** name an interface using upper camel case.",
"translation": "**坚持**使用大写驼峰命名法来命名接口。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** naming an interface without an `I` prefix.",
"translation": "**考虑**不要在接口名字前面加`I`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** using a class instead of an interface.",
"translation": "**考虑**用类代替接口。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** A class alone is less code than a _class-plus-interface_.",
"translation": "**为何?**单独一个类的代码量小于*类+接口*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** A class can act as an interface (use `implements` instead of `extends`).",
"translation": "**为何?**类可以作为接口使用(只是用`implements`代替`extends`而已)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** An interface-class can be a provider lookup token in Angular dependency injection.",
"translation": "**为何?**在 Angular 依赖注入系统中,接口类可以作为服务提供商的查找令牌。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Properties and methods",
"translation": "### 属性和方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 03-04",
"translation": "#### 样式 03-04",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use lower camel case to name properties and methods.",
"translation": "**坚持**使用小写驼峰命名法来命名属性和方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Avoid** prefixing private properties and methods with an underscore.",
"translation": "**避免**为私有属性和方法添加下划线前缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Follows conventional thinking for properties and methods.",
"translation": "**为何?**遵循传统属性和方法的命名约定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** JavaScript lacks a true private property or method.",
"translation": "**为何?** JavaScript 不支持真正的私有属性和方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** TypeScript tooling makes it easy to identify private vs. public properties and methods.",
"translation": "**为何?** TypeScript 工具让识别私有或公有属性和方法变得很简单。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Import line spacing",
"translation": "### 导入语句中的空行",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 03-06",
"translation": "#### 风格 03-06",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** leaving one empty line between third party imports and application imports.",
"translation": "**坚持**在第三方导入和应用导入之间留一个空行。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** listing import lines alphabetized by the module.",
"translation": "**考虑**按模块名字的字母顺排列导入行。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** listing destructured imported symbols alphabetically.",
"translation": "**考虑**在解构表达式中按字母顺序排列导入的东西。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** The empty line separates _your_ stuff from _their_ stuff.",
"translation": "**为何?**空行可以让阅读和定位本地导入更加容易。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Alphabetizing makes it easier to read and locate symbols.",
"translation": "**为何?**按字母顺序排列可以让阅读和定位本地导入更加容易。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## Application structure and NgModules",
"translation": "## 应用程序结构与 Angular 模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-01",
"translation": "#### 风格 04-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Do** define the structure to follow these four basic guidelines, listed in order of importance.",
"translation": "**坚持**四项基本原则定义文件结构,上面的原则是按重要顺序排列的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Locate",
"translation": "### 定位",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-02",
"translation": "#### 风格04-02",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** make locating code intuitive, simple and fast.",
"translation": "**坚持**直观、简单和快速地定位代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Identify",
"translation": "### 识别",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-03",
"translation": "#### 风格 04-03",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** name the file such that you instantly know what it contains and represents.",
"translation": "**坚持**命名文件到这个程度:看到名字立刻知道它包含了什么,代表了什么。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** be descriptive with file names and keep the contents of the file to exactly one component.",
"translation": "**坚持**文件名要具有说明性,确保文件中只包含一个组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Avoid** files with multiple components, multiple services, or a mixture.",
"translation": "**避免**创建包含多个组件、服务或者混合体的文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Flat",
"translation": "### 扁平",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-04",
"translation": "#### 风格 04-04",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** keep a flat folder structure as long as possible.",
"translation": "**坚持**尽可能保持扁平的目录结构。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** creating sub-folders when a folder reaches seven or more files.",
"translation": "**考虑**当同一目录下达到 7 个或更多个文件时创建子目录。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### _T-DRY_ (Try to be _DRY_)",
"translation": "### *T-DRY*(尽量不重复自己)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-05",
"translation": "#### 风格 04-05",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** be DRY (Don't Repeat Yourself).",
"translation": "**坚持** DRYDon't Repeat Yourself不重复自己。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Avoid** being so DRY that you sacrifice readability.",
"translation": "**避免**过度 DRY以致牺牲了阅读性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Overall structural guidelines",
"translation": "### 总体结构的指导原则",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-06",
"translation": "#### 风格 04-06",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** start small but keep in mind where the app is heading down the road.",
"translation": "**坚持**从零开始,但要考虑应用程序接下来的路往哪儿走。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** have a near term view of implementation and a long term vision.",
"translation": "**坚持**有一个近期实施方案和一个长期的愿景。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** put all of the app's code in a folder named `src`.",
"translation": "**坚持**把所有源代码都放到名为`src`的目录里。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Here is a compliant folder and file structure:",
"translation": "下面是符合规范的目录和文件结构",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### _Folders-by-feature_ structure",
"translation": "### 按特性组织的目录结构",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-07",
"translation": "#### 风格 04-07",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** create folders named for the feature area they represent.",
"translation": "**坚持**根据特性区命名目录。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** The LIFT guidelines are all covered.",
"translation": "**为何?** LIFT 原则中包含了所有这些。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Do** create an NgModule for each feature area.",
"translation": "**坚持**为每个特性区创建一个 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** NgModules make it easy to lazy load routable features.",
"translation": "**为何?** Angular 模块使惰性加载可路由的特性变得更容易。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** NgModules make it easier to isolate, test, and re-use features.",
"translation": "**为何?**Angular 模块隔离、测试和复用特性更容易。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "</div>",
"translation": "Refer to this _folder and file structure_ example.</a> <a href=\"#file-tree\">点这里查看目录和文件结构的范例",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### App _root module_",
"translation": "### 应用的*根模块*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-08",
"translation": "#### 风格 04-08",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Every app requires at least one root NgModule.",
"translation": "**为何?**每个应用都至少需要一个根 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Consider** naming the root module `app.module.ts`.",
"translation": "**考虑**把根模块命名为`app.module.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Makes it easier to locate and identify the root module.",
"translation": "**为何?**能让定位和识别根模块变得更容易。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Feature modules",
"translation": "### 特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-09",
"translation": "#### 风格 04-09",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** create an NgModule for all distinct features in an application;\nfor example, a `Heroes` feature.",
"translation": "**坚持**为应用中每个明显的特性创建一个 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can expose or hide its implementation from other modules.",
"translation": "**为何?**特性模块可以对其它模块暴露或隐藏自己的实现。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** A feature module identifies distinct sets of related components that comprise the feature area.",
"translation": "**为何?**特性模块标记出组成该特性分区的相关组件集合。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can easily be routed to both eagerly and lazily.",
"translation": "**为何?**方便路由到特性模块 —— 无论是用主动加载还是惰性加载的方式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** A feature module defines clear boundaries between specific functionality and other application features.",
"translation": "**为何?**特性模块在特定的功能和其它应用特性之间定义了清晰的边界。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** A feature module helps clarify and make it easier to assign development responsibilities to different teams.",
"translation": "**为何?**特性模块帮助澄清开发职责,以便于把这些职责指派给不同的项目组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can easily be isolated for testing.",
"translation": "**为何?**特性模块易于隔离,以便测试。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Shared feature module",
"translation": "### 共享特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-10",
"translation": "#### 风格 04-10",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Do** declare all components, directives, and pipes in the `SharedModule`.",
"translation": "**坚持**在`SharedModule`中声明所有组件、指令和管道。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** export all symbols from the `SharedModule` that other feature modules need to use.",
"translation": "**坚持**从`SharedModule`中导出其它特性模块所需的全部符号。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Avoid** specifying app-wide singleton providers in a `SharedModule`. Intentional singletons are OK. Take care.",
"translation": "**避免**在`SharedModule`中指定应用级的单例服务提供商。如果是刻意要得到多个服务单例也行,不过还是要小心。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Core feature module",
"translation": "### 核心特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-11",
"translation": "#### 风格04-11",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Avoid** importing the `CoreModule` anywhere except in the `AppModule`.",
"translation": "**避免**在`AppModule`之外的任何地方导入`CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Prevent re-import of the core module",
"translation": "### 防止多次导入`CoreModule`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-12",
"translation": "#### 风格 04-12",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Only the root `AppModule` should import the `CoreModule`.",
"translation": "应该只有`AppModule`才允许导入`CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** guard against reimporting of `CoreModule` and fail fast by adding guard logic.",
"translation": "**坚持**防范多次导入`CoreModule`,并通过添加守卫逻辑来尽快失败。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Guards against reimporting of the `CoreModule`.",
"translation": "**为何?**守卫可以阻止对`CoreModule`的多次导入。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Guards against creating multiple instances of assets intended to be singletons.",
"translation": "**为何?**守卫会禁止创建单例服务的多个实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Lazy Loaded folders",
"translation": "### 惰性加载的目录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-13",
"translation": "#### 样式 04-13",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** The folder makes it easy to identify and isolate the feature content.",
"translation": "**为何?**这种目录让标识和隔离这些特性内容变得更轻松。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Never directly import lazy loaded folders",
"translation": "### 永远不要直接导入惰性加载的目录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 04-14",
"translation": "#### 样式 04-14",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## Components",
"translation": "## 组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Component selector names",
"translation": "### 组件选择器命名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-02",
"translation": "#### 风格05-02",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.",
"translation": "**坚持**使用*中线 (dashed) 命名法*或*烤串 (kebab) 命名法*来命名组件中的元素选择器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Components as elements",
"translation": "### 把组件当做元素",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-03",
"translation": "#### 风格 05-03",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** give components an _element_ selector, as opposed to _attribute_ or _class_ selectors.",
"translation": "**坚持**给组件一个*元素*选择器,而不是*属性*或*类*选择器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Extract templates and styles to their own files",
"translation": "### 把模板和样式提取到它们自己的文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-04",
"translation": "#### 风格 05-04",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** extract templates and styles into a separate file, when more than 3 lines.",
"translation": "**坚持**当超过 3 行时,把模板和样式提取到一个单独的文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Do** specify _component-relative_ URLs, prefixed with `./`.",
"translation": "**坚持**指定*相对于模块的* URL ,给它加上`./`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Large, inline templates and styles obscure the component's purpose and implementation, reducing readability and maintainability.",
"translation": "**为何?**巨大的、内联的模板和样式表会遮盖组件的意图和实现方式,削弱可读性和可维护性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Decorate _input_ and _output_ properties",
"translation": "### 内联输入和输出属性装饰器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-12",
"translation": "#### 风格 05-12",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Consider** placing `@Input()` or `@Output()` on the same line as the property it decorates.",
"translation": "**坚持**把`@Input()`或者`@Output()`放到所装饰的属性的同一行。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** The metadata declaration attached to the directive is shorter and thus more readable.",
"translation": "**为何?**依附到指令的元数据声明会比较简短,更易于阅读。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Avoid aliasing _inputs_ and _outputs_",
"translation": "### 避免为输入和输出属性指定别名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-13",
"translation": "#### 风格 05-13",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Avoid** _input_ and _output_ aliases except when it serves an important purpose.",
"translation": "**避免**除非有重要目的,否则不要为输入和输出指定别名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Two names for the same property (one private, one public) is inherently confusing.",
"translation": "**为何?**同一个属性有两个名字(一个对内一个对外)很容易导致混淆。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Member sequence",
"translation": "### 成员顺序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-14",
"translation": "#### 风格 05-14",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** place properties up top followed by methods.",
"translation": "**坚持**把属性成员放在前面,方法成员放在后面。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** place private members after public members, alphabetized.",
"translation": "**坚持**先放公共成员,再放私有成员,并按照字母顺序排列。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Delegate complex component logic to services",
"translation": "### 把逻辑放到服务里",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-15",
"translation": "#### 风格 05-15",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Do** move reusable logic to services and keep components simple and focused on their intended purpose.",
"translation": "**坚持**把可重用的逻辑放到服务中,保持组件简单,聚焦于它们预期目的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Removes dependencies and hides implementation details from the component.",
"translation": "**为何?**从组件移除依赖并隐藏实施细节。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Keeps the component slim, trim, and focused.",
"translation": "**为何?**保持组件苗条、精简和聚焦。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Don't prefix _output_ properties",
"translation": "### 不要给输出属性加前缀",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-16",
"translation": "#### 风格 05-16",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** name events without the prefix `on`.",
"translation": "**坚持**命名事件时,不要带前缀`on`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** name event handler methods with the prefix `on` followed by the event name.",
"translation": "**坚持**把事件处理器方法命名为`on`前缀之后紧跟着事件名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** This is consistent with built-in events such as button clicks.",
"translation": "**为何?**与内置事件命名一致,例如按钮点击。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Put presentation logic in the component class",
"translation": "### 把表现层逻辑放到组件类里",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 05-17",
"translation": "#### 风格 05-17",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** put presentation logic in the component class, and not in the template.",
"translation": "**坚持**把表现层逻辑放进组件类中,而不要放在模板里。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Use directives to enhance an element",
"translation": "### 使用指令来增强已有元素",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 06-01",
"translation": "#### 风格 06-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use attribute directives when you have presentation logic without a template.",
"translation": "**坚持**当你需要有表现层逻辑,但没有模板时,使用属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Attribute directives don't have an associated template.",
"translation": "**为何?**属性型指令没有模板。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** An element may have more than one attribute directive applied.",
"translation": "**为何?**一个元素可以使用多个属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### _HostListener_/_HostBinding_ decorators versus _host_ metadata",
"translation": "### *HostListener* 和 *HostBinding* 装饰器 vs. 组件元数据 *host*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 06-03",
"translation": "#### 风格 06-03",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Do** be consistent in your choice.",
"translation": "**坚持**让你的选择保持一致。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** The property associated with `@HostBinding` or the method associated with `@HostListener`\ncan be modified only in a single place&mdash;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/content-2/guide/styleguide.md"
},
{
"original": "Compare with the less preferred `host` metadata alternative.",
"translation": "与不推荐的方式(`host`元数据)比较一下。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## Services",
"translation": "## 服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Services are singletons",
"translation": "### 服务总是单例的",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 07-01",
"translation": "#### 风格 07-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** use services as singletons within the same injector. Use them for sharing data and functionality.",
"translation": "**坚持**在同一个注入器内,把服务当做单例使用。用它们来共享数据和功能。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Services are ideal for sharing methods across a feature area or an app.",
"translation": "**为何?**服务是在特性范围或应用内共享方法的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Services are ideal for sharing stateful in-memory data.",
"translation": "**为何?**服务是共享状态性内存数据的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Single responsibility",
"translation": "### 单一职责",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 07-02",
"translation": "#### 风格 07-02",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** create services with a single responsibility that is encapsulated by its context.",
"translation": "**坚持**创建单一职责的服务,用职责封装在它的上下文中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** create a new service once the service begins to exceed that singular purpose.",
"translation": "**坚持**当服务成长到超出单一用途时,创建一个新服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** When a service has multiple responsibilities, it becomes difficult to test.",
"translation": "**为何?**当服务有多个职责时,它很难被测试。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Providing a service",
"translation": "### 提供一个服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 07-03",
"translation": "#### 风格 07-03",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Why?** The Angular injector is hierarchical.",
"translation": "**为何?** Angular 注入器是层次化的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** This is ideal when a service is sharing methods or state.",
"translation": "**为何?**服务是共享方法或状态的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Use the @Injectable() class decorator",
"translation": "### 使用 @Injectable() 类装饰器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 07-04",
"translation": "#### 风格 07-04",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## Data Services",
"translation": "## 数据服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Talk to the server through a service",
"translation": "### 通过服务与 Web 服务器通讯",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 08-01",
"translation": "#### 风格 08-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** refactor logic for making data operations and interacting with data to a service.",
"translation": "**坚持**把数据操作和与数据交互的逻辑重构到服务里。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## Lifecycle hooks",
"translation": "## 生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Use Lifecycle hooks to tap into important events exposed by Angular.",
"translation": "使用生命周期钩子来介入到 Angular 暴露的重要事件里。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### Implement lifecycle hook interfaces",
"translation": "### 实现生命周期钩子接口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style 09-01",
"translation": "#### 风格 09-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Do** implement the lifecycle hook interfaces.",
"translation": "**坚持**实现生命周期钩子接口。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "**Why?** Lifecycle interfaces prescribe typed method\nsignatures. use those signatures to flag spelling and syntax mistakes.",
"translation": "**为何?**如果使用强类型的方法签名,编译器和编辑器可以帮你揪出拼写错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "## Appendix",
"translation": "## 附录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Useful tools and tips for Angular.",
"translation": "有用的 Angular 工具和小提示",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style A-01",
"translation": "#### 风格 A-01",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "**Consider** adjusting the rules in codelyzer to suit your needs.",
"translation": "**考虑**调整 codelyzer 的规则来满足你的需求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "### File templates and snippets",
"translation": "### 文档模板和代码片段",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "#### Style A-02",
"translation": "#### 风格 A-02",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"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/content-2/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/styleguide.md"
},
{
"original": "# Template Syntax",
"translation": "# 模板语法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "{@a html}\n## HTML in templates",
"translation": "## 模板中的HTML",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Begin with the first form of data binding&mdash;interpolation&mdash;to see how much richer template HTML can be.",
"translation": "我们首先看看数据绑定的第一种形式 —— 插值表达式,它展示了模板的 HTML 可以有多丰富。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "## Interpolation ( <span class=\"syntax\">{&#xfeff;{...}}</span> )",
"translation": "## 插值表达式 ( <span class=\"syntax\">{&#xfeff;{...}}</span> )",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "You met the double-curly braces of interpolation, `{{` and `}}`, early in your Angular education.",
"translation": "在以前的 Angular 教程中,我们遇到过由双花括号括起来的插值表达式,`{{`和`}}`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "The expression can invoke methods of the host component such as `getVal()`, seen here:",
"translation": "这个表达式可以调用宿主组件的方法,就像下面用的`getVal()`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "But first, let's take a closer look at template expressions and statements.",
"translation": "讲解属性绑定之前,先深入了解一下模板表达式和模板语句。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "## Template expressions",
"translation": "## 模板表达式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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&nbsp;`=` symbol as in `[property]=\"expression\"`.",
"translation": "`{{1 + 1}}`中所包含的模板表达式是`1 + 1`。\n 在[属性绑定](guide/template-syntax#property-binding)中会再次看到模板表达式,它出现在`=`右侧的引号中,就像这样:`[property]=\"expression\"`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "JavaScript expressions that have or promote side effects are prohibited,\nincluding:",
"translation": "JavaScript 中那些具有或可能引发副作用的表达式是被禁止的,包括:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* assignments (`=`, `+=`, `-=`, ...)",
"translation": "赋值 (`=`, `+=`, `-=`, ...)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* <code>new</code>",
"translation": "`new`运算符",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* chaining expressions with <code>;</code> or <code>,</code>",
"translation": "使用`;`或`,`的链式表达式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* increment and decrement operators (`++` and `--`)",
"translation": "自增或自减操作符 (`++`和`--`)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Other notable differences from JavaScript syntax include:",
"translation": "和 JavaScript语 法的其它显著不同包括:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* no support for the bitwise operators `|` and `&`",
"translation": "不支持位运算`|`和`&`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* new [template expression operators](guide/template-syntax#expression-operators), such as `|`, `?.` and `!`.",
"translation": "具有新的[模板表达式运算符](guide/template-syntax#expression-operators),比如`|`、`?.`和`!`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### Expression context",
"translation": "### 表达式上下文",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Expression guidelines",
"translation": "### 表达式指南",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Template expressions can make or break an application.\nPlease follow these guidelines:",
"translation": "模板表达式能成就或毁掉一个应用。请遵循下列指南:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "* [Quick execution](guide/template-syntax#quick-execution)",
"translation": "[执行迅速](guide/template-syntax#quick-execution)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* [Simplicity](guide/template-syntax#simplicity)",
"translation": "[非常简单](guide/template-syntax#simplicity)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* [Idempotence](guide/template-syntax#idempotence)",
"translation": "[幂等性](guide/template-syntax#idempotence)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "The only exceptions to these guidelines should be in specific circumstances that you thoroughly understand.",
"translation": "超出上面指南外的情况应该只出现在那些你确信自己已经彻底理解的特定场景中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "#### No visible side effects",
"translation": "#### 没有可见的副作用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "A template expression should not change any application state other than the value of the\ntarget property.",
"translation": "模板表达式除了目标属性的值以外,不应该改变应用的任何状态。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "#### Quick execution",
"translation": "#### 执行迅速",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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.\nExpressions should finish quickly or the user experience may drag, especially on slower devices.\nConsider caching values when their computation is expensive.",
"translation": "Angular 执行模板表达式比我们想象的频繁。\n它们可能在每一次按键或鼠标移动后被调用。\n表达式应该快速结束否则用户就会感到拖沓特别是在较慢的设备上。\n当计算代价较高时应该考虑缓存那些从其它值计算得出的值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "#### Simplicity",
"translation": "#### 非常简单",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Although it's possible to write quite complex template expressions, you should avoid them.",
"translation": "虽然也可以写出相当复杂的模板表达式,但不要那么写。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "#### Idempotence",
"translation": "#### 幂等性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "## Template statements",
"translation": "## 模板语句",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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 `=`&nbsp;symbol as in `(event)=\"statement\"`.",
"translation": "模板**语句**用来响应由绑定目标(如 HTML 元素、组件或指令)触发的**事件**。\n模板语句将在[事件绑定](guide/template-syntax#event-binding)一节看到,它出现在`=`号右侧的引号中,就像这样:`(event)=\"statement\"`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "However, certain JavaScript syntax is not allowed:",
"translation": "然而,某些 JavaScript 语法仍然是不允许的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* <code>new</code>",
"translation": "`new`运算符",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* increment and decrement operators, `++` and `--`",
"translation": "自增和自减运算符:`++`和`--`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* operator assignment, such as `+=` and `-=`",
"translation": "操作并赋值,例如`+=`和`-=`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* the bitwise operators `|` and `&`",
"translation": "位操作符`|`和`&`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* the [template expression operators](guide/template-syntax#expression-operators)",
"translation": "[模板表达式运算符](guide/template-syntax#expression-operators)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### Statement context",
"translation": "### 语句上下文",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Statement guidelines",
"translation": "### 语句指南",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "## Binding syntax: An overview",
"translation": "## 绑定语法:概览",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Data binding is a mechanism for coordinating what users see, with application data values.\n While you could push values to and pull values from HTML,\n the application is easier to write, read, and maintain if you turn these chores over to a binding framework.\n You 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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Data direction",
"translation": "数据方向",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Syntax",
"translation": "语法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Type",
"translation": "绑定类型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "One-way",
"translation": "单向",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "from data source",
"translation": "从数据源",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "to view target",
"translation": "到视图目标",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Interpolation",
"translation": "插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Class",
"translation": "类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Style",
"translation": "样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "<td>\n<p> One-way</p>",
"translation": "单向",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "from view target",
"translation": "从视图目标",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "to data source",
"translation": "到数据源",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "<td><p>\n Event\n </p>",
"translation": "事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "<td><p>\n Two-way\n </p>",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "<td><p>\n Two-way\n </p>",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### A new mental model",
"translation": "### 新的思维模型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "You still create a structure and initialize attribute values this way in Angular templates.",
"translation": "在 Angular 模板中,我们仍使用同样的方式来创建结构和初始化 attribute 值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "That's HTML Plus.",
"translation": "这就是HTML+。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Then you learn about data binding. The first binding you meet might look like this:",
"translation": "现在开始学习数据绑定。我们碰到的第一种数据绑定是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### HTML attribute vs. DOM property",
"translation": "### HTML attribute 与 DOM property 的对比",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "* Some HTML attributes don't have corresponding properties. `colspan` is one example.",
"translation": "有些 HTML attribute 没有对应的 property如`colspan`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* Some DOM properties don't have corresponding attributes. `textContent` is one example.",
"translation": "有些 DOM property 没有对应的 attribute如`textContent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "That last category is confusing until you grasp this general rule:",
"translation": "最后一类尤其让人困惑…… 除非我们能理解这个普遍原则:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.",
"translation": "HTML attribute `value`指定了*初始*值DOM `value` property 是*当前*值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "This fact bears repeating:",
"translation": "这句话值得再强调一次:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "**Template binding works with *properties* and *events*, not *attributes*.**",
"translation": "**模板绑定是通过 *property* 和*事件*来工作的,而不是 *attribute*。**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "A world without attributes",
"translation": "没有 attribute 的世界",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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 eventsof the target object.\nHTML attributes effectively disappear.",
"translation": "在 Angular 的世界中attribute 唯一的作用是用来初始化元素和指令的状态。\n当进行数据绑定时只是在与元素和指令的 property 和事件打交道,而 attribute 就完全靠边站了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "With this model firmly in mind, read on to learn about binding targets.",
"translation": "把这个思维模型牢牢的印在脑子里,接下来,学习什么是绑定目标。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### Binding targets",
"translation": "### 绑定目标",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Type",
"translation": "绑定类型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Target",
"translation": "目标",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Examples",
"translation": "范例",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Element&nbsp;property",
"translation": "元素的 property",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Component&nbsp;property",
"translation": "组件的 property",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Directive&nbsp;property",
"translation": "指令的 property",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Event",
"translation": "事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Element&nbsp;event",
"translation": "元素的事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Component&nbsp;event",
"translation": "组件的事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Directive&nbsp;event",
"translation": "指令的事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Two-way",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Event and property",
"translation": "事件与 property",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Attribute (the&nbsp;exception)",
"translation": "attribute例外情况",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Class",
"translation": "CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Style",
"translation": "样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "With this broad view in mind, you're ready to look at binding types in detail.",
"translation": "放开眼界,我们来看看每种绑定类型的具体情况。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "## Property binding ( <span class=\"syntax\">[property]</span> )",
"translation": "## 属性绑定 ( <span class=\"syntax\">[属性名]</span> )",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Another example is disabling a button when the component says that it `isUnchanged`:",
"translation": "另一个例子是当组件说它`isUnchanged`(未改变)时禁用按钮:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Another is setting a property of a directive:",
"translation": "另一个例子是设置指令的属性:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### One-way *in*",
"translation": "### 单向*输入*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Similarly, you cannot use property binding to *call* a method on the target element.",
"translation": "也不能使用属性 绑定 来*调用*目标元素上的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Binding target",
"translation": "### 绑定目标",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "An element property between enclosing square brackets identifies the target property. The target property in the following code is the image element's `src` property.",
"translation": "包裹在方括号中的元素属性名标记着目标属性。下列代码中的目标属性是 image 元素的`src`属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Some people prefer the `bind-` prefix alternative, known as the *canonical form*:",
"translation": "有些人喜欢用`bind-`前缀的可选形式,并称之为*规范形式*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Avoid side effects",
"translation": "### 消除副作用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Of course, the expression might invoke a property or method that has side effects.\n Angular has no way of knowing that or stopping you.",
"translation": "当然,表达式可能会调用具有副作用的属性或方法。但 Angular 没法知道这一点,也没法阻止我们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Return the proper type",
"translation": "### 返回恰当的类型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Remember the brackets",
"translation": "### 别忘了方括号",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Don't make the following mistake:",
"translation": "不要出现这样的失误:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### One-time string initialization",
"translation": "### 一次性字符串初始化",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "You *should* omit the brackets when all of the following are true:",
"translation": "当满足下列条件时,*应该*省略括号:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* The target property accepts a string value.",
"translation": "目标属性接受字符串值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* The string is a fixed value that you can bake into the template.",
"translation": "字符串是个固定值,可以直接合并到模块中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* This initial value never changes.",
"translation": "这个初始值永不改变。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Property binding or interpolation?",
"translation": "### 属性绑定还是插值表达式?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "_Interpolation_ is a convenient alternative to _property binding_ in many cases.",
"translation": "在多数情况下,插值表达式是更方便的备选项。\n实际上在渲染视图之前Angular 把这些插值表达式翻译成相应的属性绑定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "When setting an element property to a non-string data value, you must use _property binding_.",
"translation": "但数据类型不是字符串时,就必须使用*属性绑定*了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "#### Content security",
"translation": "#### 内容安全",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Imagine the following *malicious content*.",
"translation": "假设下面的*恶意内容*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Interpolation handles the script tags differently than property binding but both approaches render the\ncontent harmlessly.",
"translation": "插值表达式处理 script 标签与属性绑定有所不同,但是二者都只渲染没有危害的内容。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "<img src='generated/images/guide/template-syntax/evil-title.png' alt=\"evil title made safe\">",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "## Attribute, class, and style bindings",
"translation": "## attribute、class 和 style 绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "The template syntax provides specialized one-way bindings for scenarios less well suited to property binding.",
"translation": "模板语法为那些不太适合使用属性绑定的场景提供了专门的单向数据绑定形式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### Attribute binding",
"translation": "### attribute 绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "You can set the value of an attribute directly with an **attribute binding**.",
"translation": "可以通过**attribute 绑定**来直接设置 attribute 的值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "**You must use attribute binding when there is no element property to bind.**",
"translation": "**因为当元素没有属性可绑的时候,就必须使用 attribute 绑定。**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "This fact becomes painfully obvious when you write something like this.",
"translation": "如果想写出类似下面这样的东西,现状会令我们痛苦:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "And you get this error:",
"translation": "会得到这个错误:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "You need attribute bindings to create and bind to such attributes.",
"translation": "我们需要 attribute 绑定来创建和绑定到这样的 attribute。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Bind `[attr.colspan]` to a calculated value:",
"translation": "这里把`[attr.colspan]`绑定到一个计算值:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Here's how the table renders:",
"translation": "这里是表格渲染出来的样子:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Class binding",
"translation": "### CSS 类绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Style binding",
"translation": "### 样式绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "You can set inline styles with a **style binding**.",
"translation": "通过**样式绑定**,可以设置内联样式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Some style binding styles have a unit extension. The following example conditionally sets the font size in “em” and “%” units.",
"translation": "有些样式绑定中的样式带有单位。在这里,以根据条件用 “em” 和 “%” 来设置字体大小的单位。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "{@a event-binding}",
"translation": "## Event binding ( <span class=\"syntax\">(event)</span> )\n## 事件绑定 ( <span class=\"syntax\">(事件名)</span> )",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Target event",
"translation": "### 目标事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "A **name between parentheses** &mdash; for example, `(click)` &mdash;\nidentifies the target event. In the following example, the target is the button's click event.",
"translation": "**圆括号中的名称** —— 比如`(click)` —— 标记出目标事件。在下面例子中,目标是按钮的 click 事件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Some people prefer the `on-` prefix alternative, known as the **canonical form**:",
"translation": "有些人更喜欢带`on-`前缀的备选形式,称之为**规范形式**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### *$event* and event handling statements",
"translation": "### *$event* 和事件处理语句",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "In an event binding, Angular sets up an event handler for the target event.",
"translation": "在事件绑定中Angular 会为目标事件设置事件处理器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "The binding conveys information about the event, including data values, through\nan **event object named `$event`**.",
"translation": "绑定会通过**名叫`$event`的事件对象**传递关于此事件的信息(包括数据值)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Consider this example:",
"translation": "考虑这个范例:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Custom events with <span class=\"syntax\">EventEmitter</span>",
"translation": "### 使用 <span class=\"syntax\">EventEmitter</span> 实现自定义事件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Here are the pertinent excerpts from that `HeroDetailComponent`:",
"translation": "下面的代码节选自`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Now imagine a hosting parent component that binds to the `HeroDetailComponent`'s `deleteRequest` event.",
"translation": "现在,假设有个宿主的父组件,它绑定了`HeroDetailComponent`的`deleteRequest`事件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Template statements have side effects",
"translation": "### 模板语句有副作用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "## Two-way binding ( <span class=\"syntax\">[(...)]</span> )",
"translation": "## 双向数据绑定 ( <span class=\"syntax\">[(...)]</span> )",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "[( )] = banana in a box",
"translation": "[( )] = 盒子里的香蕉",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Visualize a *banana in a box* to remember that the parentheses go _inside_ the brackets.",
"translation": "想象*盒子里的香蕉*来记住方括号套圆括号。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Clearly the two-way binding syntax is a great convenience compared to separate property and event bindings.",
"translation": "显然,比起单独绑定属性和事件,双向数据绑定语法显得非常方便。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "## Built-in directives",
"translation": "## 内置指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "## Built-in _attribute_ directives",
"translation": "## 内置*属性型*指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### NgClass",
"translation": "### NgClass 指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Adding an `ngClass` property binding to `currentClasses` sets the element's classes accordingly:",
"translation": "把`NgClass`属性绑定到`currentClasses`根据它来设置此元素的CSS类",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "It's up to you to call `setCurrentClasses()`, both initially and when the dependent properties change.",
"translation": "你既可以在初始化时调用`setCurrentClassess()`,也可以在所依赖的属性变化时调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### NgStyle",
"translation": "### NgStyle 指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Adding an `ngStyle` property binding to `currentStyles` sets the element's styles accordingly:",
"translation": "把`NgStyle`属性绑定到`currentStyles`,以据此设置此元素的样式:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "It's up to you to call `setCurrentStyles()`, both initially and when the dependent properties change.",
"translation": "你既可以在初始化时调用`setCurrentStyles()`,也可以在所依赖的属性变化时调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Two-way data binding with the `NgModel` directive makes that easy. Here's an example:",
"translation": "使用`NgModel`指令进行双向数据绑定可以简化这种工作。例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "#### _FormsModule_ is required to use _ngModel_",
"translation": "#### 使用 `ngModel` 时需要 `FormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Here's how to import the `FormsModule` to make `[(ngModel)]` available.",
"translation": "导入`FormsModule`并让`[(ngModel)]`可用的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "#### Inside <span class=\"syntax\">[(ngModel)]</span>",
"translation": "#### <span class=\"syntax\">[(ngModel)]</span>内幕",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "The following contrived example forces the input value to uppercase:",
"translation": "下面这个生造的例子强制输入框的内容变成大写:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Here are all variations in action, including the uppercase version:",
"translation": "这里是所有这些变体的动画,包括这个大写转换的版本:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "## Built-in _structural_ directives",
"translation": "## 内置*结构型*指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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>`](structural-directives.html#ngcontainer \"<ng-container>对元素进行分组。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* how to write your own structural directive.",
"translation": "如何写自己的结构型指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "_This_ section is an introduction to the common structural directives:",
"translation": "*本节*是对常见结构型指令的简介:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "* [NgForOf](guide/template-syntax#ngFor) - repeat a template for each item in a list",
"translation": "[`NgSwitch`](guide/template-syntax#ngSwitch) - 一组指令,用于切换一组视图",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### NgIf",
"translation": "### NgIf 指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Don't forget the asterisk (`*`) in front of `ngIf`.",
"translation": "别忘了`ngIf`前面的星号(`*`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "#### Show/hide is not the same thing",
"translation": "#### 这和显示/隐藏不是一回事",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Hiding an element is quite different from removing an element with `NgIf`.",
"translation": "但隐藏子树和用`NgIf`排除子树是截然不同的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "#### Guard against null",
"translation": "#### 防范空指针错误",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### NgForOf",
"translation": "### NgFor 指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "`NgForOf` is a _repeater_ directive &mdash; 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/content-2/guide/template-syntax.md"
},
{
"original": "Here is an example of `NgForOf` applied to a simple `<div>`:",
"translation": "下例中,`NgFor`应用在一个简单的`<div>`上:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "You can also apply an `NgForOf` to a component element, as in this example:",
"translation": "也可以把`NgFor`应用在一个组件元素上,就下例这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Don't forget the asterisk (`*`) in front of `ngFor`.",
"translation": "不要忘了`ngFor`前面的星号 (`*`)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "The text assigned to `*ngFor` is the instruction that guides the repeater process.",
"translation": "赋值给`*ngFor`的文本是用于指导重复器如何工作的指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "#### *ngFor microsyntax",
"translation": "#### NgFor 微语法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "The string assigned to `*ngFor` is not a [template expression](guide/template-syntax#template-expressions).\nIt's a *microsyntax* &mdash; 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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Learn about the _microsyntax_ in the [_Structural Directives_](guide/structural-directives#microsyntax) guide.",
"translation": "要了解*微语法*的更多知识,参见[_结构型指令_](guide/structural-directives#microsyntax)一章。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### Template input variables",
"translation": "### 模板输入变量",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "#### *ngFor with _index_",
"translation": "#### 带索引的`*ngFor`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "#### *ngFor with _trackBy_",
"translation": "#### 带`trackBy`的`*ngFor`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "For example, re-querying the server could reset the list with all new hero objects.",
"translation": "例如,我们可以通过重新从服务器查询来刷新英雄列表。\n 刷新后的列表可能包含很多(如果不是全部的话)以前显示过的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "In the microsyntax expression, set `trackBy` to this method.",
"translation": "在微语法中,把`trackBy`设置为该方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "* With no `trackBy`, both buttons trigger complete DOM element replacement.",
"translation": "如果没有`trackBy`这些按钮都会触发完全的DOM元素替换。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* With `trackBy`, only changing the `id` triggers element replacement.",
"translation": "有了`trackBy`,则只有修改了`id`的按钮才会触发元素替换。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "<img src=\"generated/images/guide/template-syntax/ng-for-track-by-anim.gif\" alt=\"trackBy\">",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### The _NgSwitch_ directives",
"translation": "### `NgSwitch`指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "* `NgSwitchCase` adds its element to the DOM when its bound value equals the switch value.",
"translation": "`NgSwitchCase`会在它绑定到的值等于候选值时把它所在的元素加入到DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "* `NgSwitchDefault` adds its element to the DOM when there is no selected `NgSwitchCase`.",
"translation": "`NgSwitchDefault`会在没有任何一个`NgSwitchCase`被选中时把它所在的元素加入DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "## Template reference variables ( <span class=\"syntax\">#var</span> )",
"translation": "## 模板引用变量 ( <span class=\"syntax\">#var</span> )",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "How a reference variable gets its value",
"translation": "### 模板引用变量怎么得到它的值?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Template reference variable warning notes",
"translation": "关于模板引用变量的提醒",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "## Input and Output properties",
"translation": "## 输入和输出属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "You can only bind to _another_ component or directive through its _Input_ and _Output_ properties.",
"translation": "我们只能通过它的**输入**和**输出**属性将其绑定到**其它**组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Remember that all **components** are **directives**.",
"translation": "记住,所有的**组件**都是**指令**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### Input or output?",
"translation": "### 输入还是输出?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "The terms _input_ and _output_ reflect the perspective of the target directive.",
"translation": "_输入_和_输出_这两个词是从目标指令的角度来说的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Aliasing input/output properties",
"translation": "给输入/输出属性起别名",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Sometimes the public name of an input/output property should be different from the internal name.",
"translation": "有时需要让输入/输出属性的公开名字不同于内部名字。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "## Template expression operators",
"translation": "## 模板表达式操作符",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### The pipe operator ( <span class=\"syntax\">|</span> )",
"translation": "### 管道操作符 ( | )",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "You can chain expressions through multiple pipes:",
"translation": "还可以通过多个管道串联表达式:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "And you can also [apply parameters](guide/pipes#parameterizing-a-pipe) to a pipe:",
"translation": "还能对它们使用参数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "The `json` pipe is particularly helpful for debugging bindings:",
"translation": "`json`管道对调试绑定特别有用:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "The generated output would look something like this",
"translation": "它生成的输出是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "### The safe navigation operator ( <span class=\"syntax\">?.</span> ) and null property paths",
"translation": "### 安全导航操作符 ( ?. ) 和空属性路径",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "What happens when the following data bound `title` property is null?",
"translation": "如果下列数据绑定中`title`属性为空,会发生什么?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "JavaScript throws a null reference error, and so does Angular:",
"translation": "JavaScript 抛出了空引用错误Angular 也是如此:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "Worse, the *entire view disappears*.",
"translation": "晕,*整个视图都不见了*。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "Unfortunately, the app crashes when the `currentHero` is null.",
"translation": "不幸的是,当`currentHero`为空的时候,应用崩溃了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "You could code around that problem with [*ngIf](guide/template-syntax#ngIf).",
"translation": "可以通过用[NgIf](guide/template-syntax#ngIf)代码环绕它来解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "### The non-null assertion operator ( <span class=\"syntax\">!</span> )",
"translation": "### 非空断言操作符(<span class=\"syntax\">!</span>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "The _Angular_ **non-null assertion operator (`!`)** serves the same purpose in an Angular template.",
"translation": "*Angular* 模板中的**非空断言操作符(`!`)也是同样的用途。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "You'll need this template operator when you turn on strict null checks. It's optional otherwise.",
"translation": "如果我们打开了严格控制检测,那就要用到这个模板操作符,而其它情况下则是可选的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/template-syntax.md"
},
{
"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/content-2/guide/template-syntax.md"
},
{
"original": "# Testing",
"translation": "# 测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This guide offers tips and techniques for testing Angular applications.\nThough this page includes some general testing principles and techniques,\nthe focus is on testing applications written with Angular.",
"translation": "本章提供了一些测试Angular应用的提示和技巧。虽然这里讲述了一些常规测试理念和技巧但是其重点是测试用Angular编写的应用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Live examples",
"translation": "## 在线例子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This guide presents tests of a sample application that is much like the [_Tour of Heroes_ tutorial](tutorial).\nThe sample application and all tests in this guide are available as live examples for inspection, experiment, and download:",
"translation": "这篇指南会展示一个范例应用的所有测试,这个范例应用和[《英雄指南》教程](tutorial)非常像。\n本章中的这个范例应用及其所有测试都有在线例子以供查看、试验和下载。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"1st-specs\" embedded-style>A spec to verify the test environment</live-example>.",
"translation": "<live-example plnkr=\"1st-specs\" embedded-style>用于验证测试环境的规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"banner-inline-specs\" embedded-style>The first component spec with inline template</live-example>.",
"translation": "<live-example plnkr=\"banner-inline-specs\" embedded-style>第一个带内联模板的组件规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"banner-specs\" embedded-style>A component spec with external template</live-example>.",
"translation": "<live-example plnkr=\"banner-specs\" embedded-style>带外部模板的组件规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* <live-example name=\"setup\" plnkr=\"quickstart-specs\" embedded-style>The QuickStart seed's AppComponent spec</live-example>.",
"translation": "<live-example name=\"setup\" plnkr=\"quickstart-specs\" embedded-style>快速起步种子工程的`AppComponent`规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* <live-example embedded-style>The sample application to be tested</live-example>.",
"translation": "<live-example embedded-style>所要测试的范例应用</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"app-specs\" embedded-style>All specs that test the sample application</live-example>.",
"translation": "<live-example plnkr=\"app-specs\" embedded-style>本范例应用的所有规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"bag-specs\" embedded-style>A grab bag of additional specs</live-example>.",
"translation": "<live-example plnkr=\"bag-specs\" embedded-style>其它规约汇总</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Introduction to Angular Testing",
"translation": "## Angular测试入门",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This page guides you through writing tests to explore\nand confirm the behavior of the application. Testing\ndoes the following:",
"translation": "本章教你如何编写测试程序来探索和确认应用的行为。测试的作用有:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. Guards against changes that break existing code (“regressions”).",
"translation": "测试**守护**由于代码变化而打破已有代码(“回归”)的情况。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. Clarifies what the code does both when used as intended and when faced with deviant conditions.",
"translation": "不管代码被正确使用还是错误使用,测试程序起到**澄清**代码的作用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. Reveals mistakes in design and implementation.\nTests shine a harsh light on the code from many angles.\nWhen a part of the application seems hard to test, the root cause is often a design flaw,\nsomething to cure now rather than later when it becomes expensive to fix.",
"translation": "测试程序**暴露**设计和实现可能出现的错误。测试程序从很多角度为代码亮出警报灯。当应用程序很难被测试时,\n其根本原因一般都是设计缺陷这种缺陷最好立刻被修正不要等到它变得很难被修复的时候才行动。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This chapter assumes that you know something about testing. Don't worry if you don't.\nThere are plenty of books and online resources to get up to speed.",
"translation": "本章假设你熟悉测试。但是如果你不熟悉也没有关系。有很多书本和在线资源可以帮助你。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Tools and technologies",
"translation": "### 工具与技术",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "You can write and run Angular tests with a variety of tools and technologies.\nThis guide describes specific choices that are known to work well.",
"translation": "你可以用多种工具和技术来编写和运行Angular测试程序。本章介绍了一些大家已经知道能良好工作的选择。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Technology",
"translation": "技术",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Purpose",
"translation": "目的",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [Jasmine test framework](http://jasmine.github.io/2.4/introduction.html)\n provides everything needed to write basic tests.\n It ships with an HTML test runner that executes tests in the browser.",
"translation": "[Jasmine测试框架](http://jasmine.github.io/2.4/introduction.html)提供了所有编写基本测试的工具。\n 它自带HTML测试运行器用来在浏览器中执行测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Angular testing utilities",
"translation": "Angular测试工具",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Angular testing utilities create a test environment\n for the Angular application code under test.\n Use them to condition and control parts of the application as they\n interact _within_ the Angular environment.",
"translation": "Angular测试工具为被测试的Angular应用代码创建测试环境。在应用代码与Angular环境互动时使用Angular测试工具来限制和控制应用的部分代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [karma test runner](https://karma-runner.github.io/1.0/index.html)\n is ideal for writing and running unit tests while developing the application.\n It can be an integral part of the project's development and continuous integration processes.\n This guide describes how to set up and run tests with karma.",
"translation": "[karma测试运行器](https://karma-runner.github.io/1.0/index.html)是在开发应用的过程中\n 编写和运行单元测试的理想工具。\n 它能成为项目开发和连续一体化进程的不可分割的一部分。本章讲述了如何用Karma设置和运行测试程序。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Use protractor to write and run _end-to-end_ (e2e) tests.\n End-to-end tests explore the application _as users experience it_.\n In e2e testing, one process runs the real application\n and a second process runs protractor tests that simulate user behavior\n and assert that the application respond in the browser as expected.",
"translation": "使用`Protractor`来编写和运行_端对端(e2e)_测试程序。端对端测试程序**像用户体验应用程序那样**探索它。\n 在端对端测试中一条进程运行真正的应用另一条进程运行Protractor测试程序模拟用户行为判断应用在浏览器中的反应是否正确。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Setup",
"translation": "### 环境设置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "There are two fast paths to getting started with unit testing.",
"translation": "要开始单元测试,有两条捷径:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. Start a new project following the instructions in [Setup](guide/setup \"Setup\").",
"translation": "遵循[环境设置](guide/setup \"环境设置\")中给出的步骤开始一个新项目。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. Start a new project with the\n<a href=\"https://github.com/angular/angular-cli/blob/master/README.md\" title=\"Angular CLI\">Angular CLI</a>.",
"translation": "使用[Angular CLI](https://github.com/angular/angular-cli/blob/master/README.md)创建新的项目。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Both approaches install npm packages, files, and scripts pre-configured for applications\nbuilt in their respective modalities.\nTheir artifacts and procedures differ slightly but their essentials are the same\nand there are no differences in the test code.",
"translation": "以上两种方法都安装在各自的模式下为应用预先配置的**npm包、文件和脚本**。它们的文件和规程有一点不同,但是它们的核心部分是一样的,并且在测试代码方面没有任何区别。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "In this guide, the application and its tests are based on the [setup instructions](guide/setup \"Setup\").\nFor a discussion of the unit testing setup files, [see below](guide/testing#setup-files).",
"translation": "本章中,该应用及其测试都是基于[环境设置步骤](guide/setup \"Setup\")的。\n对单元测试的环境设置文件的讨论[参见后面](guide/testing#setup-files)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Isolated unit tests vs. the Angular testing utilities",
"translation": "### 独立单元测试 vs. Angular测试工具集",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "[Isolated unit tests](guide/testing#isolated-unit-tests \"Unit testing without the Angular testing utilities\")\nexamine an instance of a class all by itself without any dependence on Angular or any injected values.\nThe tester creates a test instance of the class with `new`, supplying test doubles for the constructor parameters as needed, and\nthen probes the test instance API surface.",
"translation": "[独立单元测试](guide/testing#isolated-unit-tests \"不使用Angular测试工具集的单元测试\")用于测试那些完全不依赖Angular或不需要注入值的类实例。\n测试程序会`new`出一个测试类的实例为构造函数参数提供所需的测试替身然后测试该实例的API接口。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "*You should write isolated unit tests for pipes and services.*",
"translation": "*我们应该为管道和服务书写独立单元测试。*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "You can test components in isolation as well.\nHowever, isolated unit tests don't reveal how components interact with Angular.\nIn particular, they can't reveal how a component class interacts with its own template or with other components.",
"translation": "我们也同样可以对组件写独立单元测试。\n不过独立单元测试无法体现组件与Angular的交互。\n具体来说就是不能发现组件类如何与它的模板或其它组件交互。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Such tests require the **Angular testing utilities**.\nThe Angular testing utilities include the `TestBed` class and several helper functions from `@angular/core/testing`.\nThey are the main focus of this guide and you'll learn about them\nwhen you write your [first component test](guide/testing#simple-component-test).\nA comprehensive review of the Angular testing utilities appears [later in this guide](guide/testing#atu-apis).",
"translation": "这时你需要*Angular测试工具集*。\nAngular测试工具集包括`TestBed`类和一些来自`@angular/core/testing`的助手函数。\n本章将会重点讲解它们通过[第一个组件测试](guide/testing#simple-component-test)来讲解。\n[本章稍后的部分](guide/testing#atu-apis)将展示Angular测试工具集的全貌。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "But first you should write a dummy test to verify that your test environment is set up properly\nand to lock in a few basic testing skills.",
"translation": "但首先,我们要先随便写一个测试来验证测试环境是否已经就绪了,并掌握一些基础的测试技术。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## The first karma test",
"translation": "## 第一个`karma`测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Start with a simple test to make sure that the setup works properly.",
"translation": "编写简单的测试程序,来确认以上的配置是否工作正常。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Create a new file called `1st.spec.ts` in the application root folder, `src/app/`",
"translation": "在应用的根目录`app/`创建新文件,名叫`1st.spec.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Tests written in Jasmine are called _specs_ .\n**The filename extension must be `.spec.ts`**,\nthe convention adhered to by `karma.conf.js` and other tooling.",
"translation": "用Jasmine编写的测试程序都被叫做**specs**。**文件名后缀必须是`.spec.ts`**,这是`karma.conf.js`和其它工具所坚持和遵守的规约。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "**Put spec files somewhere within the `src/app/` folder.**\nThe `karma.conf.js` tells karma to look for spec files there,\nfor reasons explained [below](guide/testing#q-spec-file-location).",
"translation": "**将测试程序spec放到`app/`文件夹下的任何位置。**\n`karma.conf.js`告诉`Karma`在这个文件夹中寻找测试程序spec文件原因在 [这里](guide/testing#q-spec-file-location) 有所解释。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Add the following code to `src/app/1st.spec.ts`.",
"translation": "添加下面的代码到`app/1st.spec.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Run with karma",
"translation": "### 运行Karma",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Compile and run it in karma from the command line using the following command:",
"translation": "使用下面的命令从命令行中编译并在`Karma`中运行上面的测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The command compiles the application and test code and starts karma.\nBoth processes watch pertinent files, write messages to the console, and re-run when they detect changes.",
"translation": "该命令编译应用及其测试代码并启动Karma。\n两个进程都监视相关文件往控制台输入信息和检测到变化时自动重新运行。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The documentation setup defines the `test` command in the `scripts` section of npm's `package.json`.\nThe Angular CLI has different commands to do the same thing. Adjust accordingly.",
"translation": "《快速上手》在npm的`package.json`中的`scripts`里定义了`test`命令。\nAngular CLI使用不同的命令来做同样的事情。对不同的环境采取不同的方案。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "After a few moments, karma opens a browser and starts writing to the console.",
"translation": "等一小段时间后Karma便打开浏览器并开始向控制台输出。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Hide (don't close!) the browser and focus on the console output, which\nshould look something like this:",
"translation": "隐藏(不要关闭)浏览器,查看控制台的输出,应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Both the compiler and karma continue to run. The compiler output is preceded by `[0]`;\nthe karma output by `[1]`.",
"translation": "编译器和`Karma`都会持续运行。编译器的输入信息前面有`[0]``Karma`的输出前面有`[1]`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Change the expectation from `true` to `false`.",
"translation": "将期望从`true`变换为`false`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The _compiler_ watcher detects the change and recompiles.",
"translation": "**编译器**监视器检测到这个变化并重新编译。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The _karma_ watcher detects the change to the compilation output and re-runs the test.",
"translation": "**`Karma`**监视器检测到编译器输出的变化,并重新运行测试。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It fails of course.",
"translation": "正如所料,测试结果是**失败**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Restore the expectation from `false` back to `true`.\nBoth processes detect the change, re-run, and karma reports complete success.",
"translation": "将期望从`false`恢复为`true`。两个进程都检测到这个变化,自动重新运行,`Karma`报告测试成功。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The console log can be quite long. Keep your eye on the last line.\nWhen all is well, it reads `SUCCESS`.",
"translation": "控制台的日志可能会非常长。注意最后一样。当一切正常时,它会显示`SUCCESS`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Test debugging",
"translation": "### 调试测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Debug specs in the browser in the same way thatyou debug an application.",
"translation": "在浏览器中像调试应用一样调试测试程序spec。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. Reveal the karma browser window (hidden earlier).",
"translation": "显示`Karma`的浏览器窗口(之前被隐藏了)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests.",
"translation": "点击“DEBUG”按钮它打开一页新浏览器标签并重新开始运行测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "1. Pick the \"sources\" section.",
"translation": "选择“sources”页",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "1. Set a breakpoint in the test.",
"translation": "在测试程序中设置断点。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. Refresh the browser, and it stops at the breakpoint.",
"translation": "刷新浏览器...然后它就会停在断点上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Try the live example",
"translation": "### 试试这个在线例子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "You can also try this test as a <live-example plnkr=\"1st-specs\" title=\"First spec\" embedded-style></live-example> in plunker.\nAll of the tests in this guide are available as [live examples](guide/testing#live-examples \"Live examples of these tests\").",
"translation": "你还可以在plunker的<live-example plnkr=\"1st-specs\" title=\"First spec\" embedded-style></live-example>中试运行这个测试。\n本章的所有测试都有相应的[在线例子](guide/testing#live-examples \"Live examples of these tests\")。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Test a component",
"translation": "## 测试一个组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "An Angular component is the first thing most developers want to test.\nThe `BannerComponent` in `src/app/banner-inline.component.ts` is the simplest component in this application and\na good place to start.\nIt presents the application title at the top of the screen within an `<h1>` tag.",
"translation": "大多数开发人员首先要测试的就是Angular组件。\n`src/app/banner-inline.component.ts`中的`BannerComponent`是这个应用中最简单的组件,也是一个好的起点。\n它所表示的是屏幕顶部`<h1>`标签中的应用标题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This version of the `BannerComponent` has an inline template and an interpolation binding.\nThe component is probably too simple to be worth testing in real life but\nit's perfect for a first encounter with the Angular testing utilities.",
"translation": "这个版本的`BannerComponent`有一个内联模板和一个插值表达式绑定。\n这个组件可能太简单以至于在真实的项目中都不值得测试但它却是首次接触Angular测试工具集时的完美例子。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The corresponding `src/app/banner-inline.component.spec.ts` sits in the same folder as the component,\nfor reasons explained in the [FAQ](guide/testing#faq) answer to\n[\"Why put specs next to the things they test?\"](guide/testing#q-spec-file-location).",
"translation": "组件对应的`src/app/banner-inline.component.spec.ts`文件与该组件位于同一个目录中,原因详见[FAQ](guide/testing#faq)中的\n[为什么要把测试规约文件放在被测试对象旁边?](guide/testing#q-spec-file-location)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Start with ES6 import statements to get access to symbols referenced in the spec.",
"translation": "在测试文件中我们先用ES6的`import`语句来引入测试所需的符号。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here's the `describe` and the `beforeEach` that precedes the tests:",
"translation": "测试前面的`describe`和`beforeEach`如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _TestBed_",
"translation": "### _TestBed_ 测试台",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "`TestBed` is the first and most important of the Angular testing utilities.\nIt creates an Angular testing module&mdash;an `@NgModule` class&mdash;that\nyou configure with the `configureTestingModule` method to produce the module environment for the class you want to test.\nIn effect, you detach the tested component from its own application module\nand re-attach it to a dynamically-constructed Angular test module\ntailored specifically for this battery of tests.",
"translation": "`TestBed`测试台是Angular测试工具集中的首要概念。\n它创建Angular测试模块一个`@NgModule`类),我们可以通过调用它的`configureTestingModule`方法来为要测试的类生成模块环境。\n其效果是你可以把被测试的组件从原有的应用模块中剥离出来把它附加到一个动态生成的Angular测试模块上而该测试模块可以为这些测试进行特殊裁剪。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `configureTestingModule` method takes an `@NgModule`-like metadata object.\nThe metadata object can have most of the properties of a normal [NgModule](guide/ngmodule).",
"translation": "`configureTestingModule`方法接受一个类似`@NgModule`的元数据对象。这个元数据对象具有标准[Angular模块](guide/ngmodule)的大多数属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "_This metadata object_ simply declares the component to test, `BannerComponent`.\nThe metadata lack `imports` because (a) the default testing module configuration already has what `BannerComponent` needs\nand (b) `BannerComponent` doesn't interact with any other components.",
"translation": "*这里的元数据对象*只是声明了要测试的组件`BannerComponent`。\n这个元数据中没有`imports`属性,这是因为:(a) 默认的测试模块配置中已经有了`BannerComponent`所需的一切,(b) `BannerComponent`不需要与任何其它组件交互。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Call `configureTestingModule` within a `beforeEach` so that\n`TestBed` can reset itself to a base state before each test runs.",
"translation": "在`beforeEach`中调用`configureTestingModule`,以便`TestBed`可以在运行每个测试之前都把自己重置回它的基础状态。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The base state includes a default testing module configuration consisting of the\ndeclarables (components, directives, and pipes) and providers (some of them mocked)\nthat almost everyone needs.",
"translation": "基础状态中包含一个默认的测试模块配置它包含每个测试都需要的那些声明组件、指令和管道以及服务提供商有些是Mock版。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The testing shims mentioned [later](guide/testing#testbed-methods) initialize the testing module configuration\nto something like the `BrowserModule` from `@angular/platform-browser`.",
"translation": "[之前](guide/testing#setup)提到的测试垫片初始化测试模块配置到一个模块,这个模块和`@angular/platform-browser`中的`BrowserModule`类似。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This default configuration is merely a _foundation_ for testing an app.\nLater you'll call `TestBed.configureTestingModule` with more metadata that define additional\nimports, declarations, providers, and schemas to fit your application tests.\nOptional `override` methods can fine-tune aspects of the configuration.",
"translation": "这个默认的配置只是测试的*基础性*工作。稍后我们会调用`TestBed.configureTestingModule`来传入更多元数据,这些元数据定义了额外的\n`imports`、`declarations`、`providers`和试用于这些测试的概要Schema。\n可选的`override`方法可以微调配置的各个方面。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _createComponent_",
"translation": "### _createComponent_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "After configuring `TestBed`, you tell it to create an instance of the _component-under-test_.\nIn this example, `TestBed.createComponent` creates an instance of `BannerComponent` and\nreturns a [_component test fixture_](guide/testing#component-fixture).",
"translation": "在配置好`TestBed`之后,我们可以告诉它创建一个*待测组件*的实例。\n在这个例子中`TestBed.createComponent`创建了一个`BannerComponent`的实例,并返回一个[*组件测试夹具*](guide/testing#component-fixture)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Do not re-configure `TestBed` after calling `createComponent`.",
"translation": "在调用了`createComponent`之后就不要再重新配置`TestBed`了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `createComponent` method closes the current `TestBed` instance to further configuration.\nYou cannot call any more `TestBed` configuration methods, not `configureTestingModule`\nnor any of the `override...` methods. If you try, `TestBed` throws an error.",
"translation": "`createComponent`方法封闭了当前的`TestBed`实例,以免将来再配置它。\n我们不能再调用任何`TestBed`的方法修改配置:不能调用`configureTestingModule`或任何`override...`方法。如果这么做,`TestBed`就会抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _ComponentFixture_, _DebugElement_, and _query(By.css)_",
"translation": "### `ComponentFixture`、`DebugElement` 和 `query(By.css)`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `createComponent` method returns a **`ComponentFixture`**, a handle on the test environment surrounding the created component.\nThe fixture provides access to the component instance itself and\nto the **`DebugElement`**, which is a handle on the component's DOM element.",
"translation": "`createComponent`方法返回**`ComponentFixture`**,用来控制和访问已创建的组件所在的测试环境。\n 这个fixture提供了对组件实例自身的访问同时还提供了用来访问组件的DOM元素的**`DebugElement`**对象。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `title` property value is interpolated into the DOM within `<h1>` tags.\nUse the fixture's `DebugElement` to `query` for the `<h1>` element by CSS selector.",
"translation": "`title`属性被插值到DOM的`<h1>`标签中。\n用CSS选择器从fixture的`DebugElement`中`query``<h1>`元素。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The **`query`** method takes a predicate function and searches the fixture's entire DOM tree for the \n_first_ element that satisfies the predicate. \nThe result is a _different_ `DebugElement`, one associated with the matching DOM element.",
"translation": "**`query`**方法接受predicate函数并搜索fixture的整个DOM树试图寻找**第一个**满足predicate函数的元素。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `queryAll` method returns an array of _all_ `DebugElements` that satisfy the predicate.",
"translation": "`queryAll`方法返回一列数组,包含所有`DebugElement`中满足predicate的元素。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "A _predicate_ is a function that returns a boolean. \nA query predicate receives a `DebugElement` and returns `true` if the element meets the selection criteria.",
"translation": "**predicate**是返回布尔值的函数。\npredicate查询接受`DebugElement`参数,如果元素符合选择条件便返回`true`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The **`By`** class is an Angular testing utility that produces useful predicates.\nIts `By.css` static method produces a\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors\">standard CSS selector</a>\npredicate that filters the same way as a jQuery selector.",
"translation": "**`By`**类是Angular测试工具之一它生成有用的predicate。\n它的`By.css`静态方法产生<a href=\"https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors\" target=\"_blank\">标准CSS选择器</a>\npredicate与JQuery选择器相同的方式过滤。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Finally, the setup assigns the DOM element from the `DebugElement` **`nativeElement`** property to `el`.\nThe tests assert that `el` contains the expected title text.",
"translation": "最后,这个配置把`DebugElement`中的**`nativeElement`**DOM元素赋值给`el`属性。\n测试程序将判断`el`是否包含期待的标题文本。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### The tests",
"translation": "### 测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Jasmine runs the `beforeEach` function before each of these tests",
"translation": "再每个测试程序之前Jasmin都一次运行`beforeEach`函数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "These tests ask the `DebugElement` for the native HTML element to satisfy their expectations.",
"translation": "这些测试程序向`DebugElement`获取原生HTML元素来满足自己的期望。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _detectChanges_: Angular change detection within a test",
"translation": "### **detectChanges**在测试中的Angular变更检测",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Each test tells Angular when to perform change detection by calling `fixture.detectChanges()`.\nThe first test does so immediately, triggering data binding and propagation of the `title` property\nto the DOM element.",
"translation": "每个测试程序都通过调用`fixture.detectChanges()`来通知Angular执行变更检测。第一个测试程序立刻这么做触发数据绑定和并将`title`属性发送到DOM元素中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The second test changes the component's `title` property _and only then_ calls `fixture.detectChanges()`;\nthe new value appears in the DOM element.",
"translation": "第二个测试程序在更改组件的`title`属性**之后**才调用`fixture.detectChanges()`。新值出现在DOM元素中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The `TestBed.createComponent` does _not_ trigger change detection.\nThe fixture does not automatically push the component's `title` property value into the data bound element,\na fact demonstrated in the following test:",
"translation": "`TestBed.createComponent`**不会**触发变更检测。该工具不会自动将组件的`title`属性值推送到数据绑定的元素,下面的测试程序展示了这个事实:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This behavior (or lack of it) is intentional.\nIt gives the tester an opportunity to inspect or change the state of\nthe component _before Angular initiates data binding or calls lifecycle hooks_.",
"translation": "这种行为(或者缺乏的行为)是有意为之。**在Angular初始化数据绑定或者调用生命周期钩子**之前,它给测试者机会来查看或者改变组件的状态。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Try the live example",
"translation": "### 试试在线例子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Take a moment to explore this component spec as a <live-example plnkr=\"banner-inline-specs\" title=\"Spec for component with inline template\" embedded-style></live-example> and\nlock in these fundamentals of component unit testing.",
"translation": "花点时间来浏览一下该组件的规约,比如<live-example plnkr=\"banner-inline-specs\" title=\"Spec for component with inline template\" embedded-style></live-example>,深入理解组件单元测试的这些基本原理。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Automatic change detection",
"translation": "### 自动变更检测",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `BannerComponent` tests frequently call `detectChanges`.\nSome testers prefer that the Angular test environment run change detection automatically.\nThat's possible by configuring the `TestBed` with the `ComponentFixtureAutoDetect` provider .\nFirst import it from the testing utility library :",
"translation": "`BannerComponent`的测试频繁调用`detectChanges`。\n有些测试人员更希望Angular的测试环境自动进行变更检测。\n这可以通过为`TestBed`配置上`ComponentFixtureAutoDetect`提供商来做到。首先从测试工具库中导入它:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Then add it to the `providers` array of the testing module configuration:",
"translation": "然后把它添加到测试模块配置的`providers`数组中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here are three tests that illustrate how automatic change detection works.",
"translation": "下列测试阐明了自动变更检测的工作原理。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The first test shows the benefit of automatic change detection.",
"translation": "第一个测试程序展示了自动检测的好处。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "</div>",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Test a component with an external template",
"translation": "## 测试带有外部模板的组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The application's actual `BannerComponent` behaves the same as the version above but is implemented differently.\nIt has _external_ template and css files, specified in `templateUrl` and `styleUrls` properties.",
"translation": "在实际应用中,`BannerComponent`的行为和刚才的版本相同,但是实现方式不同。\n它有一个*外部*模板和CSS文件通过`templateUrl`和`styleUrls`属性来指定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "That's a problem for the tests.\nThe `TestBed.createComponent` method is synchronous.\nBut the Angular template compiler must read the external files from the file system before it can create a component instance.\nThat's an asynchronous activity.\nThe previous setup for testing the inline component won't work for a component with an external template.",
"translation": "这些测试有一个问题。\n`TestBed.createComponent`方法是同步的。\n但是Angular模板编译器必须在创建组件实例之前先从文件系统中读取这些值而这是异步的。\n以前测试内联模板时使用的设置方式不适用于外部模板。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### The first asynchronous _beforeEach_",
"translation": "### 第一个异步的`beforeEach`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The test setup for `BannerComponent` must give the Angular template compiler time to read the files.\nThe logic in the `beforeEach` of the previous spec is split into two `beforeEach` calls.\nThe first `beforeEach` handles asynchronous compilation.",
"translation": "`BannerComponent`测试的设置方式必须给Angular模板编译器一些时间来读取文件。\n以前放在`beforeEach`中的逻辑被拆分成了两个`beforeEach`调用。\n第一个`beforeEach`处理异步编译工作。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Notice the `async` function called as the argument to `beforeEach`.\nThe `async` function is one of the Angular testing utilities and\nhas to be imported.",
"translation": "注意`async`函数被用作调用`beforeEach`的参数。\n`async`函数是Angular测试工具集的一部分这里必须引入它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It takes a parameterless function and _returns a function_\nwhich becomes the true argument to the `beforeEach`.",
"translation": "它接收一个无参数的函数,并*返回一个函数*,这个函数会作为实参传给`beforeEach`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The body of the `async` argument looks much like the body of a synchronous `beforeEach`.\nThere is nothing obviously asynchronous about it.\nFor example, it doesn't return a promise and\nthere is no `done` function to call as there would be in standard Jasmine asynchronous tests.\nInternally, `async` arranges for the body of the `beforeEach` to run in a special _async test zone_\nthat hides the mechanics of asynchronous execution.",
"translation": "`async`参数的内容看起来非常像同步版`beforeEach`的函数体。\n它并不能很明显的看出来这是异步函数。\n比如它不返回承诺Promise并且也没有标准Jasmine异步测试时常用的`done`函数作为参数。\n内部实现上`async`会把`beforeEach`的函数体放进一个特殊的*异步测试区async test zone*,它隐藏了异步执行的内部机制。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "All this is necessary in order to call the asynchronous `TestBed.compileComponents` method.",
"translation": "这就是为了调用异步的`TestBed.compileComponents`方法所要做的一切。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _compileComponents_",
"translation": "### _compileComponents_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The `TestBed.compileComponents` method asynchronously compiles all the components configured in the testing module.\nIn this example, the `BannerComponent` is the only component to compile.\nWhen `compileComponents` completes, the external templates and css files have been \"inlined\"\nand `TestBed.createComponent` can create new instances of `BannerComponent` synchronously.",
"translation": "`TestBed.compileComponents`方法会异步编译这个测试模块中配置的所有组件。\n在这个例子中`BannerComponent`是唯一要编译的组件。\n当`compileComponents`完成时外部组件和css文件会被“内联”而`TestBed.createComponent`会用同步的方式创建一个`BannerComponent`的新实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "WebPack developers need not call `compileComponents` because it inlines templates and css\nas part of the automated build process that precedes running the test.",
"translation": "WebPack用户不用调用`compileComponents`因为它会在构建过程中自动内联模板和css然后执行测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "In this example, `TestBed.compileComponents` only compiles the `BannerComponent`.\nTests later in the guide declare multiple components and\na few specs import entire application modules that hold yet more components.\nAny of these components might have external templates and css files.\n`TestBed.compileComponents` compiles all of the declared components asynchronously at one time.",
"translation": "在这个例子中,`TestBed.compileComponents`只会编译`BannerComponent`。\n本章稍后的测试中会声明多个组件并且少量规约中会导入包含多个组件的应用模块。所有这些组件都可能含有外部模板和css文件。\n`TestBed.compileComponents`会同时异步编译所有这些声明的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Do not configure the `TestBed` after calling `compileComponents`.\nMake `compileComponents` the last step\nbefore calling `TestBed.createComponent` to instantiate the _component-under-test_.",
"translation": "调用了`compileComponents`之后就不能再配置`TestBed`了。\n务必确保`compileComponents`是调用`TestBed.createComponent`来实例化*待测组件*之前的最后一步。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### The second synchronous _beforeEach_",
"translation": "### 第二个同步`beforeEach`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "A _synchronous_ `beforeEach` containing the remaining setup steps follows the asynchronous `beforeEach`.",
"translation": "这个同步的`beforeEach`包含异步`beforeEach`之后的其余步骤。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "These are the same steps as in the original `beforeEach`.\nThey include creating an instance of the `BannerComponent` and querying for the elements to inspect.",
"translation": "这些步骤和原来的`beforeEach`中相同。\n包括创建`BannerComponent`实例和查询要审查的元素。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### Waiting for _compileComponents_",
"translation": "### 等待`compileComponents`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `compileComponents` method returns a promise so you can perform additional tasks _immediately after_ it finishes.\nFor example, you could move the synchronous code in the second `beforeEach`\ninto a `compileComponents().then(...)` callback and write only one `beforeEach`.",
"translation": "`compileComponents`方法返回一个承诺,来让我们可以在它完成之后*立即*执行额外的任务。\n比如我们可以把第二个`beforeEach`中的同步代码移到一个`compileComponents().then(...)`回调中,从而只需要写一个`beforeEach`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Most developers find that hard to read.\nThe two `beforeEach` calls are widely preferred.",
"translation": "大多数开发人员会觉得这样不易读,因此,更多采用的还是写两个`beforeEach`调用的方式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Try the live example",
"translation": "### 试试在线例子",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Take a moment to explore this component spec as a <live-example plnkr=\"banner-specs\" title=\"Spec for component with external template\" embedded-style></live-example>.",
"translation": "稍微花点时间,在<live-example plnkr=\"banner-specs\" title=\"Spec for component with external template\" embedded-style></live-example>中看看该组件的规约。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [Quickstart seed](guide/setup) provides a similar test of its `AppComponent`\nas you can see in _this_ <live-example name=\"setup\" plnkr=\"quickstart-specs\" title=\"QuickStart seed spec\" embedded-style></live-example>.\nIt too calls `compileComponents` although it doesn't have to because the `AppComponent`'s template is inline.",
"translation": "[“快速上手” 种子工程](guide/setup)为其`AppComponent`提供了简单的测试,在<live-example name=\"setup\" plnkr=\"quickstart-specs\" title=\"QuickStart seed spec\" embedded-style></live-example>中可以看到。\n它也调用了`compileComponents`,不过它并不是必须这么做,因为`AppComponent`的模板是内联的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "There's no harm in it and you might call `compileComponents` anyway\nin case you decide later to re-factor the template into a separate file.\nThe tests in this guide only call `compileComponents` when necessary.",
"translation": "这样做也没坏处,如果你将来可能会把模板重构到独立的文件中去,那就可以调用`compileComponents`。\n不过本章中的这些测试只会在必要时才调用`compileComponents`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "</div>",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Test a component with a dependency",
"translation": "## 测试有依赖的组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Components often have service dependencies.",
"translation": "组件经常依赖其他服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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, `src/app/welcome.component.spec.ts`:",
"translation": "`WelcomeComponent`有与服务进行交互的决策逻辑这样的逻辑让这个组件值得测试。下面是spec文件的测试模块配置`src/app/welcome.component.spec.ts`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### Provide service test doubles",
"translation": "### 提供服务替身",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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": "被测试的组件不一定要注入真正的服务。实际上服务的替身stubs, fakes, spies或者mocks通常会更加合适。\nspec的主要目的是测试组件而不是服务。真实的服务可能自身有问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "This particular test suite supplies a minimal `UserService` stub that satisfies the needs of the `WelcomeComponent`\nand its tests:",
"translation": "这个测试套件提供了最小化的`UserService`stub类用来满足`WelcomeComponent`和它的测试的需求:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Get injected services",
"translation": "### 获取注入的服务\nThe tests need access to the (stub) `UserService` injected into the `WelcomeComponent`.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### _TestBed.get_",
"translation": "### _TestBed.get_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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.\nFortunately, 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": "你**可以**通过`TestBed.get`方法来从根注入器中获取服务。\n它更容易被记住也更加简介。\n但是只有在Angular使用测试的根注入器中的那个服务实例来注入到组件时它才有效。\n幸运的是在这个测试套件中**唯一**的`UserService`提供商就是根测试模块,所以像下面这样调用`TestBed.get`很安全:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [`inject`](guide/testing#inject) utility function is another way to get one or more services from the test root injector.",
"translation": "[`inject`](guide/testing#inject)辅助函数方法是另外一种从测试的根注入器注入一个或多个服务到测试的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "For a use case in which `inject` and `TestBed.get` do not work,\nsee the section [_Override a component's providers_](guide/testing#component-override), which\nexplains why you must get the service from the component's injector instead.",
"translation": "如果遇到了`inject`和`TestBed.get`无效,的情况,请到“[**重载组件提供商**](guide/testing#component-override)”一节。那里会解释为什么要改用组件的注入器来获取服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Always get the service from an injector",
"translation": "### 总是从注入器获取服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### Final setup and tests",
"translation": "### 最后的设置和测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here's the complete `beforeEach` using `TestBed.get`:",
"translation": "这里是使用`TestBed.get`的完整`beforeEach`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "And here are some tests:",
"translation": "下面是一些测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The first is a sanity test; it confirms that the stubbed `UserService` is called and working.",
"translation": "第一个测试程序是合法测试程序,它确认这个被模拟的`UserService`是否被调用和工作正常。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The second parameter to the Jasmine matcher (e.g., `'expected name'`) is an optional addendum.\nIf the expectation fails, Jasmine displays this addendum after the expectation failure message.\nIn a spec with multiple expectations, it can help clarify what went wrong and which expectation failed .",
"translation": "Jasmine的`it`方法的第二个参数(比如`'expected name'`)是可选附加参数。\n如果这个期待失败了Jasmine在期待失败信息后面显示这个附加参数。\n在拥有多个期待的spec中它可以帮助澄清发生了什么错误哪个期待失败了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "## Test a component with an async service",
"translation": "## 测试有异步服务的组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Many services return values asynchronously.\nMost data services make an HTTP request to a remote server and the response is necessarily asynchronous.",
"translation": "许多服务异步返回值。大部分数据服务向远程服务器发起HTTP请求响应必然是异步的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The \"About\" view in this sample displays Mark Twain quotes.\nThe `TwainComponent` handles the display, delegating the server request to the `TwainService`.",
"translation": "本例的`About`视图显示马克吐温的名言。\n`TwainComponent`组件处理视图,并委派`TwainService`向服务器发起请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Both are in the `src/app/shared` folder because the author intends to display Twain quotes on other pages someday.\nHere is the `TwainComponent`.",
"translation": "两者都在`app/shared`目录里,因为作者计划将来在其它页面也显示马克吐温的名言。\n下面是`TwainComponent`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `TwainService` implementation is irrelevant for this particular test.\nIt is sufficient to see within `ngOnInit` that `twainService.getQuote` returns a promise, which means it is asynchronous.",
"translation": "`TwainService`的实现细节现在并不重要。\n`ngOnInit`的`twainService.getQuote`返回承诺,所以显然它是异步的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "In general, tests should not make calls to remote servers. \nThey should emulate such calls. The setup in this `src/app/shared/twain.component.spec.ts` shows one way to do that:",
"translation": "一般来讲,测试程序不应该向远程服务器发请求。\n它们应该仿真这样的请求。`src/app/shared/twain.component.spec.ts`里的配置是其中一种伪造方法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Spying on the real service",
"translation": "### 刺探(Spy)真实服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This setup is similar to the [`welcome.component.spec` setup](guide/testing#welcome-spec-setup).\nBut instead of creating a stubbed service object, it injects the _real_ service (see the testing module `providers`) and\nreplaces the critical `getQuote` method with a Jasmine spy.",
"translation": "本配置与[`welcome.component.spec`配置](guide/testing#welcome-spec-setup)类似。\n但是与其伪造服务对象它注入了真实的服务参见测试模块的`providers`并用Jasmine的`spy`替换关键的`getQuote`方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The spy is designed such that any call to `getQuote` receives an immediately resolved promise with a test quote.\nThe spy bypasses the actual `getQuote` method and therefore does not contact the server.",
"translation": "这个Spy的设计是所有调用`getQuote`的方法都会收到立刻解析的承诺得到一条预设的名言。Spy拦截了实际`getQuote`方法,所以它不会联系服务端。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Faking a service instance and spying on the real service are _both_ great options.\nPick the one that seems easiest for the current test suite.\nDon't be afraid to change your mind.",
"translation": "伪造服务实例和刺探真实服务都是好方法。挑选一种对当前测试套件最简单的方法。你可以随时改变主意。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Spying on the real service isn't always easy, especially when the real service has injected dependencies.\nYou can _stub and spy_ at the same time, as shown in [an example below](guide/testing#spy-stub).",
"translation": "刺探真实的服务往往并不容易,特别是真实的服务依赖其它服务时。\n我们可以同时*打桩和刺探*,就像[后面的例子](guide/testing#spy-stub)那样。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here are the tests with commentary to follow:",
"translation": "下面是接下来带有注解的测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Synchronous tests",
"translation": "### 同步测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The first two tests are synchronous.\nThanks to the spy, they verify that `getQuote` is called _after_\nthe first change detection cycle during which Angular calls `ngOnInit`.",
"translation": "前两个测试程序是同步的。\n在Spy的帮助下它们验证了在Angular调用`ngOnInit`期间发生的第一次变更检测后,`getQuote`被调用了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Neither test can prove that a value from the service is displayed.\nThe quote itself has not arrived, despite the fact that the spy returns a resolved promise.",
"translation": "两者都不能证明被显示的值是服务提供的。\n虽然spy返回了解析的承诺名言本身还没有到来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This test must wait at least one full turn of the JavaScript engine before the\nvalue becomes available. The test must become _asynchronous_.",
"translation": "这个测试程序必须等待JavaScript引擎一整个回合返回值才会有效。该测试程序必须要变成**异步的**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### The _async_ function in _it_",
"translation": "### **it**里的**async**函数方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Notice the `async` in the third test.",
"translation": "注意第三个测试程序的`async`方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `async` function is one of the Angular testing utilities.\nIt simplifies coding of asynchronous tests by arranging for the tester's code to run in a special _async test zone_\nas [discussed earlier](guide/testing#async-in-before-each) when it was called in a `beforeEach`.",
"translation": "`async`函数是**Angular TestBed**的一部分。通过将测试代码放到特殊的**异步测试区域**来运行,`async`函数简化了异步测试程序的代码。就像[以前讨论过的](guide/testing#async-in-before-each),它会在`beforeEach`中被调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Although `async` does a great job of hiding asynchronous boilerplate,\nsome functions called within a test (such as `fixture.whenStable`) continue to reveal their asynchronous behavior.",
"translation": "虽然`async`做了很多工作来尽量隐藏异步特性,但在测试程序(比如`fixture.whenStable`)里面调用函数时,有时还是会体现它们的异步行为。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `fakeAsync` alternative, [covered below](guide/testing#fake-async), removes this artifact and affords a more linear coding experience.",
"translation": "`fakeAsync`可选方法,[正如下面解释的](guide/testing#fake-async),进一步移除了异步行为,提供了更加直观的代码经验。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _whenStable_",
"translation": "### _whenStable_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The test must wait for the `getQuote` promise to resolve in the next turn of the JavaScript engine.",
"translation": "测试程序必须等待`getQuote`在JavaScript引擎的下一回合中被解析。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This test has no direct access to the promise returned by the call to `twainService.getQuote`\nbecause it is buried inside `TwainComponent.ngOnInit` and therefore inaccessible to a test that\nprobes only the component API surface.",
"translation": "本测试对`twainService.getQuote`返回的承诺没有直接的访问,因为它被埋没在`TwainComponent.ngOnInit`里,\n所以对于只测试组件API表面的测试来说它是无法被访问的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Fortunately, the `getQuote` promise is accessible to the _async test zone_ ,\nwhich intercepts all promises issued within the _async_ method call _no matter where they occur_.",
"translation": "幸运的是,**异步测试区域**可以访问`getQuote`承诺,因为它拦截所有调用**异步**方法所发出的承诺,不管它们在哪儿。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `ComponentFixture.whenStable` method returns its own promise, which resolves when the `getQuote` promise finishes.\nIn fact, the _whenStable_ promise resolves when _all pending asynchronous activities within this test_ complete &mdash; the definition of \"stable.\"",
"translation": "`ComponentFixture.whenStable`方法返回它自己的承诺,它在`getQuote`承诺完成时被解析。实际上“stable”的意思是当**所有待处理异步行为**完成时的状态在“stable”后**whenStable**承诺被解析。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Then the test resumes and kicks off another round of change detection (`fixture.detectChanges`),\nwhich tells Angular to update the DOM with the quote.\nThe `getQuote` helper method extracts the display element text and the expectation confirms that the text matches the test quote.",
"translation": "然后测试程序继续运行,并开始另一轮的变更检测(`fixture.detectChanges`,通知Angular使用名言来更新DOM。\n`getQuote`辅助方法提取出显示元素文本然后expect语句确认这个文本与预备的名言相符。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### The _fakeAsync_ function",
"translation": "### **fakeAsync**函数方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The fourth test verifies the same component behavior in a different way.",
"translation": "第四个测试程序用不同的方法验证同样的组件行为。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Notice that `fakeAsync` replaces `async` as the `it` argument.\nThe `fakeAsync` function is another of the Angular testing utilities.",
"translation": "注意,在`it`的参数中,`async`被`fakeAsync`替换。\n`fakeAsync`是另一种Angular测试工具。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Like [async](guide/testing#async), it _takes_ a parameterless function and _returns_ a function\nthat becomes the argument to the Jasmine `it` call.",
"translation": "和[async](guide/testing#async)一样,它也**接受**无参数函数并**返回**一个函数变成Jasmine的`it`函数的参数。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `fakeAsync` function enables a linear coding style by running the test body in a special _fakeAsync test zone_.",
"translation": "`fakeAsync`函数通过在特殊的**fakeAsync测试区域**运行测试程序,让测试代码更加简单直观。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The principle advantage of `fakeAsync` over `async` is that the test appears to be synchronous.\nThere is no `then(...)` to disrupt the visible flow of control.\nThe promise-returning `fixture.whenStable` is gone, replaced by `tick()`.",
"translation": "对于`async`来说,`fakeAsync`最重要的好处是测试程序看起来像同步的。里面没有任何承诺。\n没有`then(...)`链来打断控制流。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "There _are_ limitations. For example, you cannot make an XHR call from within a `fakeAsync`.",
"translation": "但是`fakeAsync`有局限性。比如,你不能从`fakeAsync`发起XHR请求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### The _tick_ function",
"translation": "### **tick**函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `tick` function is one of the Angular testing utilities and a companion to `fakeAsync`.\nYou can only call it within a `fakeAsync` body.",
"translation": "`tick`函数是Angular测试工具之一是`fakeAsync`的同伴。\n它只能在`fakeAsync`的主体中被调用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Calling `tick()` simulates the passage of time until all pending asynchronous activities finish,\nincluding the resolution of the `getQuote` promise in this test case.",
"translation": "调用`tick()`模拟时间的推移,直到全部待处理的异步任务都已完成,在这个测试案例中,包含`getQuote`承诺的解析。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It returns nothing. There is no promise to wait for.\nProceed with the same test code that appeared in the `whenStable.then()` callback.",
"translation": "它不返回任何结果。没有任何承诺需要等待。\n直接执行与之前在`whenStable.then()`的回调函数里相同的代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Even this simple example is easier to read than the third test.\nTo more fully appreciate the improvement, imagine a succession of asynchronous operations,\nchained in a long sequence of promise callbacks.",
"translation": "虽然这个例子非常简单,但是它已经比第三个测试程序更易阅读。\n为了更充分的体会`fakeAsync`的好处,试想一下一连串的异步操作,被一长串的承诺回调链在一起。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _jasmine.done_",
"translation": "### _jasmine.done_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "While the `async` and `fakeAsync` functions greatly\nsimplify Angular asynchronous testing,\nyou can still fall back to the traditional Jasmine asynchronous testing technique.",
"translation": "虽然`async`和`fakeAsync`函数大大的简化了异步测试你仍然可以回退到传统的Jasmine异步测试技术上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "You can still pass `it` a function that takes a\n[`done` callback](http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support).\nNow you are responsible for chaining promises, handling errors, and calling `done` at the appropriate moment.",
"translation": "你仍然可以将接受 [`done`回调](http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support)的函数传给`it`。\n但是你必须链接承诺、处理错误并在适当的时候调用`done`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here is a `done` version of the previous two tests:",
"translation": "下面是上面两个测试程序的`done`版本:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Although there is no direct access to the `getQuote` promise inside `TwainComponent`,\nthe spy has direct access, which makes it possible to wait for `getQuote` to finish.",
"translation": "虽然我们对`TwainComponent`里的`getQuote`承诺没有直接访问但是Spy有所以才可能等待`getQuote`完成。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Writing test functions with `done`, while more cumbersome than `async`\nand `fakeAsync`, is a viable and occasionally necessary technique.\nFor example, you can't call `async` or `fakeAsync` when testing\ncode that involves the `intervalTimer`, as is common when\ntesting async `Observable` methods.",
"translation": "写带有`done`回调的测试函数,虽然比`async`和`fakeAsync`函数笨拙,但是在少数偶然情况下却是很有必要的技巧。比如,当测试涉及`intervalTimer`的代码时,你就没法调用`async`和`fakeAsync`函数,在测试异步`Observable`函数时也一样。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Test a component with inputs and outputs",
"translation": "## 测试带有导入inputs和导出outputs的组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The `DashboardHeroComponent` is embedded in the `DashboardComponent` template like this:",
"translation": "`DashboardHeroComponent`是这样内嵌在`DashboardCompoent`的模板中的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Here's the component's definition:",
"translation": "下面是组件的定义:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "* Test it as used by `DashboardComponent`.",
"translation": "把它当作被`DashbaordComponent`使用的组件来测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Test it as a stand-alone component.",
"translation": "把它当作独立的组件来测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Test it as used by a substitute for `DashboardComponent`.",
"translation": "把它当作被`DashbaordComponent`的替代组件使用的组件来测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "A quick look at the `DashboardComponent` constructor discourages the first approach:",
"translation": "简单看看`DashbaordComponent`的构造函数就否决了第一种方案:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The [discussion below](guide/testing#routed-component) covers testing components that require the router.",
"translation": "[下面](guide/testing#routed-component) 涵盖了如何测试带有路由器的组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### Test _DashboardHeroComponent_ stand-alone",
"translation": "### 独立测试_DashboardHeroComponent_",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here's the spec file setup.",
"translation": "下面是spec文件的设置。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The async `beforeEach` was discussed [above](guide/testing#component-with-external-template).\nHaving compiled the components asynchronously with `compileComponents`, the rest of the setup\nproceeds _synchronously_ in a _second_ `beforeEach`, using the basic techniques described [earlier](guide/testing#simple-component-test).",
"translation": "异步`beforeEach`已经在[上面](guide/testing#component-with-external-template)讨论过。\n在使用`compileComponents`异步编译完组件后,接下来的设置执行另一个**同步**的`beforeEach`,使用[之前](guide/testing#simple-component-test)解释过的基本知识。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Note how the setup code assigns a test hero (`expectedHero`) to the component's `hero` property, emulating\nthe way the `DashboardComponent` would set it via the property binding in its repeater.",
"translation": "注意代码是如何将模拟英雄(`expectedHero`)赋值给组件的`hero`属性的,模拟了`DashbaordComponent`在它的迭代器中通过属性绑定的赋值方式。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The first test follows:",
"translation": "紧接着第一个测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It verifies that the hero name is propagated to template with a binding.\nBecause the template passes the hero name through the Angular `UpperCasePipe`,\nthe test must match the element value with the uppercased name:",
"translation": "它验证了英雄名字通过绑定被传递到模板了。这里有个额外步骤。模板将英雄名字传给Angular的`UpperCasePipe`\n所以测试程序必须使用大写名字来匹配元素的值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This small test demonstrates how Angular tests can verify a component's visual\nrepresentation&mdash;something not possible with\n[isolated unit tests](guide/testing#isolated-component-tests)&mdash;at\nlow cost and without resorting to much slower and more complicated end-to-end tests.",
"translation": "这个小测试演示了Angular测试是如何验证组件的视图表现的 —— 这是[孤立的单元测试](guide/testing#isolated-component-tests)无法实现的\n—— 它成本低,而且无需依靠更慢、更复杂的端对端测试。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The second test verifies click behavior. Clicking the hero should raise a `selected` event that the\nhost component (`DashboardComponent` presumably) can hear:",
"translation": "第二个测试程序验证点击行为。点击英雄应该出发`selected`事件,可供宿主组件(`DashbaordComponent`)监听:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The component exposes an `EventEmitter` property. The test subscribes to it just as the host component would do.",
"translation": "这个组件公开`EventEmitter`属性。测试程序像宿主组件那样来描述它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `heroEl` is a `DebugElement` that represents the hero `<div>`.\nThe test calls `triggerEventHandler` with the \"click\" event name.\nThe \"click\" event binding responds by calling `DashboardHeroComponent.click()`.",
"translation": "`heroEl`是个`DebugElement`,它代表了英雄所在的`<div>`。\n测试程序用“click”事件名字来调用`triggerEventHandler`。\n调用`DashboardHeroComponent.click()`时“click”事件绑定作出响应。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "If the component behaves as expected, `click()` tells the component's `selected` property to emit the `hero` object,\nthe test detects that value through its subscription to `selected`, and the test should pass.",
"translation": "如果组件像期待的那样工作,`click()`通知组件的`selected`属性就会发出`hero`对象,测试程序通过订阅`selected`事件而检测到这个值,所以测试应该成功。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _triggerEventHandler_",
"translation": "### _triggerEventHandler_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "In this example, the test triggers a \"click\" event with a null event object.",
"translation": "本例中测试程序用null事件对象触发“click”事件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The test assumes (correctly in this case) that the runtime\nevent handler&mdash;the component's `click()` method&mdash;doesn't\ncare about the event object.",
"translation": "测试程序假设(在这里应该这样)运行时间的事件处理器——组件的`click()`方法——不关心事件对象。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Other handlers are less forgiving. For example, the `RouterLink`\ndirective expects an object with a `button` property\nthat identifies which mouse button was pressed.\nThis directive throws an error if the event object doesn't do this correctly.",
"translation": "其它处理器将会更加严格。\n比如`RouterLink`指令期待事件对象,并且该对象具有`button`属性,代表了已被按下的鼠标按钮。\n如果该事件对象不具备上面的条件指令便会抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Clicking a button, an anchor, or an arbitrary HTML element is a common test task.",
"translation": "点击按钮、链接或者任意HTML元素是很常见的测试任务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Make that easy by encapsulating the _click-triggering_ process in a helper such as the `click` function below:",
"translation": "把**click触发**过程封装到辅助方法中可以简化这个任务,比如下面的`click`辅助方法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "click() is not an Angular testing utility",
"translation": "click()不是Angular测试工具",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Here's the previous test, rewritten using this click helper.",
"translation": "下面是使用了click辅助函数重新编写的上一个测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Test a component inside a test host component",
"translation": "## 在测试宿主组件中测试组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "In the previous approach, the tests themselves played the role of the host `DashboardComponent`.\nBut does the `DashboardHeroComponent` work correctly when properly data-bound to a host component?",
"translation": "在前面的方法中,测试本身扮演了宿主组件`DashbaordComponent`的角色。\n一种挥之不去的疑虑仍然存在当正常数据绑定到宿主组件时`DashboardHeroComponent`还会正常工作吗?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Testing with the actual `DashboardComponent` host is doable but seems more trouble than its worth.\nIt's easier to emulate the `DashboardComponent` host with a _test host_ like this one:",
"translation": "使用实际的`DashbaordComponent`宿主来测试是可行的,但是这么做似乎不合算。\n像下面这样使用**测试宿主组件**来模拟`DashbaordComponent`显得更加容易:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The test host binds to `DashboardHeroComponent` as the `DashboardComponent` would but without\nthe distraction of the `Router`, the `HeroService`, or even the `*ngFor` repeater.",
"translation": "测试宿主组件和`DashboardComponent`一样绑定`DashboardHeroComponent`,但是不用理会`Router`、`HeroService`服务,甚至`*ngFor`循环。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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\nin its `selectedHero` property. Later, the tests check that property to verify that the\n`DashboardHeroComponent.selected` event emitted the right hero.",
"translation": "测试宿主将组件的`hero`导入属性设置为它的模拟英雄。\n它将组件的`selected`事件绑定到它的`onSelected`处理器,使用`selectedHero`属性来记录发送来的英雄。\n然后测试检查这个属性来验证`DashboardHeroComponent.selected`事件确实发送了正确的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The setup for the test-host tests is similar to the setup for the stand-alone tests:",
"translation": "配置使用测试宿主的测试程序与配置孤立测试相似:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This testing module configuration shows two important differences:",
"translation": "这个测试模块配置展示了两个非常重要的区别:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. It _declares_ both the `DashboardHeroComponent` and the `TestHostComponent`.",
"translation": "它同时**声明**了`DashboardHeroComponent`和`TestHostComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. It _creates_ the `TestHostComponent` instead of the `DashboardHeroComponent`.",
"translation": "它**创建**了`TestHostComponent`,而非`DashboardHeroComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The tests themselves are almost identical to the stand-alone version:",
"translation": "这些测试本身和它们的孤立版本几乎相同:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "## Test a routed component",
"translation": "## 测试带路由器的组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Testing the actual `DashboardComponent` seemed daunting because it injects the `Router`.",
"translation": "测试实际的`DashbaordComponent`似乎令人生畏,因为它注入了`Router`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It also injects the `HeroService`, but faking that is a [familiar story](guide/testing#component-with-async-service).\nThe `Router` has a complicated API and is entwined with other services and application preconditions.",
"translation": "它同时还注入了`HeroService`,但是我们已经知道如何[伪造](guide/testing#component-with-async-service)它。\n`Router`的API非常复杂并且它缠绕了其它服务和许多应用的先决条件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Fortunately, the `DashboardComponent` isn't doing much with the `Router`",
"translation": "幸运的是,`DashbaordComponent`没有使用`Router`做很多事情。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This is often the case.\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.\nStubbing the router with a test implementation is an easy option. This should do the trick:",
"translation": "通常都是这样的。原则上,你测试的是组件,不是路由器,应该只关心在指定的条件下,组件是否导航到正确的地址。\n用模拟类来替换路由器是一种简单的方案。下面的代码应该可以",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Now set up the testing module with the test stubs for the `Router` and `HeroService`, and\ncreate a test instance of the `DashboardComponent` for subsequent testing.",
"translation": "现在我们来利用`Router`和`HeroService`的测试stub类来配置测试模块并为接下来的测试创建`DashboardComponent`的测试实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The following test clicks the displayed hero and confirms (with the help of a spy) that `Router.navigateByUrl` is called with the expected url.",
"translation": "下面的测试程序点击显示的英雄并利用spy来确认`Router.navigateByUrl`被调用了而且传进的url是所期待的值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### The _inject_ function",
"translation": "### _inject_函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Notice the `inject` function in the second `it` argument.",
"translation": "注意第二个`it`参数里面的`inject`函数。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `inject` function is one of the Angular testing utilities.\nIt injects services into the test function where you can alter, spy on, and manipulate them.",
"translation": "`inject`函数是Angular测试工具之一。\n它注入服务到测试函数以供修改、监视和操纵。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `inject` function has two parameters:",
"translation": "`inject`函数有两个参数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. An array of Angular dependency injection tokens.",
"translation": "一列数组包含了Angular依赖注入令牌",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. A test function whose parameters correspond exactly to each item in the injection token array.",
"translation": "一个测试函数,它的参数与注入令牌数组里的每个项目严格的一一对应。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "inject uses the TestBed Injector",
"translation": "使用TestBed注入器来注入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `inject` function uses the current `TestBed` injector and can only return services provided at that level.\nIt does not return services from component providers.",
"translation": "`inject`函数使用当前`TestBed`注入器,并且只返回这个级别提供的服务。\n它不会返回组件提供商提供的服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This example injects the `Router` from the current `TestBed` injector.\nThat's fine for this test because the `Router` is, and must be, provided by the application root injector.",
"translation": "这个例子通过当前的`TestBed`注入器来注入`Router`。\n对这个测试程序来说这是没问题的因为`Router`是(也必须是)由应用的根注入器来提供。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "If you need a service provided by the component's _own_ injector, call `fixture.debugElement.injector.get` instead:",
"translation": "如果你需要组件自己的注入器提供的服务,调用`fixture.debugElement.injector.get`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Use the component's own injector to get the service actually injected into the component.",
"translation": "使用组件自己的注入器来获取实际注入到组件的服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `inject` function 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": "`inject`函数关闭当前`TestBed`实例,使它无法再被配置。\n你不能再调用任何`TestBed`配置方法、`configureTestModule`或者任何`override...`方法,否则`TestBed`将抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Do not configure the `TestBed` after calling `inject`.",
"translation": "不要在调用`inject`以后再试图配置`TestBed`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "{@a routed-component-w-param}",
"translation": "### Test a routed component with parameters\n### 测试带有路由和路由参数的组件\nClicking a _Dashboard_ hero triggers navigation to `heroes/:id`, where `:id`\nis a route parameter whose value is the `id` of the hero to edit. \nThat URL matches a route to the `HeroDetailComponent`.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The router pushes the `:id` token value into the `ActivatedRoute.params` _Observable_ property,\nAngular injects the `ActivatedRoute` into the `HeroDetailComponent`,\nand the component extracts the `id` so it can fetch the corresponding hero via the `HeroDetailService`.\nHere's the `HeroDetailComponent` constructor:",
"translation": "路由器将`:id`令牌的值推送到`ActivatedRoute.params`**可观察**属性里,\nAngular注入`ActivatedRoute`到`HeroDetailComponent`中,\n然后组件提取`id`,这样它就可以通过`HeroDetailService`获取相应的英雄。\n下面是`HeroDetailComponent`的构造函数:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "`HeroDetailComponent` subscribes to `ActivatedRoute.params` changes in its `ngOnInit` method.",
"translation": "`HeroDetailComponent`在它的`ngOnInit`方法中监听`ActivatedRoute.params`的变化。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The expression after `route.params` chains an _Observable_ operator that _plucks_ the `id` from the `params`\nand then chains a `forEach` operator to subscribe to `id`-changing events.\nThe `id` changes every time the user navigates to a different hero.",
"translation": "`route.params`之后的表达式链接了**可观察**操作符,它从`params`中提取`id`,然后链接`forEach`操作符来订阅`id`变化事件。\n每次`id`变化时,用户被导航到不同的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `forEach` passes the new `id` value to the component's `getHero` method (not shown)\nwhich fetches a hero and sets the component's `hero` property.\nIf the`id` parameter is missing, the `pluck` operator fails and the `catch` treats failure as a request to edit a new hero.",
"translation": "`forEach`将新的`id`值传递到组件的`getHero`方法(这里没有列出来),它获取英雄并将它赋值到组件的`hero`属性。\n如果`id`参数无效,`pluck`操作符就会失败,`catch`将失败当作创建新英雄来处理。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [Router](guide/router#route-parameters) guide covers `ActivatedRoute.params` in more detail.",
"translation": "[路由器](guide/router#route-parameters)章更详尽的讲述了`ActivatedRoute.params`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "A test 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/content-2/guide/testing.md"
},
{
"original": "By now you know how to stub the `Router` and a data service.\nStubbing the `ActivatedRoute` follows the same pattern except for a complication:\nthe `ActivatedRoute.params` is an _Observable_.",
"translation": "现在,你已经知道如何模拟`Router`和数据服务。\n模拟`ActivatedRoute`遵循类似的模式,但是有个额外枝节:`ActivatedRoute.params`是**可观察对象**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Create an _Observable_ test double",
"translation": "### **可观察对象**的测试替身",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `hero-detail.component.spec.ts` relies on an `ActivatedRouteStub` to set `ActivatedRoute.params` values for each test.\nThis is a cross-application, re-usable _test helper class_.\nConsider placing such helpers in a `testing` folder sibling to the `app` folder.\nThis sample keeps `ActivatedRouteStub` in `testing/router-stubs.ts`:",
"translation": "`hero-detail.component.spec.ts`依赖`ActivatedRouteStub`来为每个测试程序设置`ActivatedRoute.params`值。\n它是跨应用、可复用的**测试辅助类**。\n我们建议将这样的辅助类放到`app`目录下的名为`testing`的目录。\n本例把`ActivatedRouteStub`放到`testing/router-stubs.ts`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Notable features of this stub are:",
"translation": "这个stub类有下列值得注意的特征",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* The stub implements only two of the `ActivatedRoute` capabilities: `params` and `snapshot.params`.",
"translation": "这个stub类只实现`ActivatedRoute`的两个功能:`params`和`snapshot.params`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* <a href=\"https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md\">_BehaviorSubject_</a>\ndrives the stub's `params` _Observable_ and returns the same value to every `params` subscriber until it's given a new value.",
"translation": "<a href=\"https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md\" target=\"_blank\">_BehaviorSubject_</a>驱使这个stub类的`params`可观察对象,并为每个`params`的订阅者返回同样的值,直到它接受到新值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* The `HeroDetailComponent` chains its expressions to this stub `params` _Observable_ which is now under the tester's control.",
"translation": "`HeroDetailComponent`链接它的表达式到这个stub类的`params`可观察对象,该对象现在被测试者的控制之下。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Setting the `testParams` property causes the `subject` to push the assigned value into `params`.\n That triggers the `HeroDetailComponent` _params_ subscription, described above, in the same way that navigation does.",
"translation": "设置`testParams`属性导致`subject`将指定的值推送进`params`。它触发上面描述过的`HeroDetailComponent`的`params`订阅,和导航的方式一样。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Setting the `testParams` property also updates the stub's internal value for the `snapshot` property to return.",
"translation": "设置`testParams`属性同时更新这个stub类内部值用于`snapshot`属性的返回。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [_snapshot_](guide/router#snapshot \"Router guide: snapshot\") is another popular way for components to consume route parameters.",
"translation": "[_snapshot_](guide/router#snapshot \"Router Chapter: snapshot\")是组件使用路由参数的另一种流行的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The router stubs in this guide are meant to inspire you. Create your own stubs to fit your testing needs.",
"translation": "本章的路由器stub类是为了给你灵感。创建你自己的stub类以适合你的测试需求。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Testing with the _Observable_ test double",
"translation": "### 测试**可观察对象**的替身",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The `createComponent` method and `page` object are discussed [in the next section](guide/testing#page-object).\nRely on your intuition for now.",
"translation": "[下一节](guide/testing#page-object)将解释`createComponent`方法和`page`对象,现在暂时跟着自己的直觉走。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "When the `id` cannot be found, the component should re-route to the `HeroListComponent`.\nThe test suite setup provided the same `RouterStub` [described above](guide/testing#routed-component) which spies on the router without actually navigating.\nThis test supplies a \"bad\" id and expects the component to try to navigate.",
"translation": "当无法找到`id`时,组件应该重新导航到`HeroListComponent`。\n该测试套件配置与[上面描述](guide/testing#routed-component)的`RouterStub`一样,它在不实际导航的情况下刺探路由器。\n该测试程序提供了“坏”的id期望组件尝试导航。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Inspect and download _all_ of the guide's application test code with this <live-example plnkr=\"app-specs\" embedded-style>live example</live-example>.",
"translation": "到<live-example plnkr=\"app-specs\">在线例子</live-example>查看和下载**所有**本章应用程序测试代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Use a _page_ object to simplify setup",
"translation": "## 使用**page**对象来简化配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `HeroDetailComponent` is a simple view with a title, two hero fields, and two buttons.",
"translation": "`HeroDetailComponent`是带有标题、两个英雄字段和两个按钮的简单视图。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "But there's already plenty of template complexity.",
"translation": "但是它已经有很多模板复杂性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "To fully exercise the component, the test needs a lot of setup:",
"translation": "要彻底测试该组件,测试程序需要一系列设置:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* It must wait until a hero arrives before `*ngIf` allows any element in DOM.",
"translation": "它必须在`*ngIf`允许元素进入DOM之前等待`hero`的到来",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* It needs references to the title `<span>` and the name `<input>` so it can inspect their values.",
"translation": "它需要标题名字span和名字输入框元素的引用用来检查它们的值",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* It needs references to the two buttons so it can click them.",
"translation": "它需要两个按钮的引用,以便点击它们",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* It needs spies for some of the component and router methods.",
"translation": "刺探spy组件和路由器的方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Tame the madness with a `Page` class that simplifies access to component properties and encapsulates the logic that sets them.\nHere's the `Page` class for the `hero-detail.component.spec.ts`",
"translation": "通过简化组件属性的访问和封装设置属性的逻辑,`Page`类可以轻松解决这个令人抓狂的难题。\n下面是为`hero-detail.component.spec.ts`准备的`page`类:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "A `createComponent` method creates a `page` objectand fills in the blanks once the `hero` arrives.",
"translation": "`createComponent`方法创建`page`,在`hero`到来时,自动填补空白。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [observable tests](guide/testing#tests-w-observable-double) in the previous 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": "上一节的[可观察对象测试](guide/testing#tests-w-observable-double)展示了`createComponent`和`page`如何让测试程序简短和即时。\n没有任何干扰无需等待承诺的解析也没有搜索DOM元素值进行比较。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here are a few more `HeroDetailComponent` tests to drive the point home.",
"translation": "这里是一些更多的`HeroDetailComponent`测试程序,进一步的展示了这一点。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Setup with module imports",
"translation": "## 模块导入imports的配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Earlier component tests configured the testing module with a few `declarations` like this:",
"translation": "此前的组件测试程序使用了一些`declarations`来配置模块,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "* `NgModel` and friends in the `FormsModule` to enable two-way data binding.",
"translation": "`FormsModule`里的`NgModel`和其它,来进行双向数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* The `TitleCasePipe` from the `shared` folder.",
"translation": "`shared`目录里的`TitleCasePipe`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Router services (which these tests are stubbing).",
"translation": "一些路由器服务测试程序将stub伪造它们",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Hero data access services (also stubbed).",
"translation": "英雄数据访问服务同样被stub伪造了",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "One approach is to configure the testing module from the individual pieces as in this example:",
"translation": "一种方法是在测试模块中一一配置,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Because many app components need the `FormsModule` and the `TitleCasePipe`, the developer created\na `SharedModule` to combine these and other frequently requested parts.\nThe test configuration can use the `SharedModule` too as seen in this alternative setup:",
"translation": "因为许多应用组件需要`FormsModule`和`TitleCasePipe`,所以开发者创建了`SharedModule`来合并它们和一些频繁需要的部件。\n测试配置也可以使用`SharedModule`,请看下面另一种配置:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It's a bit tighter and smaller, with fewer import statements (not shown).",
"translation": "它的导入声明少一些(未显示),稍微干净一些,小一些。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Import the feature module",
"translation": "### 导入特性模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `HeroDetailComponent` is part of the `HeroModule` [Feature Module](guide/ngmodule#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/ngmodule#feature-modules)的一部分,它组合了更多互相依赖的部件,包括`SharedModule`。\n试试下面这个导入`HeroModule`的测试配置:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "In fact, if you try to declare it, Angular throws an error because\n`HeroDetailComponent` is declared in both the `HeroModule` and the `DynamicTestModule` (the testing module).",
"translation": "事实上如果里试图声明它Angular会抛出错误因为`HeroDetailComponent`已经在`HeroModule`和测试模块的`DynamicTestModule`中声明。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Importing the component's feature module is often the easiest way to configure the tests,\nespecially when the feature module is small and mostly self-contained, as feature modules should be.",
"translation": "导入组件的特性模块通常是最简单的配置测试的方法,\n尤其是当特性模块很小而且几乎自包含时...特性模块应该是自包含的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Override a component's providers",
"translation": "## 重载组件的提供商",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `HeroDetailComponent` provides its own `HeroDetailService`.",
"translation": "`HeroDetailComponent`提供自己的`HeroDetailService`服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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.\nA test cannot get to child injector services from the fixture injector.\nAnd `TestBed.configureTestingModule` can't configure them either.",
"translation": "Angular创建组件时该组件有自己的注入器它是fixture注入器的子级。\nAngular使用这个子级注入器来注册组件的提供商也就是`HeroDetailService`)。\n测试程序无法从fixture的注入器获取这个子级注入器。\n而且`TestBed.configureTestingModule`也无法配置它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Angular has been creating new instances of the real `HeroDetailService` all along!",
"translation": "Angular始终都在创建真实`HeroDetailService`的实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Fortunately, the `HeroDetailService` delegates responsibility for remote data access to an injected `HeroService`.",
"translation": "幸运的是,`HeroDetailService`将远程数据访问的责任交给了注入进来的`HeroService`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [previous test configuration](guide/testing#feature-module-import) replaces the real `HeroService` with a `FakeHeroService`\nthat intercepts server requests and fakes their responses.",
"translation": "[之前的测试配置](guide/testing#feature-module-import)将真实的`HeroService`替换为`FakeHeroService`,拦截了服务起请求,伪造了它们的响应。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Notice that `TestBed.configureTestingModule` no longer provides a (fake) `HeroService` because it's [not needed](guide/testing#spy-stub).",
"translation": "注意,`TestBed.configureTestingModule`不再提供(伪造)`HeroService`,因为已经[没有必要了](guide/testing#spy-stub)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### The _overrideComponent_ method",
"translation": "### **overrideComponent**方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Focus on the `overrideComponent` method.",
"translation": "注意这个`overrideComponent`方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It takes two arguments: the component type to override (`HeroDetailComponent`) and an override metadata object.\nThe [overide metadata object](guide/testing#metadata-override-object) is a generic defined as follows:",
"translation": "它接受两个参数:要重载的组件类型(`HeroDetailComponent`)和用于重载的元数据对象。\n[重载元数据对象](guide/testing#metadata-override-object)是泛型类,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### Provide a _spy stub_ (_HeroDetailServiceSpy_)",
"translation": "### 提供一个*刺探桩Spy stub*`HeroDetailServiceSpy`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### The override tests",
"translation": "### 重载的测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### More overrides",
"translation": "### 更多重载",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Explore the options and combinations on your own.",
"translation": "自己探索这些选项和组合。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Test a _RouterOutlet_ component",
"translation": "## 测试带有_RouterOutlet_的组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `AppComponent` displays routed components in a `<router-outlet>`.\nIt also displays a navigation bar with anchors and their `RouterLink` directives.",
"translation": "`AppComponent`在`<router-outlet>`中显示导航组件。\n 它还显示了导航条,包含了链接和它们的`RouterLink`指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The component class does nothing.",
"translation": "组件的类没有做任何事。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Unit tests can confirm that the anchors are wired properly without engaging the router.\nSee why this is worth doing [below](guide/testing#why-stubbed-routerlink-tests).",
"translation": "在不涉及路由的情况下,单元测试可以确认链接的设置是否正确。\n参见[下面的内容](guide/testing#why-stubbed-routerlink-tests),了解为什么值得这么做。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Stubbing unneeded components",
"translation": "### stub伪造不需要的组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The test setup should look familiar.",
"translation": "该测试配置应该看起来很眼熟:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `AppComponent` is the declared test subject.",
"translation": "`AppComponent`是被声明的测试对象。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The setup extends the default testing module with one real component (`BannerComponent`) and several stubs.",
"translation": "使用一个真实的组件(`BannerComponent`和几个stub该配置扩展了默认测试模块。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* `BannerComponent` is simple and harmless to use as is.",
"translation": "原样使用`BannerComponent`非常简单而且无害。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* The real `WelcomeComponent` has an injected service. `WelcomeStubComponent` is a placeholder with no service to worry about.",
"translation": "真实的`WelcomeComponent`有被注入的服务。`WelcomeStubComponent`是无服务的替代品。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* The real `RouterOutlet` is complex and errors easily.\nThe `RouterOutletStubComponent` (in `testing/router-stubs.ts`) is safely inert.",
"translation": "真实的`RouterOutlet`很复杂而且容易出错。\n`testing/router-stubs.ts`里的`RouterOutletStubComponent`是安全的替代品。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The component stubs are essential. \nWithout them, the Angular compiler doesn't recognize the `<app-welcome>` and `<router-outlet>` tags \nand throws an error.",
"translation": "组件stub替代品很关键。\n没有它们Angular编译器无法识别`<app-welcome`和`<router-outlet>`标签,抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Stubbing the _RouterLink_",
"translation": "### Stub伪造_RouterLink_",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `RouterLinkStubDirective` contributes substantively to the test:",
"translation": "`RouterLinkStubDirective`为测试作出了重要的贡献:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `host` metadata property wires the click event of the host element (the `<a>`) to the directive's `onClick` method.\nThe URL bound to the `[routerLink]` attribute flows to the directive's `linkParams` property.\nClicking the anchor should trigger the `onClick` method which sets the telltale `navigatedTo` property.\nTests can inspect that property to confirm the expected _click-to-navigation_ behavior.",
"translation": "`host`元数据属性将宿主元素(`<a>`)的click事件与指令的`onClick`方法关联起来。\n绑定到`[routerLink]`的URL属性被传递到指令的`linkParams`属性。\n点击这个链接应该能触发`onClick`方法,从而设置`navigatedTo`属性。\n测试程序可以查看这个属性来确认期望的**点击导航**行为。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _By.directive_ and injected directives",
"translation": "### _By.directive_和注入的指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "A little more setup triggers the initial data binding and gets references to the navigation links:",
"translation": "再一步配置触发了数据绑定的初始化,获取导航链接的引用:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Two points of special interest:",
"translation": "特别值得注意的两点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. You can locate elements _by directive_, using `By.directive`, not just by css selectors.",
"translation": "你还可以按指令定位元素,使用`By.directive`而不仅仅是通过CSS选择器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "1. You can use the component's dependency injector to get an attached directive because\nAngular always adds attached directives to the component's injector.",
"translation": "你可以使用组件的依赖注入器来获取附加的指令因为Angular总是将附加组件添加到组件的注入器中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here are some tests that leverage this setup:",
"translation": "下面是一些使用这个配置的测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The \"click\" test _in this example_ is worthless.\nIt works hard to appear useful when in fact it\ntests the `RouterLinkStubDirective` rather than the _component_.\nThis is a common failing of directive stubs.",
"translation": "本例中的“click”测试程序其实毫无价值。\n它显得很有用但是事实上它测试的是`RouterLinkStubDirective`,而非测试组件。\n这是指令stub的通病。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### What good are these tests?",
"translation": "### 这些测试有什么好处?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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": "stub伪造的`RouterLink`测试可以确认带有链接和outlet的组件的设置的正确性确认组件有应该有的链接确认它们都指向了正确的方向。\n这些测试程序不关心用户点击链接时应用是否会成功的导航到目标组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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": "对于这样局限的测试目标stub伪造RouterLink和RouterOutlet是最佳选择。\n依靠真正的路由器会让它们很脆弱。\n它们可能因为与组件无关的原因而失败。\n例如一个导航守卫可能防止没有授权的用户访问`HeroListComponent`。\n这并不是`AppComponent`的过错,并且无论该组件怎么改变都无法修复这个失败的测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "A future guide update will explain how to write such tests with the `RouterTestingModule`.",
"translation": "未来本章的更新将介绍如何使用`RouterTestingModule`来编写这样的测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## \"Shallow component tests\" with *NO\\_ERRORS\\_SCHEMA*",
"translation": "## 使用*NO\\_ERRORS\\_SCHEMA*来“浅化”组件测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The [previous setup](guide/testing#stub-component) declared the `BannerComponent` and stubbed two other components\nfor _no reason other than to avoid a compiler error_.",
"translation": "[以前的配置](guide/testing#stub-component)声明了`BannerComponent`并stub伪造了两个其它组件**仅仅是为了避免编译错误,不是为别的原因**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Without them, the Angular compiler doesn't recognize the `<app-banner>`, `<app-welcome>` and `<router-outlet>` tags \nin the [_app.component.html_](guide/testing#app-component-html) template and throws an error.",
"translation": "没有它们Angular编译器无法识别[_app.component.html_](guide/testing#app-component-html)模板里的`<app-banner>`、`<app-welcome>`和`<router-outlet>`标签,并抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Add `NO_ERRORS_SCHEMA` to the testing module's `schemas` metadata\nto tell the compiler to ignore unrecognized elements and attributes.\nYou no longer have to declare irrelevant components and directives.",
"translation": "添加`NO_ERRORS_SCHEMA`到测试模块的`schemas`元数据中,告诉编译器忽略不认识的元素和属性。\n这样你不再需要声明无关组件和指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "These tests are ***shallow*** because they only \"go deep\" into the components you want to test.\nHere is a setup, with `import` statements, that demonstrates the improved simplicity of _shallow_ tests, relative to the stubbing setup.",
"translation": "这些测试程序比较**浅**,因为它们只“深入”到你要测试的组件。\n这里是一套配置拥有`import`语句体现了相比使用stub伪造的配置来说**浅**测试程序的简单性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The _only_ declarations are the _component-under-test_ (`AppComponent`) and the `RouterLinkStubDirective`\nthat contributes actively to the tests.\nThe [tests in this example](guide/testing#app-component-tests) are unchanged.",
"translation": "这里**唯一**声明的是**被测试的组件**(`AppComponent`)和测试需要的`RouterLinkStubDirective`。\n没有改变任何[原测试程序](guide/testing#app-component-tests)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "_Shallow component tests_ with `NO_ERRORS_SCHEMA` greatly simplify unit testing of complex templates.\nHowever, the compiler no longer alerts you to mistakes\nsuch as misspelled or misused components and directives.",
"translation": "使用`NO_ERRORS_SCHEMA`的**浅组件测试程序**很大程度上简化了拥有复杂模板组件的单元测试。\n但是编译器将不再提醒你一些错误比如模板中拼写错误或者误用的组件和指令。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Test an attribute directive",
"translation": "## 测试属性指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "It's used throughout the application, perhaps most simply in the `AboutComponent`:",
"translation": "它的使用贯穿整个应用,也许最简单的使用在`AboutComponent`里:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Testing the specific use of the `HighlightDirective` within the `AboutComponent` requires only the\ntechniques explored above (in particular the [\"Shallow test\"](guide/testing#shallow-component-test) approach).",
"translation": "使用`AboutComponent`来测试这个`HightlightDirective`的使用,只需要上面解释过的知识就够了,(尤其是[\"浅测试程序\"](guide/testing#shallow-component-test)方法)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "[Isolated unit tests](guide/testing#isolated-unit-tests) might be helpful, \nbut attribute directives like this one tend to manipulate the DOM. \nIsolated unit tests don't touch the DOMand, therefore ,\ndo not inspire confidence in the directive's efficacy.",
"translation": "[孤立单元测试](guide/testing#isolated-unit-tests)可能有用。\n但是像这样的属性指令一般都操纵DOM。孤立单元测试不能控制DOM所以不推荐用它测试指令的功能。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Here are some tests of this component:",
"translation": "下面是一些该组件的测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "A few techniques are noteworthy:",
"translation": "一些技巧值得注意:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "* `DebugElement.properties` affords access to the artificial custom property that is set by the directive.",
"translation": "`DebugElement.properties`让我们可以访问由指令设置的自定义属性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Isolated Unit Tests",
"translation": "## 孤立的单元测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Testing applications with the help of the Angular testing utilities is the main focus of this guide.",
"translation": "使用Angular测试工具测试应用程序是本章的重点。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "However, it's often more productive to explore the inner logic of application classes\nwith _isolated_ unit tests that don't depend upon Angular.\nSuch tests are often smaller and easier to read, write, and maintain.",
"translation": "但是,使用**孤立**单元测试来探索应用类的内在逻辑往往更加有效率它不依赖Angular。\n 这种测试程序通常比较小、更易阅读、编写和维护。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "They don't carry extra baggage:",
"translation": "它们不用背负额外的包袱:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Import from the Angular test libraries.",
"translation": "从Angular测试库导入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Configure a module.",
"translation": "配置模块",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Prepare dependency injection `providers`.",
"translation": "准备依赖注入`providers`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Call `inject` or `async` or `fakeAsync`.",
"translation": "调用`inject`,或者`async`,或者`fakeAsync`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "They follow patterns familiar to test developers everywhere:",
"translation": "它们会遵循测试时众所周知的模式:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Exhibit standard, Angular-agnostic testing techniques.",
"translation": "使用标准的、与Angular无关的测试技巧",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Create instances directly with `new`.",
"translation": "直接使用`new`创建实例",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Substitute test doubles (stubs, spys, and mocks) for the real dependencies.",
"translation": "用测试替身stubspy和mock替代真正的依赖",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Write both kinds of tests",
"translation": "同时采用这两种测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Good developers write both kinds of tests for the same application part, often in the same spec file.\nWrite simple _isolated_ unit tests to validate the part in isolation.\nWrite _Angular_ tests to validate the part as it interacts with Angular,\nupdates the DOM, and collaborates with the rest of the application.",
"translation": "优秀的开发者同时编写这两种测试程序来测试相同的应用部件往往在同一个spec文件。\n编写简单的**孤立**单元测试程序来验证孤立的部分。\n编写**Angular**测试程序来验证与Angular互动、更新DOM、以及与应用其它部分互动的部分。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Services",
"translation": "### 服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Services are good candidates for isolated unit testing.\nHere are some synchronous and asynchronous unit tests of the `FancyService`\nwritten without assistance from Angular testing utilities.",
"translation": "服务是应用孤立测试的好例子。\n下面是未使用Angular测试工具的一些`FancyService`的同步和异步单元测试:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "A rough line count suggests that these isolated unit tests are about 25% smaller than equivalent Angular tests.\nThat's telling but not decisive.\nThe benefit comes from reduced setup and code complexity.",
"translation": "粗略行数表明这些孤立单元测试比同等的Angular测试小25%。\n这表明了它的好处但是不是最关键的。\n主要的好处来自于缩减的配置和代码的复杂性。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Compare these equivalent tests of `FancyService.getTimeoutValue`.",
"translation": "比较下面两个同等的`FancyService.getTimeoutValue`测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "They have about the same line-count, but the Angular-dependent version\nhas more moving parts including a couple of utility functions (`async` and `inject`).\nBoth approaches work and it's not much of an issue if you're using the\nAngular testing utilities nearby for other reasons.\nOn the other hand, why burden simple service tests with added complexity?",
"translation": "它们有类似的行数。\n但是依赖Angular的版本有更多活动的部分包括一些工具函数`async`和`inject`)。\n两种方法都可行而且如果你为了某些原因使用Angular测试工具也并没有什么问题。\n反过来为什么要为简单的服务测试程序添加复杂度呢",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Pick the approach that suits you.",
"translation": "选择你喜欢的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Services with dependencies",
"translation": "### 带依赖的服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Services often depend on other services that Angular injects into the constructor.\nYou can test these services _without_ the `TestBed`.\nIn many cases, it's easier to create and _inject_ dependencies by hand.",
"translation": "服务通常依赖其它服务Angular通过构造函数注入它们。\n你可以**不使用**TestBed测试这些服务。\n在许多情况下创建和手动**注入**依赖来的更加容易。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `DependentService` is a simple example:",
"translation": "`DependentService`是一个简单的例子:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It delegates its only method, `getValue`, to the injected `FancyService`.",
"translation": "它将唯一的方法,`getValue`,委托给了注入的`FancyService`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here are several ways to test it.",
"translation": "这里是几种测试它的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The first test creates a `FancyService` with `new` and passes it to the `DependentService` constructor.",
"translation": "第一个测试程序使用`new`创建`FancyService`实例,并将它传递给`DependentService`构造函数。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "However, it's rarely that simple. The injected service can be difficult to create or control.\nYou can mock the dependency, use a dummy value, or stub the pertinent service method\nwith a substitute method that 's easy to control.",
"translation": "很少有这么简单的,注入的服务有可能很难创建和控制。\n你可以mock依赖或者使用假值或者用易于控制的替代品stub伪造相关服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "These _isolated_ unit testing techniques are great for exploring the inner logic of a service or its\nsimple integration with a component class.\nUse the Angular testing utilities when writing tests that validate how a service interacts with components\n_within the Angular runtime environment_.",
"translation": "这些**孤立**单元测试技巧是一个很好的方法,用来探索服务的内在逻辑,以及它与组件类简单的集成。\n当在**运行时间环境下**使用Angular测试工具来验证一个服务是如何与组件互动的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Pipes",
"translation": "### 管道\nPipes are easy to test without the Angular testing utilities.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### Write Angular tests too",
"translation": "### 同时也编写Angular测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Consider adding component tests such as this one:",
"translation": "考虑像这样添加组件测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Components",
"translation": "### 组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Component tests typically examine how a component class interacts with its own template or with collaborating components.\nThe Angular testing utilities are specifically designed to facilitate such tests.",
"translation": "组件测试通常检查该组件类是如何与自己的模板或者其它合作组件交互的。\nAngular测试工具是专门为这种测试设计的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Consider this `ButtonComp` component.",
"translation": "考虑这个`ButtonComp`组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The following Angular test demonstrates that clicking a button in the template leads\nto an update of the on-screen message.",
"translation": "下面的Angular测试演示点击模板里的按钮后引起了屏幕上的消息的更新。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The assertions verify that the data values flow from one HTML control (the `<button>`) to the component and\nfrom the component back to a _different_ HTML control (the `<span>`).\nA passing test means the component and its template are wired correctly.",
"translation": "该判断验证了数据绑定从一个HTML控件(`<button>`)流动到组件,以及从组件回到**不同**的HTML控件(`<span>`)。\n通过的测试程序说明组件和它的模块是否设置正确。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Isolated unit tests can more rapidly probe a component at its API boundary,\nexploring many more conditions with less effort.",
"translation": "孤立单元测试可以更快的在API边界探测组件更轻松的探索更多条件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here are a set of unit tests that verify the component's outputs in the face of a variety of\ncomponent inputs.",
"translation": "下面是一套单元测试程序,用来验证面对多种输入时组件的输出。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Isolated component tests offer a lot of test coverage with less code and almost no setup.\nThis is even more of an advantage with complex components, which\nmay require meticulous preparation with the Angular testing utilities.",
"translation": "孤立组件单元测试使用更少的代码以及几乎不存在的配置,提供了很多测试覆盖率。\n在测试复杂的组件时这个优势显得更加明显因为可能需要使用Angular测试工具进行精心准备。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "On the other hand, isolated unit tests can't confirm that the `ButtonComp` is\nproperly bound to its template or even data bound at all.\nUse Angular tests for that.",
"translation": "但是,孤立测试无法确认`ButtonComp`是否与其模板正确的绑定,或者是否有数据绑定。\n使用Angular测试来应对它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## Angular testing utility APIs",
"translation": "## Angular测试工具API",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This section takes inventory of the most useful Angular testing features and summarizes what they do.",
"translation": "本节将最有用的Angular测试功能提取出来并总结了它们的作用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The Angular testing utilities include the `TestBed`, the `ComponentFixture`, and a handful of functions that control the test environment.\nThe [_TestBed_](guide/testing#testbed-api-summary) and [_ComponentFixture_](guide/testing#component-fixture-api-summary) classes are covered separately.",
"translation": "Angular测试工具包括`TestBed`、`ComponentFixture`和一些其他函数,用来控制测试环境。\n[_TestBed_](guide/testing#testbed-api-summary)和[_ComponentFixture_](guide/testing#component-fixture-api-summary)在这里分别解释了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here's a summary of the stand-alone functions, in order of likely utility:",
"translation": "下面是一些独立函数的总结,以使用频率排序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Function",
"translation": "函数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Runs the body of a test (`it`) or setup (`beforeEach`) function within a special _async test zone_.\n See [discussion above](guide/testing#async).",
"translation": "在特殊的**async测试区域**运行测试程序(`it`)或者设置(`beforeEach`)的主体。\n 参见[上面的讨论](guide/testing#async).\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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](guide/testing#fake-async).",
"translation": "在特殊的**fakeAsync测试区域**运行测试程序(`it`)的主体,造就控制流更加线性的代码风格。\n 参见[上面的讨论](guide/testing#fake-async).\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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](guide/testing#tick).",
"translation": "接受一个可选参数,往前推移虚拟时间提供数字的毫秒数,清除在这段时间内的异步行为。\n 参见[上面的讨论](guide/testing#tick)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Injects one or more services from the current `TestBed` injector into a test function.\n See [above](guide/testing#inject).",
"translation": "从当前`TestBed`注入器注入一个或多个服务到测试函数。参见[上面](guide/testing#inject)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "A provider token for a service that turns on [automatic change detection](guide/testing#automatic-change-detection).",
"translation": "一个提供商令牌,用来设置**auto-changeDetect**的值,它默认值为`false`。\n 参见[自动变更检测](guide/testing#automatic-change-detection)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### _TestBed_ class summary",
"translation": "### _TestBed_ 类总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The module definition passed to `configureTestingModule` \nis a subset of the `@NgModule` metadata properties.",
"translation": "传递给`configureTestingModule`的模块定义是`@NgModule`元数据属性的子集。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Call `TestBed` methods _within_ a `beforeEach()` to ensure a fresh start before each individual test.",
"translation": "在`BeforeEach()`内调用`TestBed`方法,这样确保在运行每个单独测试时,都有崭新的开始。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here are the most important static methods, in order of likely utility.",
"translation": "这里列出了最重要的静态方法,以使用频率排序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Methods",
"translation": "方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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](guide/testing#compile-components).",
"translation": "在你完成配置以后异步编译测试模块。\n 如果**任何**测试组件有`templateUrl`或`styleUrls`,那么你**必须**调用这个方法。因为获取组件模块和样式文件必须是异步的。\n 参见[上面的描述](guide/testing#compile-components)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec.",
"translation": "调用完`compileComponents`之后,`TestBed`的配置就会在当前测试期间被冻结。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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`的配置就会在当前测试期间被冻结。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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`方法可以深入到当前测试模块深处,修改其中一个内部模块。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Replace metadata for the given component class, which could be nested deeply\n within an inner module.",
"translation": "替换指定组件类的元数据,该组件类可能嵌套在一个很深的内部模块中。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Replace metadata for the given directive class, which could be nested deeply\n within an inner module.",
"translation": "替换指定指令类的元数据,该指令可能嵌套在一个很深的内部模块中。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Replace metadata for the given pipe class, which could be nested deeply\n within an inner module.",
"translation": "替换指定管道类的元数据,该管道可能嵌套在一个很深的内部模块中。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Retrieve a service from the current `TestBed` injector.",
"translation": "从当前`TestBed`注入器获取一个服务。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `inject` function is often adequate for this purpose.\n But `inject` throws an error if it can't provide the service.\n What if the service is optional?",
"translation": "`inject`函数通常很适合这个任务。\n 但是如果`inject`不能提供服务,它会抛出错误。\n 如果服务是可选的呢?",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "After calling `get`, the `TestBed` configuration is frozen for the duration of the current spec.",
"translation": "一旦调用,`TestBed`的配置就会在当前测试期间被冻结。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Initialize the testing environment for the entire test run.",
"translation": "为整套测试的运行初始化测试环境。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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>`的形式提供非浏览器平台的替代品。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Reset the initial test environment, including the default testing module.",
"translation": "重设初始测试环境,包括默认测试模块在内。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### The _ComponentFixture_",
"translation": "### _ComponentFixture_对象",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### _ComponentFixture_ properties",
"translation": "### _ComponentFixture_的属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here are the most important properties for testers, in order of likely utility.",
"translation": "下面是对测试最重要的属性,以使用频率排序:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Properties",
"translation": "属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The instance of the component class created by `TestBed.createComponent`.",
"translation": "被`TestBed.createComponent`创建的组件类实例。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `DebugElement` associated with the root element of the component.",
"translation": "与组件根元素关联的`DebugElement`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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](guide/testing#debug-element-details).",
"translation": "`debugElement`在测试和调试期间提供对组件及其DOM元素的访问。\n 它是测试者至关重要的属性。它最有用的成员在[下面](guide/testing#debug-element-details)有所介绍。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The native DOM element at the root of the component.",
"translation": "组件的原生根DOM元素。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `ChangeDetectorRef` for the component.",
"translation": "组件的`ChangeDetectorRef`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "### _ComponentFixture_ methods",
"translation": "### _ComponentFixture_的方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Here are the most useful methods for testers.",
"translation": "下面是对测试最有用的方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Methods",
"translation": "方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Trigger a change detection cycle for the component.",
"translation": "为组件触发一轮变化检查。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Runs `checkNoChanges`afterwards to confirm that there are no circular updates unless\n called as `detectChanges(false)`;",
"translation": "之后,运行`checkNoChanges`,来确认没有循环更新,除非它被这样调用:`detectChanges(false)`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Set this to `true` when you want the fixture to detect changes automatically.",
"translation": "设置fixture是否应该自动试图检测变化。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Do a change detection run to make sure there are no pending changes.\n Throws an exceptions if there are.",
"translation": "运行一次变更检测来确认没有待处理的变化。如果有未处理的变化,它将抛出一个错误。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Returns a promise that resolves when the fixture is stable.",
"translation": "返回一个承诺在fixture稳定时解析。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "To resume testing after completion of asynchronous activity or\n asynchronous change detection, hook that promise.\n See [above](guide/testing#when-stable).",
"translation": "钩住这个承诺,以在异步行为或者异步变更检测之后继续测试。参见[上面](guide/testing#when-stable)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Trigger component destruction.",
"translation": "触发组件的销毁。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### _DebugElement_",
"translation": "### _DebugElement_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The `DebugElement` provides crucial insights into the component's DOM representation.",
"translation": "`DebugElement`提供了对组件的DOM的访问。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "Here are the most useful `DebugElement` members for testers, in approximate order of utility:",
"translation": "下面是`DebugElement`最有用的成员,以使用频率排序。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Member",
"translation": "成员",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The corresponding DOM element in the browser (null for WebWorkers).",
"translation": "与浏览器中DOM元素对应WebWorkers时值为null。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Calling `query(predicate: Predicate<DebugElement>)` returns the first `DebugElement`\n that matches the [predicate](guide/testing#query-predicate) at any depth in the subtree.",
"translation": "调用`query(predicate: Predicate<DebugElement>)`返回子树所有层中第一个匹配[predicate](guide/testing#query-predicate)的`DebugElement`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Calling `queryAll(predicate: Predicate<DebugElement>)` returns all `DebugElements`\n that matches the [predicate](guide/testing#query-predicate) at any depth in subtree.",
"translation": "调用`query(predicate: Predicate<DebugElement>)`返回子树所有层中所有匹配[predicate](guide/testing#query-predicate)`DebugElement`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The host dependency injector.\n For example, the root element's component instance injector.",
"translation": "宿主依赖注入器。\n 比如,根元素的组件实例注入器。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The element's own component instance, if it has one.",
"translation": "元素自己的组件实例(如果有)。 \n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The `DebugElement` parent. Null if this is the root element.",
"translation": "`DebugElement`的父级。如果`DebugElement`是根元素,`parent`为null。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The element tag name, if it is an element.",
"translation": "元素的标签名字,如果它是一个元素的话。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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](guide/testing#trigger-event-handler).",
"translation": "如果在元素的`listeners`列表中有一个对应的`listener`,则以事件名字触发。\n 第二个参数是**事件对象**,一般为事件处理器。\n 参见[上面](guide/testing#trigger-event-handler)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The callbacks attached to the component's `@Output` properties and/or the element's event properties.",
"translation": "元素的`@Output`属性以及/或者元素的事件属性所附带的回调函数。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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`元数据中列出来的令牌。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Where to find this element in the source component template.",
"translation": "source是在源组件模板中查询这个元素的处所。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "The Angular `By` class has three static methods for common predicates:",
"translation": "Angular的`By`类为常用条件方法提供了三个静态方法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* `By.all` - return all elements.",
"translation": "`By.all` - 返回所有元素",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* `By.css(selector)` - return elements with matching CSS selectors.",
"translation": "`By.css(selector)` - 返回符合CSS选择器的元素。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "## Test environment setup files",
"translation": "## 测试环境的设置文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Unit testing requires some configuration and bootstrapping that is captured in _setup files_.\nThe setup files for this guide are provided for you when you follow the [Setup](guide/setup) instructions.\nThe CLI delivers similar files with the same purpose.",
"translation": "单元测试需要一些配置和启动代码,它们被收集到了这些*设置文件*中。\n当你遵循[环境设置](guide/setup)中的步骤操作时,就会得到这些设置文件。\nCLI工具也会生成类似的文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Here's a brief description of this guide's setup files:",
"translation": "下面是对本章中这些设置文件的简短说明:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The deep details of these files and how to reconfigure them for your needs\nis a topic beyond the scope of this guide .",
"translation": "本章不会深入讲解这些文件的详情以及如何根据需要重新配置它们,那超出了本章的范围。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The karma configuration file that specifies which plug-ins to use,\n which application and test files to load, which browser(s) to use,\n and how to report test results.",
"translation": "这个karma配置文件指定了要使用那些插件、要加载那些应用文件和测试文件、要使用哪些浏览器以及如何报告测试结果。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "It loads three other setup files:",
"translation": "它加载了下列设置文件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "This shim prepares karma specifically for the Angular test environment\n and launches karma itself.\n It loads the `systemjs.config.js` file as part of that process.",
"translation": "这个垫片shim文件为karma准备Angular特有的测试环境并启动karma自身。\n 这期间,它还加载`systemjs.config.js`文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "[SystemJS](https://github.com/systemjs/systemjs/blob/master/README.md)\n loads the application and test files.\n This script tells SystemJS where to find those files and how to load them.\n It's the same version of `systemjs.config.js` you installed during [setup](guide/testing#setup).",
"translation": "[SystemJS](https://github.com/systemjs/systemjs/blob/master/README.md)加载应用文件和测试文件。\n 这个脚本告诉SystemJS到哪里去找那些文件以及如何加载它们。\n 它和你在[环境设置](guide/testing#setup)期间安装的那个`systemjs.config.js`是同一个版本。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "An optional file that supplements the SystemJS configuration in `systemjs.config.js` with\n configuration for the specific needs of the application itself.",
"translation": "一个可选的文件,它会为`systemjs.config.js`中提供SystemJS的配置加上应用自身需要的特殊配置。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "A stock `systemjs.config.js` can't anticipate those needs.\n You fill the gaps here.",
"translation": "常规的`systemjs.config.js`文件无法满足那些需求,我们需要自己填充它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The sample version for this guide adds the **model barrel**\n to the SystemJs `packages` configuration.",
"translation": "本章的例子中把**模型桶barrel*添加到了SystemJS的`packages`配置中。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### npm packages",
"translation": "### npm包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "The sample tests are written to run in Jasmine and karma.\nThe two \"fast path\" setups added the appropriate Jasmine and karma npm packages to the\n`devDependencies` section of the `package.json`.\nThey're installed when you run `npm install`.",
"translation": "这些范例测试是为在Jasmine和karma而写的。\n那两条“捷径”设置会把适当的Jasmine和Karma包添加到`package.json`的`devDependencies`区。\n当我们运行`npm install`时,它们就会被安装上。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "## FAQ: Frequently Asked Questions",
"translation": "## 常见问题\n</div>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### Why put specs next to the things they test?",
"translation": "### 为何将测试的spec配置文件放置到被测试文件的傍边",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "* Such tests are easy to find.",
"translation": "这样的测试程序很容易被找到",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* You see at a glance if a part of your application lacks tests.",
"translation": "你可以一眼看出应用程序的那些部分缺乏测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* Nearby tests can reveal how a part works in context.",
"translation": "临近的测试程序可以展示代码是如何在上下文中工作的",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* When you move the source (inevitable), you remember to move the test.",
"translation": "当你移动代码(无可避免)时,你记得一起移动测试程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "* When you rename the source file (inevitable), you remember to rename the test file.",
"translation": "当你重命名源代码文件(无可避免),你记得重命名测试程序文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"original": "### When would I put specs in a test folder?",
"translation": "### 什么时候我应该把测试spec文件放到测试目录中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "It's often better to create an appropriate folder for them in the `tests` directory.",
"translation": "通常,在`test`目录中为它们创建一个合适的目录比较好。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/testing.md"
},
{
"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/content-2/guide/testing.md"
},
{
"original": "# TypeScript Configuration",
"translation": "# TypeScript 配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "* [tsconfig.json](guide/typescript-configuration#tsconfig) &mdash; TypeScript compiler configuration.",
"translation": "[tsconfig.json](guide/typescript-configuration#tsconfig) - TypeScript编译器配置。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "* [typings](guide/typescript-configuration#typings) &mdash; TypesScript declaration files.",
"translation": "[typings](guide/typescript-configuration#typings) - TypesScript类型声明文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "## *tsconfig.json*",
"translation": "## *tsconfig.json* 文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "The [Setup](guide/setup) guide uses the following `tsconfig.json`:",
"translation": "我们在[搭建本地开发环境](guide/setup)中创建过如下的`tsconfig.json`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "This file contains options and flags that are essential for Angular applications.",
"translation": "该文件中的选项和标志是写Angular应用程序的基础。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "### *noImplicitAny* and *suppressImplicitAnyIndexErrors*",
"translation": "### *noImplicitAny*与*suppressImplicitAnyIndexErrors*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "The documentation setup sets the `noImplicitAny` flag to `true`.",
"translation": "本文档在环境搭建时将`noImplicitAny`标志设置为`true`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "When 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`并且TypeScript编译器无法推断出类型时它仍然会生成JavaScript文件。\n但是它也会**报告一个错误**。\n很多饱经沧桑的程序员更喜欢这种严格的设置因为类型检查能在编译期间捕获更多意外错误。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "The documentation setup sets this flag to `true` as well.",
"translation": "本文档在环境搭建时将`noImplicitAny`标志设置为`true`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "## TypeScript Typings",
"translation": "## TypeScript类型定义(typings)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "Use [TypeScript type definition files](https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html)&mdash;`d.ts files`&mdash;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/content-2/guide/typescript-configuration.md"
},
{
"original": "TypeScript-aware editors leverage these same definition files to display type information about library features.",
"translation": "TypeScript敏感的编辑器借助这些定义文件来显示这些库中各个特性的类型定义。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "**You need do nothing to get *typings* files for library packages that include `d.ts` files. Angular packages include them already.**",
"translation": "**我们不需要为那些包含了`d.ts`文件的库获取*类型定义*文件 —— Angular的所有包都是如此。**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "### lib.d.ts",
"translation": "### lib.d.ts 文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "Thanks to that, you have all the `es6` typings even when targeting `es5`.",
"translation": "得益于这项设置,即使编译目标设置为`es5`,我们也能获得所有的`es6`类型信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "### Installable typings files",
"translation": "### 安装类型定义文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "Many libraries&mdash;jQuery, Jasmine, and Lodash among them&mdash;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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "QuickStart identifies two *typings*, or `d.ts`, files:",
"translation": "我们在“快速上手”中指定过两个*类型定义*文件(`d.ts`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework.",
"translation": "[jasmine](http://jasmine.github.io/)是Jasmine测试框架的类型定义",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"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/content-2/guide/typescript-configuration.md"
},
{
"original": "QuickStart doesn't require these typings but many of the samples do.",
"translation": "“快速上手”本身不需要这些类型定义,但是文档中的很多例子都需要。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/typescript-configuration.md"
},
{
"original": "# Upgrading from AngularJS",
"translation": "# 从 AngularJS 升级",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "## Preparation",
"translation": "## 准备工作",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Follow the AngularJS Style Guide",
"translation": "### 遵循AngularJS风格指南",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "There are a few rules in particular that will make it much easier to do *an incremental upgrade* using the Angular `upgrade/static` module:",
"translation": "有一些特别的规则可以让使用Angular的`upgrade/static`模块进行*增量升级*变得更简单:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Using a Module Loader",
"translation": "### 使用模块加载器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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&lt;script&gt; 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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Migrating to TypeScript",
"translation": "### 迁移到TypeScript",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "#### Using Component Directives",
"translation": "#### 使用组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "To be Angular compatible, an AngularJS component directive should configure\nthese attributes:",
"translation": "要与Angular兼容AngularJS的组件型指令应该配置下列属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* `restrict: 'E'`. Components are usually used as elements.",
"translation": "`restrict: 'E'`。组件通常会以元素的方式使用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "* `controller` and `controllerAs`. Components have their own controllers.",
"translation": "`controller`和`controllerAs`。组件要有自己的控制器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* `template` or `templateUrl`. Components have their own templates.",
"translation": "`template`或`templateUrl`。组件要有自己的模板。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Component directives may also use the following attributes:",
"translation": "组件型指令还可能使用下列属性:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* `transclude: true/{}`, if the component needs to transclude content from elsewhere.",
"translation": "`transclude: true`:如果组件需要从其它地方透传内容,就设置它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* `require`, if the component needs to communicate with some parent component's\n controller.",
"translation": "`require`:如果组件需要和父组件的控制器通讯,就设置它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Component directives **should not** use the following attributes:",
"translation": "组件型指令**不能**使用下列属性:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* `compile`. This will not be supported in Angular.",
"translation": "`compile`。Angular不再支持它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "* It requires less boilerplate code.",
"translation": "它需要更少的样板代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* It enforces the use of component best practices like `controllerAs`.",
"translation": "它强制你遵循组件的最佳实践,比如`controllerAs`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* It has good default values for directive attributes like `scope` and `restrict`.",
"translation": "指令中像`scope`和`restrict`这样的属性应该有良好的默认值。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "The component directive example from above looks like this when expressed\nusing the component API:",
"translation": "如果使用这个组件API进行快捷定义那么上面看到的组件型指令就变成了这样",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "## Upgrading with ngUpgrade",
"translation": "## 使用升级适配器进行升级",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### How ngUpgrade Works",
"translation": "### 升级模块工作原理",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "#### Dependency Injection",
"translation": "#### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Dependency injection tokens are always strings",
"translation": "依赖注入的令牌(Token)永远是字符串(译注:指服务名称)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "#### Components and the DOM",
"translation": "#### 组件与DOM",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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 thatcomponent . Consider a situation\nwhere you use an Angular component from AngularJS like this:",
"translation": "当我们使用一个属于另一个框架的组件时,就会发生一个跨框架边界的切换。不过,这种切换只发生在该组件元素的*子节点*上。\n考虑一个场景我们从AngularJS中使用一个Angular组件就像这样",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "#### Change Detection",
"translation": "#### 变更检测",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Using UpgradeModule with Angular _NgModules_",
"translation": "### 通过Angular的*NgModule*来使用UpgradeModule",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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的模块进行引导时就得把Anuglar 2的模块传给`UpgradeModule`。我们来看看怎么做。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Read more about [NgModules](guide/ngmodule).",
"translation": "要了解Angular模块的更多信息请参阅[Angular模块](guide/ngmodule)页。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "### Bootstrapping hybrid applications",
"translation": "### 引导混合式应用程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Say you have an `ng-app` driven bootstrap such as this one:",
"translation": "比如我们现在有这样一个通过 `ng-app` 进行引导的应用:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Next, create an `app.module.ts` file and add the following `NgModule` class:",
"translation": "接下来,创建一个`app.module.ts`文件,并添加下列`NgModule`类:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Now you can bootstrap `AppModule` using the `platformBrowserDynamic.bootstrapModule` method.",
"translation": "现在,我们就可以使用 `platformBrowserDynamic.bootstrapModule` 方法来启动 `AppModule` 了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Using Angular Components from AngularJS Code",
"translation": "### 在AngularJS的代码中使用Angular的组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Say you have a simple Angular component that shows information about a hero:",
"translation": "假设我们有一个简单的用来显示英雄信息的Angular组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "All Angular components, directives and pipes must be declared in an NgModule.",
"translation": "所有Angular组件、指令和管道都必须声明在NgModule中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Use kebab-case for downgraded component attributes",
"translation": "在降级过的组件属性中使用中线命名法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "But when using them from AngularJS templates, you must use kebab-case:",
"translation": "但是从AngularJS的模板中使用它们时我们得使用中线命名法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Using AngularJS Component Directives from Angular Code",
"translation": "### 从Angular代码中使用AngularJS组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "A simple example of an upgradable component is one that just has a template\nand a controller:",
"translation": "可升级组件的简单例子是只有一个模板和一个控制器的指令:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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 it's 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/content-2/guide/upgrade.md"
},
{
"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\nit's children.",
"translation": "升级后的组件是Angular的**指令**,而不是**组件**因为Angular不知道AngularJS将在它下面创建元素。\nAngular所知道的是升级后的组件只是一个指令一个标签Angular不需要关心组件本身及其子元素。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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,\n provide the inputs and outputs using **Angular template syntax**,\nobserving the following rules:",
"translation": "升级后的组件也可能有输入属性和输出属性它们是在原AngularJS组件型指令的scope/controller绑定中定义的。\n当我们从Angular模板中使用该组件时我们要使用**Angular模板语法**来提供这些输入属性和输出属性,但要遵循下列规则:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Binding definition",
"translation": "绑定定义",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Template syntax",
"translation": "模板语法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Attribute binding",
"translation": "属性(Attribute)绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Expression binding",
"translation": "表达式绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "One-way binding",
"translation": "单向绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Two-way binding",
"translation": "双向绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "For example, imagine a hero detail AngularJS component directive\nwith one input and one output:",
"translation": "举个例子假设我们在AngularJS中有一个表示“英雄详情”的组件型指令它带有一个输入属性和一个输出属性",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Projecting AngularJS Content into Angular Components",
"translation": "### 把AngularJS的内容投影到Angular组件中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "</div>",
"translation": "### Transcluding Angular Content into AngularJS Component Directives\n### 把Angular的内容透传进AngularJS的组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "<code-example path=\"upgrade-module/src/app/a-to-ajs-transclusion/container.component.ts\" title=\"container.component.ts\">\n</code-example>",
"translation": "### Making AngularJS Dependencies Injectable to Angular\n### 让AngularJS中的依赖可被注入到Angular",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "You can then inject it in Angular using it's class as a type annotation:",
"translation": "然后我们可以一个字符串型令牌把它注入到Angular中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Making Angular Dependencies Injectable to AngularJS",
"translation": "### 让Angular的依赖能被注入到AngularJS中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "For example, you might have an Angular service called `Heroes`:",
"translation": "例如我们可能有一个Angular的`Heroes`服务:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "After this, the service is injectable anywhere in AngularJS code:",
"translation": "此后该服务就能被注入到AngularJS代码中的任何地方了",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "## Using Ahead-of-time compilation with hybrid apps",
"translation": "## 在混合式应用中使用AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "## PhoneCat Upgrade Tutorial",
"translation": "## PhoneCat升级教程",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "In terms of project structure, this is where the work begins:",
"translation": "在项目结构方面,我们工作的起点是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Switching to TypeScript",
"translation": "### 切换到TypeScript",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Begin by installing TypeScript to the project.",
"translation": "让我们先把TypeScript包安装到项目中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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": "我们还应该配置TypeScript编译器以便它能理解我们的项目结构。我们要往项目目录下添加一个`tsconfig.json`文件,\n就像在[搭建本地开发环境](guide/setup)中做过的那样。它将告诉TypeScript编译器该如何编译我们的源文件。\n`tsconfig.json`文件会告诉 TypeScript 编译器如何把 TypeScript 文件转成 ES5 代码,并打包进 CommonJS 模块中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Now launch the TypeScript compiler from the command line in watch mode:",
"translation": "现在,从命令行中用监视模式启动 TypeScript 编译器:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Keep this process running in the background, watching and recompiling as you make changes.",
"translation": "让这个进程一直在后台运行,监听任何变化并自动重新编译。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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的类型定义。\n当我们正确调用AngularJS的API时TypeScript会帮我们检查它 —— 比如往Angular模块中注册组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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": "我们用typings工具安装的这个[AngularJS.x类型定义文件](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/angularjs)\n并不是由Angular开发组维护的但它也已经足够全面了。借助这些类型定义的帮助它可以为AngularJS.x程序加上全面的类型注解。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Here's what the new class for the phone list component controller looks like:",
"translation": "新的“电话列表(phone list)”组件控制器类是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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": "该项目还包含一些动画,在此指南的当前版本我们先不升级它,等到后面的发行版再改。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "* Add Angular and the other new dependencies to `package.json`",
"translation": "把Angular和其它新依赖添加到`package.json`中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* The SystemJS configuration file `systemjs.config.js` to the project root directory.",
"translation": "把SystemJS的配置文件`systemjs.config.js`添加到项目的根目录。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Once these are done, run:",
"translation": "这些完成之后,就运行:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Creating the _AppModule_",
"translation": "### 创建*AppModule*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Now create a new `app.module.ts` with the minimum `NgModule` class:",
"translation": "然后创建一个新的`app.module.ts`文件,其中是一个最小化的`NgModule`类:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "### Bootstrapping a hybrid PhoneCat",
"translation": "### 引导PhoneCat的混合式应用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "First, remove the `ng-app` attribute from `index.html`.\nThen import `UpgradeModule` in the `AppModule`, and override it's `ngDoBootstrap` method:",
"translation": "首先,从`index.html`中移除`ng-app`。然后在`AppModule`中导入`UpgradeModule`,并改写它的`ngDoBootstrap`方法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "#### Why declare _angular_ as _angular.IAngularStatic_?",
"translation": "#### 为何要声明*angular*为*angular.IAngularStatic*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### Upgrading the Phone service",
"translation": "### 升级`Phone`服务",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "* For loading the list of all phones into the phone list component.",
"translation": "把所有电话的列表加载到电话列表组件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* For loading the details of a single phone into the phone detail component.",
"translation": "把一台电话的详情加载到电话详情组件中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Here's the full, final code for the service:",
"translation": "最终,该类的全部代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Now that you are loading `phone.service.ts` through an import that is resolved\nby SystemJS, you should **remove the &lt;script&gt; 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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "You could use the `toPromise` method of `Observable` to turn those\nObservables into Promises in the service. In many cases that\nreduce the number of changes to the component controllers.",
"translation": "我们也能使用`Observable`的`toPromise`方法来在服务中把这些可观察对象转变成承诺,以进一步减小组件控制器中需要修改的代码量。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "### Upgrading Components",
"translation": "### 升级组件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "#### No Angular _filter_ or _orderBy_ filters",
"translation": "#### Angular中没有`filter`或`orderBy`过滤器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Remove the &lt;script&gt; tag for the phone list component from `index.html`.",
"translation": "从`index.html`中移除电话列表组件的&lt;script&gt;标签。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Now set the remaining `phone-detail.component.ts` as follows:",
"translation": "现在,剩下的`phone-detail.component.ts`文件变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Convert the phone detail component template into Angular syntax as follows:",
"translation": "我们现在也要把该组件的模板转变成Angular的语法。\n这里是它完整的新模板",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "There are several notable changes here:",
"translation": "这里有几个值得注意的改动:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* You've removed the `$ctrl.` prefix from all expressions.",
"translation": "我们从所有表达式中移除了`$ctrl.`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-src` with property\n bindings for the standard `src` property.",
"translation": "正如我们在电话列表中做过的那样,我们把`ng-src`替换成了标准的`src`属性绑定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-repeat`s with `*ngFor`s.",
"translation": "我们把`ng-repeat`替换成了`*ngFor`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-click` with an event binding for the standard `click`.",
"translation": "我们把`ng-click`替换成了一个到标准`click`事件的绑定。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Add `PhoneDetailComponent` component to the `NgModule` _declarations_ and _entryComponents_:",
"translation": "把`PhoneDetailComponent`组件添加到`NgModule`的_declarations_和_entryComponents_中",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "You should now also remove the phone detail component &lt;script&gt; tag from `index.html`.",
"translation": "我们现在应该从`index.html`中移除电话详情组件的&lt;script>。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "#### Add the _CheckmarkPipe_",
"translation": "#### 添加*CheckmarkPipe*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "The AngularJS directive had a `checkmark` _filter_.\nTurn that into an Angular **pipe**.",
"translation": "AngularJS指令中有一个`checkmark`*过滤器*我们把它转换成Angular的**管道**。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Now import and declare the newly created pipe and\nremove the filter &lt;script&gt; tag from `index.html`:",
"translation": "当我们做这个修改时,也要同时从`core`模块文件中移除对该过滤器的注册。该模块的内容变成了:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "### AOT compile the hybrid app",
"translation": "### 对混合式应用做AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "And that's all you need to use AOT while upgrading your app!",
"translation": "这就是想要在升级应用期间AOT编译所需的一切",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "### Adding The Angular Router And Bootstrap",
"translation": "### 添加Angular路由器和引导程序",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "#### Add the Angular router",
"translation": "#### 添加Angular路由器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Angular has an [all-new router](guide/router).",
"translation": "Angular有一个[全新的路由器](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "<code-example path=\"upgrade-phonecat-3-final/index.html\" region=\"appcomponent\" title=\"index.html (body)\" linenums=\"false\">\n</code-example>",
"translation": "#### Create the _Routing Module_\n#### 创建*路由模块*\nA router needs configuration whether it's the AngularJS or Angular or any other router.",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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 it's view into the host web page.",
"translation": "现在,修改`AppModule`,让它导入这个`AppRoutingModule`,并同时声明根组件`AppComponent`。\n这会告诉Angular它应该使用根组件`AppComponent`引导应用,并把它的视图插入到宿主页面中。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "#### Generate links for each phone",
"translation": "#### 为每个电话生成链接",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "See the [Routing](guide/router) page for details.",
"translation": "要了解详情,请查看[路由与导航](guide/router)页。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "#### Use route parameters",
"translation": "#### 使用路由参数",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "You are now running a pure Angular application!",
"translation": "我们现在运行的就是纯正的Angular应用了",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "### Say Goodbye to AngularJS",
"translation": "### 再见AngularJS",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "The application is still bootstrapped as a hybrid app.\nThere's no need for that anymore.",
"translation": "应用仍然以混合式应用的方式启动,然而这再也没有必要了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Switch the bootstrap method of the application from the `UpgradeModule` to the Angular way.",
"translation": "把应用的引导(`bootstrap`)方法从`UpgradeAdapter`的改为Angular的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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 it's mapping in `systemjs.config.js` can also go.",
"translation": "还需要反安装AngularJS的外部类型定义文件。我们现在只需要Jasmine的那些。\n`systemjs.config.js`中的`@angular/upgrade`包及其映射也可以移除了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "## Appendix: Upgrading PhoneCat Tests",
"translation": "## 附录升级PhoneCat的测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "### E2E Tests",
"translation": "### E2E测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Update the `protractor-conf.js` to sync with hybrid apps:",
"translation": "再对`protractor-conf.js`做下列修改,与混合应用同步:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "When you start to upgrade components and their templates to Angular, you'll make more changes \n because 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/content-2/guide/upgrade.md"
},
{
"original": "Previous code",
"translation": "老代码",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "New code",
"translation": "新代码",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "Notes",
"translation": "说明",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "The repeater matcher relies on AngularJS `ng-repeat`",
"translation": "repeater匹配器依赖于AngularJS中的`ng-repeat`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "The repeater matcher relies on AngularJS `ng-repeat`",
"translation": "repeater匹配器依赖于AngularJS中的`ng-repeat`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "The model matcher relies on AngularJS `ng-model`",
"translation": "model匹配器依赖于AngularJS中的`ng-model`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "The model matcher relies on AngularJS `ng-model`",
"translation": "model匹配器依赖于AngularJS中的`ng-model`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "The binding matcher relies on AngularJS data binding",
"translation": "binding匹配器依赖于AngularJS的数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "Replace the `ng12Hybrid` previously added with the following in `protractor-conf.js`:",
"translation": "替换之前在`protractor-conf.js`中加入 `ng12Hybrid`,象这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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": "同样我们的测试代码中有两个Protractor API调用内部使用了`$location`。该服务没有了,\n我们就得把这些调用用一个WebDriver的通用URL API代替。第一个API是“重定向(redirect)”规约:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "And the second is the phone links spec:",
"translation": "然后是“电话链接(phone links)”规约:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"original": "### Unit Tests",
"translation": "### 单元测试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "For instance, in the phone detail component spec , you can use ES2015\nfeatures like arrow functions and block-scoped variablesand benefit from the type\ndefinitions of the AngularJS services you're consuming:",
"translation": "比如在这个电话详情组件的规约中我们不仅用到了ES2015中的箭头函数和块作用域变量这些特性还为所用的一些\nAngularJS服务提供了类型定义。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"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/content-2/guide/upgrade.md"
},
{
"original": "# User Input",
"translation": "# 用户输入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "Run the <live-example></live-example>.",
"translation": "运行<live-example></live-example",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "The following example shows an event binding that implements a click handler:",
"translation": "下例展示了一个事件绑定,它实现了一个点击事件处理器:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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 reponds\nto the click event by calling the component's `onClickMe` method.",
"translation": "等号左边的`(click)`表示把按钮的点击事件作为**绑定目标**。\n等号右边引号中的文本是**模板语句**,通过调用组件的`onClickMe`方法来响应这个点击事件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "When the user clicks the button, Angular calls the `onClickMe` method from `ClickMeComponent`.",
"translation": "当用户点击按钮时Angular 调用`ClickMeComponent`的`onClickMe`方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "### Type the _$event_",
"translation": "### *$event*的类型",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "The following example rewrites the method with types:",
"translation": "下面的例子,使用了带类型方法:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "### Passing _$event_ is a dubious practice",
"translation": "### 传入 *$event* 是靠不住的做法",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "The next section shows how to use template reference variables to address this problem.",
"translation": "下面将介绍如何用模板引用变量来解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "## Get user input from a template reference variable",
"translation": "## 从一个模板引用变量中获得用户输入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "The following example uses a template reference variable\nto implement a keystroke loopback in a simple template.",
"translation": "下面的例子使用了局部模板变量,在一个超简单的模板中实现按键反馈功能。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "Type something in the input box, and watch the display update with each keystroke.",
"translation": "在输入框中输入,就会看到每次按键时,显示也随之更新了。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "**This won't work at all unless you bind to an event**.",
"translation": "**除非你绑定一个事件,否则这将完全无法工作。**",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "Angular updates the bindings (and therefore the screen)\nonly if the app does something in response to asynchronous events, such as keystrokes.",
"translation": "只有在应用做了些异步事件如击键Angular 才更新绑定(并最终影响到屏幕)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "This 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": "本例代码将`keyup`事件绑定到了数字0这是可能是最短的模板语句。\n虽然这个语句不做什么但它满足 Angular 的要求,所以 Angular 将更新屏幕。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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`变量及其结构了。\n{@a key-event}",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "## Key event filtering (with `key.enter`)",
"translation": "## 按键事件过滤(通过`key.enter`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "Here's how it works.",
"translation": "下面展示了它是如何工作的。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "## On blur",
"translation": "## 失去焦点事件 (blur)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "To fix this issue, listen to both the _Enter_ key and the _blur_ event.",
"translation": "下面通过同时监听输入框的回车键和失去焦点事件来修正这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "</code-example>",
"translation": "## Put it all together\n## 把它们放在一起",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "Below is the \"Little Tour of Heroes\" component.",
"translation": "下面就是“简版英雄指南”组件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "</code-example>",
"translation": "### Observations\n### 小结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "* **Use template variables to refer to elements** &mdash;\nThe `newHero` template variable refers to the `<input>` element.\nYou can reference `newHero` from any sibling or child of the `<input>` element.",
"translation": "**使用模板变量来引用元素** &mdash; `newHero`模板变量引用了`<input>`元素。\n你可以在`<input>`的任何兄弟或子级元素中引用`newHero`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "* **Pass values, not elements** &mdash;\nInstead of passing the `newHero` into the component's `addHero` method,\nget the input box value and pass *that* to `addHero`.",
"translation": "**传递数值,而非元素** &mdash;\n获取输入框的值并将*它*传递给组件的`addHero`,而不要传递`newHero`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "* **Keep template statements simple** &mdash;\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": "**保持模板语句简单** &mdash;\n`(blur)`事件被绑定到两个 JavaScript 语句。\n第一句调用`addHero`。第二句`newHero.value=''`在添加新英雄到列表中后清除输入框。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "## Source code",
"translation": "## 源代码",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "Following is all the code discussed in this page.",
"translation": "下面是本章讨论过的所有源码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"original": "You have mastered the basic primitives for responding to user input and gestures.",
"translation": "你已经掌握了响应用户输入和操作的基础技术。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/user-input.md"
},
{
"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/content-2/guide/user-input.md"
},
{
"original": "# Visual Studio 2015 QuickStart",
"translation": "# Visual Studio 2015 快速上手",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "Some developers prefer Visual Studio as their Integrated Development Environment (IDE).",
"translation": "有些开发者喜欢用Visual Studio。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "## ASP.NET 4.x Project",
"translation": "## ASP.NET 4.x 项目",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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 template for Visual Studio 2015</a>。 \n 注意,最终代码与本文不对应,请适当调节。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Node.js",
"translation": "前提条件: Node.js",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Visual Studio 2015 Update 3",
"translation": "前提条件: Visual Studio 2015 Update 3",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Configure External Web tools",
"translation": "前提条件: 配置External Web tools",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "* Open the **Options** dialog with `Tools` | `Options`.",
"translation": "到`Tools` | `Options`打开**Options**对话框",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "Click OK to close the dialog.",
"translation": "* 点击OK关闭对话框。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "Restart Visual Studio for this change to take effect.",
"translation": "* 重启Visual Studio以让设置变化生效。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Install TypeScript 2.2 for Visual Studio 2015",
"translation": "前提条件: 安装TypeScript 2.2 for Visual Studio 2015",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "While Visual Studio Update 3 ships with TypeScript support out of the box, it currently doesnt 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/content-2/guide/visual-studio-2015.md"
},
{
"original": "To install TypeScript 2.2:",
"translation": "要安装TypeScript 2.2",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "At this point, Visual Studio is ready. Its a good idea to close Visual Studio and \nrestart it to make sure everything is clean.",
"translation": "至此Visual Studio准备好了。重新启动Visual Stuido这样我们可以有一个崭新的开始。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "Step 1: Download the QuickStart files",
"translation": "第一步: 现在“快速上手”文件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "Step 2: Create the Visual Studio ASP.NET project",
"translation": "第二步创建Visual Studio ASP.net项目",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "Create the ASP.NET 4.x project in the usual way as follows:",
"translation": "按照下列步骤创建ASP.NET 4.x项目",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "* In Visual Studio, select `File` | `New` | `Project` from the menu.",
"translation": "在Visual Studio中选择`File` | `New` | `Project`菜单。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "Step 3: Copy the QuickStart files into the ASP.NET project folder",
"translation": "第三步: 把“快速上手”的文件复制到ASP.NET项目所在的目录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "* src/app folder (answer *No* if asked to search for TypeScript Typings)",
"translation": "src/app目录如果询问是否要搜索TypeScript类型回答*No*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "Step 4: Restore the required packages",
"translation": "第四步: 恢复需要的包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "Restore the packages required for an Angular application as follows:",
"translation": "按下面的步骤恢复Angular应用程序需要的包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "* Ignore the warnings.",
"translation": "忽略所有警告。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "* Click the `Refresh` icon in Solution Explorer.",
"translation": "在Solution Explorer里点击`Refresh`图标。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "Step 5: Build and run the app",
"translation": "第五步:构建和运行应用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "### To run in VS with F5",
"translation": "### 按 F5 以在 VS 中运行",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "### For apps that use routing",
"translation": "### 为了使用路由的应用",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "#### Configure IIS rewrite rules",
"translation": "#### 配置 IIS 重写规则",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"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/content-2/guide/visual-studio-2015.md"
},
{
"original": "It's faster to run without the debugger by pressing `Ctrl-F5`.",
"translation": "按`Ctrl-F5`不带调试器的运行应用,速度会更快。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "The default browser opens and displays the QuickStart sample application.",
"translation": "默认浏览器打开并显示《快速上手》例子应用。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "Try editing any of the project files. Save and refresh the browser to\nsee the changes.",
"translation": "尝试编辑任何项目文件,*保存*并刷新浏览器来查看效果。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/visual-studio-2015.md"
},
{
"original": "# Webpack: An Introduction",
"translation": "# Webpack简介",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "# Contents",
"translation": "# 目录",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [What is Webpack?](guide/webpack#what-is-webpack)",
"translation": "[什么是Webpack](guide/webpack#what-is-webpack)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Entries and outputs](guide/webpack#entries-outputs)",
"translation": "[入口与输出](guide/webpack#entries-outputs)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Multiple bundles](guide/webpack#multiple-bundles)",
"translation": "[多重包](guide/webpack#multiple-bundles)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Loaders](guide/webpack#loaders)",
"translation": "[加载器](guide/webpack#loaders)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Plugins](guide/webpack#plugins)",
"translation": "[插件](guide/webpack#plugins)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Configuring Webpack](guide/webpack#configure-webpack)",
"translation": "[配置Webpack](guide/webpack#configure-webpack)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Common configuration](guide/webpack#common-configuration)",
"translation": "[公共配置](guide/webpack#common-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Inside `webpack.common.js`](guide/webpack#inside-webpack-commonjs)",
"translation": "[深入`webpack.common.js`](guide/webpack#inside-webpack-commonjs)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [entry](guide/webpack#common-entries)",
"translation": "[入口](guide/webpack#common-entries)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [resolve extension-less imports](guide/webpack#common-resolves)",
"translation": "[解析无扩展名的导入](guide/webpack#common-resolves)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Plugins](guide/webpack#plugins)",
"translation": "[插件](guide/webpack#plugins)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Environment specific configuration](guide/webpack#environment-configuration)",
"translation": "[针对特定环境进行配置](guide/webpack#environment-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Development configuration](guide/webpack#development-configuration)",
"translation": "[开发环境配置](guide/webpack#development-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Production configuration](guide/webpack#production-configuration)",
"translation": "[生产环境配置](guide/webpack#production-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Trying it out](guide/webpack#try)",
"translation": "[试一下](guide/webpack#try)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Highlights](guide/webpack#highlights)",
"translation": "[重点](guide/webpack#highlights)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [Conclusion](guide/webpack#conclusion)",
"translation": "[总结](guide/webpack#conclusion)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "## What is Webpack?",
"translation": "## 什么是Webpack",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "### Entries and outputs",
"translation": "### 入口与输出",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Webpack inspects that file and traverses its `import` dependencies recursively.",
"translation": "Webpack探查那个文件并且递归遍历它的`import`依赖。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:",
"translation": "然后它把这些文件**输出**到当前配置所指定的_包文件_`app.js`中:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "#### Multiple bundles",
"translation": "#### 多重包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "### Loaders",
"translation": "### 加载器(Loader)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "When Webpack encounters `import` statements like the following,\nit applies the `test` RegEx patterns.",
"translation": "当Webpack遇到如下所示的`import`语句时,它就会调用正则表达式的`test`方法。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "When a pattern matches the filename, Webpack processes the file with the associated loader.",
"translation": "如果一个模式匹配上文件名Webpack就用它所关联的加载器处理这个文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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.\n Then 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追加到页面上的*&lt;style&gt;*元素中)。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "### Plugins",
"translation": "### 插件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "## Configuring Webpack",
"translation": "## 配置Webpack",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Begin by setting up the development environment.",
"translation": "从设置开发环境开始。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "Create a new project folder.",
"translation": "创建一个新的项目文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "Add these files :",
"translation": "把下列文件添加到根目录下:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Open a terminal window and install the npm packages.",
"translation": "打开命令行窗口并安装这些*npm*包",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "### Polyfills",
"translation": "### Polyfills 填充库",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "You'll need polyfills to run an Angular application in most browsers as explained\nin the [Browser Support](guide/browser-support) guide.",
"translation": "我们在[_浏览器支持_](guide/browser-support)章节里解释过Angular应用要能在大多数的浏览器里运行它还需要一些polyfills。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "### Common configuration",
"translation": "### 通用配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Gather the common configuration in a file called `webpack.common.js`.",
"translation": "我们可以把这些通用的配置收归到一个文件,命名为`webpack.common.js`。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "### Inside _webpack.common.js_",
"translation": "### webpack.common.js解读",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "* [`entry`](guide/webpack#common-entries)&mdash;the entry-point files that define the bundles.",
"translation": "[`entries`](guide/webpack#common-entries) - 包体的入口文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [`resolve`](guide/webpack#common-resolves)&mdash;how to resolve file names when they lack extensions.",
"translation": "[`resolve`](guide/webpack#common-resolves) - 省略扩展名时如何解释文件名。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* [`module.rules`](guide/webpack#common-rules)&mdash; `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/content-2/guide/webpack.md"
},
{
"original": "* [`plugins`](guide/webpack#common-plugins)&mdash;creates instances of the plugins.",
"translation": "[`plugins`](guide/webpack#common-plugins) - 创建插件的实例。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "#### _entry_",
"translation": "#### _entry_ 入口",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "The first export is the `entry` object:",
"translation": "如上所述,第一个导出的对象是*entries*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "This `entry` object defines the three bundles:",
"translation": "`entry`对象定义了三个包:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* `polyfills`&mdash;the polyfills needed to run Angular applications in most modern browsers.",
"translation": "`polyfills` - 使得Angular应用能够运行在大多数的现代浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* `vendor`&mdash;the third-party dependencies such as Angular, lodash, and bootstrap.css.",
"translation": "`vendor` - 第三方依赖如Angular、lodash和bootstrap.css。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* `app`&mdash;the application code.",
"translation": "`app` - 应用代码。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "#### _resolve_ extension-less imports",
"translation": "#### _resolve_ 无扩展名的文件导入",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "#### _module.rules_",
"translation": "#### _module.rules_ 规则",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "Rules tell Webpack which loaders to use for each file, or module:",
"translation": "Rules用来告诉Webpack加载不同文件或模块时该用哪个加载器。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* `awesome-typescript-loader`&mdash;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/content-2/guide/webpack.md"
},
{
"original": "* `angular2-template-loader`&mdash;loads angular components' template and styles.",
"translation": "`angular2-template-loader` - 用于加载Angular组件的模板和样式",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* `html-loader`&mdash;for component templates.",
"translation": "`html-loader` - 为组件模板准备的加载器",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* images/fonts&mdash;Images and fonts are bundled as well.",
"translation": "`images/fonts` - 图片和字体文件也能被打包。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* CSS&mdash;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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Multiple loaders can be chained using the array notation.",
"translation": "多重加载器也能使用数组形式串联起来。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "#### _plugins_",
"translation": "#### _插件_",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "Finally, create instances of three plugins:",
"translation": "最后,创建三个插件实例:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "#### *CommonsChunkPlugin*",
"translation": "#### *CommonsChunkPlugin* 插件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "#### _HtmlWebpackPlugin_",
"translation": "#### _HtmlWebpackPlugin_ 插件",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "### Environment-specific configuration",
"translation": "### 环境相关的配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "These files tend to be short and simple.",
"translation": "这些文件越小越简单越好。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "### Development configuration",
"translation": "### 开发环境配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "Here is the `webpack.dev.js` development configuration file.",
"translation": "下面是开发环境的而配置文件`webpack.dev.js`",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "The development build relies on the Webpack development server, configured near the bottom of the file.",
"translation": "开发环境下的构建依赖于Webpack的开发服务器我们在靠近文件底部的地方配置了它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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`中插入适当的&lt;script&gt;和&lt;link&gt;标签。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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`插件就会转而把一个&lt;link&gt;标签写进`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/content-2/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "### Production configuration",
"translation": "### 产品环境配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "Configuration of a *production* build resembles *development* configuration with a few key changes.",
"translation": "*产品环境*下的配置和*开发环境*下的配置很相似……除了一些关键的改动。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Put the production output bundle files in the `dist` folder.",
"translation": "把产品环境的输出包放在`dist`目录下。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "There are additional plugins:",
"translation": "还有一些别的插件:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* *`NoEmitOnErrorsPlugin`&mdash; stops the build if there is an error.",
"translation": "*`NoEmitOnErrorsPlugin`* - 如果出错就停止构建。*",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "*`UglifyJsPlugin`&mdash; minifies the bundles.",
"translation": "`UglifyJsPlugin` - 最小化(minify)生成的包。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* *`ExtractTextPlugin`&mdash; extracts embedded css as external files, adding cache-busting hash to the filename.",
"translation": "*`ExtractTextPlugin`* - 把内嵌的css抽取成外部文件并为其文件名添加“缓存无效哈希”。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* *`DefinePlugin`&mdash; use to define environment variables that you can reference within the application.",
"translation": "*`DefinePlugin`* - 用来定义环境变量,以便我们在自己的程序中引用它。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* *`LoaderOptionsPlugins`&mdash; to override options of certain loaders.",
"translation": "*`LoaderOptionsPlugins`* - 为特定的加载器提供选项。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "### Test configuration",
"translation": "### 测试环境配置",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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": "我们不用预编译TypeScriptWebpack随时在内存中转译我们的TypeScript文件并且把产出的JS直接反馈给Karma。\n硬盘上没有任何临时文件。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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&mdash;and only&mdash;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/content-2/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "## Trying it out",
"translation": "## 试一试",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "Highlights",
"translation": "### 重点:",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "* There are no `<script>` or `<link>` tags in the `index.html`. \nThe `HtmlWebpackPlugin` inserts them dynamically at runtime.",
"translation": "在`index.html`中没有&lt;script&gt;或&lt;link&gt;标签。\n `HtmlWebpackPlugin`会在运行时动态插入它们。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"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/content-2/guide/webpack.md"
},
{
"original": "* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.\n The application imports these modules too; they'd be duplicated in the `app.js` bundle\n if 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`包中。\n{@a conclusion}",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "## Conclusion",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "You've learned just enough Webpack to configurate development, test and production builds \nfor a small Angular application.",
"translation": "我们学到了刚好够用来在开发、测试、产品环境下构建一个小型Angular应用的Webpack配置知识。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "_You could always do more_. Search the web for expert advice and expand your Webpack knowledge.",
"translation": "_但我们还能做得更多_。搜索互联网来获得专家的建议并扩展你对Webpack的认识。",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"original": "[Back to top](guide/webpack#top)",
"translation": "[回到顶部](guide/webpack#top)",
"sourceFile": "/Users/twer/private/GDE/content-2/guide/webpack.md"
},
{
"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/content-2/marketing/docs.md"
},
{
"original": "## Assumptions",
"translation": "## 基本假设",
"sourceFile": "/Users/twer/private/GDE/content-2/marketing/docs.md"
},
{
"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 \"学习 JavaScript\")和来自[最新标准](https://babeljs.io/learn-es2015/ \"Latest JavaScript standards\")的一些知识,比如 [类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes \"ES2015 类\") 和 [模块](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import \"ES2015 模块\")。\n下列代码范例都是用最新版本的JavaScript写的利用[类型](https://www.typescriptlang.org/docs/handbook/classes.html \"TypeScript 类型\")实现依赖注入,并使用[装饰器](https://www.typescriptlang.org/docs/handbook/decorators.html \"装饰器\")来提供元数据。",
"sourceFile": "/Users/twer/private/GDE/content-2/marketing/docs.md"
},
{
"original": "## Feedback",
"translation": "## 反馈",
"sourceFile": "/Users/twer/private/GDE/content-2/marketing/docs.md"
},
{
"original": "You can sit with us!",
"translation": "你也可以和我们一起做贡献!",
"sourceFile": "/Users/twer/private/GDE/content-2/marketing/docs.md"
},
{
"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/content-2/marketing/docs.md"
},
{
"original": "<h1 class=\"no-toc\">Tutorial: Tour of Heroes</h1",
"translation": "教程:英雄指南",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"original": "By the end of the tutorial you will be able to do the following:",
"translation": "在本教程的最后,我们将完成下列工作:",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "* Use built-in Angular directives to show and hide elements and display lists of hero data.",
"translation": "使用内置指令来显示 / 隐藏元素,并且显示英雄数据的列表。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "* Create Angular components to display hero details and show an array of heroes.",
"translation": "创建 Angular 组件以显示英雄的详情,并显示一个英雄数组。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "* Use one-way data binding for read-only data.",
"translation": "为只读数据使用单项数据绑定。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "* Add editable fields to update a model with two-way data binding.",
"translation": "添加可编辑字段,使用双向数据绑定来更新模型。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "* Bind component methods to user events, like keystrokes and clicks.",
"translation": "把组件中的方法绑定到用户事件上,比如按键和点击。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"original": "* Format data with pipes.",
"translation": "使用管道来格式化数据。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "* Create a shared service to assemble the heroes.",
"translation": "创建共享的服务来管理这些英雄。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "* Use routing to navigate among different views and their components.",
"translation": "使用路由在不同的视图及其组件之间导航。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"original": "## What you'll build",
"translation": "## 我们要构建出什么",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"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/content-2/tutorial/index.md"
},
{
"original": "The following diagram captures all of the navigation options.",
"translation": "下面这张图汇总了我们所有可能的导航路径。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "Here's the app in action:",
"translation": "下图演示了我们应用中的所有操作。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/index.md"
},
{
"original": "# The Hero Editor",
"translation": "# 英雄编辑器",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"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/content-2/tutorial/toh-pt1.md"
},
{
"original": "## Create the heroes component",
"translation": "## 创建英雄列表组件",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"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`属性的类型换成`Hero`。\n然后以`1`为 id、以 “Windstorm” 为名字,初始化它。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"original": "The revised `HeroesComponent` class file should look like this:",
"translation": "修改后的 `HeroesComponent` 类应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"original": "The browser refreshes and display's the hero's information.",
"translation": "浏览器自动刷新,并显示这位英雄的信息。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"original": "## Edit the hero",
"translation": "## 编辑英雄名字",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"original": "Users should be able to edit the hero name in an `<input>` textbox.",
"translation": "用户应该能在一个`<input>`输入框中编辑英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"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/content-2/tutorial/toh-pt1.md"
},
{
"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/content-2/tutorial/toh-pt1.md"
},
{
"original": "### Two-way binding",
"translation": "### 双向绑定",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"original": "Refactor the details area in the `HeroesComponent` template so it looks like this:",
"translation": "把模板中的英雄名字重构成这样:",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"original": "**[(ngModel)]** is Angular's two-way data binding syntax.",
"translation": "**[(ngModel)]** 是 Angular 的双向数据绑定语法。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"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/content-2/tutorial/toh-pt1.md"
},
{
"original": "### The missing _FormsModule_",
"translation": "### 缺少 `FormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"original": "Notice that the app stopped working when you added `[(ngModel)]`.",
"translation": "注意,当我们加上 `[(ngModel)]` 之后这个应用无法工作了。",
"sourceFile": "/Users/twer/private/GDE/content-2/tutorial/toh-pt1.md"
},
{
"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/content-2/tutorial/toh-pt1.md"
},
{
"original": "## Transpile",
"translation": "## 转译transpile)",
"sourceFile": "/Users/twer/private/GDE/content-1/_fragments/glossary-t2.md"
},
{
"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/content-1/_fragments/glossary-t2.md"
},
{
"original": "## TypeScript",
"translation": "## TypeScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-1/_fragments/glossary-t2.md"
},
{
"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/content-1/_fragments/glossary-t2.md"
},
{
"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/content-1/_fragments/glossary-t2.md"
},
{
"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/content-1/_fragments/glossary-t2.md"
},
{
"original": "Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).",
"translation": "更多信息,见[typescript.org](http://www.typescriptlang.org/)。",
"sourceFile": "/Users/twer/private/GDE/content-1/_fragments/glossary-t2.md"
},
{
"original": "# AngularJS to Angular Quick Reference",
"translation": "# 从 AngularJS 到 Angular 快速参考",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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 的 1.x 版本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "## Template basics",
"translation": "## 模板基础",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Bindings/interpolation",
"translation": "### 绑定/插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Bindings/interpolation",
"translation": "### 绑定/插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Filters",
"translation": "### 过滤器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "To filter output in AngularJS templates, use the pipe character (|) and one or more filters.",
"translation": "要在AngularJS中过滤输出使用管道字符(|)以及一个或多个过滤器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "This example filters the `title` property to uppercase.",
"translation": "在这个例子中,我们把`title`属性过滤成了大写形式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Pipes",
"translation": "### 管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Filters/pipes](guide/ajs-quick-reference#filters-pipes) below.",
"translation": "请参见下面[过滤器/管道](guide/ajs-quick-reference#filters-pipes)了解更多信息。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Local variables",
"translation": "### 局部变量",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Here, `movie` is a user-defined local variable.",
"translation": "这里的`movie`是一个用户定义的局部变量",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Input variables",
"translation": "### 输入变量",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Angular has true template input variables that are explicitly defined using the `let` keyword.",
"translation": "在Angular中我们有了真正的模板输入变量它需要使用`let`关键字进行明确定义。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "## Template directives",
"translation": "## 模板指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "The application startup process is called **bootstrapping**.",
"translation": "应用的启动过程被称为**引导**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Bootstrapping",
"translation": "### 引导",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "For more information see the [Setup](guide/setup) page.",
"translation": "要了解更多,参见[搭建本地开发环境](guide/setup)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "You can specify multiple classes, as shown in the second example.",
"translation": "就像第二个例子中展示的可以指定多个CSS类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "You can specify multiple classes, as shown in the second example.",
"translation": "就像第二个例子中所展示的那样,可以同时指定多个类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `click` event",
"translation": "### 绑定到`click`事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Component decorator",
"translation": "### Component装饰器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Architecture Overview](guide/architecture#components).",
"translation": "要了解更多,请参见[架构概览](guide/architecture#components)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### ng-hide\n 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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `hidden` property",
"translation": "### 绑定`hidden`属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Routing is handled differently in Angular.",
"translation": "路由在Angular中的处理方式不同。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `href` property",
"translation": "### 绑定到`href`属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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中移除。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "For more information on two-way binding with `ngModel`, see the [NgModel&mdash;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&mdash;使用`[(ngModel)]`进行双向绑定](../guide/template-syntax.html#ngModel)部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the table row (`<tr>`) element repeats for each movie object in the collection of movies.",
"translation": "在这个例子中,对`movies`集合中的每一个`movie`对象重复渲染了这个表格行元素(`<tr>`)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "For more information, see [Structural Directives](guide/structural-directives).",
"translation": "要了解更多信息,参见[结构性指令](guide/structural-directives)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the `<div>` element is shown if the `favoriteHero` variable is truthy.",
"translation": "在这个例子中,如果`favoriteHero`变量为真,`<div>`元素就会显示出来。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `hidden` property",
"translation": "### 绑定到`hidden`属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "In this example, the `<div>` element is hidden if the `favoriteHero` variable is not truthy.",
"translation": "在这个例子中,如果`favoriteHero`变量不是真值,`<div>`元素就会被隐藏。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Bind to the `src` property",
"translation": "### 绑定到`src`属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "The (*) before `ngSwitchCase` and `ngSwitchDefault` is required in this example.",
"translation": "在这个例子中,`ngSwitchCase`和`ngSwitchDefault`前面的星号(*)是必须的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "## Filters/pipes",
"translation": "## 过滤器/管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Formats a number as currency.",
"translation": "把一个数字格式化成货币。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `currency` pipe is similar although some of the parameters have changed.",
"translation": "Angular的`currency`管道和1中很相似只是有些参数变化了。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Formats a date to a string based on the requested format.",
"translation": "基于要求的格式把日期格式化成字符串。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `date` pipe is similar.",
"translation": "Angular的`date`管道和它很相似。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Selects a subset of items from the defined collection, based on the filter criteria.",
"translation": "基于过滤条件从指定的集合中选取出一个子集。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Converts a JavaScript object into a JSON string. This is useful for debugging.",
"translation": "把一个JavaScript对象转换成一个JSON字符串。这对调试很有用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `json` pipe does the same thing.",
"translation": "Angular的`json`管道做完全相同的事。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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)个条目。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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中一样如果们改用组件中的代码实现此操作性能将会提升。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Converts the string to lowercase.",
"translation": "把该字符串转成小写形式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "The Angular `lowercase` pipe does the same thing.",
"translation": "Angular的`lowercase`管道和1中的功能完全相同。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "Formats a number as text.",
"translation": "把数字格式化为文本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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)百分比格式,如第三个范例所示。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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排序了。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "## Modules/controllers/components",
"translation": "## 模块/控制器/组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### none",
"translation": "### 没了",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Angular modules",
"translation": "### Angular模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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模块用来对控制器、服务和其它代码进行跟踪。第二个参数定义该模块依赖的其它模块列表。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "NgModules, defined with the `NgModule` decorator, serve the same purpose:",
"translation": "Angular的模块用`NgModule`装饰器进行定义,有如下用途:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "* `imports`: specifies the list of other modules that this module depends upon",
"translation": "`imports`: 指定当前模块依赖的其它模块列表",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "* `declaration`: keeps track of your components, pipes, and directives.",
"translation": "`declaration`: 用于记录组件、管道和指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "For more information on modules, see [NgModules](guide/ngmodule).",
"translation": "要了解关于模块的更多知识,参见[NgModules](guide/ngmodule)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Component decorator",
"translation": "### 组件装饰器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "This is how you associate a template with logic, which is defined in the component class.",
"translation": "这就是把模板关联到代码的方式,它定义在组件类中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Controller function",
"translation": "### 控制器函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "In AngularJS, you write the code for the model and methods in a controller function.",
"translation": "在Angular1中我们在控制器函数中写模型和方法的代码。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Component class",
"translation": "### 组件类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "In Angular, you create a component class.",
"translation": "在Angular中我们写组件类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Dependency injection",
"translation": "### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Dependency injection",
"translation": "### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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)部分。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "## Style sheets",
"translation": "## 样式表",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"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/content-1/guide/ajs-quick-reference.md"
},
{
"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`标签来为应用程序定义样式。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### Link tag",
"translation": "### Link标签",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "In Angular, you can continue to use the link tag to define the styles for your application in the `index.html` file.\n But now you can also encapsulate styles for your components.",
"translation": "在Angular2中我们可以继续在`index.html`中使用link标签来为应用程序定义样式。\n 但是也能在组件中封装样式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "### StyleUrls\n 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/content-1/guide/ajs-quick-reference.md"
},
{
"original": "This allows you to set appropriate styles for individual components that wont leak into\n other parts of the application.",
"translation": "这让我们可以为各个组件设置合适的样式,而不用担心它被泄漏到程序中的其它部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ajs-quick-reference.md"
},
{
"original": "# Animations",
"translation": "# 动画",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "For other browsers, a polyfill is required. Grab\n[`web-animations.min.js` from GitHub](https://github.com/web-animations/web-animations-js) and\nadd it to your page.",
"translation": "至于其它浏览器,就需要一个填充库(polyfill)了。你可以[从这里获取`web-animations.min.js`](https://github.com/web-animations/web-animations-js),并把它加入你的页面中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "The examples in this page are available as a <live-example></live-example>.",
"translation": "本章中引用的这个例子可以到<live-example></live-example>去体验。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "## Transitioning between two states",
"translation": "## 快速起步范例:在两个状态间转场",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "Animations can be defined inside `@Component` metadata.",
"translation": "动画会被定义在`@Component`元数据中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "## States and transitions",
"translation": "## 状态与转场",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "Angular animations are defined as logical **states** and **transitions**\nbetween states.",
"translation": "Angular动画是由**状态**和**状态之间的转场效果**所定义的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "We can define *styles* for each animation state:",
"translation": "我们可以为每个动画状态定义了*一组样式*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "### The wildcard state `*`",
"translation": "### `*`(通配符)状态",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "* The `active => *` transition applies when the element's state changes from `active` to anything else.",
"translation": "当该元素的状态从`active`变成任何其它状态时,`active => *`转场都会生效。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "* The `* => *` transition applies when *any* change between two states takes place.",
"translation": "当在*任意*两个状态之间切换时,`* => *`转场都会生效。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "### The `void` state",
"translation": "### `void`状态",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "The wildcard state `*` also matches `void`.",
"translation": "`*`通配符状态也能匹配`void`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "## Example: Entering and leaving",
"translation": "## 例子:进场与离场",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "* Enter: `void => *`",
"translation": "进场:`void => *`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "* Leave: `* => void`",
"translation": "离场:`* => void`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "These two common animations have their own aliases:",
"translation": "这两个常见的动画有自己的别名:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "## Example: Entering and leaving from different states",
"translation": "## 范例:从不同的状态下进场和离场",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "* Inactive hero enter: `void => inactive`",
"translation": "非激活英雄进场:`void => inactive`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "* Active hero enter: `void => active`",
"translation": "激活英雄进场:`void => active`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "* Inactive hero leave: `inactive => void`",
"translation": "非激活英雄离场:`inactive => void`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "* Active hero leave: `active => void`",
"translation": "激活英雄离场:`active => void`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "This gives you fine-grained control over each transition:",
"translation": "现在就对每一种转场都有了细粒度的控制:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "## Animatable properties and units",
"translation": "## 可动的(Animatable)属性与单位",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "If you don't provide a unit when specifying dimension, Angular assumes the default of `px`:",
"translation": "对大多数尺寸类属性而言,还能只定义一个数字,那就表示它使用的是像素(px)数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "* `50` is the same as saying `'50px'`",
"translation": "`50`相当于`'50px'`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "## Automatic property calculation",
"translation": "## 自动属性值计算",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "## Animation timing",
"translation": "## 动画时间线",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "### Duration",
"translation": "### 持续时间",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "* As a plain number, in milliseconds: `100`",
"translation": "作为一个普通数字,以毫秒为单位,如:`100`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "* In a string, as milliseconds: `'100ms'`",
"translation": "作为一个字符串,以毫秒为单位,如:`'100ms'`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "* In a string, as seconds: `'0.1s'`",
"translation": "作为一个字符串,以秒为单位,如:`'0.1s'`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "### Delay",
"translation": "### 延迟",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "* Wait for 100ms and then run for 200ms: `'0.2s 100ms'`",
"translation": "等待100毫秒然后运行200毫秒`'0.2s 100ms'`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "### Easing",
"translation": "### 缓动函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "* Run for 200ms, with easing: `'0.2s ease-in-out'`",
"translation": "运行200毫秒并且带缓动`'0.2s ease-in-out'`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "### Example",
"translation": "### 例子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "## Multi-step animations with keyframes",
"translation": "## 基于关键帧(Keyframes)的多阶段动画",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "This example adds some \"bounce\" to the enter and leave animations with\nkeyframes:",
"translation": "在这个例子中,我们使用关键帧来为进场和离场动画添加一些“反弹效果”:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "## Parallel animation groups",
"translation": "## 并行动画组(Group)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "One group animates the element transform and width; the other group animates the opacity.",
"translation": "其中一个动画组对元素的`transform`和`width`做动画,另一个组则对`opacity`做动画。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "A callback is fired when an animation is started and also when it is done.",
"translation": "当动画开始和结束时,会触发一个回调。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"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/content-1/guide/animations.md"
},
{
"original": "Those callbacks will fire whether or not an animation is picked up.",
"translation": "无论动画是否实际执行过,那些回调都会触发。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/animations.md"
},
{
"original": "# Ahead-of-Time Compilation",
"translation": "# 预 (AoT) 编译器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "This cookbook describes how to radically improve performance by compiling _ahead-of-time_ (AOT)\nduring a build process.",
"translation": "本章描述了如何通过在构建期间使用预编译AOT编译技术来根本性的提高性能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## Overview",
"translation": "## 概览",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"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 the _Angular compiler_.",
"translation": "Angular应用主要包含组件和它们的HTML模板。\n在浏览器可以渲染应用之前组件和模板必须要被**Angular编译器**转换为可以执行的JavaScript。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"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/content-1/guide/aot-compiler.md"
},
{
"original": "You can compile the app in the browser, at runtime, as the application loads, using the **_just-in-time_ (JIT) compiler**.\nThis is the standard development approach shown throughout the documentation.\nIt's great but it has shortcomings.",
"translation": "你可以在浏览器中使用*即时编译器*Just-in-Time - JIT在运行期间编译该应用也就是在应用加载时。\n这是本文档中展示过的标准开发方式。\n它很不错但是有自己的缺点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "JIT compilation incurs a runtime performance penalty.\nViews take longer to render because of the in-browser compilation step.\nThe application is bigger because it includes the Angular compiler\nand a lot of library code that the application won't actually need.\nBigger apps take longer to transmit and are slower to load.",
"translation": "JIT编译导致运行期间的性能损耗。\n由于需要在浏览器中执行这个编译过程视图需要花更长时间才能渲染出来。\n由于应用包含了Angular编译器以及大量实际上并不需要的库代码所以文件体积也会更大。\n更大的应用需要更长的时间进行传输加载也更慢。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Compilation can uncover many component-template binding errors.\nJIT compilation discovers them at runtime, which is late in the process.",
"translation": "编译可以发现一些组件模板绑定错误。JIT编译在运行时才揭露它们那样有点太晚了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The **_ahead-of-time_ (AOT) compiler** can catch template errors early and improve performance\nby compiling at build time.",
"translation": "而**预编译**AOT会在构建时编译这样可以在早期截获模板错误提高应用性能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "{@a aot-jit}",
"translation": "## _Ahead-of-time_ (AOT) vs _just-in-time_ (JIT)\n## 预编译AOT vs 即时编译JIT",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "There is actually only one Angular compiler. The difference between AOT and JIT is a matter of timing and tooling.\nWith AOT, the compiler runs once at build time using one set of libraries;\nwith JIT it runs every time for every user at runtime using a different set of libraries.",
"translation": "事实上只有一个Angular编译器AOT和JIT之间的差别仅仅在于编译的时机和所用的工具。\n使用AOT编译器仅仅使用一组库在构建期间运行一次使用JIT编译器在每个用户的每次运行期间都要用不同的库运行一次。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## Why do AOT compilation?",
"translation": "## 为什么需要AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "*Faster rendering*",
"translation": "**渲染得更快**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"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/content-1/guide/aot-compiler.md"
},
{
"original": "*Fewer asynchronous requests*",
"translation": "**需要的异步请求更少**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"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/content-1/guide/aot-compiler.md"
},
{
"original": "*Smaller Angular framework download size*",
"translation": "**需要下载的Angular框架体积更小**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"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/content-1/guide/aot-compiler.md"
},
{
"original": "*Detect template errors earlier*",
"translation": "**提早检测模板错误**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"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/content-1/guide/aot-compiler.md"
},
{
"original": "*Better security*",
"translation": "**更安全**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"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/content-1/guide/aot-compiler.md"
},
{
"original": "## Compile with AOT",
"translation": "## 用AOT进行编译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Preparing for offline compilation takes a few simple steps.\nTake the <a href='../guide/setup.html'>Setup</a> as a starting point.\nA few minor changes to the lone `app.component` lead to these two class and HTML files:",
"translation": "AOT编译需要一些简单的准备步骤。我们先从<a href='../guide/setup.html'>搭建本地开发环境</a>开始。\n只要单独对`app.component`文件的类文件和HTML文件做少量修改就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Install a few new npm dependencies with the following command:",
"translation": "用下列命令安装少量新的npm依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "You will run the `ngc` compiler provided in the `@angular/compiler-cli` npm package\ninstead of the TypeScript compiler (`tsc`).",
"translation": "你要用`@angular/compiler-cli`包中提供的`ngc`编译器来代替TypeScript编译器`tsc`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "`ngc` is a drop-in replacement for `tsc` and is configured much the same way.",
"translation": "`ngc`是一个`tsc`的高仿替代品,它们的配置方式几乎完全一样。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "`ngc` requires its own `tsconfig.json` with AOT-oriented settings.\nCopy the original `src/tsconfig.json` to a file called `tsconfig-aot.json` on the project root,\nthen modify it as follows.",
"translation": "`ngc`需要自己的带有AOT专用设置的`tsconfig.json`。\n把原始的`tsconfig.json`拷贝到一个名叫`tsconfig-aot.json`的文件中,然后像这样修改它:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The `compilerOptions` section is unchanged except for one property.\n**Set the `module` to `es2015`**.\nThis is important as explained later in the [Tree Shaking](guide/aot-compiler#tree-shaking) section.",
"translation": "`compilerOptions`部分只修改了一个属性:**把`module`设置为`es2015`。\n这一点非常重要我们会在后面的[摇树优化](guide/aot-compiler#tree-shaking)部分解释为什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "What's really new is the `ngc` section at the bottom called `angularCompilerOptions`.\nIts `genDir` property tells the compiler\nto store the compiled output files in a new `aot` folder.",
"translation": "`ngc`区真正新增的内容是底部的`angularCompilerOptions`。\n它的`genDir`属性告诉编译器把编译结果保存在新的`aot`目录下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The `\"skipMetadataEmit\" : true` property prevents the compiler from generating metadata files with the compiled application.\nMetadata files are not necessary when targeting TypeScript files, so there is no reason to include them.",
"translation": "`\"skipMetadataEmit\" : true`属性阻止编译器为编译后的应用生成元数据文件。\n当输出成TypeScript文件时元数据并不是必须的因此不需要包含它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "***Component-relative template URLS***",
"translation": "***相对于组件的模板URL***",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The AOT compiler requires that `@Component` URLS for external templates and CSS files be _component-relative_.\nThat means that the value of `@Component.templateUrl` is a URL value _relative_ to the component class file.\nFor example, an `'app.component.html'` URL means that the template file is a sibling of its companion `app.component.ts` file.",
"translation": "AOT编译器要求`@Component`中的外部模板和CSS文件的URL是*相对于组件的*。\n这意味着`@Component.templateUrl`的值是一个*相对于*组件类文件的URL值。\n例如`'app.component.html'` URL表示模板文件与它相应的`app.component.ts`文件放在一起。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "While JIT app URLs are more flexible, stick with _component-relative_ URLs for compatibility with AOT compilation.",
"translation": "而JIT应用的URL更灵活固定写成*相对于组件的*URL的形式对AOT编译的兼容性也更好。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "***Compiling the application***",
"translation": "*** 编译该应用 ***",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Initiate AOT compilation from the command line using the previously installed `ngc` compiler by executing:",
"translation": "在命令行中执行下列命令,借助刚安装好的`ngc`编译器来启动AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Windows users should surround the `ngc` command in double quotes:",
"translation": "Windows用户应该双引号`ngc`命令:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "`ngc` expects the `-p` switch to point to a `tsconfig.json` file or a folder containing a `tsconfig.json` file.",
"translation": "`ngc`希望`-p`选项指向一个`tsconfig.json`文件,或者一个包含`tsconfig.json`文件的目录。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "After `ngc` completes, look for a collection of _NgFactory_ files in the `aot` folder.\nThe `aot` folder is the directory specified as `genDir` in `tsconfig-aot.json`.",
"translation": "在`ngc`完成时,会在`aot`目录下看到一组*NgFactory*文件(该目录是在`tsconfig-aot.json`的`genDir`属性中指定的)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "These factory files are essential to the compiled application.\nEach component factory creates an instance of the component at runtime by combining the original class file\nand a JavaScript representation of the component's template.\nNote that the original component class is still referenced internally by the generated factory.",
"translation": "这些工厂文件对于编译后的应用是必要的。\n每个组件工厂都可以在运行时创建一个组件的实例其中带有一个原始的类文件和一个用JavaScript表示的组件模板。\n注意原始的组件类依然是由所生成的这个工厂进行内部引用的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The curious can open `aot/app.component.ngfactory.ts` to see the original Angular template syntax\n compiled to TypeScript, its intermediate form.",
"translation": "如果你好奇,可以打开`aot/app.component.ngfactory.ts`来看看原始Angular模板语法被编译成TypeScript时的中间结果。JIT compilation generates these same _NgFactories_ in memory where they are largely invisible.\nAOT compilation reveals them as separate, physical files.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Do not edit the _NgFactories_! Re-compilation replaces these files and all edits will be lost.",
"translation": "不要编辑这些*NgFactory*!重新编译时会替换这些文件,你做的所有修改都会丢失。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## Bootstrap",
"translation": "## 引导",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The AOT approach changes application bootstrapping.",
"translation": "AOT也改变了应用的引导方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Instead of bootstrapping `AppModule`, you bootstrap the application with the generated module factory, `AppModuleNgFactory`.",
"translation": "引导的方式从引导`AppModule`改成了引导生成的模块工厂:`AppModuleNgFactory`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Make a copy of `main.ts` and name it `main-jit.ts`.\nThis is the JIT version; set it aside as you may need it [later](guide/aot-compiler#run-jit \"Running with JIT\").",
"translation": "复制一份`main.ts`并把它改名为`main-jit.ts`。\n这就是JIT版本先把它放在一边我们[稍后](guide/aot-compiler#run-jit \"Running with JIT\")会用到它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Open `main.ts` and convert it to AOT compilation.\nSwitch from the `platformBrowserDynamic.bootstrap` used in JIT compilation to\n`platformBrowser().bootstrapModuleFactory` and pass in the AOT-generated `AppModuleNgFactory`.",
"translation": "打开`main.ts`并把它改成AOT编译。\n从`platformBrowserDynamic.bootstrap`改成使用`platformBrowser().bootstrapModuleFactory`并把`AppModuleNgFactory`的AOT编译结果传给它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Here is AOT bootstrap in `main.ts` next to the original JIT version:",
"translation": "这里是AOT版本`main.ts`中的引导过程下一个是你所熟悉的JIT版本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Be sure to [recompile](guide/aot-compiler#compile) with `ngc`!",
"translation": "确保用`ngc`进行[重新编译](guide/aot-compiler#compile)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## Tree shaking",
"translation": "## 摇树优化Tree shaking",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "AOT compilation sets the stage for further optimization through a process called _tree shaking_.\nA tree shaker walks the dependency graph, top to bottom, and _shakes out_ unused code like\ndead leaves in a tree.",
"translation": "AOT编译为接下来通过一个叫做*摇树优化*的过程做好了准备。\n摇树优化器从上到下遍历依赖图谱并且*摇掉*用不到的代码,这些代码就像是圣诞树中那些死掉的松针一样。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Tree shaking can greatly reduce the downloaded size of the application \nby removing unused portions of both source and library code. \nIn fact, most of the reduction in small apps comes from removing unreferenced Angular features.",
"translation": "通过移除源码和库代码中用不到的部分,摇树优化可以大幅缩减应用的下载体积。\n事实上在小型应用中大部分的缩减都是因为筛掉了那些没用到的Angular特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "For example, this demo application doesn't use anything from the `@angular/forms` library.\nThere is no reason to download forms-related Angular code and tree shaking ensures that you don't.",
"translation": "例如,这个演示程序中没有用到`@angular/forms`库中的任何东西那么也就没有理由去下载这些与表单有关的Angular代码了。摇树优化可以帮你确保这一点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Tree shaking and AOT compilation are separate steps.\nTree shaking can only target JavaScript code.\nAOT compilation converts more of the application to JavaScript,\nwhich in turn makes more of the application \"tree shakable\".",
"translation": "摇树优化和AOT编译是单独的步骤。\n摇树优化仅仅针对JavaScript代码。\nAOT编译会把应用中的大部分都转换成JavaScript这种转换会让应用更容易被“摇树优化”。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "### Rollup",
"translation": "### Rollup 工具",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "This cookbook illustrates a tree shaking utility called _Rollup_.",
"translation": "这个烹饪宝典中用来示范的摇树优化工具是*Rollup*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Rollup statically analyzes the application by following the trail of `import` and `export` statements.\nIt produces a final code _bundle_ that excludes code that is exported, but never imported.",
"translation": "Rollup会通过跟踪`import`和`export`语句来对本应用进行静态分析。\n它所生成的最终代码*捆*中会排除那些被导出过但又从未被导入的代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Rollup can only tree shake `ES2015` modules which have `import` and `export` statements.",
"translation": "Rollup只能对`ES2015`模块摇树,因为那里有`import`和`export`语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Recall that `tsconfig-aot.json` is configured to produce `ES2015` modules.\n It's not important that the code itself be written with `ES2015` syntax such as `class` and `const`.\n What matters is that the code uses ES `import` and `export` statements rather than `require` statements.",
"translation": "回忆一下,`tsconfig-aot.json`中曾配置为生成`ES2015`的模块。\n 代码本身是否用到了`ES2015`语法(例如`class`和`const`)并不重要,重要的是这些代码使用的应该是`import`和`export`语句,而不是`require`语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "In the terminal window, install the Rollup dependencies with this command:",
"translation": "通过下列命令安装Rollup依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Next, create a configuration file (`rollup-config.js`)\nin the project root directory to tell Rollup how to process the application.\nThe cookbook configuration file looks like this.",
"translation": "接下来,在项目根目录新建一个配置文件(`rollup-config.js`来告诉Rollup如何处理应用。\n本烹饪书配置文件是这样的",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "This config file tells Rollup that the app entry point is `src/app/main.js` .\nThe `dest` attribute tells Rollup to create a bundle called `build.js` in the `dist` folder.\nIt overrides the default `onwarn` method in order to skip annoying messages about the AOT compiler's use of the `this` keyword.",
"translation": "这个配置文件告诉Rollup该应用的入口点是`app/main.js`。\n`dest`属性告诉Rollup要在`dist`目录下创建一个名叫`build.js`的捆文件。\n它覆盖了默认的`onwarn`方法以便忽略由于AOT编译器使用`this`关键字导致的噪音消息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The next section covers the plugins in more depth.",
"translation": "下一节我们将深入讲解插件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "### Rollup Plugins",
"translation": "### Rollup插件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Optional plugins filter and transform the Rollup inputs and output.",
"translation": "这些可选插件过滤并转换Rollup的输入和输出。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "*RxJS*",
"translation": "*RxJS* 库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Rollup expects application source code to use `ES2015` modules. \nNot all external dependencies are published as `ES2015` modules.\nIn fact, most are not. Many of them are published as _CommonJS_ modules.",
"translation": "Rollup期望应用的源码使用`ES2015`模块。\n但并不是所有外部依赖都发布成了`ES2015`模块。\n事实上大多数都不是。它们大多数都发布成了*CommonJS*模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The _RxJs_ Observable library is an essential Angular dependency published as an ES5 JavaScript _CommonJS_ module.",
"translation": "可观察对象库*RxJS*是Angular所依赖的基础之一它就是发布成了ES5 JavaScript的*CommonJS*模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Luckily, there is a Rollup plugin that modifies _RxJs_\nto use the ES `import` and `export` statements that Rollup requires.\nRollup then preserves the parts of `RxJS` referenced by the application\nin the final bundle. Using it is straigthforward. Add the following to\nthe `plugins` array in `rollup-config.js`:",
"translation": "幸运的是有一个Rollup插件它会修改*RxJS*以使用Rollup所需的ES`import`和`export`语句。\n然后Rollup就可以把该应用中用到的那部分`RxJS`代码留在“捆”文件中了。\n它的用法很简单。把下列代码添加到`rollup-config.js`的`plugins`数组中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "*Minification*",
"translation": "*最小化*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Rollup tree shaking reduces code size considerably. Minification makes it smaller still.\nThis cookbook relies on the _uglify_ Rollup plugin to minify and mangle the code.\nAdd the following to the `plugins` array:",
"translation": "Rollup做摇树优化时会大幅减小代码体积。最小化过程则会让它更小。\n本烹饪宝典依赖于Rollup插件*uglify*来最小化并混淆代码。\n把下列代码添加到`plugins`数组中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "In a production setting, you would also enable gzip on the web server to compress\n the code into an even smaller package going over the wire.",
"translation": "在生产环境中我们还应该打开Web服务器的gzip特性来把代码压缩得更小。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "### Run Rollup",
"translation": "### 运行Rollup",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Execute the Rollup process with this command:",
"translation": "通过下列命令执行Rollup过程",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Windows users should surround the `rollup` command in double quotes:",
"translation": "Windows用户要把`rollup`命令放进双引号中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## Load the bundle",
"translation": "## 加载捆文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Loading the generated application bundle does not require a module loader like SystemJS.\nRemove the scripts that concern SystemJS.\nInstead, load the bundle file using a single `<script>` tag **_after_** the `</body>` tag:",
"translation": "加载所生成的应用捆文件并不需要使用像SystemJS这样的模块加载器。\n移除与SystemJS有关的那些脚本吧。\n改用`<script>`标签来加载这些捆文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## Serve the app",
"translation": "## 启动应用服务器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "You'll need a web server to host the application.\nUse the same `lite-server` employed elsewhere in the documentation:",
"translation": "你需要一个Web服务器来作为应用的宿主。\n像与文档中其它部分一样用`lite-server`吧:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The server starts, launches a browser, and the app should appear.",
"translation": "启动了服务器、打开浏览器,应用就出现了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## AOT QuickStart source code",
"translation": "## AOT快速起步源代码",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Here's the pertinent source code:",
"translation": "下面是相关源代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## Workflow and convenience script",
"translation": "## 工作流与便利脚本",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "You'll rebuild the AOT version of the application every time you make a change.\nThose _npm_ commands are long and difficult to remember.",
"translation": "每当修改时我们都将重新构建应用的AOT版本。\n那些*npm*命令太长,很难记。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Add the following _npm_ convenience script to the `package.json` so you can compile and rollup in one command.",
"translation": "把下列*npm*便利脚本添加到`package.json`中以便用一条命令就可以完成编译和Rollup打包工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Open a terminal window and try it.",
"translation": "打开终端窗口,并试一下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "### Develop JIT along with AOT",
"translation": "### 先用JIT开发再AOT发布",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "AOT compilation and rollup together take several seconds.\nYou may be able to develop iteratively a little faster with SystemJS and JIT.\nThe same source code can be built both ways. Here's one way to do that.",
"translation": "AOT编译和Rollup打包加起来要花好几秒钟。\n用SystemJS和JIT可以让开发期间的迭代更快一点。\n同一套源码可以用这两种方式构建。下面是方法之一",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "* Make a copy of `index.html` and call it `index-jit.html`.",
"translation": "复制一份`index.html`并命名为`index-jit.html`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "* Delete the script at the bottom of `index-jit.html` that loads `bundle.js`",
"translation": "删除`index-jit.html`底部用来加载`bundle.js`的脚本",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "* Restore the SystemJS scripts like this:",
"translation": "代之以如下的SystemJS脚本",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Notice the slight change to the `system.import` which now specifies `src/app/main-jit`.\nThat's the JIT version of the bootstrap file that we preserved [above](guide/aot-compiler#bootstrap).",
"translation": "注意,这里稍微修改了一下`system.import`,现在它指向了`src/app/main-jit`。\n这就是我们[以前](guide/aot-compiler#bootstrap)预留的JIT版本的引导文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Open a _different_ terminal window and enter `npm start`.",
"translation": "打开*另一个*终端窗口,并输入`npm start`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "That compiles the app with JIT and launches the server.\nThe server loads `index.html` which is still the AOT version, which you can confirm in the browser console.\nChange the address bar to `index-jit.html` and it loads the JIT version.\nThis is also evident in the browser console.",
"translation": "它会使用JIT方式编译本应用并启动服务器。\n服务器仍然加载的是AOT版的`index.html`,我们可以在浏览器的控制台中确认这一点。\n在地址栏中改为`index-jit.html`它就会加载JIT版这同样可以在浏览器控制台中确认。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Develop as usual.\nThe server and TypeScript compiler are in \"watch mode\" so your changes are reflected immediately in the browser.",
"translation": "照常开发。服务器和TypeScript编译器都处于“监听模式”因此我们的修改都可以立刻反映到浏览器中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "To see those changes in AOT, switch to the original terminal and re-run `npm run build:aot`.\nWhen it finishes, go back to the browser and use the back button to\nreturn to the AOT version in the default `index.html`.",
"translation": "要对比AOT版的变化可以切换到原来的终端窗口中并重新运行`npm run build:aot`。\n结束时回到浏览器中并用浏览器的后退按钮回到默认`index.html`中的AOT版本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Now you can develop JIT and AOT, side-by-side.",
"translation": "现在我们就可以同时进行JIT和AOT开发了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "## Tour of Heroes",
"translation": "## 英雄指南",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The sample above is a trivial variation of the QuickStart application.\nIn this section you apply what you've learned about AOT compilation and tree shaking\nto an app with more substance, the [_Tour of Heroes_](tutorial/toh-pt6) application.",
"translation": "上面的例子是《快速上手》应用的一个简单的变体。\n在本节中你将在一个更多内容的应用 - [英雄指南](tutorial/toh-pt6)上使用从AOT编译和摇树优化学到的知识。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "### JIT in development, AOT in production",
"translation": "### 开发器使用JIT, 产品期使用AOT",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Today AOT compilation and tree shaking take more time than is practical for development. That will change soon.\nFor now, it's best to JIT compile in development and switch to AOT compilation before deploying to production.",
"translation": "目前AOT编译和摇树优化对开发来说占用的时间太多了。这将在未来得到改变。\n当前的最佳实践是在开发器使用JIT编译然后在发布产品前切换到AOT编译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Fortunately, the source code can be compiled either way without change _if_ you account for a few key differences.",
"translation": "幸运的是,**如果**你处理了几个关键不同点,源代码可以在没有任何变化时,采取两种方式的任何一种都能编译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The JIT and AOT apps require their own `index.html` files because they setup and launch so differently.",
"translation": "JIT和AOT应用的设置和加载非常不一样因此它们需要各自的`index.html`文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Here they are for comparison:",
"translation": "下面是它们的比较:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The JIT version relies on `SystemJS` to load individual modules.\nIts scripts appear in its `index.html`.",
"translation": "JIT版本依靠`SystemJS`来加载单个模块,并需要`reflect-metadata`垫片。\n所以它们出现在它的`index.html`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "JIT and AOT applications boot in much the same way but require different Angular libraries to do so.\nThe key differences, covered in the [Bootstrap](guide/aot-compiler#bootstrap) section above,\nare evident in these `main` files which can and should reside in the same folder:",
"translation": "AOT版本用一个单独的脚本来加载整个应用 - `aot/dist/build.js`。它不需要`SystemJS`和`reflect-metadata`垫片,所以它们不会出现在`index.html`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "***TypeScript configuration***",
"translation": "***TypeScript配置***",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "JIT-compiled applications transpile to `commonjs` modules.\nAOT-compiled applications transpile to _ES2015_/_ES6_ modules to facilitate tree shaking.\nAOT requires its own TypeScript configuration settings as well.",
"translation": "JIT编译的应用编译为`commonjs`模块。\nAOT编译的应用编译为**ES2015/ES6**模块,用来支持摇树优化。\n而且AOT需要它自己的TypeScript配置设置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "You'll need separate TypeScript configuration files such as these:",
"translation": "你将需要单独的TypeScript配置文件像这些",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "`@types` and node modules",
"translation": "<header>\n @Types和node模块\n</header>In the file structure of _this particular sample project_,\nthe `node_modules` folder happens to be two levels up from the project root.\nTherefore, `\"typeRoots\"` must be set to `\"../../node_modules/@types/\"`.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "### Tree shaking",
"translation": "### 摇树优化",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Rollup does the tree shaking as before.",
"translation": "Rollup和以前一样仍然进行摇树优化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "### Running the application",
"translation": "### 运行应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The general audience instructions for running the AOT build of the Tour of Heroes app are not ready.",
"translation": "面向大众的运行AOT构建的英雄指南应用的说明还没有准备好。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The following instructions presuppose that you have downloaded the\n <a href=\"generated/zips/toh-pt6/toh-pt6.zip\" target=\"_blank\">Tour of Heroes' zip</a>\n and run `npm install` on it.",
"translation": "下列步骤假设你已经下载了<a href=\"generated/zips/toh-pt6/toh-pt6.zip\" target=\"_blank\">《英雄指南》的zip包</a>,并且在其中运行过了`npm install`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Run the JIT-compiled app with `npm start` as for all other JIT examples.",
"translation": "和其他JIT例子一样使用`npm start`命令运行JIT编译的应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Compiling with AOT presupposes certain supporting files, most of them discussed above.",
"translation": "AOT编译假设上面介绍的一些支持文件都以准备好。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "With the following npm script in the `scripts` section of the `package.json`, you can easily serve\nthe AOT-compiled application:",
"translation": "使用下面的npm脚本扩展`package.json`文件的`scripts`部分:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Copy the AOT distribution files into the `/aot` folder with the node script:",
"translation": "使用下面的node脚本拷贝AOT发布文件到`/aot/`目录:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "You won't do that again until there are updates to `zone.js` or the `core-js` shim for old browsers.",
"translation": "直到`zone.js`或者支持老版本浏览器的`core-js`垫片有更新,你不需要再这样做。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Now AOT-compile the app and launch:",
"translation": "现在AOT编译应用并使用`lite`服务器启动它:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "### Inspect the Bundle",
"translation": "### 检查包裹",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "It's fascinating to see what the generated JavaScript bundle looks like after Rollup.\nThe code is minified, so you won't learn much from inspecting the bundle directly.\nBut the <a href=\"https://github.com/danvk/source-map-explorer/blob/master/README.md\">source-map-explorer</a>\ntool can be quite revealing.",
"translation": "看看Rollup之后生成的JavaScript包非常神奇。\n代码已经被最小化所以你不会从中直接学到任何知识。\n但是<a href=\"https://github.com/danvk/source-map-explorer/blob/master/README.md\" target=\"_blank\">source-map-explorer</a> 工具非常有用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Install it:",
"translation": "安装:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "Run the following command to generate the map.",
"translation": "运行下面的命令来生成源映射。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "The `source-map-explorer` analyzes the source map generated with the bundle and draws a map of all dependencies,\nshowing exactly which application and NgModules and classes are included in the bundle.",
"translation": "`source-map-explorer`分析从包生成的源映射并画出一个依赖地图显示包中包含哪些应用程序和Angular模块和类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/aot-compiler.md"
},
{
"original": "# Architecture Overview",
"translation": "# 架构概览",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "The framework consists of several libraries, some of them core and some optional.",
"translation": "该框架包括一系列库,有些是核心库,有些是可选库。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "The code referenced on this page is available as a <live-example></live-example>.",
"translation": "本章所引用的代码见<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "## Modules",
"translation": "## 模块",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "NgModules are a big deal.\nThis page introduces modules; the [NgModules](guide/ngmodule) page covers them in depth.",
"translation": "_Angular 模块_很重要。这里只是简单介绍在 [Angular 模块](guide/ngmodule)中会做深入讲解。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "* `providers` - creators of [services](guide/architecture#services) that this module contributes to\n the global collection of services; they become accessible in all parts of the app.",
"translation": "`providers` - [服务](guide/architecture#services)的创建者,并加入到全局服务列表中,可用于应用任何部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* `bootstrap` - the main application view, called the _root component_,\n that hosts all other app views. Only the _root module_ should set this `bootstrap` property.",
"translation": "`bootstrap` - 指定应用的主视图称为_根组件_它是所有其它视图的宿主。只有_根模块_才能设置`bootstrap`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "Here's a simple root module:",
"translation": "下面是一个简单的根模块:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "The `export` of `AppComponent` is just to show how to export; 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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "### NgModules vs. JavaScript modules",
"translation": "### NgModules vs. JavaScript 模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "The NgModule &mdash; a class decorated with `@NgModule` &mdash; is a fundamental feature of Angular.",
"translation": "NgModule一个带`@NgModule`装饰器的类)是 Angular 的基础特性之一。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "### Angular libraries",
"translation": "### Angular 模块库",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Each Angular library name begins with the `@angular` prefix.",
"translation": "每个 Angular 库的名字都带有`@angular`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "You also import NgModules from Angular _libraries_ using JavaScript import statements:",
"translation": "还可以使用 JavaScript 的导入语句从 Angular _库_中导入 Angular _模块_",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "## Components",
"translation": "## 组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "A _component_ controls a patch of screen called a *view*.",
"translation": "_组件_负责控制屏幕上的一小块区域我们称之为*视图*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "For example, the following views are controlled by components:",
"translation": "例如,下列视图都是由组件控制的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* The app root with the navigation links.",
"translation": "带有导航链接的应用根组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* The list of heroes.",
"translation": "英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* The hero editor.",
"translation": "英雄编辑器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "You define a component's application logic&mdash;what it does to support the view&mdash;inside a class.\nThe class interacts with the view through an API of properties and methods.",
"translation": "我们在类中定义组件的应用逻辑,为视图提供支持。\n组件通过一些由属性和方法组成的 API 与视图交互。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "## Templates",
"translation": "## 模板",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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 `<hero-detail>` uses Angular's [template syntax](guide/template-syntax).",
"translation": "模板除了可以使用像`<h2>`和`<p>`这样的典型的 HTML 元素,还能使用其它元素。\n例如像`*ngFor`、`{{hero.name}}`、`(click)`、`[hero]`和`<hero-detail>`这样的代码使用了 Angular 的[模板语法](guide/template-syntax)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "In the last line of the template, the `<hero-detail>` tag is a custom element that represents a new component, `HeroDetailComponent`.",
"translation": "在模板的最后一行,`<hero-detail>`标签就是一个用来表示新组件`HeroDetailComponent`的自定义元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Notice how `<hero-detail>` rests comfortably among native HTML elements. Custom components mix seamlessly with native HTML in the same layouts.",
"translation": "注意到了吗?`<hero-detail>`舒适地躺在原生 HTML 元素之间。\n自定义组件和原生 HTML 在同一布局中融合得天衣无缝。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "## Metadata",
"translation": "## 元数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "Metadata tells Angular how to process a class.",
"translation": "<p style=\"padding-top:10px\">元数据告诉 Angular 如何处理一个类。</p>\n<br class=\"clear\">",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Here are a few of the most useful `@Component` configuration options:",
"translation": "`@Component`的配置项包括:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* `selector`: CSS selector that tells Angular to create and insert an instance of this component\nwhere it finds a `<hero-list>` tag in *parent* HTML.\nFor example, if an app's HTML contains `<hero-list></hero-list>`, then\nAngular inserts an instance of the `HeroListComponent` view between those tags.",
"translation": "`selector` CSS 选择器,它告诉 Angular 在*父级* HTML 中查找`<hero-list>`标签,创建并插入该组件。\n 例如,如果应用的 HTML 包含`<hero-list></hero-list>` Angular 就会把`HeroListComponent`的一个实例插入到这个标签中。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "The template, metadata, and component together describe a view.",
"translation": "模板、元数据和组件共同描绘出这个视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "## Data binding",
"translation": "## 数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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 如何把二者联系起来。As the diagram shows, there are four forms of data binding syntax. Each form has a direction &mdash; to the DOM, from the DOM, or in both directions.如图所示,数据绑定的语法有四种形式。每种形式都有一个方向 —— 绑定到 DOM 、绑定自 DOM 以及双向绑定。<br class=\"clear\">",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "The `HeroListComponent` [example](guide/architecture#templates) template has three forms:",
"translation": "`HeroListComponent`[示例](guide/architecture#templates)模板中有三种形式:",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Data binding plays an important role in communication between a template and its component.",
"translation": "数据绑定在模板与对应组件的交互中扮演了重要的角色。\n<br class=\"l-clear-both\">",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "Data binding is also important for communication between parent and child components.",
"translation": "数据绑定在父组件与子组件的通讯中也同样重要。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "## Directives",
"translation": "## 指令 (directive)",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Two *other* kinds of directives exist: _structural_ and _attribute_ directives.",
"translation": "还有两种*其它*类型的指令_结构型_指令和_属性 (attribute) 型_指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "**Structural** directives alter layout by adding, removing, and replacing elements in DOM.",
"translation": "**结构型**指令通过在 DOM 中添加、移除和替换元素来修改布局。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "## Services",
"translation": "## 服务",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Examples include:",
"translation": "例如:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* logging service",
"translation": "日志服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* data service",
"translation": "数据服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* message bus",
"translation": "消息总线",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* tax calculator",
"translation": "税款计算器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* application configuration",
"translation": "应用程序配置",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Here's an example of a service class that logs to the browser console:",
"translation": "下面是一个服务类的范例,用于把日志记录到浏览器的控制台:",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Services are everywhere.",
"translation": "服务无处不在。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "## Dependency injection",
"translation": "## 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-1/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 使用依赖注入来提供新组件以及组件所需的服务。<br class=\"clear\">",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "The process of `HeroService` injection looks a bit like this:",
"translation": "`HeroService`注入的过程差不多是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "You can register providers in modules or in components.",
"translation": "我们可以在模块中或组件中注册提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "Points to remember about dependency injection:",
"translation": "需要记住的关于依赖注入的要点是:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* Dependency injection is wired into the Angular framework and used everywhere.",
"translation": "依赖注入渗透在整个 Angular 框架中,被到处使用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* The *injector* is the main mechanism.",
"translation": "**注入器 (injector)** 是本机制的核心。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* An injector maintains a *container* of service instances that it created.",
"translation": "注入器负责维护一个*容器*,用于存放它创建过的服务实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* An injector can create a new service instance from a *provider*.",
"translation": "注入器能使用*提供商*创建一个新的服务实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* A *provider* is a recipe for creating a service.",
"translation": "*提供商*是一个用于创建服务的配方。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* Register *providers* with injectors.",
"translation": "把*提供商*注册到注入器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "## Wrap up",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/architecture.md"
},
{
"original": "* [Modules](guide/architecture#modules)",
"translation": "[模块](guide/architecture#modules)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* [Components](guide/architecture#components)",
"translation": "[组件](guide/architecture#components)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* [Templates](guide/architecture#templates)",
"translation": "[模板](guide/architecture#templates)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* [Metadata](guide/architecture#metadata)",
"translation": "[元数据](guide/architecture#metadata)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* [Data binding](guide/architecture#data-binding)",
"translation": "[数据绑定](guide/architecture#data-binding)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* [Directives](guide/architecture#directives)",
"translation": "[指令](guide/architecture#directives)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* [Services](guide/architecture#services)",
"translation": "[服务](guide/architecture#services)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "* [Dependency injection](guide/architecture#dependency-injection)",
"translation": "[依赖注入](guide/architecture#dependency-injection)",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/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/content-1/guide/architecture.md"
},
{
"original": "> [**Pipes**](guide/pipes): Use pipes in your templates to improve the user experience by transforming values for display. Consider this `currency` pipe expression:",
"translation": "> [**管道**](guide/pipes):在模板中使用管道转换成用于显示的值,以增强用户体验。例如,`currency`管道表达式:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "> It displays a price of 42.33 as `$42.33`.",
"translation": "> 它把价格“42.33”显示为`$42.33`。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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 框架交互时进行单元测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/architecture.md"
},
{
"original": "# Attribute Directives",
"translation": "# 属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "An **Attribute** directive changes the appearance or behavior of a DOM element.",
"translation": "**属性**型指令用于改变一个 DOM 元素的外观或行为。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Try the <live-example title=\"Attribute Directive example\"></live-example>.",
"translation": "你可以到这里试试:<live-example title=\"Attribute Directive example\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "## Directives overview",
"translation": "## 指令概览",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "There are three kinds of directives in Angular:",
"translation": "在 Angular 中有三种类型的指令:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. Components&mdash;directives with a template.",
"translation": "组件 &mdash; 拥有模板的指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. Structural directives&mdash;change the DOM layout by adding and removing DOM elements.",
"translation": "结构型指令 &mdash; 通过添加和移除 DOM 元素改变 DOM 布局的指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. Attribute directives&mdash;change the appearance or behavior of an element, component, or another directive.",
"translation": "属性型指令 &mdash; 改变元素、组件或其它指令的外观和行为的指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "## Build a simple attribute directive",
"translation": "## 创建一个简单的属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "This page demonstrates building a simple _myHighlight_ 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/content-1/guide/attribute-directives.md"
},
{
"original": "### Write the directive code",
"translation": "### 编写指令代码",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Follow the [setup](guide/setup) instructions for creating a new local project\nnamed <code>attribute-directives</code>.",
"translation": "按照[开发环境](guide/setup)的说明,创建一个名叫<code>attribute-directives</code>的项目文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Create the following source file in the indicated folder:",
"translation": "在指定的文件夹下创建下列源码文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "The `import` statement specifies symbols from the Angular `core`:",
"translation": "`import`语句指定了从 Angular 的`core`库导入的一些符号。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. `Directive` provides the functionality of the `@Directive` decorator.",
"translation": "`Directive`提供`@Directive`装饰器功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. `ElementRef` [injects](guide/dependency-injection) into the directive's constructor\nso the code can access the DOM element.",
"translation": "`ElementRef`[注入](guide/dependency-injection)到指令构造函数中。这样代码就可以访问 DOM 元素了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. `Input` allows data to flow from the binding expression into the directive.",
"translation": "`Input`将数据从绑定表达式传达到指令中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Next, the `@Directive` decorator function contains the directive metadata in a configuration object\nas an argument.",
"translation": "然后,`@Directive`装饰器函数以配置对象参数的形式,包含了指令的元数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "`@Directive` requires a CSS selector to identify\nthe HTML in the template that is associated with the directive.",
"translation": "`@Directive`装饰器需要一个 CSS 选择器,以便从模板中识别出关联到这个指令的 HTML。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "The [CSS selector for an attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors)\nis the attribute name in square brackets.\nHere, the directive's selector is `[myHighlight]`.\nAngular locates all elements in the template that have an attribute named `myHighlight`.",
"translation": "[用于 attribute 的 CSS 选择器](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors)就是属性名称加方括号。\n这里指令的选择器是`[myHighlight]`Angular 将会在模板中找到所有带`myHighlight`属性的元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "### Why not call it \"highlight\"?",
"translation": "### 为什么不直接叫做 \"highlight\"",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Though *highlight* is a more concise name than *myHighlight* and would work,\na 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.",
"translation": "尽管*highlight* 是一个比 *myHighlight* 更简洁的名字,而且它确实也能工作。\n但是最佳实践是在选择器名字前面添加前缀以确保它们不会与标准 HTML 属性冲突。\n它同时减少了与第三方指令名字发生冲突的危险。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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.\nFor a simple demo, the short prefix, `my`, helps distinguish your custom directive.",
"translation": "确认你**没有**给`highlight`指令添加**`ng`**前缀。\n那个前缀属于 Angular使用它可能导致难以诊断的 bug。例如这个简短的前缀`my`可以帮助你区分自定义指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "After the `@Directive` metadata comes the directive's controller class,\ncalled `HighlightDirective`, which contains the logic for the directive.\nExporting `HighlightDirective` makes it accessible to other components.",
"translation": "`@Directive`元数据之后就是该指令的控制器类,名叫`HighlightDirective`,它包含该指令的逻辑。\n然后导出`HighlightDirective`,以便让它能从其它组件中访问到。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Angular creates a new instance of the directive's controller class for\neach matching element, injecting an Angular `ElementRef`\ninto the constructor.\n`ElementRef` is a service that grants direct access to the DOM element\nthrough its `nativeElement` property.",
"translation": "Angular 会为每个匹配的元素创建一个指令控制器类的实例,并把 Angular 的`ElementRef`和`Renderer`注入进构造函数。\n`ElementRef`是一个服务,它赋予我们通过它的`nativeElement`属性直接访问 DOM 元素的能力。\n`Renderer`服务允许通过代码设置元素的样式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "## Apply the attribute directive",
"translation": "## 使用属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "To use the new `HighlightDirective`, create a template that\napplies the directive as an attribute to a paragraph (`<p>`) element.\nIn Angular terms, the `<p>` element is the attribute **host**.",
"translation": "要使用这个新的`HighlightDirective`,创建一个模板,把这个指令作为属性应用到一个段落(`p`)元素上。\n用 Angular 的话说,`<p>`元素就是这个属性型指令的**宿主**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Put the template in its own <code>app.component.html</code>\nfile that looks like this:",
"translation": "我们把这个模板放到它的<code>app.component.html</code>文件中,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Now reference this template in the `AppComponent`:",
"translation": "现在,在`AppComponent`中引用这个模板:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Next, add an `import` statement to fetch the `Highlight` directive and\nadd that class to the `declarations` NgModule metadata. This way Angular\nrecognizes the directive when it encounters `myHighlight` in the template.",
"translation": "接下来,添加了一个`import`语句来获得`Highlight`指令类,并把这个类添加到 NgModule 元数据的`declarations`数组中。\n这样当 Angular 在模板中遇到`myHighlight`时,就能认出这是指令了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Now when the app runs, the `myHighlight` directive highlights the paragraph text.",
"translation": "运行应用,就会看到我们的指令确实高亮了段落中的文本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Your directive isn't working?",
"translation": "### 你的指令没生效?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Did you remember to add the directive to the `declarations` attribute of `@NgModule`?\nIt is easy to forget!",
"translation": "你记着设置`@NgModule`的`declarations`数组了吗?它很容易被忘掉。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Open the console in the browser tools and look for an error like this:",
"translation": "打开浏览器调试工具的控制台,会看到像这样的错误信息:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Angular detects that you're trying to bind to *something* but it can't find this directive\nin the module's `declarations` array.\nAfter specifying `HighlightDirective` in the `declarations` array,\nAngular knows it can apply the directive to components declared in this module.",
"translation": "Angular 检测到你正在尝试绑定到*某些东西*,但它不认识。所以它在`declarations`元数据数组中查找。\n把`HighlightDirective`列在元数据的这个数组中Angular 就会检查对应的导入语句,从而找到`highlight.directive.ts`,并了解`myHightlight`的功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "To summarize, Angular found the `myHighlight` attribute on the `<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>`元素上发现了一个`myHighlight`属性。\n然后它创建了一个`HighlightDirective`类的实例,并把所在元素的引用注入到了指令的构造函数中。\n在构造函数中我们把`<p>`元素的背景设置为了黄色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "## Respond to user-initiated events",
"translation": "## 响应用户引发的事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Currently, `myHighlight` 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": "当前,`myHighlight`只是简单的设置元素的颜色。\n这个指令应该在用户鼠标悬浮一个元素时设置它的颜色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Begin by adding `HostListener` to the list of imported symbols;\nadd the `Input` symbol as well because you'll need it soon.",
"translation": "先把`HostListener`加进导入列表中,同时再添加`Input`符号,因为我们很快就要用到它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "Of course you could reach into the DOM with standard JavaScript and and attach event listeners manually.\nThere are at least three problems with _that_ approach:",
"translation": "当然你可以通过标准的JavaScript方式手动给宿主 DOM 元素附加一个事件监听器。\n但这种方法至少有三个问题",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. You have to write the listeners correctly.",
"translation": "必须正确的书写事件监听器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. The code must *detach* the listener when the directive is destroyed to avoid memory leaks.",
"translation": "当指令被销毁的时候,必须*拆卸*事件监听器,否则会导致内存泄露。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "1. Talking to DOM API directly isn't a best practice.",
"translation": "必须直接和 DOM API 打交道,应该避免这样做。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "The handlers delegate to a helper method that sets the color on the DOM element, `el`,\nwhich you declare and initialize in the constructor.",
"translation": "这些处理器委托给了一个辅助方法它用于为DOM元素设置颜色`el`就是你在构造器中声明和初始化过的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Here's the updated directive in full:",
"translation": "下面是修改后的指令代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Run the app and confirm that the background color appears when the mouse hovers over the `p` and\ndisappears as it moves out.We run the app and confirm that the background color appears as we move the mouse over the `p` and\ndisappears as we move out.",
"translation": "运行本应用并确认:当把鼠标移到`p`上的时候,背景色就出现了,而移开的时候,它消失了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "## Pass values into the directive with an _@Input_ data binding",
"translation": "## 使用数据绑定向指令传递值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "Start by adding a `highlightColor` property to the directive class like this:",
"translation": "我们先把`highlightColor`属性添加到指令类中,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "### Binding to an _@Input_ property",
"translation": "### 绑定到_@Input_属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "Try it by adding the following directive binding variations to the `AppComponent` template:",
"translation": "试试把下列指令绑定变量添加到`AppComponent`的模板中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Add a `color` property to the `AppComponent`.",
"translation": "把`color`属性添加到`AppComponent`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Let it control the highlight color with a property binding.",
"translation": "让它通过属性绑定来控制高亮颜色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "The `[myHighlight]` 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 (`[myHighlight]`) to do both jobs.\nThat's a crisp, compact syntax.",
"translation": "`[myHighlight]`属性同时做了两件事:把这个高亮指令应用到了`<p>`元素上,并且通过属性绑定设置了该指令的高亮颜色。\n我们复用了该指令的属性选择器`[myHighlight]`来同时完成它们。\n这是清爽、简约的语法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "You'll have to rename the directive's `highlightColor` property to `myHighlight` because that's now the color property binding name.",
"translation": "我们还要把该指令的`highlightColor`改名为`myHighlight`,因为它是颜色属性目前的绑定名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "This is disagreeable. The word, `myHighlight`, is a terrible property name and it doesn't convey the property's intent.",
"translation": "这可不好。因为`myHighlight`是一个糟糕的属性名,而且不能反映该属性的意图。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "### Bind to an _@Input_ alias",
"translation": "### 绑定到_@Input_别名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Fortunately you can name the directive property whatever you want _and_ **_alias it_** for binding purposes.",
"translation": "幸运的是,我们可以随意命名该指令的属性,并且**给它指定一个用于绑定的别名**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "_Inside_ the directive the property is known as `highlightColor`.\n_Outside_ the directive, where you bind to it, it's known as `myHighlight`.",
"translation": "在指令内部,该属性叫`highlightColor`,在外部,当我们绑定到它时,它叫`myHighlight`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "Now that you're binding to `highlightColor`, modify the `onMouseEnter()` method to use it. \nIf someone neglects to bind to `highlightColor`, highlight in red:",
"translation": "现在,我们绑定到了`highlightColor`属性,并修改`onMouseEnter()`方法来使用它。\n如果有人忘了绑定到`highlightColor`,那就用红色进行高亮。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Here's the latest version of the directive class.",
"translation": "这是最终版本的指令类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "## Write a harness to try it",
"translation": "## 写个测试程序试验下",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "Update <code>app.component.html</code> as follows:",
"translation": "把`app.component.html`修改成这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Revise the `AppComponent.color` so that it has no initial value.",
"translation": "修改`AppComponent.color`,让它不再有初始值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Here are the harness and directive in action.",
"translation": "下面是测试程序和指令的动图。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "## Bind to a second property",
"translation": "## 绑定到第二个属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "This highlight directive has a single customizable property. In a real app, it may need more.",
"translation": "本例的指令只有一个可定制属性,真实的应用通常需要更多。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "At the moment, the default color&mdash;the color that prevails until\nthe user picks a highlight color&mdash;is hard-coded as \"red\".\nLet the template developer set the default color.",
"translation": "目前,默认颜色(它在用户选取了高亮颜色之前一直有效)被硬编码为红色。我们要让模板的开发者也可以设置默认颜色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "Add a second **input** property to `HighlightDirective` called `defaultColor`:",
"translation": "把第二个名叫`defaultColor`的**输入**属性添加到`HighlightDirective`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "How do you bind to a second property when you're already binding to the `myHighlight` attribute name?",
"translation": "当已经绑定过`myHighlight`属性时,要如何绑定到第二个属性呢?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "Here's how the harness should work when you're done coding.",
"translation": "当这些代码完成时,测试程序工作时的动图如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "This page covered how to:",
"translation": "本章介绍了如何:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "* [**Bind** values to the directive](guide/attribute-directives#bindings).",
"translation": "[把值**绑定**到指令中](guide/attribute-directives#bindings)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "The final source code follows:",
"translation": "最终的源码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "### Appendix: Why add _@Input_?",
"translation": "### 附录:为什么要加*@Input*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "In this demo, the `hightlightColor` property is an ***input*** property of\nthe `HighlightDirective`. You've seen it applied without an alias:",
"translation": "在这个例子中`hightlightColor`是`HighlightDirective`的一个***输入型***属性。我们见过它没有用别名时的代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "You've seen it with an alias:",
"translation": "也见过用别名时的代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "Now apply that reasoning to the following example:",
"translation": "试用此原理分析下列范例:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"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/content-1/guide/attribute-directives.md"
},
{
"original": "* The `myHighlight` 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": "`myHighlight`属性位于左侧,它引用了`MyHighlightDirective`中一个*带别名的*属性,它不是模板所属组件的一部分,因此存在信任问题。\n所以该属性必须带`@Input`装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/attribute-directives.md"
},
{
"original": "# Bootstrapping",
"translation": "# 启动过程",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "An NgModule class describes how the application parts fit together.\nEvery application has at least one NgModule, the _root_ module\nthat you [bootstrap](#main) to launch the application.\nYou can call it anything you want. The conventional name is `AppModule`.",
"translation": "Angular 模块类描述应用的部件是如何组合在一起的。\n每个应用都至少有一个 Angular 模块,也就是*根*模块,用来[引导](#main)并运行应用。\n你可以为它取任何名字。常规名字是`AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "The [setup](guide/setup) instructions produce a new project with the following minimal `AppModule`.\nYou'll evolve this module as your application grows.",
"translation": "[开发环境](guide/setup)讲解了如何使用下面这个最小的`AppModule`来创建一个新项目。\n这个模块随着应用的成长而演变。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "After the `import` statements, you come to a class adorned with the\n**`@NgModule`** [_decorator_](guide/glossary#decorator '\"Decorator\" explained').",
"translation": "`import`语句之后,可以看到一个**`@NgModule`**[装饰器](guide/glossary#decorator '\"Decorator\" explained')修饰的类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"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`标记为 Angular 模块类(也叫`NgModule`类)。\n`@NgModule`接受一个_元数据_对象告诉 Angular 如何编译和启动应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "* **_imports_** &mdash; the `BrowserModule` that this and every application needs to run in a browser.",
"translation": "**_imports_** &mdash; `BrowserModule`,这个和每个在浏览器中运行应用都需要它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "* **_declarations_** &mdash; the application's lone component, which is also ...",
"translation": "**_declarations_** &mdash; 应用的唯一组件,它同时也是...",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "* **_bootstrap_** &mdash; the _root_ component that Angular creates and inserts into the `index.html` host web page.",
"translation": "**_bootstrap_** &mdash; _根_组件Angular 创建它并插入`index.html`宿主页面。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "The [NgModules](guide/ngmodule) guide dives deeply into the details of NgModules.\nAll you need to know at the moment is a few basics about these three properties.",
"translation": "[Angular 模块 (NgModules)](guide/ngmodule) 指南深入讲解了 Angular 模块。\n现在先初步了解这三个属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "### The _imports_ array",
"translation": "### `imports`数组",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "NgModules are a way to consolidate features that belong together into discrete units.\nMany features of Angular itself are organized as NgModules.\nHTTP services are in the `HttpModule`. The router is in the `RouterModule`.\nEventually you may create a feature module.",
"translation": "Angular 模块把特性合并成离散单元的一种方式。\nAngular 自身的许多特性也是通过 Angular 模块组织的。\nHTTP 服务在`HttpModule`里。路由器在`RouterModule`中。\n最终你可能也会创建特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "Add a module to the `imports` array when the application requires its features.",
"translation": "当应用需要模块的特性时,将其添加到`imports`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "_This_ application, like most applications, executes in a browser.\nEvery application that executes in a browser needs the `BrowserModule` from `@angular/platform-browser`.\nSo every such application includes the `BrowserModule` in its _root_ `AppModule`'s `imports` array.\nOther guide and cookbook pages will tell you when you need to add additional modules to this array.",
"translation": "_这个_应用和大多数其他应用一样在浏览器中运行。\n每个浏览器中运行的应用都需要`@angular/platform-browser`里的`BrowserModule`。\n所以每个这样的应用都在其_根_`AppModule`的`imports`数组中包含`BrowserModule`。\n在需要添加额外模块到此数组时其他指南和烹饪宝典页面会告诉你。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "**Only `NgModule` classes** go in the `imports` array. Do not put any other kind of class in `imports`.",
"translation": "`imports`数组中应该**只有`NgModule`类**。不要放置其它类型的类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "The `import` statements at the top of the file and the NgModule's `imports` array\nare unrelated and have completely different jobs.",
"translation": "不要将 Angular 模块的`imports`数组与文件顶部的`import`语句弄混淆了。它们的功能不同。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "The _JavaScript_ `import` statements give you access to symbols _exported_ by other files\nso you can reference them within _this_ file.\nYou add `import` statements to almost every application file.\nThey have nothing to do with Angular and Angular knows nothing about them.",
"translation": "_JavaScript_ 的`import`声明允许你访问在其他文件中_导出_的符号这样你可以在_当前_文件引用它们。\n我们会往几乎所有类型的应用中加入`import`语句。\n它们与 Angular 毫无关系Angular 对它们也一无所知。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "The _module's_ `imports` array appears _exclusively_ in the `@NgModule` metadata object.\nIt tells Angular about specific _other_ NgModules&mdash;all of them classes decorated\nwith `@NgModule`&mdash;that the application needs to function properly.",
"translation": "_模块_的`imports`数组是`@NgModule`元数据中*独有的*。它告诉 Angular 特定 Angular 模块的信息 &mdash; 用`@NgModule`装饰的类 &mdash; 应用需要它们来正常工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "### The _declarations_ array",
"translation": "### *declarations* 数组",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "You tell Angular which components belong to the `AppModule` by listing it in the module's `declarations` array.\nAs you create more components, you'll add them to `declarations`.",
"translation": "通过将其列到`AppModule`模块的`declarations`数组中,可以告诉 Angular 哪个组件属于`AppModule`。\n在创建更多组件的过程中逐步将它们添加到`declarations`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "You must declare _every_ component in an `NgModule` class.\nIf you use a component without declaring it, you'll see a clear error message in the browser console.",
"translation": "你必须在一个`NgModule`类声明*每一个*组件。\n否则当你使用这些组件时就会在浏览器的控制台中看到一个明显的错误信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "You'll learn to create two other kinds of classes &mdash;\n[directives](guide/attribute-directives) and [pipes](guide/pipes) &mdash;\nthat you must also add to the `declarations` array.",
"translation": "你将会学习如何创建其他两种类 &mdash; [指令](guide/attribute-directives)和[管道](guide/pipes) &mdash;\n它们也必须被添加到`declarations`数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "**Only _declarables_** &mdash; _components_, _directives_ and _pipes_ &mdash; belong in the `declarations` array.\nDo not put any other kind of class in `declarations`; _not_ `NgModule` classes, _not_ service classes, _not_ model classes.",
"translation": "**只有*可以声明的** &mdash; _组件_、_指令_和_管道_ &mdash; 属于`declarations`数组。\n不要将其他类型的类添加到`declarations`中,例如`NgModule`类, 服务类,模型类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "### The _bootstrap_ array",
"translation": "### _bootstrap_ 数组",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "You launch the application by [_bootstrapping_](#main) the root `AppModule`.\nAmong other things, the _bootstrapping_ process creates the component(s) listed in the `bootstrap` array\nand inserts each one into the browser DOM.",
"translation": "通过[_引导_](#main)根`AppModule`来启动应用。\n在启动过程中其中一步是创建列在`bootstrap`数组的组件,\n并将它们每一个都插入到浏览器的DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "Each bootstrapped component is the base of its own tree of components.\nInserting a bootstrapped component usually triggers a cascade of component creations that fill out that tree.",
"translation": "每个被引导的组件都是它自己的组件树的根。\n插入一个被引导的组件通常触发一系列组件的创建并形成组件树。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "While you can put more than one component tree on a host web page, that's not typical.\nMost applications have only one component tree and they bootstrap a single _root_ component.",
"translation": "虽然你可以将多个组件树插入到宿主页面,但并不普遍。\n大多数应用只有一个组件树它们引导单一_根_组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "You can call the one _root_ component anything you want but most developers call it `AppComponent`.",
"translation": "你可以为这个_根_组件取任何名字但是大多数程序员将其取名为`AppComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "Which brings us to the _bootstrapping_ process itself.",
"translation": "下面让我们来看看*引导*过程本身。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "## Bootstrap in _main.ts_",
"translation": "## 在*main.ts*中引导",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "There are many ways to bootstrap an application.\nThe variations depend upon how you want to compile the application and where you want to run it.",
"translation": "引导应用的方法很多。\n它们取决于你想如何编译应用以及应用将在哪儿运行。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "In the beginning, you will compile the application dynamically with the _Just-in-Time (JIT)_ compiler\nand you'll run it in a browser. You can learn about other options later.",
"translation": "开始时你将使用_即时 (JiT) _编译器动态编译应用。然后在浏览器中运行它。\n稍后你可以了解其他选项。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "The recommended place to bootstrap a JIT-compiled browser application is in a separate file\nin the `src` folder named `src/main.ts`",
"translation": "引导即时编译的浏览器应用的推荐地点是在`src`目录中一个名为`src/main.ts`的单独文件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "This code creates a browser platform for dynamic (JIT) compilation and\nbootstraps the `AppModule` described above.",
"translation": "上面的代码为动态 (JiT) 编译创建浏览器平台,并引导上面提到的`AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "The _bootstrapping_ process sets up the execution environment,\ndigs the _root_ `AppComponent` out of the module's `bootstrap` array,\ncreates an instance of the component and inserts it within the element tag identified by the component's `selector`.",
"translation": "引导过程搭建运行环境,从模块的`bootstrap`数组中提出_根_`AppComponent` 创建该组件的实例,并将其插入到组件`selector`标识的元素标签中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "The `AppComponent` selector &mdash; here and in most documentation samples &mdash; is `my-app`\nso Angular looks for a `<my-app>` tag in the `index.html` like this one ...",
"translation": "`AppComponent`选择器 &mdash; 在这里以及文档大部分例子中 &mdash; 是`my-app`\n所以 Angular 在`index.html`中查找像这样的`<my-app>`标签...",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "... and displays the `AppComponent` there.",
"translation": "...然后在那儿显示`AppComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "This file is very stable. Once you've set it up, you may never change it again.",
"translation": "该文件非常稳定。一旦配置好,你可能永远不会再修改它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "## More about NgModules",
"translation": "## 关于Angular模块的更多知识",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "Your initial app has only a single module, the _root_ module.\nAs your app grows, you'll consider subdividing it into multiple \"feature\" modules,\nsome of which can be loaded later (\"lazy loaded\") if and when the user chooses\nto visit those features.",
"translation": "你最初的应用只有一个单一的模块 —— *根*模块。\n当这个应用不断成长时你就要考虑把它们拆分到多个 \"特性\" 模块中了。\n这些特性模块中的一部分可以稍后加载即惰性加载它们只会在用户访问到这些特性时才会加载。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "When you're ready to explore these possibilities, visit the [NgModules](guide/ngmodule) guide.",
"translation": "如果你要了解这些知识,请访问[Angular 模块 (NgModule)](guide/ngmodule)页",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/bootstrapping.md"
},
{
"original": "# Browser support",
"translation": "# 浏览器支持",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "Angular supports most recent browsers. This includes the following specific versions:",
"translation": "Angular 支持大多数常用浏览器,包括下列版本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "latest",
"translation": "最新版",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "latest",
"translation": "最新版",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"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/content-1/guide/browser-support.md"
},
{
"original": "</div>",
"translation": "## Polyfills #\n## 填充库 (polyfill) #\nAngular 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.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "You can compensate by loading polyfill scripts (\"polyfills\") on the host web page (`index.html`)\nthat implement missing features in JavaScript.",
"translation": "你可以通过在宿主页面 (`index.html`) 中加载填充脚本 (“polyfills”) 来加以弥补,这些脚本实现了浏览器缺失的 JavaScript 特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "A particular browser may require at least one polyfill to run _any_ Angular application.\nYou may need additional polyfills for specific features.",
"translation": "要运行 Angular 应用,某些浏览器可能需要至少一个填充库。除此之外,如果要支持某些特定的特性,你可能还需要另一些填充库。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "The tables below can help you determine which polyfills to load, depending on the browsers you target and the features you use.",
"translation": "下表将帮你决定加载哪些填充库,具体取决于目标浏览器和要用到的特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"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/content-1/guide/browser-support.md"
},
{
"original": "</div>",
"translation": "### Mandatory polyfills ##\n### 强制性填充库 ##\nThese are the polyfills required to run an Angular application on each supported browser:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "Browsers (Desktop & Mobile)",
"translation": "<p>\n 浏览器(桌面和移动)\n </p>\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "Polyfills Required",
"translation": "需要的填充库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "</table>",
"translation": "### Optional browser features to polyfill ##\n### 可选浏览器特性的填充库 ##\nSome features of Angular may require additional polyfills.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "For example, the animations library relies on the standard web animation API, which is only available in Chrome and Firefox today.\nYou'll need a polyfill to use animations in other browsers.",
"translation": "例如,动画库依赖于标准的 web 动画 API目前它只在 Chrome 和 Firefox 上可用。你可能需要一个填充库来在其它浏览器上使用动画功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "Here are the features which may require additional polyfills:",
"translation": "下列特性可能需要更多填充库:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "<th>\n Feature",
"translation": "特性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "<th>\n Polyfill",
"translation": "填充库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "<th style=\"width: 50%\">\n Browsers (Desktop & Mobile)",
"translation": "浏览器(桌面和移动)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "<td>\n [Animations](guide/animations)",
"translation": "[动画](guide/animations)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "[Web Animations](guide/browser-support#web-animations)",
"translation": "[Web 动画](guide/browser-support#web-animations)\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "All but Chrome and Firefox<br>Not supported in IE9",
"translation": "除 Chrome 和 Firefox 外的所有,但不支持 IE9",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "If you use the following deprecated i18n pipes: [date](api/common/DeprecatedDatePipe), [currency](api/common/DeprecatedCurrencyPipe), [decimal](api/common/DeprecatedDecimalPipe) and [percent](api/common/DeprecatedPercentPipe)",
"translation": "如果你使用下列已废弃的i18n管道\n [date](api/common/DeprecatedDatePipe)、[currency](api/common/DeprecatedCurrencyPipe)、[decimal](api/common/DeprecatedDecimalPipe) 和 [percent](api/common/DeprecatedPercentPipe)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "<td>\n <p>All but Chrome, Firefox, Edge, IE11 and Safari 10</p>",
"translation": "除了 Chrome、Firefox、Edge、IE11 和 Safari 10 外的所有浏览器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "[NgClass](api/common/NgClass) on SVG elements",
"translation": "<p>在 SVG 元素上应用 [NgClass](api/common/NgClass)</p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "[Http](guide/http) when sending and receiving binary data",
"translation": "用 [Http](guide/http) 发送和接收二进制数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "</table>",
"translation": "### Suggested polyfills ##\n### 建议的填充库 ##\nBelow are the polyfills which are used to test the framework itself. They are a good starting point for an application.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "Polyfill",
"translation": "填充库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "Licence",
"translation": "授权方式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "Size*",
"translation": "大小*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "Public domain",
"translation": "公共域",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "\\* Figures are for minified and gzipped code, \ncomputed with the <a href=\"http://closure-compiler.appspot.com/home\" >closure compiler</a>.",
"translation": "\\* 这些指标测量的是最小化 (minify) 并且 gzip 过的代码,使用 <a href=\"http://closure-compiler.appspot.com/home\" target=\"_blank\">closure compiler</a>\n计算出的结果。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/browser-support.md"
},
{
"original": "# Change Log",
"translation": "# 变更记录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## All mention of moduleId removed. \"Component relative paths\" guide deleted (2017-03-13)",
"translation": "## 移除了所有的moduleId引用。移除了“组件相对路径” 的烹饪书。(2017-03-13)\nWe 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.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## NEW: Downloadable examples for each guide (2017-02-28)",
"translation": "## 新增:每篇指南都增加了可下载的范例程序 (2017-02-28)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## Template Syntax/Structural Directives: refreshed (2017-02-06)",
"translation": "## 模板语法/结构型指令:更新了 (2017-02-06)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## NEW: Samples re-structured with `src/` folder (2017-02-02)",
"translation": "## 新增:调整了范例程序的结构,移到了`src/`文件夹 (2017-02-02)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "Notably:",
"translation": "要点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "* `app/main.ts` moved to `src/main.ts`.",
"translation": "把`app/main.ts`移到`src/main.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "* `app/` moved to `src/app/`.",
"translation": "把`app/`移到`src/app/`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "* `index.html`, `styles.css` and `tsconfig.json` moved inside `src/`.",
"translation": "把`index.html`、`styles.css`和`tsconfig.json`移到`src/`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "* `systemjs.config.js` now imports `main.js` instead of `app`.",
"translation": "`systemjs.config.js`现在要导入`main.js`而不是`app`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "* Added `lite-server` configuration (`bs-config.json`) to serve `src/`.",
"translation": "新增了一个`lite-server`配置(`bs-config.json`)以便在`src/`下启动开发服务器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "## NEW: Reactive Forms guide (2017-01-31)",
"translation": "## 新增响应式Reactive表单指南 (2017-01-31)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## NEW: Deployment guide (2017-01-30)",
"translation": "## 新增:部署指南 (2017-01-30)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## Hierarchical Dependency Injection: refreshed (2017-01-13)",
"translation": "## 多级依赖注入:更新完毕 (2017-01-13)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## Miscellaneous (2017-01-05)",
"translation": "## 杂项 (2017-01-05)* [Setup](guide/setup) guide: \nadded (optional) instructions on how to remove _non-essential_ files. [环境搭建](guide/setup)指南:\n 添加了(可选的)步骤说明,告诉你如何移除*非核心*文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "* All samples prepend template/style URLs with `./` as a best practice.",
"translation": "所有范例都在模板/样式的URL之前添加`./`前缀 …… 而且你在实际开发中也应该这么做。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "* [Style Guide](guide/styleguide): copy edits and revised rules.",
"translation": "[风格指南](guide/styleguide):复制了编辑过的和修改过的规则。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "## Router: more detail (2016-12-21)",
"translation": "## 路由:更详细 (2016-12-21)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "Added section on how to set default request headers (and other request options) to\nHTTP guide.",
"translation": "添加了一节“如何设置默认的请求头(以及其它配置项)”",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "## Testing: added component test plunkers (2016-12-02)",
"translation": "## 测试添加了组件测试的plunker范例 (2016-12-02)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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](guide/testing#live-examples) and [Setup anatomy](guide/setup-systemjs-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并在[测试](guide/testing#live-examples)和[环境设置剖析](guide/setup-systemjs-anatomy)中链接到它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "## Internationalization: pluralization and _select_ (2016-11-30)",
"translation": "## 国际化:单复数和`select` (2016-11-30)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## Testing: karma file updates (2016-11-30)",
"translation": "## 测试更新了karma文件 (2016-11-30)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "* Displays Jasmine Runner output in the karma-launched browser.",
"translation": "在启动了karma的浏览器中显示Jasmine的输出。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "## QuickStart Rewrite (2016-11-18)",
"translation": "## 全新《快速上手》 (2016-11-18)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## ES6 described in \"TypeScript to JavaScript\" (2016-11-14)",
"translation": "## 在“从TypeScript到JavaScript”增加ES6的描述 (2016-11-14)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "The updated TypeScript to JavaScript guide (removed August 2017, PR #18694)\nexplains how to write apps in ES6/7",
"translation": "更新了“[从TypeScript到JavaScript](guide/ts-to-js)”烹饪宝典解释如何使用ES6/7编写应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "by translating the common idioms in the TypeScript documentation examples\n(and elsewhere on the web) to ES6/7 and ES5.",
"translation": "将TypeScript文档示例中以及网站其它地方的习惯用法翻译成ES6/7和ES5。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## npm _@types_ packages replace _typings_ (2016-10-20)",
"translation": "## 使用npm的_@types_包替换_typings_ (2016-10-20)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## \"Template Syntax\" explains two-way data binding syntax (2016-10-20)",
"translation": "## \"模板语法\"添加了双向数据绑定语法的解释(2016-10-20)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## \"Router\" _preload_ syntax and _:enter_/_:leave_ animations (2016-10-19)",
"translation": "## \"路由器\"_预加载_语法和_:enter_/_:leave_动画(2016-10-19)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "New `:enter` and `:leave` aliases make animation more natural.",
"translation": "新`:enter`和`:leave`语法,让动画更加自然。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## NEW \"Ahead of time (AOT) Compilation\" guide (2016-10-11)",
"translation": "## 添加了新的“预编译(AoT)\"烹饪书(2016-10-11)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## \"Routing and Navigation\" guide with the _Router Module_ (2016-10-5)",
"translation": "## 在“路由和导航”向导中添加**路由模块** (2016-10-5)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "[Routing and Navigation](guide/router)",
"translation": "[路由与导航](guide/router)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "All guided samples with routing use the _Routing Module_ and prose content has been updated,\nmost conspicuously in the\n[NgModule](guide/ngmodule) guide and [NgModule FAQ](guide/ngmodule-faq) guide.",
"translation": "所有使用路由的例子都使用**路由模块**,相关内容也被更新。更新最多的是[Angular模块NgModule](guide/ngmodule)章和[Angular模块常见问题](guide/ngmodule-faq)烹饪书。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "## New \"Internationalization\" guide (2016-09-30)",
"translation": "## 全新“国际化”烹饪书(2016-09-30)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## \"Style Guide\" with _NgModules_ (2016-09-27)",
"translation": "## “风格指南”中添加了_NgModules_(2016-09-27)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "[StyleGuide](guide/styleguide) explains recommended conventions for NgModules.",
"translation": "[StyleGuide](guide/styleguide)解释了我们为Angular模块NgModule而推荐的约定。\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.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"original": "## _moduleId: module.id_ everywhere (2016-09-25)",
"translation": "## moduleId到处添加module.id(2016-09-25)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "## \"Lifecycle Hooks\" guide simplified (2016-09-24)",
"translation": "## 简化了“生命周期钩子”章(2016-09-24)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/change-log.md"
},
{
"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/content-1/guide/change-log.md"
},
{
"original": "<h1 class=\"no-toc\">Cheat Sheet</h1",
"translation": "速查表",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/cheatsheet.md"
},
{
"original": "# Component Interaction",
"translation": "# 组件之间的交互",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "This cookbook contains recipes for common component communication scenarios\nin which two or more components share information.",
"translation": "本烹饪宝典包含了常见的组件通讯场景,也就是让两个或多个组件之间共享信息的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "For an in-depth look at each fundamental concepts in component communication, we can find detailed description and\nsamples in the [Component Communication]() document.",
"translation": "要深入了解组件通讯的各个基本概念,在[组件通讯]()文档中可以找到详细的描述和例子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "# Contents",
"translation": "# 目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "* [Parent and children communicate via a service](guide/component-interaction#bidirectional-service)",
"translation": "[通过服务进行父子通讯](guide/component-interaction#bidirectional-service)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "**See the <live-example name=\"component-interaction\"></live-example>**.",
"translation": "**参见<live-example name=\"cb-component-interaction\"></live-example>**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "## Pass data from parent to child with input binding",
"translation": "## 通过输入型绑定把数据从父组件传到子组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "The second `@Input` aliases the child component property name `masterName` as `'master'`.",
"translation": "第二个`@Input`为子组件的属性名`masterName`指定一个别名`master`(译者注:不推荐为起别名,请参见风格指南).",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "The `HeroParentComponent` nests the child `HeroChildComponent` inside an `*ngFor` repeater, \nbinding its `master` string property to the child's `master` alias, and each iteration's `hero` instance to the child's `hero` property.",
"translation": "父组件`HeroParentComponent`把子组件的`HeroChildComponent`放到`*ngFor`循环器中,把自己的`master`字符串属性绑定到子组件的`master`别名上,并把每个循环的`hero`实例绑定到子组件的`hero`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "The running application displays three heroes:",
"translation": "运行应用程序会显示三个英雄:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "E2E test that all children were instantiated and displayed as expected:",
"translation": "端到端测试,用于确保所有的子组件都像所期待的那样被初始化并显示出来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "## Intercept input property changes with a setter",
"translation": "## 通过setter截听输入属性值的变化",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "Use an input property setter to intercept and act upon a value from the parent.",
"translation": "使用一个输入属性的setter以拦截父组件中值的变化并采取行动。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "Here's the `NameParentComponent` demonstrating name variations including a name with all spaces:",
"translation": "下面的`NameParentComponent`展示了各种名字的处理方式,包括一个全是空格的名字。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "E2E tests of input property setter with empty and non-empty names:",
"translation": "端到端测试输入属性的setter分别使用空名字和非空名字。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "## Intercept input property changes with *ngOnChanges()*",
"translation": "## 通过*ngOnChanges()*来截听输入属性值的变化",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "You may prefer this approach to the property setter when watching multiple, interacting input properties.",
"translation": "当需要监视多个、交互式输入属性的时候本方法比用属性的setter更合适。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "Learn about `ngOnChanges()` in the [LifeCycle Hooks](guide/lifecycle-hooks) chapter.",
"translation": "学习关于`ngOnChanges()`的更多知识,参见[生命周期钩子](guide/lifecycle-hooks)一章。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "Here's the output of a button-pushing sequence:",
"translation": "下面是点击按钮的结果。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "## Parent listens for child event",
"translation": "## 父组件监听子组件的事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "Clicking a button triggers emission of a `true` or `false` ,the boolean *payload*.",
"translation": "点击按钮会触发`true`或`false`(布尔型*有效载荷*)的事件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "The framework passes the event argument &mdash; represented by `$event` &mdash; to the handler method, \nand the method processes it:",
"translation": "框架(Angular)把事件参数(用`$event`表示)传给事件处理方法,这个方法会处理:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "Test that clicking the *Agree* and *Disagree* buttons update the appropriate counters:",
"translation": "测试确保点击*Agree*和*Disagree*按钮时,计数器被正确更新。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "## Parent interacts with child via *local variable*",
"translation": "## 父组件与子组件通过*本地变量*互动",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "{@a countdown-timer-example} \nThe following is a child `CountdownTimerComponent` that repeatedly counts down to zero and launches a rocket. It has `start` and `stop` methods that control the clock and it displays a countdown status message in its own template.",
"translation": "子组件`CountdownTimerComponent`进行倒计时,归零时发射一个导弹。`start`和`stop`方法负责控制时钟并在模板里显示倒计时的状态信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "The `CountdownLocalVarParentComponent` that hosts the timer componentis as follows:",
"translation": "让我们来看看计时器组件的宿主组件`CountdownLocalVarParentComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "Here we see the parent and child working together.",
"translation": "下面是父组件和子组件一起工作时的效果。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "## Parent calls an _@ViewChild()_",
"translation": "## 父组件调用*@ViewChild()*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "Here is the parent, `CountdownViewChildParentComponent`:",
"translation": "下面是父组件`CountdownViewChildParentComponent`:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "It takes a bit more work to get the child view into the parent component *class*.",
"translation": "把子组件的视图插入到父组件类需要做一点额外的工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "First, you have to import references to the `ViewChild` decorator and the `AfterViewInit` lifecycle hook.",
"translation": "首先,你要使用`ViewChild`装饰器导入这个引用,并挂上`AfterViewInit`生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "These methods access the injected timer component directly.",
"translation": "这些方法可以直接访问被注入的计时器组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "测试一下!",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "## Parent and children communicate via a service",
"translation": "## 父组件和子组件通过服务来通讯",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "A parent component and its children share a service whose interface enables bi-directional communication *within the family*.",
"translation": "父组件和它的子组件共享同一个服务,利用该服务*在家庭内部*实现双向通讯。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "This `MissionService` connects the `MissionControlComponent` to multiple `AstronautComponent` children.",
"translation": "这个`MissionService`把`MissionControlComponent`和多个`AstronautComponent`子组件连接起来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "Test it",
"translation": "### 测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"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/content-1/guide/component-interaction.md"
},
{
"original": "[Back to top](guide/component-interaction#top)",
"translation": "[回到顶部](guide/component-interaction#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-interaction.md"
},
{
"original": "# Component Styles",
"translation": "# 组件样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "Additionally, Angular can bundle *component styles*\nwith components, enabling a more modular design than regular stylesheets.",
"translation": "另外Angular 还能把*组件样式*捆绑在我们的组件上,以实现比标准样式表更加模块化的设计。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "This page describes how to load and apply these component styles.",
"translation": "在本章中,我们将学到如何加载和使用这些*组件样式*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "## Table Of Contents",
"translation": "## 目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* [Using component styles](guide/component-styles#using-component-styles)",
"translation": "[使用组件样式](guide/component-styles#using-component-styles)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* [Special selectors](guide/component-styles#special-selectors)",
"translation": "[特殊的选择器](guide/component-styles#special-selectors)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* [Loading styles into components](guide/component-styles#loading-styles)",
"translation": "[把样式加载进组件](guide/component-styles#loading-styles)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* [Controlling view encapsulation: native, emulated, and none](guide/component-styles#view-encapsulation)",
"translation": "[控制视图的封装模式:仿真 (Emulated)、原生 (Native) 或无 (None)](guide/component-styles#view-encapsulation)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* [Appendix 1: Inspecting the CSS generated in emulated view encapsulation](guide/component-styles#inspect-generated-css)",
"translation": "[附录 1审查生成的运行时组件样式](guide/component-styles#inspect-generated-css)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* [Appendix 2: Loading styles with relative URLs](guide/component-styles#relative-urls)",
"translation": "[附录 2使用相对 URL 加载样式](guide/component-styles#relative-urls)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "You can run the <live-example></live-example> in Plunker and download the code from there.",
"translation": "你可以在Plunker上运行本章这些代码的<live-example></live-example>并下载这些代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "## Using component styles",
"translation": "## 使用组件样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "The selectors you put into a component's styles apply only within the template\nof that component. The `h1` selector in the preceding example applies only to the `<h1>` tag\nin the template of `HeroAppComponent`. Any `<h1>` elements elsewhere in\nthe application are unaffected.",
"translation": "我们放在组件样式中的选择器,*只会应用在组件自身的模板中*。上面这个例子中的`h1`选择器只会对\n`HeroAppComponent`模板中的`<h1>`标签生效,而对应用中其它地方的`<h1>`元素毫无影响。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "This is a big improvement in modularity compared to how CSS traditionally works.",
"translation": "这种模块化相对于 CSS 的传统工作方式是一个巨大的改进。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "* Changes to styles elsewhere in the application don't affect the component's styles.",
"translation": "我们组件的样式*不会*因为别的地方修改了样式而被意外改变。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "## Special selectors",
"translation": "## 特殊的选择器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "### :host",
"translation": "### :host 选择器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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": "这是我们能以宿主元素为目标的*唯一*方式。除此之外,我们将没办法指定它,\n因为宿主不是组件自身模板的一部分而是父组件模板的一部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "### :host-context",
"translation": "### :host-context 选择器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "### (deprecated) `/deep/`, `>>>`, and `::ng-deep`",
"translation": "### 已废弃 `/deep/`、`>>>`和`::ng-deep`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "Component styles normally apply only to the HTML in the component's own template.",
"translation": "组件样式通常只会作用于组件自身的 HTML 上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "The `/deep/` combinator also has the aliases `>>>`, and `::ng-deep`.",
"translation": "`/deep/` 组合器还有两个别名:`>>>`和`::ng-deep`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "## Loading component styles",
"translation": "## 把样式加载进组件中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "There are several ways to add styles to a component:",
"translation": "有几种方式把样式加入组件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* By setting `styles` or `styleUrls` metadata.",
"translation": "设置`styles`或`styleUrls`元数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* Inline in the template HTML.",
"translation": "内联在模板的 HTML 中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "* With CSS imports.",
"translation": "通过 CSS 文件导入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "The scoping rules outlined earlier apply to each of these loading patterns.",
"translation": "上述作用域规则对所有这些加载模式都适用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "### Styles in metadata",
"translation": "### 元数据中的样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "You can add a `styles` array property to the `@Component` decorator.\nEach string in the array (usually just one string) defines the CSS.",
"translation": "我们可以给`@Component`装饰器添加一个`styles`数组型属性。\n这个数组中的每一个字符串通常也只有一个定义一份 CSS。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "### Style URLs in metadata",
"translation": "### 元数据中指定样式表的URL",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "You can load styles from external CSS files by adding a `styleUrls` attribute\ninto a component's `@Component` decorator:",
"translation": "通过在组件的`@Component`装饰器中添加`styleUrls`属性我们可以从外部CSS文件中加载样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "The URL is relative to the *application root*, which is usually the\nlocation of the `index.html` web page that hosts the application. \nThe style file URL is *not* relative to the component file.\nThat's why the example URL begins `src/app/`.\nTo specify a URL relative to the component file, see [Appendix 2](guide/component-styles#relative-urls).",
"translation": "URL是***相对于应用程序根目录的***,它通常是应用的宿主页面`index.html`所在的地方。\n 这个样式文件的 URL *不是*相对于组件文件的。这就是为什么范例中的 URL 用`src/app/`开头。\n 参见[附录 2](guide/component-styles#relative-urls) 来了解如何指定相对于组件文件的 URL。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "If you use module bundlers like Webpack, you can also use the `styles` attribute\nto load styles from external files at build time. You could write:",
"translation": "像 Webpack 这类模块打包器的用户可能会使用`styles`属性来在构建时从外部文件中加载样式。它们可能这样写:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "Set the `styles` property, notthe `styleUrls` property. The module \nbundler loads the CSS strings, not Angular. \nAngular sees the CSS strings onlyafter the bundler loads them. \nTo Angular, it 's as if you wrote the `styles` array by hand. \nFor information on \nloading CSS in this manner, refer to the module bundler's documentation.",
"translation": "注意,这时候我们是在设置`styles`属性,**而不是**`styleUrls`属性!\n是模块打包器在加载 CSS 字符串,而不是 Angular。\nAngular 看到的只是打包器加载它们之后的 CSS 字符串。\n对 Angular 来说,这跟我们手写了`styles`数组没有任何区别。\n要了解这种 CSS 加载方式的更多信息,请参阅相应模块打包器的文档。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "### Template inline styles",
"translation": "### 模板内联样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "You can embed styles directly into the HTML template by putting them\ninside `<style>` tags.",
"translation": "我们也可以在组件的 HTML 模板中嵌入`<style>`标签。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "### Template link tags",
"translation": "### 模板中的link标签",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "You can also embed `<link>` tags into the component's HTML template.",
"translation": "我们也可以在组件的 HTML 模板中嵌入`<link>`标签。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "As with `styleUrls`, the link tag's `href` URL is relative to the \napplication root, not the component file.",
"translation": "像`styleUrls`标签一样,这个 link 标签的`href`指向的 URL 也是相对于应用的根目录的,而不是组件文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "### CSS @imports",
"translation": "### CSS @imports 语法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "## View encapsulation",
"translation": "## 控制视图的封装模式:原生 (Native)、仿真 (Emulated) 和无 (None)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "To set the components encapsulation mode, use the `encapsulation` property in the component metadata:",
"translation": "通过组件元数据中的`encapsulation`属性来设置组件封装模式:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "## Appendix: Inspecting generated CSS",
"translation": "## 附录 1查看仿真 (Emulated) 模式下生成的 CSS",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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 元素都被加上了一些额外的属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "There are two kinds of generated attributes:",
"translation": "我们看到了两种被生成的属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"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/content-1/guide/component-styles.md"
},
{
"original": "## Appendix: Loading with relative URLs",
"translation": "## 附录 2使用相对 URL 加载样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "It's common practice to split a component's code, HTML, and CSS into three separate files in the same directory:",
"translation": "把组件的代码 (ts/js)、HTML 和 CSS 分别放到同一个目录下的三个不同文件,是一个常用的实践:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "You include the template and CSS files by setting the `templateUrl` and `styleUrls` metadata properties respectively.\nBecause these files are co-located with the component,\nit would be nice to refer to them by name without also having to specify a path back to the root of the application.",
"translation": "我们会通过设置元数据的`templateUrl`和`styleUrls`属性把模板和 CSS 文件包含进来。\n既然这些文件都与组件代码文件放在一起那么通过名字而不是到应用程序根目录的全路径来指定它就会是一个漂亮的方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "You can use a relative URL by prefixing your filenames with `./`:",
"translation": "我们也可以通过为文件名加上`./`前缀来使用相对URL",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/component-styles.md"
},
{
"original": "# Dependency Injection",
"translation": "# 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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依赖注入的许多特性。\n{@a toc}",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "# Contents",
"translation": "# 目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Application-wide dependencies](guide/dependency-injection-in-action#app-wide-dependencies)",
"translation": "[应用程序全局依赖](guide/dependency-injection-in-action#app-wide-dependencies)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [External module configuration](guide/dependency-injection-in-action#external-module-configuration)",
"translation": "[外部模块配置](guide/dependency-injection-in-action#external-module-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [`@Injectable()` and nested service dependencies](guide/dependency-injection-in-action#nested-dependencies)",
"translation": "[`@Injectable()`与嵌套服务的依赖](guide/dependency-injection-in-action#nested-dependencies)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Limit service scope to a component subtree](guide/dependency-injection-in-action#service-scope)",
"translation": "[把服务作用域限制到一个子组件树](guide/dependency-injection-in-action#service-scope)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Multiple service instances (sandboxing)](guide/dependency-injection-in-action#multiple-service-instances)",
"translation": "[多个服务实例(沙箱)](guide/dependency-injection-in-action#multiple-service-instances)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Qualify dependency lookup with `@Optional()` and `@Host()`](guide/dependency-injection-in-action#qualify-dependency-lookup)",
"translation": "[使用`@Optional()`和`@Host()`装饰器来限定依赖查找方式](guide/dependency-injection-in-action#qualify-dependency-lookup)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Demonstration](guide/dependency-injection-in-action#demonstration)",
"translation": "[演示](guide/dependency-injection-in-action#demonstration)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Inject the component's DOM element](guide/dependency-injection-in-action#component-element)",
"translation": "[注入组件的DOM元素](guide/dependency-injection-in-action#component-element)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Define dependencies with providers](guide/dependency-injection-in-action#providers)",
"translation": "[使用提供商定义依赖](guide/dependency-injection-in-action#providers)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Defining providers](guide/dependency-injection-in-action#defining-providers)",
"translation": "[定义提供商](guide/dependency-injection-in-action#defining-providers)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [The *provide* object literal](guide/dependency-injection-in-action#provide)",
"translation": "[*provide* 字面量](guide/dependency-injection-in-action#provide)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [`useValue`&mdash;the *value provider*](guide/dependency-injection-in-action#usevalue)",
"translation": "[`useValue` - *值提供商*](guide/dependency-injection-in-action#usevalue)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [`useClass`&mdash;the *class provider*](guide/dependency-injection-in-action#useclass)",
"translation": "[`useClass` - *类提供商*](guide/dependency-injection-in-action#useclass)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [`useExisting`&mdash;the *alias provider*](guide/dependency-injection-in-action#useexisting)",
"translation": "[`useExisting` - *别名提供商*](guide/dependency-injection-in-action#useexisting)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [`useFactory`&mdash;the *factory provider*](guide/dependency-injection-in-action#usefactory)",
"translation": "[`useFactory` - *工厂提供商*](guide/dependency-injection-in-action#usefactory)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Provider token alternatives: the class-interface and `InjectionToken`](guide/dependency-injection-in-action#tokens)",
"translation": "[提供商可选令牌:类接口与`InjectionToken`](guide/dependency-injection-in-action#tokens)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [class-interface](guide/dependency-injection-in-action#class-interface)",
"translation": "[类-接口](guide/dependency-injection-in-action#class-interface)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Inject into a derived class](guide/dependency-injection-in-action#di-inheritance)",
"translation": "[注入到一个派生类](guide/dependency-injection-in-action#di-inheritance)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Find a parent component by injection](guide/dependency-injection-in-action#find-parent)",
"translation": "[通过注入来查找父组件](guide/dependency-injection-in-action#find-parent)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Find parent with a known component type](guide/dependency-injection-in-action#known-parent)",
"translation": "[通过已知组件类型查找父组件](guide/dependency-injection-in-action#known-parent)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Cannot find a parent by its base class](guide/dependency-injection-in-action#base-parent)",
"translation": "[无法通过自己的基类查找父组件](guide/dependency-injection-in-action#base-parent)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Find a parent by its class-interface](guide/dependency-injection-in-action#class-interface-parent)",
"translation": "[通过类-接口查找父组件](guide/dependency-injection-in-action#class-interface-parent)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Find a parent in a tree of parents with `@SkipSelf()`](guide/dependency-injection-in-action#parent-tree)",
"translation": "[在父组件树里查找一个父组件(*@SkipSelf*)](guide/dependency-injection-in-action#parent-tree)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [The `Parent` class-interface](guide/dependency-injection-in-action#parent-token)",
"translation": "[`Parent`类接口](guide/dependency-injection-in-action#parent-token)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [A `provideParent()` helper function](guide/dependency-injection-in-action#provideparent)",
"translation": "[`provideParent()`助手函数](guide/dependency-injection-in-action#provideparent)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "* [Break circularities with a forward class reference (*forwardRef*)](guide/dependency-injection-in-action#forwardref)",
"translation": "* [使用类的前向引用(*forwardRef*)打破循环依赖](guide/dependency-injection-in-action#forwardref)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Application-wide dependencies",
"translation": "## 应用程序全局依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Register providers for dependencies used throughout the application in the root application component, `AppComponent`.",
"translation": "在应用程序根组件`AppComponent`中注册那些被应用程序全局使用的依赖提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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#injector-providers)\nguide.",
"translation": "*提供商*是用来新建或者交付服务的。\nAngular拿到“类提供商”之后会通过`new`操作来新建服务实例。\n从[依赖注入](guide/dependency-injection#injector-providers)一章可以学到关于提供商的更多知识。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## External module configuration",
"translation": "## 外部模块配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Generally, register providers in the `NgModule` rather than in the root application component.",
"translation": "我们通常会在`NgModule`中注册提供商,而不是在应用程序根组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## _@Injectable()_ and nested service dependencies",
"translation": "## *@Injectable*和嵌套服务依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The following example shows injecting both the `LoggerService` and the `UserContext` in the `AppComponent`.",
"translation": "在下列例子中,我们往`AppComponent`里注入的`LoggerService`和`UserContext`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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 justuse `new` to instantiateone .",
"translation": "当Angular新建`AppComponent`时,依赖注入框架先创建一个`LoggerService`的实例,然后创建`UserContextService`实例。\n`UserContextService`需要框架已经创建好的`LoggerService`实例和尚未创建的`UserService`实例。\n`UserService`没有其它依赖,所以依赖注入框架可以直接`new`一个实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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`) and the framework does the rest.",
"translation": "依赖注入最帅的地方在于,`AppComponent`的作者不需要在乎这一切。作者只是在(`LoggerService`和`UserContextService`的)构造函数里面简单的声明一下,框架就完成了剩下的工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Once all the dependencies are in place, the `AppComponent` displays the user information:",
"translation": "一旦所有依赖都准备好了,`AppComponent`就会显示用户信息:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### *@Injectable()*",
"translation": "### *@Injectable()* 注解",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Notice the `@Injectable()`decorator on the `UserContextService` class.",
"translation": "注意在`UserContextService`类里面的`@Injectable()`装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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 of consistency and to avoid future pain.",
"translation": "但是在给它添加依赖的那一瞬间,该服务就会停止工作,要想修复它,就必须要添加`@Injectable()`。\n为了保持一致性和防止将来的麻烦推荐从一开始就加上`@Injectable()`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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&mdash;*any* decorator&mdash;is sufficient to identify dependency types.",
"translation": "`AppComponent`类有两个依赖,但它没有`@Injectable()`。\n它不需要`@Injectable()`,这是因为组件类有`@Component`装饰器。\n在用TypeScript的Angular应用里有一个*单独的*装饰器 &mdash; *任何*装饰器 &mdash; 来标识依赖的类型就够了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Limit service scope to a component subtree",
"translation": "## 把服务作用域限制到一个组件支树",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### Take a break!",
"translation": "### 休息一下!",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Multiple service instances (sandboxing)",
"translation": "## 多个服务实例(sandboxing)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Sometimes you want multiple instances of a service at *the same level of the component hierarchy*.",
"translation": "在*同一个级别的组件树*里,有时需要一个服务的多个实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Imagine a `HeroBiosComponent` that presents three instances of the `HeroBioComponent`.",
"translation": "想象一下,一个`HeroBiosComponent`组件显示三个`HeroBioComponent`的实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Qualify dependency lookup with _@Optional()_ and `@Host()`",
"translation": "## 使用*@Optional()*和`@Host()`装饰器来限定依赖查找方式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "As you now know, dependencies can be registered at any level in the component hierarchy.",
"translation": "我们知道,依赖可以被注入到任何组件级别。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The `@Host` decorator stops the upward search at the *host component*.",
"translation": "`@Host`装饰器将把往上搜索的行为截止在*宿主组件*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### Demonstration",
"translation": "### 示范",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Focus on the template:",
"translation": "注意看模板:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Here's the `HeroContactComponent` which demonstrates the qualifying decorators:",
"translation": "下面的`HeroContactComponent`,示范了限定型装饰器(@Optional和@Host)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Focus on the constructor parameters:",
"translation": "注意看构造函数的参数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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 in the component tree happens to have it.",
"translation": "`@Host()`函数是`heroCache`属性的装饰器,确保从其父组件`HeroBioComponent`得到一个缓存服务。如果该父组件不存在这个服务Angular就会抛出错误即使组件树里的再上级有某个组件拥有这个服务Angular也会抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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`的装饰器,我们知道在应用程序中,只有一个`LoggerService`实例,也就是在`AppComponent`级提供的服务。\n该宿主`HeroBioComponent`没有自己的`LoggerService`提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Here's the `HeroBiosAndContactsComponent` in action.",
"translation": "下面是`HeroBiosAndContactsComponent`的执行结果:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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)`\n{@a component-element}",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Inject the component's DOM element",
"translation": "## 注入组件的DOM元素",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Define dependencies with providers",
"translation": "## 使用提供商来定义依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "This section demonstrates how to write providers that deliver dependent services.",
"translation": "在这个部分,我们将演示如何编写提供商来提供被依赖的服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Get a service from a dependency injector by giving it a ***token***.",
"translation": "我们给依赖注入器提供***令牌***来获取服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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&mdash;unless the request was [optional](guide/dependency-injection-in-action#optional).",
"translation": "如果注入器无法根据令牌在自己内部找到对应的提供商,它便将请求移交给它的父级注入器,这个过程不断重复,直到没有更多注入器为止。\n如果没找到注入器就抛出一个错误...除非这个请求是[可选的](guide/dependency-injection-in-action#optional)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### Defining providers",
"translation": "### 定义提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The code behind it gives you plenty to think about.",
"translation": "这段代码的背后有很多值得深入思考的地方。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "#### The *provide* object literal",
"translation": "#### *provide*对象",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "#### useValue &mdash; the *value provider*",
"translation": "#### useValue - *值-提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The other providers create their values *lazily* when they're needed for injection.",
"translation": "其它提供商只在需要注入它们的时候才创建并*惰性加载*它们的值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "#### useClass &mdash; the *class provider*",
"translation": "#### useClass - *类-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The `useClass` provider creates and returns new instance of the specified class.",
"translation": "`userClass`提供商创建并返回一个指定类的新实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Here are two examples in the `HeroOfTheMonthComponent`:",
"translation": "请看下面`HeroOfTheMonthComponent`里的两个例子:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The `DateLoggerService` inherits from `LoggerService`; it appends the current date/time to each message:",
"translation": "`DateLoggerService`从`LoggerService`继承;它把当前的日期/时间附加到每条信息上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "#### _useExisting_&mdash;the *alias provider*",
"translation": "#### useExisting - *别名-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Now put it to use in a simplified version of the `HeroOfTheMonthComponent`.",
"translation": "现在,在一个简化版的`HeroOfTheMonthComponent`中使用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Behind the scenes,Angular actually sets the `logger` parameter to the full service registered under the `LoggingService` token \nwhich 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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The following image, which displays the logging date, confirms the point:",
"translation": "在下面的图片中,显示了日志日期,可以确认这一点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "#### _useFactory_&mdash; the *factory provider*",
"translation": "#### useFactory - *工厂-提供商*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The `useFactory` provider creates a dependency object by calling a factory function\nas in this example.",
"translation": "`useFactory` 提供商通过调用工厂函数来新建一个依赖对象,如下例所示。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "That returned function takes a winning `Hero` and a `HeroService` as arguments.",
"translation": "这个返回的函数需要一个`Hero`和一个`HeroService`参数。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Provider token alternatives: the *class-interface* and *InjectionToken*",
"translation": "## 备选提供商令牌:*类-接口*和*InjectionToken*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Angular dependency injection is easiest when the provider *token* is a class\nthat is also the type of the returned dependency object , orwhat you usually call the *service*.",
"translation": "Angular依赖注入当*令牌*是类的时候是最简单的,该类同时也是返回的依赖对象的类型(通常直接称之为*服务*)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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": "但令牌不一定都是类,就算它是一个类,它也不一定都返回类型相同的对象。这是下一节的主题。\n{@a class-interface}",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### class-interface",
"translation": "### 类-接口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The `MinimalLogger` is an abstract class.",
"translation": "该`MinimalLogger`是一个抽象类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "You usually inherit from an abstract class.\nBut *no class* in this application inherits from `MinimalLogger`.",
"translation": "我们通常从一个抽象类继承。但这个应用中并没有类会继承`MinimalLogger`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "#### Why *MinimalLogger* is a class and not a TypeScript interface",
"translation": "#### 为什么*MinimalLogger*是一个类而不是一个TypeScript接口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### _InjectionToken_",
"translation": "### _InjectionToken_ 值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "You created the `TITLE` token like this:",
"translation": "这样创建`TITLE`令牌:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Inject into a derived class",
"translation": "## 注入到派生类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "In this contrived example, `SortedHeroesComponent` inherits from `HeroesBaseComponent` \nto display a *sorted* list of heroes.",
"translation": "在这个刻意生成的例子里,`SortedHeroesComponent`继承自`HeroesBaseComponent`,显示一个*被排序*的英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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这就是为什么我们要在`ngOnInit`里面调用`HeroService`,而不是在构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Overriding the base class's `afterGetHeroes()` method solves the problem.",
"translation": "覆盖基类的`afterGetHeroes()`方法可以解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "These complications argue for *avoiding component inheritance*.",
"translation": "分析上面的这些复杂性是为了强调*避免使用组件继承*这一点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Find a parent component by injection",
"translation": "## 通过注入来找到一个父组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "This section describes some techniques for doing that.",
"translation": "本章节描述了这项技术。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### Find a parent component of known type",
"translation": "### 找到已知类型的父组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "You use standard class injection to acquire a parent component whose type you know.",
"translation": "我们使用标准的类注入来获取已知类型的父组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "In the following example, the parent `AlexComponent` has several children including a `CathyComponent`:",
"translation": "在下面的例子中,父组件`AlexComponent`有几个子组件,包括`CathyComponent`:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### Cannot find a parent by its base class",
"translation": "### 无法通过它的基类找到一个父级",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "What if you *don't* know the concrete parent component class?",
"translation": "如果*不*知道具体的父组件类名怎么办?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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]{#alex},我们看到`Alex`组件*扩展*(*派生*)自一个叫`Base`的类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### Find a parent by its class-interface",
"translation": "### 通过类-接口找到父组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Write an [*alias provider*](guide/dependency-injection-in-action#useexisting)&mdash;a `provide` object literal with a `useExisting`\ndefinition&mdash;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`函数 &mdash;\n它新建一个*备选的*方式来注入同一个组件实例,并把这个提供商添加到`AlexComponent`的`@Component`元数据里的`providers`数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Alex* and family in action:",
"translation": "下面是*Alex*和其家庭的运行结果:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### Find the parent in a tree of parentswith _@SkipSelf()_",
"translation": "### 通过父级树找到父组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Imagine one branch of a component hierarchy: *Alice* -> *Barry* -> *Carol*. \nBoth *Alice* and *Barry* implement the `Parent` *class-interface*.",
"translation": "想象组件树中的一个分支为:*Alice* -> *Barry* -> *Carol*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Barry*:",
"translation": "下面是*Barry*的代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "For now, focus on *Barry*'s constructor:",
"translation": "眼下,请注意*Barry*的构造函数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "It's identical to *Carol*'s constructor except for the additional `@SkipSelf` decorator.",
"translation": "除额外添加了一个的`@SkipSelf`外,它和*Carol*的构造函数一样。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "`@SkipSelf` is essential for two reasons:",
"translation": "添加`@SkipSelf`主要是出于两个原因:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "2. Angular throws a cyclic dependency error if you omit the `@SkipSelf` decorator.",
"translation": "如果没写`@SkipSelf`装饰器的话Angular就会抛出一个循环依赖错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "`Cannot instantiate cyclic dependency! (BethComponent -> Parent -> BethComponent)`",
"translation": "`不能创建循环依赖实例!(BethComponent -> Parent -> BethComponent)`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Here's *Alice*, *Barry* and family in action:",
"translation": "这里是*Alice**Barry*和该家庭的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### The *Parent* class-interface",
"translation": "### *Parent*类-接口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The example defines a `Parent` *class-interface*.",
"translation": "我们的例子定义了一个`Parent`*类-接口*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "### A _provideParent()_ helper function",
"translation": "### *provideParent()*助手函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "You can extract that logic into a helper function like this:",
"translation": "可以像这样把该逻辑抽取到一个助手函数里:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Now you can add a simpler, more meaningful parent provider to your components:",
"translation": "现在就可以为组件添加一个更简单、直观的父级提供商了:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "And here's how you could use it with a different parent type:",
"translation": "下面的代码演示了如何使它添加一个不同类型的父级:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "## Break circularities with a forward class reference (*forwardRef*)",
"translation": "## 使用一个前向引用(*forwardRef*)来打破循环",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The Angular `forwardRef()` function creates an *indirect* reference that Angular can resolve later.",
"translation": "Angular的`forwardRef()`函数建立一个*间接地*引用Angular可以随后解析。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "The *Parent Finder* sample is full of circular class references that are impossible to break.",
"translation": "*Parent Finder*是一个充满了无法解决的循环引用的例子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"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/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "Break the circularity with `forwardRef`:",
"translation": "我们使用`forwardRef`来打破这种循环:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection-in-action.md"
},
{
"original": "# Dependency Injection",
"translation": "# 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "**Dependency injection** is an important application design pattern.\nAngular has its own dependency injection framework, and\nyou really can't build an Angular application without it.\nIt's used so widely that almost everyone just calls it _DI_.",
"translation": "**依赖注入**是重要的程序设计模式。\n Angular 有自己的依赖注入框架,离开了它,几乎没法构建 Angular 应用。\n 它使用得非常广泛,以至于几乎每个人都会把它简称为 _DI_。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "This page covers what DI is, why it's so useful,\nand [how to use it](guide/dependency-injection#angular-di) in an Angular app.",
"translation": "本章将学习什么是 DI它有什么用。\n 然后,将学习在 Angular 应用中该[如何使用它](guide/dependency-injection#angular-di)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Run the <live-example></live-example>.",
"translation": "运行<live-example></live-example>.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a why-di }",
"translation": "## Why dependency injection?\n## 为什么需要依赖注入?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "The `Car` class creates everything it needs inside its constructor.\nWhat's the problem?",
"translation": "`Car`类会在它的构造函数中创建所需的每样东西。\n问题何在",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The problem is that the `Car` class is brittle, inflexible, and hard to test.",
"translation": "问题在于,这个`Car`类过于脆弱、缺乏弹性并且难以测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "How can you make `Car` more robust, flexible, and testable?",
"translation": "该如何让`Car`更强壮、有弹性以及可测试?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a ctor-injection}\nThat's super easy. Change the `Car` constructor to a version with DI:",
"translation": "{@a ctor-injection}\n答案非常简单。把`Car`的构造函数改造成使用 DI 的版本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "This example leverages TypeScript's constructor syntax for declaring\nparameters and properties simultaneously.",
"translation": "这个例子又一次借助 TypeScript 的构造器语法来同时定义参数和属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Now you can create a car by passing the engine and tires to the constructor.",
"translation": "现在,通过往构造函数中传入引擎和轮胎来创建一辆车。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Now, if someone extends the `Engine` class, that is not `Car`'s problem.",
"translation": "这样一来,如果有人扩展了`Engine`类,那就不再是`Car`类的烦恼了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "**You just learned what dependency injection is**.",
"translation": "**刚刚学习了什么是依赖注入**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "You _could_ write a giant class to do that:",
"translation": "可以写一个巨型类来做这件事:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "This is what a **dependency injection framework** is all about.",
"translation": "这就是“**依赖注入框架**”存在的原因。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Now that you know what dependency injection is and appreciate its benefits,\nread on to see how it is implemented in Angular.",
"translation": "现在,我们知道了什么是依赖注入,以及它的优点。再来看看它在 Angular 中是怎么实现的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a angular-di}",
"translation": "## Angular dependency injection\n## Angular 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Angular ships with its own dependency injection framework. This framework can also be used\nas a standalone module by other applications and frameworks.",
"translation": "Angular 附带了自己的依赖注入框架。此框架也能被当做独立模块用于其它应用和框架中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "To see what it can do when building components in Angular,\nstart with a simplified version of the `HeroesComponent`\nthat from the [The Tour of Heroes](tutorial/).",
"translation": "要了解Angular构建组件时注入器做了什么我们先从[英雄指南](tutorial/)中构建的`HeroesComponent`的简化版本开始。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The `HeroesComponent` is the root component of the *Heroes* feature area.\nIt governs all the child components of this area.\nThis stripped down version has only one child, `HeroListComponent`,\nwhich displays a list of heroes.",
"translation": "`HeroesComponent`是*英雄*特性区域的根组件。它管理区域内所有子组件。\n简化后的版本只有一个子组件`HeroListComponent`,用来显示英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Right now `HeroListComponent` gets heroes from `HEROES`, an in-memory collection\ndefined in another file.\nThat may suffice in the early stages of development, but it's far from ideal.\nAs soon as you try to test this component or want to get your heroes data from a remote server,\nyou'll have to change the implementation of `heroes` and\nfix every other use of the `HEROES` mock data.",
"translation": "现在`HeroListComponent`从`HEROES`获得英雄数据,是在另一个文件中定义的内存数据集。\n 它在开发的早期阶段可能还够用,但离完美就差得远了。\n 一旦开始测试此组件,或者想从远端服务器获得英雄数据,就不得不修改`heroes`的实现,\n 还要修改每个用到了`HEROES`模拟数据的地方。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "It's better to make a service that hides how the app gets hero data.",
"translation": "最好用一个服务把获取英雄数据的代码封装起来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Given that the service is a\n[separate concern](https://en.wikipedia.org/wiki/Separation_of_concerns),\nconsider writing the service code in its own file.",
"translation": "因为服务是一个[分离关注点](https://en.wikipedia.org/wiki/Separation_of_concerns)\n 建议你把服务代码放到它自己的文件里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "See [this note](guide/dependency-injection#one-class-per-file) for details.",
"translation": "参阅[这一条](guide/dependency-injection#one-class-per-file)来了解详情。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The following `HeroService` exposes a `getHeroes` method that returns\nthe same mock data as before, but none of its consumers need to know that.",
"translation": "`HeroService`暴露了`getHeroes`方法,返回跟以前一样的模拟数据,但它的消费者不需要知道这一点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The `@Injectable()` decorator above the service class is\ncovered [shortly](guide/dependency-injection#injectable).",
"translation": "注意服务类上面这个`@Injectable()`装饰器。[很快](guide/dependency-injection#injectable)会讨论它的用途。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Of course, this isn't a real service.\nIf the app were actually getting data from a remote server, the API would have to be\nasynchronous, perhaps returning a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).\nYou'd also have to rewrite the way components consume the service.\nThis is important in general, but not in this example.",
"translation": "我们甚至没有假装这是一个真实的服务。\n如果真的从远端服务器获取数据这个 API 必须是异步的,可能得返回\n[ES2015 承诺 (promise)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)。\n需要重新处理组件消费该服务的方式。通常这个很重要但是目前的故事不需要。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "A service is nothing more than a class in Angular.\nIt remains nothing more than a class until you register it with an Angular injector.",
"translation": "服务只是 Angular 中的一个类。\n有 Angular 注入器注册它之前,没有任何特别之处。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a injector-config}",
"translation": "### Configuring the injector\n### 配置注入器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You don't have to create an Angular injector.\nAngular creates an application-wide injector for you during the bootstrap process.",
"translation": "不需要创建 Angular 注入器。\nAngular 在启动过程中自动为我们创建一个应用级注入器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You do have to configure the injector by registering the **providers**\nthat create the services the application requires.\nThis guide explains what [providers](guide/dependency-injection#providers) are later.",
"translation": "我们必须通过注册**提供商 (provider)** 来配置注入器,这些提供商为应用创建所需服务。\n 在本章的稍后部分会解释什么是[提供商](guide/dependency-injection#providers)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You can either register a provider within an [NgModule](guide/ngmodule) or in application components.",
"translation": "或者在 [NgModule](guide/ngmodule) 中注册提供商,或者在应用组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "### Registering providers in an _NgModule_",
"translation": "### 在_NgModule_中注册提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Here's the `AppModule` that registers two providers, `UserService` and an `APP_CONFIG` provider,\nin its `providers` array.",
"translation": "在`AppModule`的`providers`中注册了两个提供商,`UserService`和`APP_CONFIG`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Because the `HeroService` is used _only_ within the `HeroesComponent`\nand its subcomponents, the top-level `HeroesComponent` is the ideal\nplace to register it.",
"translation": "由于`HeroService`*只*会在`HeroesComponent`及其子组件中使用,所以顶层组件`HeroesComponent`是一个合理的注册位置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "### Registering providers in a component",
"translation": "### 在组件中注册提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Here's a revised `HeroesComponent` that registers the `HeroService` in its `providers` array.",
"translation": "下面是更新的`HerosComponent`,把`HeroService`注册到了它的`providers`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "### When to use _NgModule_ versus an application component",
"translation": "### 该用 NgModule 还是应用组件?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "On the one hand, a provider in an `NgModule` is registered in the root injector. That means that every provider\nregistered within an `NgModule` will be accessible in the _entire application_.",
"translation": "一方面NgModule 中的提供商是被注册到根注入器。这意味着在 NgModule 中注册的提供商可以被整个应用访问。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "On the other hand, a provider registered in an application component is available only on that component and all its children.",
"translation": "另一方面,在应用组件中注册的提供商只在该组件及其子组件中可用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Here, the `APP_CONFIG` service needs to be available all across the application, so it's\nregistered in the `AppModule` `@NgModule` `providers` array.\nBut since the `HeroService` is only used within the *Heroes*\nfeature area and nowhere else, it makes sense to register it in\nthe `HeroesComponent`.",
"translation": "这里,`APP_CONFIG`服务需要在应用中到处可用,所以它被注册到了`AppModule` `@NgModule`的`providers`数组。\n但是由于`HeroService`只在*英雄*特性区用到了,其它地方没有用过,因此在`HeroesComponent`中注册它是有道理的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Also see *\"Should I add app-wide providers to the root `AppModule` or the root `AppComponent`?\"* in the [NgModule FAQ](guide/ngmodule-faq#q-root-component-or-module).",
"translation": "参见 [NgModule FAQ](guide/ngmodule-faq#q-root-component-or-module) 一章的\n **我该把“全应用级”提供商加到根模块`AppModule`还是根组件`AppComponent`**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a prep-for-injection}",
"translation": "### Preparing the _HeroListComponent_ for injection\n### 为注入准备`HeroListComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The `HeroListComponent` should get heroes from the injected `HeroService`.\nPer the dependency injection pattern, the component must ask for the service in its\nconstructor, [as discussed earlier](guide/dependency-injection#ctor-injection).\nIt's a small change:",
"translation": "`HeroListComponent`应该从注入的`HeroService`获取英雄数据。\n遵照依赖注入模式的要求组件必须在它的构造函数中请求这些服务[就像以前解释过的那样](guide/dependency-injection#ctor-injection)。\n只是个小改动",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Adding a parameter to the constructor isn't all that's happening here.",
"translation": "往构造函数中添加参数并不是这里所发生的一切。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Note that the constructor parameter has the type `HeroService`, and that\nthe `HeroListComponent` class has an `@Component` decorator\n(scroll up to confirm that fact).\nAlso recall that the parent component (`HeroesComponent`)\nhas `providers` information for `HeroService`.",
"translation": "注意,构造函数参数的类型是`HeroService`,并且`HeroListComponent`类有一个`@Component`装饰器\n往上翻可以确认。另外记得父级组件 (`HeroesComponent`) 有`HeroService`的`providers`信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The constructor parameter type, the `@Component` decorator,\nand the parent's `providers` information combine to tell the\nAngular injector to inject an instance of\n`HeroService` whenever it creates a new `HeroListComponent`.",
"translation": "构造函数参数类型、`@Component`装饰器和父级的`providers`信息合起来告诉 Angular 的注入器,\n任何新建`HeroListComponent`的时候,注入一个`HeroService`的实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "### Implicit injector creation",
"translation": "### 隐式注入器的创建",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You saw how to use an injector to create a new\n`Car` earlier in this guide.\nYou _could_ create such an injector\nexplicitly:",
"translation": "本章前面的部分我们看到了如何使用注入器来创建一个新`Car`。\n你可以像这样显式创建注入器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You won't find code like that in the Tour of Heroes or any of the other\ndocumentation samples.\nYou *could* write code that [explicitly creates an injector](guide/dependency-injection#explicit-injector) if you *had* to,\nbut it's not always the best choice.\nAngular takes care of creating and calling injectors\nwhen it creates components for you&mdash;whether through HTML markup, as in `<hero-list></hero-list>`,\nor after navigating to a component with the [router](guide/router).\nIf you let Angular do its job, you'll enjoy the benefits of automated dependency injection.",
"translation": "无论在《英雄指南》还是其它范例中,都没有出现这样的代码。\n在必要时*可以*写[使用显式注入器的代码](guide/dependency-injection#explicit-injector),但却很少这样做。\n当 Angular 创建组件时 —— 无论通过像`<hero-list></hero-list>`这样的 HTML 标签还是通过[路由](guide/router)导航到组件 —— 它都会自己管理好注入器的创建和调用。\n只要让 Angular 做好它自己的工作,我们就能安心享受“自动依赖注入”带来的好处。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a singleton-services}",
"translation": "### Singleton services\n### 单例服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Dependencies are singletons within the scope of an injector.\nIn this guide's example, a single `HeroService` instance is shared among the\n`HeroesComponent` and its `HeroListComponent` children.",
"translation": "在一个注入器的范围内,依赖都是单例的。\n在这个例子中`HeroesComponent`和它的子组件`HeroListComponent`共享同一个`HeroService`实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "However, Angular DI is a hierarchical injection\nsystem, which means that nested injectors can create their own service instances.\nFor more information, see [Hierarchical Injectors](guide/hierarchical-dependency-injection).",
"translation": "然而Angular DI 是一个分层的依赖注入系统,这意味着嵌套的注入器可以创建它们自己的服务实例。\n要了解更多知识参见[多级依赖注入器](guide/hierarchical-dependency-injection)一章。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a testing-the-component}",
"translation": "### Testing the component\n### 测试组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Learn more in [Testing](guide/testing).",
"translation": "要学习更多知识,参见[测试](guide/testing)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a service-needs-service}",
"translation": "### When the service needs a service\n### 当服务需要别的服务时",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The `HeroService` is very simple. It doesn't have any dependencies of its own.",
"translation": "这个`HeroService`非常简单。它本身不需要任何依赖。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Here is the revision compared to the original.",
"translation": "下面是在原来的基础上所做的修改:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The constructor now asks for an injected instance of a `Logger` and stores it in a private property called `logger`.\nYou call that property within the `getHeroes()` method when anyone asks for heroes.",
"translation": "现在,这个构造函数要求注入一个`Logger`类的实例,并把它存到名为`logger`的私有属性中。\n 当别人请求英雄数据时,在`getHeroes()`方法中调用这个属性的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "### Why _@Injectable()_?",
"translation": "### 为什么要用 _@Injectable()_?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "**[@Injectable()](api/core/Injectable)** marks a class as available to an\ninjector for instantiation. Generally speaking, an injector reports an\nerror when trying to instantiate a class that is not marked as\n`@Injectable()`.",
"translation": "**<a href=\"../api/core/Injectable\">@Injectable()</a>** 标识一个类可以被注入器实例化。\n 通常,在试图实例化没有被标识为`@Injectable()`的类时,注入器会报错。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "As it happens, you could have omitted `@Injectable()` from the first\nversion of `HeroService` because it had no injected parameters.\nBut you must have it now that the service has an injected dependency.\nYou need it because Angular requires constructor parameter metadata\nin order to inject a `Logger`.",
"translation": "碰巧,第一版的`HeroService`省略了`@Injectable()`,那因为它没有注入的参数。\n 但是现在必须要有它,因为服务有了一个注入的依赖。\n 我们需要它,因为 Angular 需要构造函数参数的元数据来注入一个`Logger`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Suggestion: add @Injectable() to every service class",
"translation": "建议:为每个服务类都添加 @Injectable()",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Consider adding `@Injectable()` to every service class, even those that don't have dependencies\nand, therefore, do not technically require it. Here's why:",
"translation": "建议为每个服务类都添加`@Injectable()`,包括那些没有依赖严格来说并不需要它的。因为:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "<b>Future proofing:</b> No need to remember <code>@Injectable()</code> when you add a dependency later.",
"translation": "<b>面向未来:</b> 没有必要记得在后来添加依赖的时候添加 <code>@Injectable()</code>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "<b>Consistency:</b> All services follow the same rules, and you don't have to wonder why a decorator is missing.",
"translation": "<b>一致性:</b>所有的服务都遵循同样的规则,不需要考虑为什么某个地方少了一个。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Injectors are also responsible for instantiating components\nlike `HeroesComponent`. So why doesn't `HeroesComponent` have\n`@Injectable()`?",
"translation": "注入器同时负责实例化像`HerosComponent`这样的组件。为什么不标记`HerosComponent`为`@Injectable()`呢?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You *can* add it if you really want to. It isn't necessary because the\n`HeroesComponent` is already marked with `@Component`, and this\ndecorator class (like `@Directive` and `@Pipe`, which you learn about later)\nis a subtype of [@Injectable()](api/core/Injectable). It is in\nfact `@Injectable()` decorators that\nidentify a class as a target for instantiation by an injector.",
"translation": "我们**可以**添加它。但是没有必要,因为`HerosComponent`已经有`@Component`装饰器了,\n `@Component`(和随后将会学到的`@Directive`和`@Pipe`一样)是 <a href=\"../api/core/Injectable\">Injectable</a> 的子类型。\n 实际上,正是这些`@Injectable()`装饰器是把一个类标识为注入器实例化的目标。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "At runtime, injectors can read class metadata in the transpiled JavaScript code\nand use the constructor parameter type information\nto determine what things to inject.",
"translation": "在运行时,注入器可以从编译后的 JavaScript 代码中读取类的元数据,\n并使用构造函数的参数类型信息来决定注入什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Not every JavaScript class has metadata.\nThe TypeScript compiler discards metadata by default.\nIf the `emitDecoratorMetadata` compiler option is true \n(as it should be in the `tsconfig.json`),\nthe compiler adds the metadata to the generated JavaScript \nfor _every class with at least one decorator_.",
"translation": "不是每一个 JavaScript 类都有元数据。\nTypeScript 编译器默认忽略元数据。\n如果`emitDecoratorMetadata`编译器选项为`true`(在`tsconfig.json`中它应该为`true`\n编译器就会在生成的 JavaScript 中为_每一个至少拥有一个装饰器的类_添加元数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "While any decorator will trigger this effect, mark the service class with the\n[@Injectable()](api/core/Injectable) decorator\nto make the intent clear.",
"translation": "当然,任何装饰器都会触发这个效果,用 <a href=\"../api/core/Injectable\">@Injectable()</a> 来标识服务\n只是为了让这一意图更明显。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Always include the parentheses",
"translation": "别忘了带括号",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Always write `@Injectable()`, not just `@Injectable`.\nThe application will fail mysteriously if you forget the parentheses.",
"translation": "总是使用`@Injectable()`的形式,不能只用`@Injectable`。\n如果忘了括号应用就会神不知鬼不觉的失败",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "## Creating and registering a logger service",
"translation": "## 创建和注册日志服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Inject a logger into `HeroService` in two steps:",
"translation": "要把日志服务注入到`HeroService`中需要两步:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "1. Create the logger service.",
"translation": "创建日志服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "1. Register it with the application.",
"translation": "把它注册到应用中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The logger service is quite simple:",
"translation": "这个日志服务很简单:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You're likely to need the same logger service everywhere in your application,\nso put it in the project's `app` folder and\nregister it in the `providers` array of the application module, `AppModule`.",
"translation": "应用的每个角落都可能需要日志服务,所以把它放到项目的`app`目录,\n并在应用模块`AppModule`的元数据`providers`数组里注册它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "If you forget to register the logger, Angular throws an exception when it first looks for the logger:",
"translation": "如果忘了注册这个日志服务Angular 会在首次查找这个日志服务时,抛出一个异常。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "That's Angular telling you that the dependency injector couldn't find the *provider* for the logger.\nIt needed that provider to create a `Logger` to inject into a new\n`HeroService`, which it needed to\ncreate and inject into a new `HeroListComponent`.",
"translation": "Angular 告诉我们,依赖注入器找不到日志服务的*提供商*。\n在创建`HeroListComponent`的新实例时需要创建并注入`HeroService`\n而`HeroService`需要创建并注入一个`Logger`实例,\nAngular 需要这个`Logger`实例的提供商来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The chain of creations started with the `Logger` provider. *Providers* are the subject of the next section.",
"translation": "这个“创建链”始于`Logger`的提供商。这个*提供商*就是下一节的主题 。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "{@a providers}",
"translation": "## Injector providers\n## 注入器的提供商们",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "A 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 and other services.",
"translation": "提供商*提供*依赖值的一个具体的、运行时的版本。\n注入器依靠**提供商**创建服务的实例,注入器再将服务的实例注入组件或其它服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You must register a service *provider* with the injector, or it won't know how to create the service.",
"translation": "必须为注入器注册一个服务的*提供商*,否则它不知道该如何创建该服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Earlier you registered the `Logger` service in the `providers` array of the metadata for the `AppModule` like this:",
"translation": "我们在前面通过`AppModule`元数据中的`providers`数组注册过`Logger`服务,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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.\nBut it's not the only way.",
"translation": "有很多方式可以*提供*一些实现 `Logger`类的东西。\n `Logger`类本身是一个显而易见而且自然而然的提供商。\n 但它不是唯一的选项。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "### The *Provider* class and _provide_ object literal",
"translation": "### *Provider*类和一个提供商的字面量",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "You wrote the `providers` array like this:",
"translation": "像下面一样写`providers`数组:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "The first is the [token](guide/dependency-injection#token) that serves as the key for both locating a dependency value\nand registering the provider.",
"translation": "第一个是[令牌 (token)](guide/dependency-injection#token),它作为键值 (key) 使用,用于定位依赖值和注册提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The second is 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/content-1/guide/dependency-injection.md"
},
{
"original": "### Alternative class providers",
"translation": "### 备选的类提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "### Class provider with dependencies",
"translation": "### 带依赖的类提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Configure it like `BetterLogger`.",
"translation": "就像之前在`BetterLogger`中那样配置它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "### Aliased class providers",
"translation": "### 别名类提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "The solution: alias with the `useExisting` option.",
"translation": "解决方案:使用`useExisting`选项指定别名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "### Value providers",
"translation": "### 值提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "### Factory providers",
"translation": "### 工厂提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Suppose also that the injectable service has no independent access to the source of this information.",
"translation": "还假设这个可注入的服务没法通过独立的源访问此信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "This situation calls for a **factory provider**.",
"translation": "这种情况下,请调用**工厂提供商**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Instead, the `HeroService` constructor takes a boolean flag to control display of secret heroes.",
"translation": "让`HeroService`的构造函数带上一个布尔型的标志,来控制是否显示隐藏的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "A factory provider needs a factory function:",
"translation": "工厂提供商需要一个工厂方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Although the `HeroService` has no access to the `UserService`, the factory function does.",
"translation": "虽然`HeroService`不能访问`UserService`,但是工厂方法可以。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "{@a token}",
"translation": "## Dependency injection tokens\n## 依赖注入令牌",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "This is especially convenient when you consider that most dependency values are provided by classes.",
"translation": "这是一个特殊的规约,因为大多数依赖值都是以类的形式提供的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "### Non-class dependencies",
"translation": "### 非类依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "What if the dependency value isn't a class? Sometimes the thing you want to inject is a\n string, function, or object.",
"translation": "如果依赖值不是一个类呢?有时候想要注入的东西是一个字符串,函数或者对象。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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)\n but these configuration objects aren't always instances of a class.\n They can be object literals such as this one:",
"translation": "应用程序经常为很多很小的因素定义配置对象例如应用程序的标题或网络API终点的地址。\n 但是这些配置对象不总是类的实例,它们可能是对象,如下面这个:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "### TypeScript interfaces aren't valid tokens",
"translation": "### TypeScript 接口不是一个有效的令牌",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "The `HERO_DI_CONFIG` constant has an interface, `AppConfig`. Unfortunately, you\ncannot use a TypeScript interface as a token:",
"translation": "`CONFIG`常量有一个接口:`AppConfig`。不幸的是,不能把 TypeScript 接口用作令牌:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "### _InjectionToken_",
"translation": "### _InjectionToken_ 值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Register the dependency provider using the `InjectionToken` object:",
"translation": "使用这个`InjectionToken`对象注册依赖的提供商:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Alternatively, you can provide and inject the configuration object in an ngModule like `AppModule`.",
"translation": "或者在 ngModule 中提供并注入这个配置对象,如`AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "</div>",
"translation": "## Optional dependencies\n## 可选依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "{@a explicit-injector}",
"translation": "## Appendix: Working with injectors directly\n## 附录:直接使用注入器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "Developers rarely work directly with an injector, but\nhere's an `InjectorComponent` that does.",
"translation": "这里的`InjectorComponent`直接使用了注入器,\n但我们很少直接使用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "An `Injector` is itself an injectable service.",
"translation": "`Injector`本身是可注入的服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"original": "Framework developers may take this approach when they\nmust acquire services generically and dynamically.",
"translation": "框架开发人员必须采用通用的或者动态的方式获取服务时,可能采用这个方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "## Appendix: Why have one class per file",
"translation": "## 附录:为什么建议每个文件只放一个类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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/content-1/guide/dependency-injection.md"
},
{
"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).\nBut why flirt with trouble?\nAvoid the problem altogether by defining components and services in separate files.",
"translation": "在`forwardRef()`方法的帮助下,实际上也可以先定义组件,\n具体说明见这篇[博客](http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html)。\n但是为什么要先给自己找麻烦呢\n还是通过在独立的文件中定义组件和服务完全避免此问题吧。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dependency-injection.md"
},
{
"original": "# Deployment",
"translation": "# 部署",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "This page describes tools and techniques for deploy and optimize your Angular application.",
"translation": "本章会描述部署和优化Angular应用的工具与技术。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "## Overview",
"translation": "## 概览",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "This guide describes techniques for preparing and deploying an Angular application to a server running remotely.\nThe techniques progress from _easy but suboptimal_ to _more optimal and more involved_.",
"translation": "本章描述把Angular应用发布到远端服务器时所需的准备与部署技术。从*简单却未优化*的版本到*充分优化但涉及更多知识*的版本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* The [simple way](guide/deployment#dev-deploy \"Simplest deployment possible\") is to copy the development environment to the server.",
"translation": "[最简单的方式](guide/deployment#dev-deploy \"Simplest deployment possible\")只是把文件拷贝到服务器上的部署环境",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* [_Ahead of Time_ compilation (AOT)](guide/deployment#aot \"AOT Compilation\") is the first of\n[several optimization strategies](guide/deployment#optimize).\nYou'll also want to read the [detailed instructions in the AOT Cookbook](guide/aot-compiler \"AOT Cookbook\").",
"translation": "[*预编译*(AOT)](guide/deployment#aot \"AOT Compilation\")是第一种[优化策略](guide/deployment#optimize)。\n详情参见[烹饪宝典中的AOT章节](guide/aot-compiler \"AOT Cookbook\")。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* [Webpack](guide/deployment#webpack \"Webpack Optimization\") is a popular general purpose packaging tool with a rich ecosystem, including plugins for AOT.\nThe Angular [webpack guide](guide/webpack \"Webpack: an introduction\") can get you started and\n_this_ page provides additional optimization advice, but you'll probably have to learn more about webpack on your own.",
"translation": "[Webpack](guide/deployment#webpack \"Webpack Optimization\")是具有完善生态系统的常用通用打包工具包括为AOT准备的插件。\n 你可以从[Webpack章](guide/webpack \"Webpack: an introduction\")开始它提供了更多优化建议但是你可能要自己去学习更多Webpack的知识。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* The [Angular configuration](guide/deployment#angular-configuration \"Angular configuration\") section calls attention to\nspecific client application changes that could improve performance.",
"translation": "[Angular配置](guide/deployment#angular-configuration \"Angular configuration\")一节专注于如何修改应用程序来提高性能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* The [Server configuration](guide/deployment#server-configuration \"Server configuration\") section describes\nserver-side changes that may be necessary, _no matter how you deploy the application_.",
"translation": "[服务端配置](guide/deployment#server-configuration \"Server configuration\")一节描述了服务端的修改,*无论我们打算如何部署本应用*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "## Simplest deployment possible",
"translation": "## 最简化的部署方式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "The simplest way to deploy the app is to publish it to a web server\ndirectly out of the development environment.",
"translation": "部署应用最简化的方式是直接把它发布到开发环境之外的Web服务器上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "It's already running locally. You'll just copy it, almost _as is_,\nto a non-local server that others can reach.",
"translation": "它已经在本地运行过了。我们基本上只要把它原封不动的复制到别人能访问到的非本地服务器上就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. Copy _everything_ (or [_almost_ everything](guide/deployment#node-modules \"Loading npm packages from the web\"))\nfrom the local project folder to a folder on the server.",
"translation": "把一切文件(或[*几乎*一切文件](guide/deployment#node-modules \"Loading npm packages from the web\"))从本地项目目录下复制到服务器的目录下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. If you're serving the app out of a subfolder,\nedit a version of `index.html` to set the `<base href>` appropriately.\nFor example, if the URL to `index.html` is `www.mysite.com/my/app/`, set the _base href_ to\n`<base href=\"/my/app/\">`.\nOtherwise, leave it alone.\n[More on this below](guide/deployment#base-tag).",
"translation": "如果准备把该应用放在子目录下,就要编辑`index.html`,并适当设置`<base href>`。\n 比如,如果到`index.html`的URL是`www.mysite.com/my/app/`,就把*基地址*设置为`<base href=\"/my/app/\">`。如果是放在根路径下就不用动它。\n 详情参见[稍后](guide/deployment#base-tag)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. Configure the server to redirect requests for missing files to `index.html`.\n[More on this below](guide/deployment#fallback).",
"translation": "把服务器上缺失的文件重定向到`index.html`,详情参见[稍后](guide/deployment#fallback)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. Enable production mode as [described below](guide/deployment#enable-prod-mode) (optional).",
"translation": "按照[稍后](guide/deployment#enable-prod-mode)的描述启用生产模式(可选)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "That's the simplest deployment you can do.",
"translation": "这就是最简化的部署方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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.\nBe sure to read about [optimizing for production](guide/deployment#optimize \"Optimizing for production\") below.",
"translation": "这不是生产级部署。它没有优化过,并且对用户来说也不够快。\n但是当你向经理、团队成员或其它利益相关者内部分享你的进度和想法时它是足够的。\n一定要读读稍后的[为生产环境优化](guide/deployment#optimize \"Optimizing for production\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### Load npm package files from the web (SystemJS)",
"translation": "### 从Web上加载npm包SystemJS",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "The `node_modules` folder of _npm packages_ contains much more code\nthan is needed to actually run your app in the browser.\nThe `node_modules` for the Quickstart installation is typically 20,500+ files and 180+ MB.\nThe application itself requires a tiny fraction of that to run.",
"translation": "`node_modules`文件夹包含着在浏览器中运行应用时所需的更多代码。\n\"快速上手\"项目中所需的`node_modules`通常由20,500+个文件和180+ MB的体积。\n运行应用时其实只需要其中很小的一部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "It takes a long time to upload all of that useless bulk and\nusers will wait unnecessarily while library files download piecemeal.",
"translation": "上传这些不需要的文件需要很长时间,而在库的下载期间,用户得进行不必要的等待。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Load the few files you need from the web instead.",
"translation": "我们可以转而从网上下载所需的这少量文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "(1) Make a copy of `index.html` for deployment and replace all `node_module` scripts\nwith versions that load from the web. It might look like this.",
"translation": "(1) 复制一份专用于部署的`index.html`,并把所有的`node_module`脚本替换成加载网上的版本。代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "(2) Replace the `systemjs.config.js` script with a script that\nloads `systemjs.config.server.js`.",
"translation": "(2) 把`systemjs.config.js`脚本改为加载`systemjs.config.server.js`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "(3) Add `systemjs.config.server.js` (shown in the code sample below) to the `src/` folder.\nThis alternative version configures _SystemJS_ to load _UMD_ versions of Angular\n(and other third-party packages) from the web.",
"translation": "(3) 把 `systemjs.config.server.js`(稍后有代码)复制到`src/`文件夹。\n这个版本会从网上加载Angular的*UMD*版本(和其它第三方包)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Modify `systemjs.config.server.js` as necessary to stay in sync with changes\nyou make to `systemjs.config.js`.",
"translation": "把对`systemjs.config.js`的修改也随时同步到`systemjs.config.server.js`文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Notice the `paths` key:",
"translation": "注意`paths`属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "In the standard SystemJS config, the `npm` path points to the `node_modules/`.\nIn this server config, it points to\n<a href=\"https://unpkg.com/\" title=\"unpkg.com\">https://unpkg.com</a>,\na site that hosts _npm packages_,\nand loads them from the web directly.\nThere are other service providers that do the same thing.",
"translation": "在标准的SystemJS配置中`npm`路径指向`node_modules/`。\n在服务器端的配置中它指向<a href=\"https://unpkg.com/\" target=\"_blank\" title=\"unpkg.com\">https://unpkg.com</a>(一个专门存放*npm包*的服务器),\n并从网上直接加载它们。\n还有另一些服务提供商做同样的事。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "If you are unwilling or unable to load packages from the open web,\nthe inventory in `systemjs.config.server.js` identifies the files and folders that\nyou would copy to a library folder on the server.\nThen change the config's `'npm'` path to point to that folder.",
"translation": "如果你不想或无法从公网上加载这些包,也可以把`systemjs.config.server.js`中所指出的这些文件或文件夹复制到服务器上的一个库目录。\n然后修改配置中的`'npm'`路径指向该文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### Practice with an example",
"translation": "### 用一个例子实践一下",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "The following trivial router sample app shows these changes.",
"translation": "下面这个例子展示了所有的修改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Practice with this sample before attempting these techniques on your application.",
"translation": "在真实应用中尝试这些技术之前,先用这个例子实践一下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. Follow the [setup instructions](guide/setup \"Angular QuickStart setup\") for creating a new project\nnamed <code>simple-deployment</code>.",
"translation": "遵循[设置步骤](guide/setup \"Angular QuickStart setup\")创建一个名叫`simple-deployment`的新项目。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. Add the \"Simple deployment\" sample files shown above.",
"translation": "添加上述的“简单部署”范例文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. Run it with `npm start` as you would any project.",
"translation": "像其它项目一样使用`npm start`来运行它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. Inspect the network traffic in the browser developer tools.\nNotice that it loads all packages from the web.\nYou could delete the `node_modules` folder and the app would still run\n(although you wouldn't be able to recompile or launch `lite-server`\nuntil you restored it).",
"translation": "在浏览器的开发者工具中审查网络包。注意,它从网上加载了所有包。\n 我们可以删除`node_modules`文件夹,该应用仍然可以正常工作(但没办法再重新编译它或者启动`lite-server`了)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "1. Deploy the sample to the server (minus the `node_modules` folder!).",
"translation": "把范例工程部署到服务器上(但`node_modules`文件夹除外)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "When you have that working, try the same process on your application.",
"translation": "掌握这些之后,就可以在你的真实项目中试用这些过程了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "## Optimize for production",
"translation": "## 为生产环境优化",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Although deploying directly from the development environment works, it's far from optimal.",
"translation": "虽然可以直接从开发环境下部署,但是它还远远没有优化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "The client makes many small requests for individual application code and template files,\na fact you can quickly confirm by looking at the network tab in a browser's developer tools.\nEach small file download can spend more time communicating with the server than transferring data.",
"translation": "客户端发起了很多小的请求来取得一个个单独的应用代码和模板文件从浏览器开发工具的Network标签中就可以确认这一点。\n每个小文件都会花费很多时间在与服务器建立通讯而不是传输内容上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Development files are full of comments and whitespace for easy reading and debugging.\nThe browser downloads entire libraries, instead of just the parts the app needs.\nThe volume of code passed from server to client (the \"payload\")\ncan be significantly larger than is strictly necessary to execute the application.",
"translation": "开发环境下的文件有很多注释和空格,以便于阅读和调试。\n浏览器会下载整个库而不只是应用需要的那部分。\n从服务器传到客户端的代码即有效载荷的数量会显著大于应用运行时真正需要的那部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "The many requests and large payloads mean\nthe app takes longer to launch than it would if you optimized it.\nSeveral seconds may pass (or worse) before the user can see or do anything useful.",
"translation": "大量请求和载荷意味着应用相对于优化过的版本会花更多时间进行启动。\n当用户看到什么或做什么有用的事情之前就已经过去了浪费了很多秒。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Does it matter? That depends upon business and technical factors you must evaluate for yourself.",
"translation": "这重要吗?取决于很多业务和技术方面的因素,我们必须自己评估它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "If it _does_ matter, there are tools and techniques to reduce the number of requests and the size of responses.",
"translation": "如果重要,那么有很多工具和技术可以减少请求数和体积。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Ahead-of-Time (AOT) Compilation: pre-compiles Angular component templates.",
"translation": "预编译AOT预编译Angular的组件模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Bundling: concatenates modules into a single file (bundle).",
"translation": "打捆Bundle把这些模块串接成一个单独的捆文件bundle。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Inlining: pulls template html and css into the components.",
"translation": "内联把模板html和css拉到组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Minification: removes excess whitespace, comments, and optional tokens.",
"translation": "最小化移除不必要的空格、注释和可选令牌Token。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Uglification: rewrites code to use short, cryptic variable and function names.",
"translation": "混淆:使用短的、无意义的变量名和函数名来重写代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Dead code elimination: removes unreferenced modules and unused code.",
"translation": "消除死代码:移除未引用过的模块和未使用过的代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Pruned libraries: drop unused libraries and pare others down to the features you need.",
"translation": "修剪库:移除未使用过的库,并把其它库裁剪到只剩下你需要的那些特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Performance measurement: focus on optimizations that make a measurable difference.",
"translation": "性能度量:集中精力做那些能产生可测量差异的优化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Each tool does something different.\nThey work best in combination and are mutually reinforcing.",
"translation": "每个工具做的事情都不一样,但它们结合起来会相辅相成。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "You can use any build system you like.\nWhatever system you choose, be sure to automate it so that\nbuilding for production is a single step.",
"translation": "我们也可以使用任何喜欢的构建系统。\n无论选择的是什么都务必把它自动化以便可以一步构建出产品。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### Ahead-of-Time (AOT) compilation",
"translation": "### 预编译AOT",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "The Angular _Ahead-of-Time_ compiler pre-compiles application components and their templates\nduring the build process.",
"translation": "Angular的*预编译*器会在构建过程中预先编译应用的组件及其模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Apps compiled with AOT launch faster for several reasons.",
"translation": "预编译过的应用启动更快,原因如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Application components execute immediately, without client-side compilation.",
"translation": "应用组件会立即执行,不需要客户端编译过程。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* Templates are embedded as code within their components so there is no client-side request for template files.",
"translation": "模板会被内嵌在组件中,因此不会再从客户端请求模板文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* You don't download the Angular compiler, which is pretty big on its own.",
"translation": "我们不用再下载Angular编译器模块它本身太大了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* The compiler discards unused Angular directives that a tree-shaking tool can then exclude.",
"translation": "编译器会丢弃那些摇树优化tree-shaking工具能排除的代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Learn more about AOT Compilation in the [AOT Cookbook](guide/aot-compiler \"AOT Cookbook\")\nwhich describes running the AOT compiler from the command line\nand using [_rollup_](guide/deployment#rollup) for bundling, minification, uglification and tree shaking.",
"translation": "要了解AOT编译器的更多知识参见[烹饪宝典中的AOT一章](guide/aot-compiler \"AOT Cookbook\")\n它描述了如何在命令行中执行AOT编译器并使用[_rollup_](guide/deployment#rollup)进行构建、最小化、混淆和摇树优化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### Webpack (and AOT)",
"translation": "### Webpack与AOT",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "<a href=\"https://webpack.js.org/\" title=\"Webpack 2\">Webpack 2</a> is another\ngreat option for inlining templates and style-sheets, for bundling, minifying, and uglifying the application.\nThe \"[Webpack: an introduction](guide/webpack \"Webpack: an introduction\")\" guide will get you started\nusing webpack with Angular.",
"translation": "<a href=\"https://webpack.js.org/\" target=\"_blank\" title=\"Webpack 2\">Webpack 2</a>是另一个选项,它可以内联模板、样式表、打包、最小化和混淆应用。\n\"[Webpack简介](guide/webpack \"Webpack: an introduction\")\"一章中将会教你如何配合Angular使用Webpack。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Consider configuring _Webpack_ with the official\n<a href=\"https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack\" title=\"Ahead-of-Time Webpack Plugin\">\nAngular Ahead-of-Time Webpack Plugin</a>.\nThis plugin transpiles the TypeScript application code,\nbundles lazy loaded `NgModules` separately,\nand performs AOT compilation &mdash; without any changes to the source code.",
"translation": "考虑使用官方的<a href=\"https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack\" target=\"_blank\" title=\"Ahead-of-Time Webpack Plugin\">\nAngular预编译插件</a>来配置*Webpack*。\n这个插件会转译TypeScript代码、独立打包延迟加载的`NgModules`而且不用对源码做任何修改就能执行AOT编译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### Dead code elimination with _rollup_",
"translation": "### 使用`rollup`消除死代码",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Any code that you don't call is _dead code_.\nYou can reduce the total size of the application substantially by removing dead code from the application and from third-party libraries.",
"translation": "任何永远不会调到的代码就是*死代码*。\n通过移除应用和第三方库中的死代码可以实质性减小应用的总大小。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "_Tree shaking_ is a _dead code elimination_ technique that removes entire exports from JavaScript modules.\nIf a library exports something that the application doesn't import, a tree shaking tool removes it from the code base.",
"translation": "*摇树优化*是一种*消除死代码*的技术它会从JavaScript模块中移除导出。\n如果一个库导出了一些东西但是应用代码没有导入过它摇树工具就会从代码中移除它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Tree shaking was popularized by\n<a href=\"http://rollupjs.org/\" title=\"Rollup\">Rollup</a>, a popular tool with an ecosystem of\nplugins for bundling, minification, and uglification.\nLearn more about tree shaking and dead code elmination in\n<a href=\"https://medium.com/@Rich_Harris/tree-shaking-versus-dead-code-elimination-d3765df85c80#.15ih9cyvl\" title=\"Tree-shaking and Dead Code Elimination\">\nthis post</a> by rollup-creator, Rich Harris.",
"translation": "常用的摇树优化工具是<a href=\"http://rollupjs.org/\" target=\"_blank\" title=\"Rollup\">Rollup</a>,一个带有查件的生态系统,可以完成打包、最小化和混淆。\n要了解关于摇树优化和消除死代码技术的更多知识参见<a href=\"https://medium.com/@Rich_Harris/tree-shaking-versus-dead-code-elimination-d3765df85c80#.15ih9cyvl\" target=\"_blank\" title=\"Tree-shaking and Dead Code Elimination\">这个帖子</a>它的作者就是rollup之父Rich Harris。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### Pruned libraries",
"translation": "### 修剪库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Don't count on automation to remove all dead code.",
"translation": "不要指望自动移除所有死代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Remove libraries that you don't use, especially unnecessary scripts in `index.html`.\nConsider smaller alternatives to the libraries that you do use.",
"translation": "手动移除不用的库,特别是`index.html`中不用的脚本。\n为实际使用的那些库则努力选择更小的代用库。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Some libraries offer facilities for building a custom, skinny version with just the features you need.\nOther libraries let you import features _a la carte_.\n**RxJS** is a good example; import RxJS `Observable` operators individually instead of the entire library.",
"translation": "有些库可以构建出只带所需特性的、自定义的、带皮肤的版本。另一些库则可以让你按需导入它的特性。\n**RxJS**就是一个很好的例子,我们会单独导入`Observable`的操作符operator而不是导入整个库。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### Measure performance first",
"translation": "### 首先,度量性能",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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": "<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>是开始学习度量性能的好地方。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "## Angular configuration",
"translation": "## Angular配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "Angular configuration can make the difference between whether the app launches quickly or doesn't load at all.",
"translation": "修改Angular配置可以显示出快速启动应用和完全不加载之间的差异。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### The `base` tag",
"translation": "### `base`标签",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "The HTML [_&lt;base href=\"...\"/&gt;_](/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中的[_&lt;base href=\"...\"/&gt;_](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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "When the `base` tag is misconfigured, 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/content-1/guide/deployment.md"
},
{
"original": "### Enable production mode",
"translation": "### 启用生产模式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "To enable [production mode](api/core/enableProdMode) when running remotely, add the following code to the `main.ts`.",
"translation": "要在远程运行时启用[生产模式](api/core/enableProdMode),请把下列代码添加到`main.ts`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "### Lazy loading",
"translation": "### 惰性加载",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "#### Don't eagerly import something from a lazy loaded module",
"translation": "#### 不要立即导入惰性加载模块中的任何东西",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "The\n[Angular Ahead-of-Time Webpack Plugin](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack)\nautomatically recognizes lazy loaded `NgModules` and creates separate bundles for them.",
"translation": "[Angular预编译插件](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack)会自动识别惰性加载的`NgModules`,并为它们创建单独的包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "## Server configuration",
"translation": "## 服务端配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "### Routed apps must fallback to `index.html`",
"translation": "### 带路由的应用必须以`index.html`作为后备页面",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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 &mdash;\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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "#### Fallback configuration examples",
"translation": "#### 后备页面配置范例",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "#### Development servers",
"translation": "#### 开发服务器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "#### Production servers",
"translation": "#### 生产服务器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "* [Apache](https://httpd.apache.org/): add a\n[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html)\nto the `.htaccess` file as show\n[here](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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "### Requesting services from a different server (CORS)",
"translation": "### 请求来自另一个服务器的服务CORS",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"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/content-1/guide/deployment.md"
},
{
"original": "## Next steps",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "If you want to go beyond the [simple _copy-deploy_](guide/deployment#dev-deploy \"Simplest deployment possible\") approach,\nread the [AOT Cookbook](guide/aot-compiler \"AOT Cookbook\") next.",
"translation": "如果我们准备超越[简单*复制*部署](guide/deployment#dev-deploy \"Simplest deployment possible\")的方式,请参阅[烹饪宝典中的AOT部分](guide/aot-compiler \"AOT Cookbook\")。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/deployment.md"
},
{
"original": "# Displaying Data",
"translation": "# 显示数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "The final UI looks like this:",
"translation": "最终的用户界面是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "## Showing component properties with interpolation",
"translation": "## 使用插值表达式显示组件属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "Follow the [setup](guide/setup) instructions for creating a new project\nnamed <code>displaying-data</code>.",
"translation": "按照[开发环境](guide/setup)的说明,创建一个新项目,名为<code>displaying-data</code>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "When you're done, it should look like this:",
"translation": "修改完之后,它应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "You added two properties to the formerly empty component: `title` and `myHero`.",
"translation": "再把两个属性`title`和`myHero`添加到之前空白的组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "The revised template displays the two component properties using double curly brace\ninterpolation:",
"translation": "修改完的模板会使用双花括号形式的插值表达式来显示这两个模板属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "The template is a multi-line string within ECMAScript 2015 backticks (<code>\\`</code>).\nThe backtick (<code>\\`</code>)&mdash;which is *not* the same character as a single\nquote (`'`)&mdash;allows you to compose a string over several lines, which makes the\nHTML more readable.",
"translation": "模板是包在 ECMAScript 2015 反引号 (<code>\\`</code>) 中的一个多行字符串。\n反引号 (<code>\\`</code>) &mdash; 注意,不是单引号 (') &mdash; 允许把一个字符串写在多行上,\n使 HTML 模板更容易阅读。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "The CSS `selector` in the `@Component` decorator specifies an element named `<my-app>`.\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/content-1/guide/displaying-data.md"
},
{
"original": "When you bootstrap with the `AppComponent` class (in <code>main.ts</code>), Angular looks for a `<my-app>`\nin the `index.html`, finds it, instantiates an instance of `AppComponent`, and renders it\ninside the `<my-app>` tag.",
"translation": "当我们通过`main.ts`中的`AppComponent`类启动时Angular 在`index.html`中查找一个`<my-app>`元素,\n然后实例化一个`AppComponent`,并将其渲染到`<my-app>`标签中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "Now run the app. It should display the title and hero name:",
"translation": "运行应用。它应该显示出标题和英雄名:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "The next few sections review some of the coding choices in the app.",
"translation": "回顾一下前面所做的决定,看看还有哪些其它选择。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "## Template inline or template file?",
"translation": "## 内联 (inline) 模板还是模板文件?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "In either style, the template data bindings have the same access to the component's properties.",
"translation": "无论用哪种风格,模板数据绑定在访问组件属性方面都是完全一样的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "## Constructor or variable initialization?",
"translation": "## 使用构造函数还是变量初始化?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "Although this example uses variable assignment to initialize the components, you can instead declare and initialize the properties using a constructor:",
"translation": "虽然这个例子使用了变量赋值的方式初始化组件,你还可以使用构造函数来声明和初始化属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "This app uses more terse \"variable assignment\" style simply for brevity.",
"translation": "为了让本应用更加简短,它采用了更简单的“变量赋值”风格。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "## Showing an array property with ***ngFor**",
"translation": "## 使用***ngFor***显示数组属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "Now the heroes appear in an unordered list.",
"translation": "现在,英雄们出现在了一个无序列表中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "## Creating a class for the data",
"translation": "## 为数据创建一个类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "Create a new file in the `app` folder called `hero.ts` with the following code:",
"translation": "在`app`目录下创建一个名叫`hero.ts`的新文件,内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "You've defined a class with a constructor and two properties: `id` and `name`.",
"translation": "你定义了一个类,具有一个构造函数和两个属性:`id`和`name`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "It might not look like the class has properties, but it does.\n The declaration of the constructor parameters takes advantage of a TypeScript shortcut.",
"translation": "它可能看上去不像是有属性的类,但它确实有,利用的是 TypeScript 提供的简写形式 —— 用构造函数的参数直接定义属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "Consider the first parameter:",
"translation": "来看第一个参数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "That brief syntax does a lot:",
"translation": "这个简写语法做了很多:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "* Declares a constructor parameter and its type",
"translation": "声明了一个构造函数参数及其类型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "* Declares a public property of the same name",
"translation": "声明了一个同名的公共属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "* Initializes that property with the corresponding argument when we \"new\" an instance of the class",
"translation": "当我们`new`出该类的一个实例时,把该属性初始化为相应的参数值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "### Using the Hero class",
"translation": "### 使用 Hero 类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "Our display looks the same, but now we know much better what a hero really is.",
"translation": "从显示上看还是一样,但现在我们知道了更多英雄信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "## Conditional display with NgIf",
"translation": "## 通过 NgIf 进行条件显示",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "Let's change the example to display a message if there are more than three heroes.",
"translation": "让我们来修改这个例子,如果多于三位英雄,显示一条消息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "Now you know how to use:",
"translation": "现在你知道了如何使用:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "* **Interpolation** with double curly braces to display a component property.",
"translation": "带有双花括号的**插值表达式 (interpolation) **来显示一个组件属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "* **ngFor** to display an array of items.",
"translation": "用 **ngFor** 显示数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"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/content-1/guide/displaying-data.md"
},
{
"original": "* **ngIf** to conditionally display a chunk of HTML based on a boolean expression.",
"translation": "用 **ngIf** 根据一个布尔表达式有条件地显示一段 HTML。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "Here's the final code:",
"translation": "下面是最终的代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/displaying-data.md"
},
{
"original": "# Dynamic Component Loader",
"translation": "# 动态组件加载器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "Component templates are not always fixed. An application may need to load new components at runtime.",
"translation": "组件的模板不会永远是固定的。应用可能会需要在运行期间加载一些新的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "This cookbook shows you how to use `ComponentFactoryResolver` to add components dynamically.",
"translation": "这本烹饪书为你展示如何使用`ComponentFactoryResolver`来动态添加组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "See the <live-example name=\"dynamic-component-loader\"></live-example>\nof the code in this cookbook.",
"translation": "到<live-example name=\"cb-dynamic-component-loader\"></live-example>查看本烹饪书的源码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "## Dynamic component loading",
"translation": "## 动态组件加载",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "The following example shows how to build a dynamic ad banner.",
"translation": "下面的例子展示了如何构建动态广告条。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"original": "Angular comes with its own API for loading components dynamically.",
"translation": "Angular 自带的API就能支持动态加载组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "## The anchor directive",
"translation": "## 指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"original": "## Loading components",
"translation": "## 加载组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"original": "## Resolving components",
"translation": "## 解析组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "Take a closer look at the methods in `ad-banner.component.ts`.",
"translation": "深入看看`ad-banner.component.ts`中的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"original": "**How _loadComponent()_ chooses an ad**",
"translation": "**`loadComponent()`如何选择广告**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "The `loadComponent()` method chooses an ad using some math.",
"translation": "`loadComponent()`方法使用某种算法选择了一个广告。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"original": "To add the component to the template, you call `createComponent()` on `ViewContainerRef`.",
"translation": "要把这个组件添加到模板中,我们可以调用`ViewContainerRef`的`createComponent()`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"original": "#### Selector references",
"translation": "#### 对选择器的引用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"original": "## The _AdComponent_ interface",
"translation": "## 公共的`AdComponent`接口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"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/content-1/guide/dynamic-component-loader.md"
},
{
"original": "Here are two sample components and the `AdComponent` interface for reference:",
"translation": "下面就是两个范例组件及其`AdComponent`接口:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "## Final ad banner",
"translation": "## 最终的广告栏",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "The final ad banner looks like this:",
"translation": "最终的广告栏是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "See the <live-example name=\"dynamic-component-loader\"></live-example>.",
"translation": "参见<live-example name=\"cb-dynamic-component-loader\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-component-loader.md"
},
{
"original": "# Dynamic Forms",
"translation": "# 动态表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "Building handcrafted forms canbe 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/content-1/guide/dynamic-form.md"
},
{
"original": "It may be more economical to create the forms dynamically, based on metadata that describes the business object model.",
"translation": "基于业务对象模型的元数据,动态创建表单可能会更划算。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"original": "See the <live-example name=\"dynamic-form\"></live-example>.",
"translation": "参见<live-example name=\"dynamic-form\"></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "## Bootstrap",
"translation": "## 程序启动",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "Start by creating an `NgModule` called `AppModule`.",
"translation": "让我们从创建一个名叫`AppModule`的`NgModule`开始。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "This cookbook uses [reactive forms](guide/reactive-forms).",
"translation": "这个烹饪书使用[响应式表单](guide/reactive-forms)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"original": "Bootstrap the `AppModule` in `main.ts`.",
"translation": "我们在`main.ts`中启动`AppModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "## Question model",
"translation": "## 问卷问题模型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"original": "The following `QuestionBase` is a fundamental question class.",
"translation": "下面是我们建立的最基础的问卷问题基类,名叫`QuestionBase`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"original": "`DropdownQuestion` presents a list of choices in a select box.",
"translation": "`DropdownQuestion`表示一个带可选项列表的选择框。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"original": "## Question form components",
"translation": "## 问卷表单组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"original": "`DynamicFormComponent` is the entry point and the main container for the form.",
"translation": "`DynamicFormComponent`是表单的主要容器和入口点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "It presents a list of questions, each bound to a `<df-question>` component element.\nThe `<df-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": "它代表了问卷问题列表,每个问题都被绑定到一个`<df-question>`组件元素。\n`<df-question>`标签匹配到的是组件`DynamicFormQuestionComponent`,该组件的职责是根据各个问卷问题对象的值来动态渲染表单控件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"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`。\n{@a questionnaire-data}",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "## Questionnaire data",
"translation": "## 问卷数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"original": "Finally, display an instance of the form in the `AppComponent` shell.",
"translation": "最后,在`AppComponent`里显示出表单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "## Dynamic Template",
"translation": "## 动态模板",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"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/content-1/guide/dynamic-form.md"
},
{
"original": "The final form looks like this:",
"translation": "完整的表单是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "[Back to top](guide/dynamic-form#top)",
"translation": "[回到顶部](guide/dynamic-form#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/dynamic-form.md"
},
{
"original": "# Form Validation",
"translation": "# 表单验证",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"original": "Improve overall data quality by validating user input for accuracy and completeness.",
"translation": "我们可以通过验证用户输入的准确性和完整性,来增强整体数据质量。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "## Template-driven validation",
"translation": "## 模板驱动验证",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "Note the following:",
"translation": "请注意以下几点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "* `#name=\"ngModel\"` exports `NgModel` into a local variable callled `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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "#### Why check _dirty_ and _touched_?",
"translation": "#### 为何检查**dirty**和**touched**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "## Reactive form validation",
"translation": "## 响应式表单的验证",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "### Validator functions",
"translation": "### 验证器函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"original": "There are two types of validator functions: sync validators and async validators.",
"translation": "有两种验证器函数:同步验证器和异步验证器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "### Built-in validators",
"translation": "### 内置验证器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "To update the hero form to be a reactive form, you can use some of the same \nbuilt-in validators&mdash;this time, in function form. See below:",
"translation": "要想把这个英雄表单改造成一个响应式表单,我们还是用那些内置验证器,但这次改为用它们的函数形态。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"original": "Note that:",
"translation": "注意",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"original": "* The name control sets up two built-in validators&mdash;`Validators.required` and `Validators.minLength(4)`&mdash;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/content-1/guide/form-validation.md"
},
{
"original": "* As these validators are all sync validators, you pass them in as the second argument.",
"translation": "由于这些验证器都是同步验证器,因此我们要把它们作为第二个参数传进去。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"original": "* Support multiple validators by passing the functions in as an array.",
"translation": "可以通过把这些函数放进一个数组后传进去,可以支持多重验证器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "Key takeaways:",
"translation": "关键改动是:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "## Custom validators",
"translation": "## 自定义验证器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "### Adding to reactive forms",
"translation": "### 添加响应式表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "### Adding to template-driven forms",
"translation": "### 添加到模板驱动表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "The corresponding `ForbiddenValidatorDirective` serves as a wrapper around the `forbiddenNameValidator`.",
"translation": "`ForbiddenValidatorDirective`指令相当于`forbiddenNameValidator`的包装器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "Once the `ForbiddenValidatorDirective` is ready, you can simply add its selector, `forbiddenName`, to any input element to activate it. For example:",
"translation": "一旦 `ForbiddenValidatorDirective` 写好了,我们只要把`forbiddenName`选择器添加到输入框上就可以激活这个验证器了。比如:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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`&mdash;the instance in the form with\nits `forbiddenName` property bound to “bob\". If you were to replace\n`useExisting` with `useClass`, then youd be registering a new class instance, one that\ndoesnt have a `forbiddenName`.",
"translation": "你可能注意到了自定义验证器指令是用`useExisting`而不是`useClass`来实例化的。注册的验证器必须是这个 `ForbiddenValidatorDirective` 实例本身,也就是表单中 `forbiddenName` 属性被绑定到了\"bob\"的那个。如果用`useClass`来代替`useExisting`,就会注册一个新的类实例,而它是没有`forbiddenName`的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"original": "## Control status CSS classes",
"translation": "## 表示控件状态的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"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/content-1/guide/form-validation.md"
},
{
"original": "# Forms",
"translation": "# 表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "* Build an Angular form with a component and template.",
"translation": "用组件和模板构建 Angular 表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Use `ngModel` to create two-way data bindings for reading and writing input-control values.",
"translation": "用`ngModel`创建双向数据绑定,以读取和写入输入控件的值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Track state changes and the validity of form controls.",
"translation": "跟踪状态的变化,并验证表单控件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Provide visual feedback using special CSS classes that track the state of the controls.",
"translation": "使用特殊的CSS类来跟踪控件的状态并给出视觉反馈",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Display validation errors to users and enable/disable form controls.",
"translation": "向用户显示验证错误提示,以及启用/禁用表单控件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Share information across HTML elements using template reference variables.",
"translation": "使用模板引用变量在 HTML 元素之间共享信息",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "You can run the <live-example></live-example> in Plunker and download the code from there.",
"translation": "你可以在Plunker中运行<live-example></live-example>,并且从那里下载代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Template-driven forms",
"translation": "## 模板驱动的表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "You can also use a reactive (or model-driven) approach to build forms.\nHowever, this page focuses on template-driven forms.",
"translation": "你还可以使用响应式(也叫模型驱动)的方式来构建表单。不过本章中只介绍模板驱动表单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "You can build almost any form with an Angular template&mdash;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 模板,可以构建几乎所有表单 &mdash; 登录表单、联系人表单…… 以及任何的商务表单。\n 可以创造性的摆放各种控件、把它们绑定到数据、指定校验规则、显示校验错误、有条件的禁用或\n 启用特定的控件、触发内置的视觉反馈等等,不胜枚举。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "You'll learn to build a template-driven form that looks like this:",
"translation": "我们将学习构建如下的“模板驱动”表单:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "If you delete the hero name, the form displays a validation error in an attention-grabbing style:",
"translation": "如果删除了英雄的名字,表单就会用醒目的样式把验证错误显示出来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "You can customize the colors and location of the \"required\" bar with standard CSS.",
"translation": "稍后,会使用标准 CSS 来定制“必填”条的颜色和位置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "You'll build this form in small steps:",
"translation": "我们将一点点构建出此表单:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Create the `Hero` model class.",
"translation": "创建`Hero`模型类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Create the component that controls the form.",
"translation": "创建控制此表单的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Create a template with the initial form layout.",
"translation": "创建具有初始表单布局的模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Bind data properties to each form control using the `ngModel` two-way data-binding syntax.",
"translation": "使用`ngModel`双向数据绑定语法把数据属性绑定到每个表单输入控件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Add a `name` attribute to each form-input control.",
"translation": "往每个表单输入控件上添加`name`属性 (attribute)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Add custom CSS to provide visual feedback.",
"translation": "添加自定义 CSS 来提供视觉反馈。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Show and hide validation-error messages.",
"translation": "显示和隐藏有效性验证的错误信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Handle form submission with *ngSubmit*.",
"translation": "使用 **ngSubmit** 处理表单提交。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Disable the forms *Submit* button until the form is valid.",
"translation": "禁用此表单的提交按钮,直到表单变为有效。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Setup",
"translation": "## 搭建",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Follow the [setup](guide/setup) instructions for creating a new project\nnamed angular-forms.",
"translation": "按照[搭建本地开发环境](guide/setup)的说明创建一个名为angular-forms的新项目。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Create the Hero model class",
"translation": "## 创建 Hero 模型类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "In the `app` directory, create the following file with the given content:",
"translation": "在应用文件夹中创建下列文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "It's an anemic model with few requirements and no behavior. Perfect for the demo.",
"translation": "这是一个少量需求和零行为的贫血模型。对演示来说很完美。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "The TypeScript compiler generates a public field for each `public` constructor parameter and\nautomatically assigns the parameters value to that field when you create heroes.",
"translation": "TypeScript 编译器为每个`public`构造函数参数生成一个公共字段,在创建新的英雄实例时,自动把参数值赋给这些公共字段。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "You can create a new hero like this:",
"translation": "可以这样创建新英雄:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Create a form component",
"translation": "## 创建表单组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Create the following file with the given content:",
"translation": "创建下列文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Theres 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/content-1/guide/forms.md"
},
{
"original": "Understanding this component requires only the Angular concepts covered in previous pages.",
"translation": "只需要前面章节中学过的概念,就可以完全理解这个组件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* The code imports the Angular core library and the `Hero` model you just created.",
"translation": "这段代码导入了Angular核心库以及我们刚刚创建的`Hero`模型。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "* The `templateUrl` property points to a separate file for the template HTML.",
"translation": "`moduleId: module.id`属性设置了基地址,用于从相对模块路径加载`templateUrl`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* You defined dummy data for `model` and `powers`, as befits a demo.",
"translation": "`templateUrl`属性指向一个独立的 HTML 模板文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "### Why the separate template file?",
"translation": "### 为何分离模板文件?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Why don't you write the template inline in the component file as you often do elsewhere?",
"translation": "为什么不与我们在其他地方常常做的那样,以内联的方式把模板写在组件文件中呢?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "There is no \"right\" answer for all occasions. Inline templates are useful when they are short.\nMost form templates aren't short. TypeScript and JavaScript files generally aren't the best place to\nwrite (or read) large stretches of HTML, and few editors help with files that have a mix of HTML and code.",
"translation": "没有什么答案在所有场合都总是“正确”的。当模板足够短的时候,内联形式更招人喜欢。\n但大多数的表单模板都不短。通常TypeScript 和 JavaScript 文件不是写(读)大型 HTML 的好地方,\n而且没有几个编辑器能对混写的 HTML 和代码提供足够的帮助。\n我们还是喜欢内容清晰、目标明确的短文件像这个一样。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Form templates tend to be large, even when displaying a small number of fields,\nso it's usually best to put the HTML template in a separate file.\nYou'll write that template file in a moment. First,\nrevise the `app.module.ts` and `app.component.ts` to make use of the new `HeroFormComponent`.",
"translation": "就算是在仅仅显示少数表单项目时,表单模板一般都比较庞大。所以通常最好的方式是将 HTML 模板放到单独的文件中。\n一会儿将编写这个模板文件。在这之前先退一步再看看`app.module.ts`和`app.component.ts`,让它们使用新的`HeroFormComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Revise *app.module.ts*",
"translation": "## 修改 *app.module.ts*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Replace the contents of the \"QuickStart\" version with the following:",
"translation": "把“快速上手”版的文件替换为如下内容:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "There are three changes:",
"translation": "有三处更改:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. You import `FormsModule` and the new `HeroFormComponent`.",
"translation": "导入`FormsModule`和新组件`HeroFormComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. You add the `FormsModule` to the list of `imports` defined in the `@NgModule` decorator. This gives the application\naccess to all of the template-driven forms features, including `ngModel`.",
"translation": "把`FormsModule`添加到`ngModule`装饰器的`imports`列表中,这样应用就能访问模板驱动表单的所有特性,包括`ngModel`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. You add the `HeroFormComponent` to the list of `declarations` defined in the `@NgModule` decorator. This makes\nthe `HeroFormComponent` component visible throughout this module.",
"translation": "把`HeroFormComponent`添加到`ngModule`装饰器的`declarations`列表中,使`HeroFormComponent`组件在整个模块中可见。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "If a component, directive, or pipe belongs to a module in the `imports` array, _don't_ re-declare it in the `declarations` array.\nIf 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/content-1/guide/forms.md"
},
{
"original": "## Revise *app.component.ts*",
"translation": "## 修改 *app.component.ts*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "`AppComponent` is the application's root component. It will host the new `HeroFormComponent`.",
"translation": "`AppComponent`是应用的根组件,`HeroFormComponent`将被放在其中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Replace the contents of the \"QuickStart\" version with the following:",
"translation": "把“快速上手”的版本内容替换成下列代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "There are only two changes.\nThe `template` is simply the new element tag identified by the component's `selector` property.\nThis displays the hero form when the application component is loaded.\nYou've also dropped the `name` field from the class body.",
"translation": "这里只做了两处修改。\n`template`中只剩下这个新的元素标签,即组件的`selector`属性。这样当应用组件被加载时,就会显示这个英雄表单。\n另外我们还从类中移除了`name`字段。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Create an initial HTML form template",
"translation": "## 创建初始 HTML 表单模板",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Create the template file with the following contents:",
"translation": "用下列内容新建模板文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "You added a *Submit* button at the bottom with some classes on it for styling.",
"translation": "在底部添加个 *Submit* 按钮,它还带一些 CSS 样式类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "*You're not using Angular yet*. There are no bindings or extra directives, just layout.",
"translation": "**我们还没有真正用到Angular**。没有绑定,没有额外的指令,只有布局。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "In template driven forms, if you've imported `FormsModule`, you don't have to do anything\nto 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/content-1/guide/forms.md"
},
{
"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/)。纯粹是装饰。\n我们使用 Bootstrap 来美化表单。嘿,一点样式都没有的表单算个啥!",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Angular forms don't require a style library",
"translation": "Angular 表单不需要任何样式库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Angular makes no use of the `container`, `form-group`, `form-control`, and `btn` classes or\nthe 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/content-1/guide/forms.md"
},
{
"original": "To add the stylesheet, open `index.html` and add the following link to the `<head>`:",
"translation": "我们来添加样式表。打开`index.html`,并把下列链接添加到`<head>`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Add powers with _*ngFor_",
"translation": "## 用 ***ngFor*** 添加超能力",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Add the following HTML *immediately below* the *Alter Ego* group:",
"translation": "在 *Alter Ego* 的紧下方添加如下 HTML",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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模板输入变量`p`在每个迭代指向不同的超能力,使用双花括号插值表达式语法来显示它的名称。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Two-way data binding with _ngModel_",
"translation": "## 使用 *ngModel* 进行双向数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Running the app right now would be disappointing.",
"translation": "如果立即运行此应用,你将会失望。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Now you need to display, listen, and extract at the same time.",
"translation": "现在,需要同时进行显示、监听和提取。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Find the `<input>` tag for *Name* and update it like this:",
"translation": "找到 *Name* 对应的`<input>`标签,并且像这样修改它:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "You added a diagnostic interpolation after the input tag\nso you can see what you're doing.\nYou left yourself a note to throw it away when you're done.",
"translation": "在 input 标签后添加用于诊断的插值表达式,以看清正在发生什么事。\n给自己留个备注提醒我们完成后移除它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Focus on the binding syntax: `[(ngModel)]=\"...\"`.",
"translation": "聚焦到绑定语法`[(ngModel)]=\"...\"`上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "### The _NgForm_ directive",
"translation": "### `NgForm`指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "What `NgForm` directive?\nYou didn't add an [NgForm](api/forms/NgForm) directive.",
"translation": "什么是`NgForm`指令?\n但我们明明没有添加过[NgForm](api/forms/NgForm)指令啊!",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "The `NgForm` directive supplements the `form` element with additional features.\nIt holds the controls you created for the elements with an `ngModel` directive\nand `name` attribute, and monitors their properties, including their validity.\nIt also has its own `valid` property which is true only *if every contained\ncontrol* is valid.",
"translation": "`NgForm`指令为`form`增补了一些额外特性。\n它会控制那些带有`ngModel`指令和`name`属性的元素,监听他们的属性(包括其有效性)。\n它还有自己的`valid`属性,这个属性只有在*它包含的每个控件*都有效时才是真。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "That's *two-way data binding*.\nFor more information, see\n[Two-way binding with NgModel](guide/template-syntax#ngModel) on the\nthe [Template Syntax](guide/template-syntax) page.",
"translation": "**这就是双向数据绑定!**要了解更多信息,参见[模板语法](guide/template-syntax)页的[使用NgModel进行双向绑定](guide/template-syntax#ngModel)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Internally, Angular creates `FormControl` instances and\nregisters them with an `NgForm` directive that Angular attached to the `<form>` tag.\nEach `FormControl` is registered under the name you assigned to the `name` attribute.\nRead 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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "After revision, the core of the form should look like this:",
"translation": "修改之后,这个表单的核心是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Each input element has an `id` property that is used by the `label` element's `for` attribute\nto match the label to its input control.",
"translation": "每个 input 元素都有`id`属性,`label`元素的`for`属性用它来匹配到对应的输入控件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "*Delete* the `{{diagnostic}}` binding at the top as it has served its purpose.",
"translation": "表单顶部的`{{diagnostic}}`绑定已经完成了它的使命,**删除**它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Track control state and validity with _ngModel_",
"translation": "## 通过 **ngModel** 跟踪修改状态与有效性验证",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "State",
"translation": "状态",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Class if true",
"translation": "为真时的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Class if false",
"translation": "为假时的 CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "The control has been visited.",
"translation": "控件被访问过。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "The control's value has changed.",
"translation": "控件的值变化了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "The control's value is valid.",
"translation": "控件的值有效。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Now run the app and look at the _Name_ input box.\nFollow these steps *precisely*:",
"translation": "现在,运行本应用,并让*姓名*输入框获得焦点。\n然后严格按照下面四个步骤来做",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Look but don't touch.",
"translation": "查看输入框,但别碰它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Click inside the name box, then click outside it.",
"translation": "点击输入框,然后点击输入框外面。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Add slashes to the end of the name.",
"translation": "在名字的末尾添加些斜杠。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Erase the name.",
"translation": "删除名字。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "The actions and effects are as follows:",
"translation": "动作和它对应的效果如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "You should see the following transitions and class names:",
"translation": "我们会看到下列转换及其类名:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "*Delete* the `#spy` template reference variable and the `TODO` as they have served their purpose.",
"translation": "**删除**模板引用变量`#spy`和`TODO`,因为它们已经完成了使命。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Add custom CSS for visual feedback",
"translation": "## 添加用于视觉反馈的自定义 CSS",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Update the `<head>` of `index.html` to include this style sheet:",
"translation": "更新`index.html`中的`<head>`,以包含这个样式表:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Show and hide validation error messages",
"translation": "## 显示和隐藏验证错误信息",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "When the user deletes the name, the form should look like this:",
"translation": "当用户删除姓名时,应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "To achieve this effect, extend the `<input>` tag with the following:",
"translation": "要达到这个效果,在`<input>`标签中添加:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* A [template reference variable](guide/template-syntax#ref-vars).",
"translation": "[模板引用变量](guide/template-syntax#ref-vars)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Here's an example of an error message added to the _name_ input box:",
"translation": "这个例子中我们把一条错误信息添加到了_name_输入框中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Why \"ngModel\"?\nA directive's [exportAs](api/core/Directive) property\ntells Angular how to link the reference variable to the directive.\nYou 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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "The hero *Alter Ego* is optional so you can leave that be.",
"translation": "英雄的*第二人格*是可选项,所以不用改它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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 *did not restore the pristine state* of the form controls.",
"translation": "使用浏览器工具审查这个元素就会发现,这个 *name* 输入框并不是全新的。\n表单记得我们在点击 *New Hero* 前输入的名字。\n更换了英雄*并不会重置控件的“全新”状态*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "Now clicking \"New Hero\" resets both the form and its control flags.",
"translation": "现在点击“New Hero”重设表单和它的控制标记。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Submit the form with _ngSubmit_",
"translation": "## 使用 *ngSubmit* 提交该表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "If you run the application now, you find that the button is enabled&mdash;although\nit doesn't do anything useful yet.",
"translation": "重新运行应用。表单打开时,状态是有效的,按钮是可用的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "For you, it was as simple as this:",
"translation": "有了 Angular它就是这么简单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "1. Define a template reference variable on the (enhanced) form element.",
"translation": "定义模板引用变量放在强化过的form 元素上",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "2. Refer to that variable in a button many lines away.",
"translation": "从很多行之外的按钮上引用这个变量。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Toggle two form regions (extra credit)",
"translation": "## 切换两个表单区域(额外的奖励)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Submitting the form isn't terribly dramatic at the moment.",
"translation": "提交表单还是不够激动人心。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "An unsurprising observation for a demo. To be honest,\njazzing it up won't teach you anything new about forms.\nBut this is an opportunity to exercise some of your newly won\nbinding skills.\nIf you aren't interested, skip to this page's conclusion.",
"translation": "对演示来说,这个收场很平淡的。老实说,即使让它更出彩,也无法教给我们任何关于表单的新知识。\n但这是练习新学到的绑定技能的好机会。\n如果你不感兴趣可以跳到本章的总结部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "For a more strikingly visual effect,\nhide the data entry area and display something else.",
"translation": "来实现一些更炫的视觉效果吧。\n 隐藏掉数据输入框,显示一些其它东西。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "When you click the *Edit* button, this block disappears and the editable form reappears.",
"translation": "当点*Edit*按钮时,这个只读块消失了,可编辑的表单重新出现了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "## Conclusion",
"translation": "## 结论",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"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/content-1/guide/forms.md"
},
{
"original": "* An Angular HTML form template.",
"translation": "Angular HTML 表单模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* A form component class with a `@Component` decorator.",
"translation": "带有`@Component`装饰器的表单组件类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Handling form submission by binding to the `NgForm.ngSubmit` event property.",
"translation": "通过绑定到`NgForm.ngSubmit`事件属性来处理表单提交。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Template-reference variables such as `#heroForm` and `#name`.",
"translation": "模板引用变量,例如`#heroForm`和`#name`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* `[(ngModel)]` syntax for two-way data binding.",
"translation": "`[(ngModel)]`语法用来实现双向数据绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* The use of `name` attributes for validation and form-element change tracking.",
"translation": "`name`属性的用途是有效性验证和对表单元素的变更进行追踪。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* The reference variables `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/content-1/guide/forms.md"
},
{
"original": "* Controlling the *Submit* button's enabled state by binding to `NgForm` validity.",
"translation": "通过绑定到`NgForm`的有效性状态,控制*Submit*按钮的禁用状态。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "* Custom CSS classes that provide visual feedback to users about invalid controls.",
"translation": "定制 CSS 类来给用户提供无效控件的视觉反馈。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "The final project folder structure should look like this:",
"translation": "最终的项目目录结构是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "Heres the code for the final version of the application:",
"translation": "这里是源码的最终版本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/forms.md"
},
{
"original": "# Angular Glossary",
"translation": "# Angular 词汇表",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Ahead-of-time (AOT) compilation",
"translation": "## 预 (ahead-of-time, AoT) 编译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "You can compile Angular applications at build time.\nBy compiling your application using the compiler-cli, `ngc`, you can bootstrap directly\nto 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/content-1/guide/glossary.md"
},
{
"original": "## Annotation",
"translation": "## 注解",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "In practice, a synonym for [Decoration](guide/glossary#decorator).",
"translation": "实际上,是[装饰 (decoration)](guide/glossary#decorator) 的同义词。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Attribute directives",
"translation": "## 属性型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "For example, you can use the `ngClass` directive to add and remove CSS class names.",
"translation": "例如,`ngClass`指令就是典型的属性型指令。它可以添加或移除 CSS 类名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Learn about them in the [_Attribute Directives_](guide/attribute-directives) guide.",
"translation": "要了解更多信息,请参见[_属性型指令_](guide/attribute-directives)页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Barrel",
"translation": "## 封装桶",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "For example, imagine three ES2015 modules in a `heroes` folder:",
"translation": "例如,设想在`heroes`目录下有三个 ES2015 模块:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Without a barrel, a consumer needs three import statements:",
"translation": "如果没有封装桶,消费者需要三条导入语句:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Now a consumer can import what it needs from the barrel.",
"translation": "现在,消费者就就可以从这个封装桶中导入它需要的东西了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "You can often achieve the same result using [NgModules](guide/glossary#ngmodule) instead.",
"translation": "注意,你可以利用 [Angular 模块](guide/glossary#ngmodule)达到同样的目的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Binding",
"translation": "## 绑定 (binding)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Sometimes refers to a [dependency-injection](guide/glossary#dependency-injection) binding\nbetween a \"token\"&mdash;also referred to as a \"key\"&mdash;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/content-1/guide/glossary.md"
},
{
"original": "## Bootstrap",
"translation": "## 启动/引导 (bootstrap)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Bootstrapping identifies an application's top level \"root\" [component](guide/glossary#component),\nwhich is the first component that is loaded for the application.\nFor more information, see the [Setup](guide/setup) page.",
"translation": "通过应用程序根 Angular 模块来启动 Angular 应用程序。\n 启动过程标识应用的顶级“根”[组件 (component)](guide/glossary#component),也就是应用加载的第一个组件。\n 更多信息,见[设置](guide/setup)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## camelCase",
"translation": "## 驼峰式命名法 (camelCase)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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)。\n在文档中提到“驼峰式命名法 (camelCase) ”的时候,我们所指的都是小驼峰命名法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Component",
"translation": "## 组件 (component)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "An Angular class responsible for exposing data to a [view](guide/glossary#view) and handling most of the views display and user-interaction logic.",
"translation": "组件是一个 Angular 类,用于把数据展示到[视图 (view)](guide/glossary#view),并处理几乎所有的视图显示和交互逻辑。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## dash-case",
"translation": "## 中线命名法 (dash-case)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Data binding",
"translation": "## 数据绑定 (data binding)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "* [Interpolation](guide/template-syntax#interpolation)",
"translation": "[插值表达式 (interpolation)](guide/template-syntax#interpolation)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* [Property binding](guide/template-syntax#property-binding)",
"translation": "[property 绑定 (property binding)](guide/template-syntax#property-binding)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* [Event binding](guide/template-syntax#event-binding)",
"translation": "[事件绑定 (event binding)](guide/template-syntax#event-binding)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* [Attribute binding](guide/template-syntax#attribute-binding)",
"translation": "[attribute 绑定 (attribute binding)](guide/template-syntax#attribute-binding)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* [Class binding](guide/template-syntax#class-binding)",
"translation": "[CSS 类绑定 (class binding)](guide/template-syntax#class-binding)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* [Style binding](guide/template-syntax#style-binding)",
"translation": "[样式绑定 (style binding)](guide/template-syntax#style-binding)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Decorator | decoration",
"translation": "## 装饰器decorator | decoration",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "A *function* that adds metadata to a class, its members (properties, methods) and function arguments.",
"translation": "装饰器是一个**函数**,它将元数据添加到类、类成员(属性、方法)和函数参数。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "To apply a decorator, position it immediately above or to the left of the item it decorates.",
"translation": "要想应用装饰器,把它放到被装饰对象的上面或左边。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Always include parentheses `()` when applying a decorator.",
"translation": "永远别忘了在装饰器后面加括号`()`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Dependency injection",
"translation": "## 依赖注入dependency injection",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Read more in the [Dependency Injection](guide/dependency-injection) page.",
"translation": "更多信息,参见[依赖注入 (dependency injection)](guide/dependency-injection)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Directive",
"translation": "## 指令 (directive)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "A directive is usually associated with an HTML element or attribute.\nThis element or attribute is often referred to as the directive itself.\nWhen 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": "指令几乎总与 HTML 元素或属性 (attribute) 相关。\n我们通常把这些关联到的 HTML 元素或者属性 (attribute) 当做指令本身。\n当 Angular 在 HTML 模板中遇到一个指令的时候,\n它会创建匹配的指令类的实例并把浏览器中这部分 DOM 的控制权交给它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Directives fall into one of the following categories:",
"translation": "指令分为三类:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## ECMAScript",
"translation": "## ECMAScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Angular developers can write in ES5 directly.",
"translation": "Angular 的开发人员也可以选择直接使用 ES5 编程。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## ES2015",
"translation": "## ES2015 语言",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.",
"translation": "[ECMAScript](guide/glossary#ecmascript) 2015 的缩写。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## ES5",
"translation": "## ES5 语言",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## ES6",
"translation": "## ES6 语言",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Short hand for [ECMAScript](guide/glossary#ecmascript) 2015.",
"translation": "[ECMAScript](guide/glossary#ecmascript) 2015 的简写。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Injector",
"translation": "## 注入器 (injector)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Input",
"translation": "## 输入属性 (input)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Interpolation",
"translation": "## 插值表达式 (interpolation)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Just-in-time (JIT) compilation",
"translation": "## 即时 (just-in-time, JiT) 编译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## kebab-case",
"translation": "## 烤串命名法 (kebab-case)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "See [dash-case](guide/glossary#dash-case).",
"translation": "见[中线命名法 (dash-case)](guide/glossary#dash-case)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Lifecycle hooks",
"translation": "## 生命周期钩子 (lifecycle hook)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Angular calls these hook methods in the following order:",
"translation": "Angular 会按以下顺序调用钩子方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "* `ngOnInit`: after the first `ngOnChanges`.",
"translation": "`ngOnInit` - 在第一次`ngOnChanges`完成后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* `ngDoCheck`: developer's custom change detection.",
"translation": "`ngDoCheck` - 开发者自定义变更检测。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* `ngAfterContentInit`: after component content initialized.",
"translation": "`ngAfterContentInit` - 在组件内容初始化后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* `ngAfterContentChecked`: after every check of component content.",
"translation": "`ngAfterContentChecked` - 在组件内容每次检查后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* `ngAfterViewInit`: after a component's views are initialized.",
"translation": "`ngAfterViewInit` - 在组件视图初始化后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* `ngAfterViewChecked`: after every check of a component's views.",
"translation": "`ngAfterViewChecked` - 在组件视图每次检查后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* `ngOnDestroy`: just before the directive is destroyed.",
"translation": "`ngOnDestroy` - 在指令销毁前调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Read more in the [Lifecycle Hooks](guide/lifecycle-hooks) page.",
"translation": "更多信息,见[生命周期钩子 (lifecycle hook)](guide/lifecycle-hooks)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Module",
"translation": "## 模块 (module)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Angular has the following types of modules:",
"translation": "Angular有下列模块类型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* [NgModules](guide/glossary#ngmodule).\nFor details and examples, see the [NgModules](guide/ngmodule) page.",
"translation": "[Angular 模块](guide/glossary#ngmodule),见[Angular 模块](guide/ngmodule)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* ES2015 modules, as described in this section.",
"translation": "本节描述的 ES2015 模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "A cohesive block of code dedicated to a single purpose.",
"translation": "模块是一个内聚的代码块,具有单一用途。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Angular apps are modular.",
"translation": "Angular 应用程序是模块化的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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 (although most examples use SystemJS).\nYou can use any module library that conforms to the standard.",
"translation": "采用这个标准的应用程序需要一个模块加载器来按需加载模块,并解析模块间的依赖关系。\nAngular 不附带模块加载器也不偏爱任何第三方库虽然大多数例子使用SystemJS。\n你可以选择任何与这个标准兼容的模块化库。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## NgModule",
"translation": "## 可观察对象 (observable)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Observable",
"translation": "## Observable 对象",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "To use observables, Angular uses a third-party library called Reactive Extensions (RxJS).\nObservables are a proposed feature for ES 2016, the next version of JavaScript.",
"translation": "为了使用`Observable` Angular 采用了名为 Reactive Extensions (RxJS) 的第三方包。\n在下个版本的 JavaScript - ES 2016 中,`Observable`是建议的特性之一。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Output",
"translation": "## 输出属性 (output)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## PascalCase",
"translation": "## Pascal 命名法 (PascalCase)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Pipe",
"translation": "## 管道 (pipe)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Provider",
"translation": "## 提供商 (provider)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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&mdash;sometimes called a \"recipe\"&mdash;that can create a dependency value.",
"translation": "依赖注入系统依靠提供商来创建依赖的实例。\n它把一个查找令牌和代码有时也叫“配方”关联到一起以便创建依赖值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Reactive forms",
"translation": "## 响应式表单 (reactive forms)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "When building reactive forms:",
"translation": "构建响应式表单时:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "* The \"source of truth\" is the component. The validation is defined using code in the component.",
"translation": "组件是“真理之源”。表单验证在组件代码中定义。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "* The template input elements do *not* use `ngModel`.",
"translation": "模板中的`input`元素**不**使用`ngModel`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Router",
"translation": "## 路由器 (router)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "A [routing component's](guide/glossary#routing-component) template has a `RouterOutlet` element\n where it can display views produced by the router.",
"translation": "[路由组件](guide/glossary#routing-component)的模板中带有一个`RouterOutlet`元素,那是显示路由器生成的视图的地方。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Other views in the application likely have anchor tags or buttons with `RouterLink`\n directives that users can click to navigate.",
"translation": "应用中的其它视图中某些锚标签或按钮上带有`RouterLink`指令,用户可以点击它们进行导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Router module",
"translation": "## 路由器模块 (router module)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Routing component",
"translation": "## 路由组件 (routing component)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "For more information, see the [Routing & Navigation](guide/router) page.",
"translation": "更多信息,见[路由与导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Scoped package",
"translation": "## 范围化包 (scoped package)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Service",
"translation": "## 服务 (service)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Applications often require services such as a hero data service or a logging service.",
"translation": "应用程序经常需要服务,例如英雄数据服务或者日志服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Applications often require services such as a data service or a logging service.",
"translation": "应用通常都需要服务,比如数据服务或者日志服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## snake_case",
"translation": "## 蛇形命名法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Structural directives",
"translation": "## 结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Read more in the [Structural Directives](guide/structural-directives) page.",
"translation": "更多信息,见[结构型指令](guide/structural-directives)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Template",
"translation": "## 模板 (template)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Template-driven forms",
"translation": "## 模板驱动表单 (template-driven forms)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "When building template-driven forms:",
"translation": "当构建模板驱动表单时:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Read about how to build template-driven forms\nin the [Forms](guide/forms) page.",
"translation": "要了解如何构建模板驱动表单的更多信息,参见[表单](guide/forms)页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## Template expression",
"translation": "## 模板表达式 (template expression)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Transpile",
"translation": "## 转译transpile)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## TypeScript",
"translation": "## TypeScript 语言",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).",
"translation": "更多信息,见[typescript.org](http://www.typescriptlang.org/)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "## View",
"translation": "## 视图 (view)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "## Zone",
"translation": "## 区域 (zone)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "A mechanism for encapsulating and intercepting\na JavaScript application's asynchronous activity.",
"translation": "区域是一种用来封装和截听 JavaScript 应用程序异步活动的机制。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "The browser DOM and JavaScript have a limited number\n of 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)\n calls 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/content-1/guide/glossary.md"
},
{
"original": "Zones intercept all of these activities and give a \"zone client\" the opportunity\n to take action before and after the async activity finishes.",
"translation": "区域能截听所有这些活动,并让“区域的客户”有机会在异步活动完成之前和之后采取行动。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"original": "Angular runs your application in a zone where it can respond to\n asynchronous events by checking for data changes and updating\n the information it displays via [data bindings](guide/glossary#data-binding).",
"translation": "Angular 会在一个 Zone 区域中运行应用程序,在这个区域中,它可以对异步事件做出反应,可以通过检查数据变更、利用[数据绑定 (data bindings)](guide/glossary#data-binding) 来更新信息显示。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/glossary.md"
},
{
"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/content-1/guide/glossary.md"
},
{
"original": "# Hierarchical Dependency Injectors",
"translation": "# 多级依赖注入器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "This guide explores this system and how to use it to your advantage.",
"translation": "在本章中,我们将浏览这个体系,并告诉你如何善用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "Try the <live-example></live-example>.",
"translation": "试试<live-example></live-example>.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "## The injector tree",
"translation": "## 注入器树",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Injector bubbling",
"translation": "### 注入器冒泡",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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.\n This is a topic for another day.",
"translation": "我们还可以“盖住”这次冒泡。一个中层的组件可以声称自己是“宿主”组件。\n向上查找提供商的过程会截止于这个“宿主”组件。\n我们先保留这个问题等改天再讨论这个选项。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Re-providing a service at different levels",
"translation": "### 在不同层级再次提供同一个服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "## Component injectors",
"translation": "## 组件注入器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "The ability to configure one or more providers at different levels opens up interesting and useful possibilities.",
"translation": "在不同层次上重新配置一个或多个提供商的能力,开启了一些既有趣又有用的可能性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: service isolation",
"translation": "### 场景:服务隔离",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "Instead, provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:",
"translation": "我们可以换一种方案:在`VillainsListComponent`元数据的`providers`中提供`VillainsService`,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: multiple edit sessions",
"translation": "### 场景:多重编辑会话",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "Each tax return component has the following characteristics:",
"translation": "每个报税单组件都有下列特征:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Is its own tax return editing session.",
"translation": "属于它自己的报税单会话。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Can change a tax return without affecting a return in another component.",
"translation": "可以修改一个报税单,而不会影响另一个组件中的申报单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "* Has the ability to save the changes to its tax return or cancel them.",
"translation": "能把所做的修改保存到它的报税单中,或者放弃它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "Here is the `HeroTaxReturnComponent` that makes use of it.",
"translation": "下面是正在使用它的`HeroTaxReturnComponent`组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "Look closely at the metadata for the `HeroTaxReturnComponent`. Notice the `providers` property.",
"translation": "但仔细看`HeroTaxReturnComponent`的元数据,注意`providers`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "### Scenario: specialized providers",
"translation": "### 场景:专门的提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "You create a car component (A) that displays a car constructed from these three generic services.",
"translation": "我们创建了一个车辆组件A它显示一个从另外三个通用服务构造出的车辆。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"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/content-1/guide/hierarchical-dependency-injection.md"
},
{
"original": "# HttpClient",
"translation": "# HttpClient 库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"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/content-1/guide/http.md"
},
{
"original": "With `HttpClient`, `@angular/common/http` provides a simplified API for HTTP functionality for use with Angular applications, building on top of the `XMLHttpRequest` interface exposed by browsers.\nAdditional benefits of `HttpClient` include testability support, strong typing of request and response objects, request and response interceptor support, and better error handling via apis based on Observables.",
"translation": "`@angular/common/http`中的`HttpClient`类Angular 为应用程序提供了一个简化的 API 来实现 HTTP 功能。它基于浏览器提供的`XMLHttpRequest`接口。\n`HttpClient`带来的其它优点包括可测试性、强类型的请求和响应对象、发起请求与接收响应时的拦截器支持以及更好的、基于可观察Observable对象的错误处理机制。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "## Setup: installing the module",
"translation": "## 初始设置:安装本模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Before you can use the `HttpClient`, you need to install the `HttpClientModule` which provides it. This can be done in your application module, and is only necessary once.",
"translation": "在使用`HttpClient`之前,要先安装`HttpClientModule`以提供它。这可以在应用模块中做,而且只需要做一次。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Once you import `HttpClientModule` into your app module, you can inject `HttpClient`\ninto your components and services.",
"translation": "一旦把`HttpClientModule`引入了应用模块中,我们就可以把`HttpClient`注入到组件和服务中去了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "## Making a request for JSON data",
"translation": "## 发起一个请求来获取 JSON 数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "The most common type of request applications make to a backend is to request JSON data. For example, suppose you have an API endpoint that lists items, `/api/items`, which returns a JSON object of the form:",
"translation": "在应用发给服务器的请求中最常见的就是获取一个JSON数据。比如假设我们有一个用来获取条目列表的 API 端点 `/api/items`,它会返回一个如下格式的 JSON 对象:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "The `get()` method on `HttpClient` makes accessing this data straightforward.",
"translation": "`HttpClient`的`get()`方法可以让访问此数据的代码非常直白:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Typechecking the response",
"translation": "### 响应体的类型检查",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "In the above example, the `data['results']` field access stands out because you use bracket notation to access the results field. If you tried to write `data.results`, TypeScript would correctly complain that the `Object` coming back from HTTP does not have a `results` property. That's because while `HttpClient` parsed the JSON response into an `Object`, it doesn't know what shape that object is.",
"translation": "在上面的例子中,访问`data['results']`是用方括号语法来取得results字段的。如果写成`data.results`TypeScript 就会抱怨说来自HTTP的`Object`没有一个名叫`results`的属性。\n那是因为`HttpClient`把 JSON 格式的响应体解析成了一个`Object`,它并不知道这个对象的形态应该是什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "You can, however, tell `HttpClient` what type the response will be, which is recommended.\nTo do so, first you define an interface with the correct shape:",
"translation": "然而,我们其实可以告诉`HttpClient`这个响应体应该是什么类型的,而且这是推荐的做法。\n要这样做首先我们要定义一个接口来描述这个类型的正确形态",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Then, when you make the `HttpClient.get` call, pass a type parameter:",
"translation": "然后,当我们发起 `HttpClient.get` 调用时,传入一个类型参数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Reading the full response",
"translation": "### 读取完整的响应体",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"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, and inspecting those can be necessary. To do this, you can tell `HttpClient` you want the full response instead of just the body with the `observe` option:",
"translation": "响应体可能并不包含我们需要的全部信息。有时候服务器会返回一个特殊的响应头或状态码,以标记出特定的条件,因此读取它们可能是必要的。要这样做,我们就要通过`observe`选项来告诉`HttpClient`,你想要完整的响应信息,而不是只有响应体:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "As you can see, the resulting object has a `body` property of the correct type.",
"translation": "如你所见,这个结果对象具有一个带正确类型的`body`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Error handling",
"translation": "### 错误处理",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"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_ instead of a successful response.",
"translation": "如果这个请求导致了服务器错误怎么办?甚至,在烂网络下请求都没到服务器该怎么办?`HttpClient`就会返回一个错误error而不再是成功的响应。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "To handle it, add an error handler to your `.subscribe()` call:",
"translation": "要处理它,可以在`.subscribe()`调用中添加一个错误处理器:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### Getting error details",
"translation": "#### 获取错误详情",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Detecting that an error occurred is one thing, but it's more useful to know what error actually occurred. The `err` parameter to the callback above is of type `HttpErrorResponse`, and contains useful information on what went wrong.",
"translation": "检测错误的发生是第一步,不过如果知道具体发生了什么错误才会更有用。上面例子中传给回调函数的`err`参数的类型是`HttpErrorResponse`,它包含了这个错误中一些很有用的信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "There are two types of errors that can occur. If the backend returns an unsuccessful response code (404, 500, etc.), it gets returned as an error. Also, if something goes wrong client-side, such as an exception gets thrown in an RxJS operator, or if a network error prevents the request from completing successfully, an actual `Error` will be thrown.",
"translation": "可能发生的错误分为两种。如果后端返回了一个失败的返回码如404、500等它会返回一个错误。同样的如果在客户端这边出了错误比如在RxJS操作符中抛出的异常或某些阻碍完成这个请求的网络错误就会抛出一个`Error`类型的异常。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "In both cases, you can look at the `HttpErrorResponse` to figure out what happened.",
"translation": "这两种情况下,我们可以查看`HttpErrorResponse`来判断到底发生了什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### `.retry()`",
"translation": "#### `.retry()` 操作符",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "One way to deal with errors is to simply retry the request. This strategy can be useful when the errors are transient and unlikely to repeat.",
"translation": "解决问题的方式之一,就是简单的重试这次请求。这种策略对于那些临时性的而且不大可能重复发生的错误会很有用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "RxJS has a useful operator called `.retry()`, which automatically resubscribes to an Observable, thus reissuing the request, upon encountering an error.",
"translation": "RxJS有一个名叫`.retry()`的很有用的操作符,它会在遇到错误时自动重新订阅这个可观察对象,也就会导致再次发送这个请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "First, import it:",
"translation": "首先,导入它:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Then, you can use it with HTTP Observables like this:",
"translation": "然后,你可以把它用在 HTTP 的可观察对象上,比如这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Requesting non-JSON data",
"translation": "### 请求非 JSON 数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Not all APIs return JSON data. Suppose you want to read a text file on the server. You have to tell `HttpClient` that you expect a textual response:",
"translation": "并非所有的 API 都会返回 JSON 数据。假如我们要从服务器上读取一个文本文件,那就要告诉 `HttpClient` 我们期望获得的是文本格式的响应:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "## Sending data to the server",
"translation": "## 把数据发送到服务器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "In addition to fetching data from the server, `HttpClient` supports mutating requests, that is, sending data to the server in various forms.",
"translation": "除了从服务器获取数据之外,`HttpClient` 还支持 \"修改\" 型请求,也就是说,使用各种格式把数据发送给服务器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Making a POST request",
"translation": "### 发起一个 POST 请求",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "One common operation is to POST data to a server; for example when submitting a form. The code for\nsending a POST request is very similar to the code for GET:",
"translation": "常用的操作之一就是把数据 POST 到服务器,比如提交表单。下面这段发送 POST 请求的代码和发送 GET 请求的非常像:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "*Note the `subscribe()` method.* All Observables returned from `HttpClient` are _cold_, which is to say that they are _blueprints_ for making requests. Nothing will happen until you call `subscribe()`, and every such call will make a separate request. For example, this code sends a POST request with the same data twice:",
"translation": "*注意这个`subscribe()`方法*。 所有从`HttpClient`返回的可观察对象都是*冷的cold*,也就是说,它们只是发起请求的*蓝图*而已。在我们调用`subscribe()`之前,什么都不会发生,而当我们每次调用`subscribe()`时,就会独立发起一次请求。\n比如下列代码会使用同样的数据发送两次同样的 POST 请求:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Configuring other parts of the request",
"translation": "### 配置请求中的其它部分",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Besides the URL and a possible request body, there are other aspects of an outgoing request which you may wish to configure. All of these are available via an options object, which you pass to the request.",
"translation": "除了 URL 和可能的请求体之外,要发送的请求中你可能还希望配置一些别的东西。所有这些都可以通过给这次请求传一个额外的`options`(选项)对象来解决。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### Headers",
"translation": "#### 头",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "One common task is adding an `Authorization` header to outgoing requests. Here's how you do that:",
"translation": "最常见的就是往发出的请求中添加一个`Authorization`头,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "The `HttpHeaders` class is immutable, so every `set()` returns a new instance and applies the changes.",
"translation": "`HttpHeaders`类是不可变对象immutable所以每个`set()`都会返回一个新实例,并且应用上这些修改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### URL Parameters",
"translation": "#### URL 参数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Adding URL parameters works in the same way. To send a request with the `id` parameter set to `3`, you would do:",
"translation": "添加 URL 参数的方法也一样。比如要发送一个请求,并把`id`参数设置为`3`,就要这样写:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "In this way, you send the POST request to the URL `/api/items/add?id=3`.",
"translation": "这种情况下,我们会往 URL `/api/items/add?id=3` 上发送一个 POST 请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "## Advanced usage",
"translation": "## 高级用法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "The above sections detail how to use the basic HTTP functionality in `@angular/common/http`, but sometimes you need to do more than just make requests and get data back.",
"translation": "上一节详细讲解了如何在`@angular/common/http`中使用基本的 HTTP 功能,但是有时候除了发起请求和获取数据之外,我们还要做更多。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Intercepting all requests or responses",
"translation": "### 拦截所有的请求和响应。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "A major feature of `@angular/common/http` is _interception_, the ability to declare interceptors which sit in between your application and the backend. When your application makes a request, interceptors transform it\nbefore sending it to the server, and the interceptors can transform the response on its way back before your application sees it. This is useful for everything from authentication to logging.",
"translation": "`@angular/common/http`的主要特性之一是*拦截器*,它能声明一些拦截器,拦在应用和后端之间。当应用程序发起一个请求时,拦截器可以在请求被发往服务器之前先转换这个请求。并且在应用看到服务器发回来的响应之前,转换这个响应。这对于处理包括认证和记录日志在内的一系列工作都非常有用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### Writing an interceptor",
"translation": "#### 写一个拦截器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "To implement an interceptor, you declare a class that implements `HttpInterceptor`, which\nhas a single `intercept()` method. Here is a simple interceptor which does nothing but forward the request through without altering it:",
"translation": "要实现一个拦截器,就要声明一个实现了`HttpInterceptor`接口的类,它只有一个`intercept()`方法。下面是一个最简单的拦截器,它什么也不做,只是简单的转发请求而不做任何修改:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "`intercept` is a method which transforms a request into an Observable that eventually returns the response. In this sense, each interceptor is entirely responsible for handling the request by itself.",
"translation": "`intercept`是一个方法它把一个请求对象转换成一个返回这个响应的可观察对象Observable。从这个意义上说每个拦截器都要完全自己处理这个请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Most of the time, though, interceptors will make some minor change to the request and forward it to the rest of the chain. That's where the `next` parameter comes in. `next` is an `HttpHandler`, an interface that, similar to `intercept`, transforms a request into an Observable for the response. In an interceptor, `next` always represents the next interceptor in the chain, if any, or the final backend if there are no more interceptors. So most interceptors will end by calling `next` on the request they transformed.",
"translation": "当然,大多数时候,拦截器会对请求做一些小的修改,然后才把它转给拦截器链中的其它部分,也就是所传进来的`next`参数。`next`是一个`HttpHandler`,是一个类似于`intercept`的接口,它会把一个请求对象转换成一个可观察的响应对象。在拦截器中,`next`总是代表位于拦截器链中的下一个拦截器(如果有的话),如果没有更多拦截器了,它就会是最终的后端。所以,大多数拦截器的最后一句都会以它们转换后请求对象为参数调用`next.handle`函数。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Our do-nothing handler simply calls `next.handle` on the original request, forwarding it without mutating it at all.",
"translation": "我们这个什么也不做的处理器只是简单地在原始请求上调用`next.handle`,什么也不改动就转发出去。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "This pattern is similar to those in middleware frameworks such as Express.js.",
"translation": "这种工作模式类似于一些框架如Express.js中的中间件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "##### Providing your interceptor",
"translation": "##### 提供你自己的拦截器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Simply declaring the `NoopInterceptor` above doesn't cause your app to use it. You need to wire it up in your app module by providing it as an interceptor, as follows:",
"translation": "像上面这样简单地声明`NoopInterceptor`并不会让我们的应用实际使用它。还要通过把它作为拦截器提供给我们的应用模块才会生效,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Note the `multi: true` option. This is required and tells Angular that `HTTP_INTERCEPTORS` is an array of values, rather than a single value.",
"translation": "注意`multi: true`选项。这是必须的,因为它会告诉 Angular 这个 `HTTP_INTERCEPTORS` 表示的是一个数组,而不是单个的值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "##### Events",
"translation": "##### 事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "You may have also noticed that the Observable returned by `intercept` and `HttpHandler.handle` is not an `Observable<HttpResponse<any>>` but an `Observable<HttpEvent<any>>`. That's because interceptors work at a lower level than the `HttpClient` interface. A single request can generate multiple events, including upload and download progress events. The `HttpResponse` class is actually an event itself, with a `type` of `HttpEventType.HttpResponseEvent`.",
"translation": "注意,`intercept`和`HttpHandler.handle`返回的可观察对象并不是`Observable<HttpResponse<any>>`,而是`Observable<HttpEvent<any>>`。\n这是因为拦截器所工作的层级要低于 `HttpClient` 接口。单个请求会生成多个事件,比如表示上传和下载过程的事件。`HttpResponse`类实际上本身也是一个事件,只是它的`type`是`HttpEventType.HttpResponseEvent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "An interceptor must pass through all events that it does not understand or intend to modify. It must not filter out events it didn't expect to process. Many interceptors are only concerned with the outgoing request, though, and will simply return the event stream from `next` without modifying it.",
"translation": "拦截器必须透传所有它不理解或不打算修改的事件。它不能过滤掉自己不准备处理的事件。很多拦截器只关心要发出的请求,而只简单的返回`next`所返回的事件流,而不修改它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "##### Ordering",
"translation": "##### 顺序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "When you provide multiple interceptors in an application, Angular applies them in the order that you\nprovided them.",
"translation": "当我们在一个应用中提供了多个拦截器时Angular 会按照你提供时的顺序应用它们(译注:即模块的`providers`数组中列出的顺序)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "##### Immutability",
"translation": "##### 不可变性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Interceptors exist to examine and mutate outgoing requests and incoming responses. However, it may be surprising to learn that the `HttpRequest` and `HttpResponse` classes are largely immutable.",
"translation": "拦截器要检查和修改准备发出的请求和接收进来的响应。但是,你可能会惊奇的发现`HttpRequest`和`HttpResponse`类在很大程度上却是不可变的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "This is for a reason: because the app may retry requests, the interceptor chain may process an individual request multiple times. If requests were mutable, a retried request would be different than the original request. Immutability ensures the interceptors see the same request for each try.",
"translation": "这是有原因的:因为应用可能会重发请求,而拦截器链可能会多次处理同一个请求。如果请求是可变的,每次重试时的请求都可能和原始的请求不一样。而不可变对象可以确保拦截器每次重试时处理的都是同一个请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "There is one case where type safety cannot protect you when writing interceptors&mdash;the request body. It is invalid to mutate a request body within an interceptor, but this is not checked by the type system.",
"translation": "在一种情况下类型安全体系无法在写拦截器时提供保护 —— 请求体body。在拦截器中修改请求体本应是无效的但类型检查系统无法发现它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "If you have a need to mutate the request body, you need to copy the request body, mutate the copy, and then use `clone()` to copy the request and set the new body.",
"translation": "如果确实需要修改请求体,我们就得自己复制它,修改这个复本,然后使用`clone()`来复制这个请求,并使用这个新的请求体。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Since requests are immutable, they cannot be modified directly. To mutate them, use `clone()`:",
"translation": "由于请求都是不可变的,所以不能直接修改它们。要想修改,就使用`clone()`函数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "As you can see, the hash accepted by `clone()` allows you to mutate specific properties of the request while copying the others.",
"translation": "如你所见,传给`clone()`函数的这个哈希对象可以让我们在复制时修改请求中的特定属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### Setting new headers",
"translation": "#### 设置新的头",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "A common use of interceptors is to set default headers on outgoing responses. For example, assuming you have an injectable `AuthService` which can provide an authentication token, here is how you would write an interceptor which adds it to all outgoing requests:",
"translation": "拦截器的常见用途之一是为所发出的请求设置默认的请求头。比如,假设我们有一个可注入的`AuthService`,它可以提供一个认证令牌,而我们希望写一个拦截器,它负责把这个令牌添加到所有要发出的请求中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "The practice of cloning a request to set new headers is so common that there's actually a shortcut for it:",
"translation": "这种克隆一个请求并设置一组新的请求头的操作非常常见,因此有了一种快捷写法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "An interceptor that alters headers can be used for a number of different operations, including:",
"translation": "这种可以修改头的拦截器可以用于很多不同的操作,比如:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "* Authentication/authorization",
"translation": "认证 / 授权",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "* Caching behavior; for example, If-Modified-Since",
"translation": "控制缓存行为。比如`If-Modified-Since`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "* XSRF protection",
"translation": "XSRF 防护",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### Logging",
"translation": "#### 记日志",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Because interceptors can process the request and response _together_, they can do things like log or time requests. Consider this interceptor which uses `console.log` to show how long each request takes:",
"translation": "由于拦截器可以同时处理请求和响应,因此可以用来记日志或请求计时等。考虑下面这个拦截器,它使用`console.log`来显示每个请求花了多久:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n \tconst started = Date.now();\n return next\n .handle(req)\n .do(event => {\n if (event instanceof HttpResponse) {\n const elapsed = Date.now() - started;\n console.log(`Request for ${req.urlWithParams} took ${elapsed} ms.`);\n }\n });\n }\n}\n```\nNotice the RxJS `do()` operator&mdash;it adds a side effect to an Observable without affecting the values on the stream. Here, it detects the `HttpResponse` event and logs the time the request took.",
"translation": "注意 RxJS 的 `do()`操作符 —— 它为可观察对象添加一个副作用,而不会影响到流中的值。这里,它会检测`HttpResponse`的事件,并且记录这个请求花费的时间。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### Caching",
"translation": "#### 缓存",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "You can also use interceptors to implement caching. For this example, assume that you've written an HTTP cache with a simple interface:",
"translation": "我们也可以使用拦截器来实现缓存。比如,假设我们已经写了一个 HTTP 缓存,它具有如下的简单接口:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "An interceptor can apply this cache to outgoing requests.",
"translation": "拦截器可以把这个缓存应用到所发出的请求上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Obviously this example glosses over request matching, cache invalidation, etc., but it's easy to see that interceptors have a lot of power beyond just transforming requests. If desired, they can be used to completely take over the request flow.",
"translation": "显然,这个例子忽略了请求匹配、缓存失效等问题,但是很容易看出除了转换请求外,拦截器还有很强力的功能。如果需要,它们可以完全接管请求流程。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "To really demonstrate their flexibility, you can change the above example to return _two_ response events if the request exists in cache&mdash;the cached response first, and an updated network response later.",
"translation": "为了实际演示它们的灵活性,我们可以把上面的例子改为:如果请求已经存在于缓存中了,就返回*两个*响应事件,第一个是缓存的响应,第二个是从网络上更新过来的响应。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Now anyone doing `http.get(url)` will receive _two_ responses if that URL has been cached before.",
"translation": "现在,如果 URL 被缓存过,那么任何人调用`http.get(url)`时都会收到*两次*响应。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Listening to progress events",
"translation": "### 监听进度事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Sometimes applications need to transfer large amounts of data, and those transfers can take time. It's a good user experience practice to provide feedback on the progress of such transfers; for example, uploading files&mdash;and `@angular/common/http` supports this.",
"translation": "有时候应用需要传输一大堆数据,这时传输就需要花一些时间。在这种传输过程中(比如上传文件)给用户一些关于进度的反馈能带来更好的用户体验,而`@angular/common/http`支持它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "To make a request with progress events enabled, first create an instance of `HttpRequest` with the special `reportProgress` option set:",
"translation": "要发起一个支持进度事件的请求,首先要创建一个设置过`reportProgress`选项的`HttpRequest`实例:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "This option enables tracking of progress events. Remember, every progress event triggers\nchange detection, so only turn them on if you intend to actually update the UI on each event.",
"translation": "该选项让我们可以跟踪进度事件。记住,每个进度事件都会触发变更检测,所以应该只有在你真的打算在每个事件中更新 UI 时才打开它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Next, make the request through the `request()` method of `HttpClient`. The result will be an Observable of events, just like with interceptors:",
"translation": "接下来,通过`HttpClient`上的`request()`方法发起这个请求。其结果应该是一个关于事件的可观察对象,就像拦截器中看到的那样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "## Security: XSRF Protection",
"translation": "## 安全XSRF 防护",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"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/content-1/guide/http.md"
},
{
"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/content-1/guide/http.md"
},
{
"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/content-1/guide/http.md"
},
{
"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/content-1/guide/http.md"
},
{
"original": "### Configuring custom cookie/header names",
"translation": "### 配置自定义 cookie/header 名称",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "If your backend service uses different names for the XSRF token cookie or header, use `HttpClientXsrfModule.withConfig()` to override the defaults.",
"translation": "如果我们的后端服务中对 XSRF 令牌的 cookie 或 头使用了不一样的名字,就要使用 `HttpClientXsrfModule.withConfig()` 来覆盖掉默认值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "## Testing HTTP requests",
"translation": "## 测试 HTTP 请求",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Like any external dependency, the HTTP backend needs to be mocked as part of good testing practice. `@angular/common/http` provides a testing library `@angular/common/http/testing` that makes setting up such mocking straightforward.",
"translation": "如同所有的外部依赖一样HTTP 后端也需要在良好的测试实践中被 Mock 掉。`@angular/common/http` 提供了一个测试库 `@angular/common/http/testing`,它让我们可以直截了当的进行这种 Mock 。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Mocking philosophy",
"translation": "### Mock 方法论",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Angular's HTTP testing library is designed for a pattern of testing where the app executes code and makes requests first. After that, tests expect that certain requests have or have not been made, perform assertions against those requests, and finally provide responses by \"flushing\" each expected request, which may trigger more new requests, etc. At the end, tests can optionally verify that the app has made no unexpected requests.",
"translation": "Angular 的 HTTP 测试库是为这种模式的测试而设计的应用执行代码并首先发起请求之后测试代码会期待expect特定的请求发起过或没发起然后对那些请求进行断言最终通过刷新flushing每个被期待的请求来提供响应此后还可能会触发更多新的请求。最后测试代码还可以根据需要去验证应用不曾发起过预期之外的请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Setup",
"translation": "### 初始设置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "To begin testing requests made through `HttpClient`, import `HttpClientTestingModule` and add it to your `TestBed` setup, like so:",
"translation": "要开始测试那些通过`HttpClient`发起的请求,就要导入`HttpClientTestingModule`模块,并把它加到你的`TestBed` 设置里去,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "That's it. Now requests made in the course of your tests will hit the testing backend instead of the normal backend.",
"translation": "这样就可以了。现在,在测试代码中发起的请求将会抵达后端的测试替身,而不是标准后端(真实服务器)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "### Expecting and answering requests",
"translation": "### 期待并回复请求",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "With the mock installed via the module, you can write a test that expects a GET Request to occur and provides a mock response. The following example does this by injecting both the `HttpClient` into the test and a class called `HttpTestingController`",
"translation": "在通过本模块安装了 Mock 之后,我们可以就写一个测试来期待发生一个 GET 请求,并给出一个 Mock 版的响应。\n下列例子通过把 `HttpClient` 同时注入到测试代码和一个名叫`HttpTestingController`的类中来做到这一点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"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/content-1/guide/http.md"
},
{
"original": "#### Custom request expectations",
"translation": "#### 自定义请求的预期",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "If matching by URL isn't sufficient, it's possible to implement your own matching function. For example, you could look for an outgoing request that has an Authorization header:",
"translation": "如果根据 URL 匹配还不满足要求也可以实现我们自己的匹配函数。比如我们可以查找一个具有特定认证Authorization头的对外请求",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "Just as with the `expectOne()` by URL in the test above, if 0 or 2+ requests match this expectation, it will throw.",
"translation": "和前面根据 URL 进行测试时一样,如果零或两个以上的请求匹配上了这个期待,它就会抛出异常。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "#### Handling more than one request",
"translation": "#### 处理一个以上的请求",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "If you need to respond to duplicate requests in your test, use the `match()` API instead of `expectOne()`, which takes the same arguments but returns an array of matching requests. Once returned, these requests are removed from future matching and are your responsibility to verify and flush.",
"translation": "如果我们需要在测试中对重复的请求进行响应,可以使用`match()` API 来代替 `expectOne()`它的参数不变但会返回一个与这些请求相匹配的数组。一旦返回这些请求就会从将来要匹配的列表中移除而验证和刷新flush是我们自己的职责。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/http.md"
},
{
"original": "# Internationalization (i18n)",
"translation": "# 国际化i18n",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Angular's _internationalization_ (_i18n_) tools help make your app available in multiple languages.",
"translation": "Angular的*国际化**i18n*)工具可以帮助我们使用多个语言发布应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Try this <live-example name=\"i18n\" title=\"i18n Example in Spanish\">live example</live-example>\nof a JIT-compiled app, translated into Spanish.",
"translation": "**试试** 这个翻译为西班牙语版JiT编译应用的<live-example name=\"i18n\">在线例子</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Angular and _i18n_ template translation",
"translation": "## Angular和_i18n_模板翻译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Application internationalization is a challenging, many-faceted effort that\ntakes dedication and enduring commitment.\nAngular's _i18n_ internationalization facilities can help.",
"translation": "应用程序国际化很具有挑战性,多方面的努力,需要持久的奉献和决心。\nAngular的_i18n_国际化工具可以帮助你。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "This page describes the _i18n_ tools available to assist translation of component template text\ninto multiple languages.",
"translation": "本章描述了一些_i18n_工具它们可以帮你把组件模板文本翻译成多种语言。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Practitioners of _internationalization_ refer to a translatable text as a \"_message_\".\nThis page uses the words \"_text_\" and \"_message_\" interchangeably and in the combination, \"_text message_\".",
"translation": "**国际化**工作者通常将一个可翻译的文本叫作“信息”。\n本章使用了“文本”和“信息”它们可以互换也可以组合“文本信息”。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The _i18n_ template translation process has four phases:",
"translation": "_i18n_模板翻译流程有四个阶段",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. Mark static text messages in your component templates for translation.",
"translation": "在组件模板中标记需要翻译的静态文本信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. An angular _i18n_ tool extracts the marked messages into an industry standard translation source file.",
"translation": "Angular的_i18n_工具将标记的信息提取到一个行业标准的翻译源文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. A translator edits that file, translating the extracted text messages into the target language,\nand returns the file to you.",
"translation": "翻译人员编辑该文件,翻译提取出来的文本信息到目标语言,并将该文件还给你。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. The Angular compiler imports the completed translation files,\nreplaces the original messages with translated text, and generates a new version of the application\nin the target language.",
"translation": "Angular编译器导入完成翻译的文件使用翻译的文本替换原始信息并生成新的目标语言版本的应用程序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You need to build and deploy a separate version of the application for each supported language.",
"translation": "你可以为每种支持的语言构建和部署单独的应用程序版本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Mark text with the _i18n_ attribute",
"translation": "## 使用_i18n_属性标记文本",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The Angular `i18n` attribute is a marker for translatable content.\nPlace it on every element tag whose fixed text should be translated.",
"translation": "Angular的`i18n`属性是可翻译内容的标记。\n将它放到每个固定文本需要翻译的元素标签中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "`i18n` is not an Angular _directive_.\nIt's a custom _attribute_, recognized by Angular tools and compilers.\nAfter translation, the compiler removes it.",
"translation": "`i18n`不是Angular指令。\n它是一个自定义**属性**Angular工具和编译器认识它。\n它将在完成翻译**之后**,被编译器移除。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "In the accompanying sample, an `<h1>` tag displays a simple English language greeting\nthat you translate into Spanish:",
"translation": "在例子中,`<h1>`标签显示了一句简单的英文问候语,它将被翻译为西班牙语:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Add the `i18n` attribute to the tag to mark it for translation.",
"translation": "添加`i18n`属性到该标签上,把它标记为需要翻译的文本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Help the translator with a _description_ and _meaning_",
"translation": "### 用描述和意图来帮助翻译人员",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "In order to translate it accurately, the translator may\nneed a description of the message.\nAssign a description to the i18n attribute:",
"translation": "翻译人员可能需要待翻译文本的描述才能翻译准确。\n为i18n属性添加描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "In order to deliver a correct translation, the translator may need to\nknow the _meaning_ or _intent_ of the text within _this particular_ application context.",
"translation": "为了给出正确的翻译,翻译者需要知道你这段文本在特定情境下的 *真实意图*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You add context by beginning the string with the _meaning_ and\nseparating it from the _description_ with the `|` character (`<meaning>|<description>`):",
"translation": "在描述的前面,我们为指定的字符串添加一些上下文含义,用`|`将其与描述文字隔开(`<意图>|<描述>`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "While all appearances of a message with the _same_ meaning have the _same_ translation,\na message with *a variety of possible meanings* could have different translations.\nThe Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file\nto facilitate contextually-specific translations.",
"translation": "如果所有地方出现的文本具有**相同**含义时,它们应该有**相同**的翻译,\n但是如果在某些地方它具有**不同含义**,那么它应该有不同的翻译。\nAngular的提取工具在翻译源文件中保留**含义**和**描述**,以支持符合特定上下文的翻译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Set a custom _id_ to improve search and maintenance",
"translation": "### 设置一个自定义的`id`来提升可搜索性和可维护性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The angular _i18n_ extractor tool generates a file with a _translation unit_ entry for each `i18n` attribute 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/content-1/guide/i18n.md"
},
{
"original": "This _id_ is obscure and difficult for humans to read or remember.",
"translation": "这个`id`对于人类来说太晦涩,难于阅读和记忆。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Worse, when you change the translatable text, perhaps to fix a typo,\nthe extractor tool generates a new _id_ for that translation.\nYou will lose the translation unless you update it with the new _id_.\nThat [complicates maintenance](#maintenance).",
"translation": "更糟的是,当我们修改这段可翻译的文字时(比如修改一个拼写错误),提取工具会生成一个新的`id`。\n我们就会丢失这段翻译成果除非把它修改为新的`id`。那样维护起来就太复杂了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Consider specifying your own, meaningful _id_ in the `i18n` attribute, **prefixed with `@@`**.",
"translation": "要想自己为`i18n`属性指定一个有意义的`id`,可以给它**添加`@@`前缀**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Now the extractor tool and compiler will generate a translation unit with _your custom id_ and never change it.",
"translation": "现在,提取工具和编译器就会用*你的自定义id`生成一个翻译单元,而不会再改变它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Here is the `i18n` attribute with a _definition_, followed by the custom `id`:",
"translation": "下面这个例子中的`i18n`属性中有一个*定义*,然后跟着自定义`id`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Here is a _meaning_ and a _description_ and the _id_ at the end:",
"translation": "下面这个例子带有*含义*和*描述*,最后是`id`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Be sure to define _unique_ custom ids. If you use the same id for 2 _different_ blocks of text, only the first one will be extracted,\n and its translation used in both blocks of text.",
"translation": "为了确保定义出*唯一*的自定义id。如果我们对两个*不同的*文本块使用了同一个id那么就只有一个会被提取出来然后其翻译结果会被用于全部文本块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "For example:",
"translation": "比如:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "with the translation:",
"translation": "带有翻译结果的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Both `<p>` elements will contain the text `Hola`.",
"translation": "两个`<p>`元素都会包含文本`Hola`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Translate text without creating an element",
"translation": "### 翻译文本,而不必创建元素",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "If there is a stretch of text that you'd like to translate, you could wrap it in a `<span>` tag.\nBut 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>` will be transformed into an html comment:",
"translation": "如果要翻译一段纯文本,我们就可以把它用`<span>`标签包裹起来。\n但如果由于某些原因比如CSS结构方面的考虑我们可能不希望仅仅为了翻译而创建一个新的DOM元素那么也可以把这段文本包裹进一个`<ng-container>`元素中。`<ng-container>`将被转换成一个HTML注释",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Add _i18n_ translation attributes",
"translation": "## 添加 *i18n* 翻译属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You've added an image to your template. You care about accessibility too so you add a `title` attribute:",
"translation": "我们已经把一个图片添加到了模板中。我们也关心可访问性,故此也添加了一个`title`属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The `title` attribute needs to be translated.\nAngular i18n support has more translation attributes in the form,`i18n-x`, where `x` is the\nname of the attribute to translate.",
"translation": "这个 `title` 属性也需要翻译。\nAngular i18n 支持更多形如`i18n-x`的属性,其中的`x`就是要翻译的属性名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "To translate the `title` on the `img` tag from the previous example, write:",
"translation": "为了翻译前面例子中`img`标签上的`title`属性,就要这样写:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You can also assign a meaning and a description with the `i18n-x=\"<meaning>|<description>\"` syntax.",
"translation": "我们也同样可以使用`i18n-x=\"<meaning>|<description>\"`语法来指定一个含义和描述。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Handle singular and plural",
"translation": "## 处理单数与复数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Different languages have different pluralization rules.",
"translation": "不同的语言有不同的单复数规则。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Suppose your application says something about a collection of wolves.\nIn English, depending upon the number of wolves, you could display \"no wolves\", \"one wolf\", \"two wolves\", or \"a wolf pack\".\nOther languages might express the _cardinality_ differently.",
"translation": "假设应用中需要谈论一些狼。\n在英语中根据狼的数量可能要显示为\"no wolves\"、\"one wolf\"、\"two wolves\"或\"a wolf pack\"。\n而在其它语言中则可能会有不同的**基数**规则。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Here's how you could mark up the component template to display the phrase appropriate to the number of wolves:",
"translation": "下面我们示范要如何书写组件模板来显示适当的短语来表示狼的数量:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* The first parameter is the key. It is bound to the component property (`wolves`) that determines the number of wolves.",
"translation": "第一个参数是key。它绑定到了组件中表示狼的数量的`wolves`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* The second parameter identifies this as a `plural` translation type.",
"translation": "第二个参数表示这是一个`plural`(复数)翻译类型。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* The third parameter defines a pluralization pattern consisting of pluralization\ncategories and their matching values.",
"translation": "第三个参数定义了一组复数表示模式,这个模式由复数类别和它们所匹配的值组成。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Pluralization categories include:",
"translation": "复数类别包括:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* =0 (or any other number)",
"translation": "=0 (或其它数字)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* zero",
"translation": "zero",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* one",
"translation": "one一个)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* two",
"translation": "two两个",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* few",
"translation": "few少数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* many",
"translation": "many很多",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* other",
"translation": "other其它",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Put the default _English_ translation in braces (`{}`) next to the pluralization category.",
"translation": "把默认的*英语*翻译结果放在复数类别之后的括号(`{}`)中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* When you're talking about one wolf, you could write `=1 {one wolf}`.",
"translation": "如果要说一只狼,就写`=1 {one wolf}`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* For zero wolves, you could write `=0 {no wolves}`.",
"translation": "如果要说零只狼,就写`=0 {no wolves}`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* For two wolves, you could write `=2 {two wolves}`.",
"translation": "如果要说两只狼,就写`=2 {two wolves}`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You could keep this up for three, four, and every other number of wolves.\nOr you could specify the **`other`** category as a catch-all for any unmatched cardinality\nand write something like: `other {a wolf pack}`.",
"translation": "三只、四只或其它数量的狼也都以此类推。\n或者我们也可以指定**`other`**类来捕获所有未匹配上的数量,写法为:`other {a wolf pack}`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "This syntax conforms to the\n<a href=\"http://userguide.icu-project.org/formatparse/messages\" title=\"ICU Message Format\">ICU Message Format</a>\nthat derives from the\n<a href=\"http://cldr.unicode.org/\" title=\"CLDR\">Common Locale Data Repository (CLDR)</a>,\nwhich specifies the\n<a href=\"http://cldr.unicode.org/index/cldr-spec/plural-rules\" title=\"Pluralization Rules\">pluralization rules</a>.",
"translation": "这个写法符合<a href=\"http://userguide.icu-project.org/formatparse/messages\" title=\"ICU Message Format\">ICU消息格式</a>,它源自<a href=\"http://cldr.unicode.org/\" title=\"CLDR\">通用区域设置数据库(CLDR)</a>,其中指定了<a href=\"http://cldr.unicode.org/index/cldr-spec/plural-rules\" title=\"Pluralization Rules\">复数规则</a>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Select among alternative texts",
"translation": "## 在候选文本中选择",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The application displays different text depending upon whether the hero is male or female.\nThese text alternatives require translation too.",
"translation": "该应用还要根据英雄是男是女而显示出不同的文本,这些候选文本也同样需要翻译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You can handle this with a `select` translation.\nA `select` also follows the\n<a href=\"http://userguide.icu-project.org/formatparse/messages\" title=\"ICU Message Format\">ICU message syntax</a>.\nYou choose among alternative translation based on a string value instead of a number.",
"translation": "我们可以使用`select`翻译器来处理它。\n`select`也同样遵循<a href=\"http://userguide.icu-project.org/formatparse/messages\" title=\"ICU Message Format\"> ICU 消息语法</a>。我们在候选文本之间选择,但根据的是一个字符串值而不再是数字。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The following format message in the component template binds to the component's `gender`\nproperty, which outputs either an \"m\" or an \"f\".\nThe message maps those values to the appropriate translation:",
"translation": "组件模板中的下列消息格式绑定到了组件的`gender`属性,这个属性的取值是\"m\"或\"f\"。\n这个消息会把那些值映射到适当的翻译文本",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Nesting pluralization and selection expressions",
"translation": "## 把\"复数\"与\"选择\"表达式嵌套在一起",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You can also nest different ICU expressions together. For example:",
"translation": "我们也可以把不同的 ICU 表达式嵌套在一起,比如:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Create a translation source file with the _ng-xi18n_ tool",
"translation": "## 使用_ng-xi18n_工具创建翻译源文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Use the **_ng-xi18n_ extraction tool** to extract the `i18n`-marked texts \ninto a translation source file in an industry standard format.",
"translation": "使用`ng-xi18n`提取工具来将`i18n`标记的文本提取到一个符合行业标准格式的翻译源文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "This is an Angular CLI tool in the `@angular/compiler-cli` npm package.\nIf you haven't already installed the CLI and its `platform-server` peer dependency, do so now:",
"translation": "它是在`@angular/compiler-cli` npm包中的一个Angular CLI工具。\n如果你还没有安装这个CLI和它的 `platform-server`,安装它们:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Open a terminal window at the root of the application project and enter the `ng-xi18n` command:",
"translation": "在应用的项目根目录打开一个终端窗口,并输入`ng-xi18n`命令:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"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 (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/content-1/guide/i18n.md"
},
{
"original": "### Other translation formats",
"translation": "### 其它翻译格式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Angular i18n tooling supports XLIFF 1.2 and XLIFF 2 as well as the\n<a href=\"http://cldr.unicode.org/development/development-process/design-proposals/xmb\" >XML Message Bundle (XMB)</a>.",
"translation": "除了<a href=\"http://cldr.unicode.org/development/development-process/design-proposals/xmb\" >XML消息捆(XMB)</a>格式外Angular的i18n工具也同样支持 XLIFF 1.2和XLIFF 2 格式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You can specify your choice of format _explicitly_ with the `--i18nFormat` flag as illustrated in these example commands",
"translation": "我们可以使用`--i18nFormat`来明确指定想用的格式,范例如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The sample in _this_ guide sticks with the default _XLIFF 1.2_ format.",
"translation": "本章的范例默认使用 _XLIFF 1.2_ 格式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Other options",
"translation": "### 其它选项",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You may have to specify additional options.\nFor example, if the `tsconfig.json` TypeScript configuration\nfile is located somewhere other than in the root folder,\nyou must identify the path to it with the `-p` option:",
"translation": "我们还可能需要指定其它选项。\n比如如果TypeScript的配置文件`tsconfig.json`位于其它地方而不是根目录,我们就要通过`-p`选项来明确指出它的路径。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Add an _npm_ script for convenience",
"translation": "### 添加`npm`便利脚本",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Consider adding a convenience shortcut to the `scripts` section of the `package.json`\nto make the command easier to remember and run:",
"translation": "考虑在`package.json`的`scripts`区中添加一个便利脚本,来让命令更容易记忆和运行:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Now you can issue command variations such as these:",
"translation": "现在,我们就可以使用这些命令的变体形式了,比如:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Note the `--` flag before the options.\nIt tells _npm_ to pass every flag thereafter to `ng-xi18n`.",
"translation": "注意选项前面的`--`标识。它告诉`npm`要把这个参数后面的每一个标识都透传给`ng-xi18n`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Translate text messages",
"translation": "## 翻译文本信息",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The `ng-xi18n` command generates a translation source file \nin the project root folder named `messages.xlf`.\nThe next step is to translate the English language template\ntext into the specific language translation\nfiles. The guide sample creates a Spanish translation file.",
"translation": "`ng-xi18n`命令在项目根目录生成一个名为`messages.xlf`的翻译源文件。\n下一步是将英文模板文本翻译到目标语言的翻译文件。\n本烹饪书创建了一个西班牙语翻译文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Create a localization folder",
"translation": "### 新建一个本土化目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You will probably translate into more than one other language so it's a good idea\nfor the project structure to reflect your entire internationalization effort.",
"translation": "你很有可能翻译到更多其他语言,所以为全部国际化工作做适当的调整项目目录结构是理所当然的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "One approach is to dedicate a folder to localization and store related assets ,\nsuch as internationalization files, there.",
"translation": "其中一种方法是为本土化和相关资源(比如国际化文件)创建一个专门的目录。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Localization and internationalization are\n<a href=\"https://en.wikipedia.org/wiki/Internationalization_and_localization\">different but closely related terms</a>.",
"translation": "本土化和国际化是<a href=\"https://en.wikipedia.org/wiki/Internationalization_and_localization\" target=\"_blank\">不同但是很相近的概念</a>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "This guide follows that suggestion. It has a `locale` folder under `src/`.\nAssets within the folder carry a filename extension that matches a language-culture code from a\n<a href=\"https://msdn.microsoft.com/en-us/library/ee825488(v=cs.20).aspx\">well-known codeset</a>.",
"translation": "本指南遵循了那个建议。在`src/`目录下,有一个专门的`locale`目录,该目录中的文件都带有一个代号作为扩展名,它们来自这个<a href=\"https://msdn.microsoft.com/en-us/library/ee825488(v=cs.20).aspx\">众所周知的代号表</a>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Make a copy of the `messages.xlf` file, put it in the `locale` folder and\nrename it `messages.es.xlf`for the Spanish language translation.\nDo the same for each target language.",
"translation": "复制一下`messages.xlf`文件,把它放进`locale`目录,并改名为`messages.es.xlf`以用于西班牙语的翻译。对其它目标语言也同样要这么做。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Translate text nodes",
"translation": "### 翻译文本节点",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "In the real world, you send the `messages.es.xlf` file to a Spanish translator who fills in the translations\nusing one of the\n<a href=\"https://en.wikipedia.org/wiki/XLIFF#Editors\">many XLIFF file editors</a>.",
"translation": "在现实世界中,`messages.es.xlf`文件会被发给西班牙语翻译,他们使用<a href=\"https://en.wikipedia.org/wiki/XLIFF#Editors\" target=\"_blank\">这些XLIFF文件编辑器</a>中的一种来翻译它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "This sample file is easy to translate without a special editor or knowledge of Spanish.\nOpen `messages.es.xlf` and find the first `<trans-unit>` section:",
"translation": "我们不需要任何编辑器或者西班牙语知识就可以轻易的翻译本例子文件。\n打开`messages.es.xlf`并找到`<trans-unit>`节点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "This XML element represents the translation of the `<h1>` greeting tag you marked with the `i18n` attribute.",
"translation": "这个XML元素代表了你使用`i18n`属性标记的`<h1>`问候语标签的翻译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Using the _source_, _description_, and _meaning_ elements to guide your translation,\nreplace the `<target/>` tag with the Spanish greeting:",
"translation": "翻译中利用_source_、_description_和_meaning_元素的信息替换`<target/>`标签为西班牙语问候语:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "**The tool generated the `id`s for _these_ translation units. Don't touch them.**\nEach `id` depends upon the content of the message and its assigned meaning.\nChange either factor and the `id` changes as well.",
"translation": "注意`id`是工具生成的。不要修改它。\n它的值取决于两个因素信息的内容和其指定的含义。\n改变任何一个因素`id`就会改变。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "See the **[translation file maintenance discussion](#maintenance)**.",
"translation": "参见**[关于如何维护翻译结果文件的讨论](#maintenance)**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "This is why you should **[specify custom ids](#custom-id \"Set a custom id\")** and avoid tool generated ids.",
"translation": "这就是为什么我们应该**[指定自定义 id](#custom-id \"Set a custom id\")**避免让工具自动生成id。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Translate _plural_ and _select_",
"translation": "## 翻译*复数plural*和*选择select*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Translating _plural_ and _select_ messages is a little tricky.",
"translation": "翻译*复数*和*选择*类的消息有点棘手。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The `<source>` tag is empty for `plural` and `select` translation\nunits, which makes them hard to correlate with the original template.\nThe `XLIFF` format doesn't yet support the ICU rules.\nHowever, the `XMB` format does support the ICU rules.",
"translation": "对于复数(`plural`)和选择(`select`)类型的翻译单元来说,<source>`标签是空的,这让它们很难和原始模板关联起来。\n`XLIFF` 不支持这种 ICU 规则,但`XMB`格式却支持。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You'll just have to look for them in relation to other translation units that you recognize from elsewhere in the source template.\nIn this example, you know the translation unit for the `select` must be just below the translation unit for the logo.",
"translation": "我们要根据从原始模板中其它地方识别出来的翻译单元来找到建立它和原始模板之间的关联。\n比如在这个例子中我们知道`select`一定会出现在logo的翻译单元的紧下方。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Translate _plural_",
"translation": "### 翻译*复数*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "To translate a `plural`, translate its ICU format match values:",
"translation": "要翻译一个复数就要翻译它的ICU格式中匹配的值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Translate _select_",
"translation": "### 翻译*选择*select",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The `select` behaves a little differently. Here again is the ICU format message in the component template:",
"translation": "`select`的行为略有不同。我们仍然来看组件模板中的ICU格式的消息",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The extraction tool broke that into _two_ translation units.",
"translation": "提取工具会把它拆成*两个*翻译单元。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The first unit contains the text that was _outside_ the `select`.\nIn place of the `select` is a placeholder, `<x id=\"ICU\">`, that represents the `select` message.\nTranslate the text and leave the placeholder where it is.",
"translation": "第一个单元包含`select`之外的文本。\n这里的`select`是一个占位符`<x id=\"ICU\">`,用来表示`select`中的消息。\n翻译这段文本并把占位符放在那里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The second translation unit, immediately below the first one, contains the `select` message. Translate that.",
"translation": "第一个翻译单元的紧下方就是第二个翻译单元,包含`select`中的消息。翻译它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Here they are together, after translation:",
"translation": "在翻译之后,它们会放在一起:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Translate a nested expression",
"translation": "### 翻译嵌套的表达式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "A nested expression is not different from the previous ones. As in the previous example, we have _two_ translation units.",
"translation": "嵌套的表达式和前一节没有什么不同。就像上一个例子中那样,我们有*两个*翻译单元。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The first one contains the text outside the nested expression:",
"translation": "第一个包含嵌套表达式外部的文本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The second unit contains the complete nested expression:",
"translation": "第二个包含完整的嵌套表达式:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "And both together:",
"translation": "放在一起时:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The entire template translation is complete. It's\ntime to incorporate that translation into the application.",
"translation": "整个模板的翻译就完成了。现在就该把翻译结果放回到应用程序中了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### The app before translation",
"translation": "### 翻译前的应用程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "When the previous steps finish, the sample app _and_ its translation file are as follows:",
"translation": "如下所示,是完成前面的步骤后的例子应用**和**它的翻译文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## Merge the completed translation file into the app",
"translation": "## 合并已经翻译的文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "To merge the translated text into component templates,\ncompile the application with the completed translation file.\nThe process is the same whether the file is in `.xlf` format or \nin another format that Angular understands, such as `.xtb`.",
"translation": "要合并已经翻译的文件到组件模板,使用翻译过的文件编译应用。\n不管文件是`.xlf`格式还是其他Angular接受的格式`.xlif`和`.xtb`),流程是一样的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You provide the Angular compiler with three new pieces of information:",
"translation": "你要为Angular编译器提供下列三种新信息",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* The translation file.",
"translation": "翻译文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* The translation file format.",
"translation": "翻译文件的格式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* The <a href=\"https://en.wikipedia.org/wiki/XLIFF\">_Locale ID_</a>\n (`es` or `en-US` for instance).",
"translation": "目标<a href=\"https://en.wikipedia.org/wiki/XLIFF\" target=\"_blank\">_语言环境ID_</a>\n (例如`es`或`en-US`)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "_How_ you provide this information depends upon whether you compile with\nthe JIT (_Just-in-Time_) compiler or the AOT (_Ahead-of-Time_) compiler.",
"translation": "你如何提供这些信息取决于你使用的是JiT即时编译器还是AoT预先编译器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* With [JIT](guide/i18n#jit), you provide the information at bootstrap time.",
"translation": "使用[JiT](guide/i18n#jit)时,在引导时提供",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* With [AOT](guide/i18n#aot), you pass the information as `ngc` options.",
"translation": "使用[AoT](guide/i18n#aot)时,在`ngc`命令的选项里提供",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Merge with the JIT compiler",
"translation": "### 用JiT编译器合并",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The JIT compiler compiles the application in the browser as the application loads.\nTranslation with the JIT compiler is a dynamic process of:",
"translation": "JiT即时编译器在应用程序加载时在浏览器中编译应用。\n在使用JiT编译器的环境中翻译是一个动态的流程包括",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "2. Importing the appropriate language translation file as a string constant.",
"translation": "导入合适的语言翻译文件到一个字符串常量,",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "3. Creating corresponding translation providers to guide the JiT compiler.",
"translation": "新建对应的翻译提供商来指导JiT编译器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "4. Bootstrapping the application with those providers.",
"translation": "使用这些提供商来启动应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Open `index.html` and revise the launch script as follows:",
"translation": "打开`index.html`并这样修改加载脚本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "In this sample, the user's language is hard-coded as a global `document.locale` variable\nin the `index.html`.",
"translation": "在本例中,用户的语言在`index.html`中被硬编码到一个全局的`document.locale`变量中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### SystemJS text plugin",
"translation": "### SystemJS文本插件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Notice the SystemJS mapping of `text` to a `systemjs-text-plugin.js`.\nWith the help of a text plugin, SystemJS can read any file as raw text and\nreturn the contents as a string.\nYou'll need it to import the language translation file.",
"translation": "注意SystemJS将`text`映射为`systemjs-text-plug.js`。\n在这个文本插件的帮助下SystemJS可以读取任何原始文件并将其内容作为字符串返回。\n你需要使用它来导入语言翻译文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "SystemJS doesn't ship with a raw text plugin but it's easy to add.\nCreate the following `systemjs-text-plugin.js` in the `src/` folder:",
"translation": "SystemJS没有自带原始文本插件但是我们很容易添加它。\n在`src/`目录新建下面的`systemjs-text-plugin.js`文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Create translation providers",
"translation": "### 新建翻译提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Three providers tell the JIT compiler how to translate the template texts for a particular language\nwhile compiling the application:",
"translation": "三种提供商帮助JiT编译在编译应用时将模板文本翻译到某种语言",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* `TRANSLATIONS` is a string containing the content of the translation file.",
"translation": "`TRANSLATIONS`是含有翻译文件内容的字符串。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlf2`, or `xtb`.",
"translation": "`TRANSLATIONS_FORMAT`是文件的格式: `xlf`、`xlif`或`xtb`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* `LOCALE_ID` is the locale of the target language.",
"translation": "`LOCALE_ID`是目标语言的语言环境。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The `getTranslationProviders()` function in the following `src/app/i18n-providers.ts`\ncreates those providers based on the user's _locale_\nand the corresponding translation file:",
"translation": "在下面的`src/app/i18n-providers.ts`文件的`getTranslationProviders()`函数中,根据用户的**语言环境**和对应的翻译文件构建这些提供商:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. It gets the locale from the global `document.locale` variable that was set in `index.html`.",
"translation": "它从在`index.html`中设置的全局`document.locale`变量中获取语言环境。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. If there is no locale or the language is U.S. English (`en-US`), there is no need to translate.\n The function returns an empty `noProviders` array as a `Promise`.\n It must return a `Promise` because this function could read a translation file asynchronously from the server.",
"translation": "如果没有语言环境或者语言是美国英语(`en-US`),则就无需翻译。该函数以`Promise`的形式返回一个空的`noProviders`数组。它必须要返回`Promise`,因为这个函数可能异步从服务器读取翻译文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. It creates a transaction filename from the locale according to the name and location convention\n[described earlier](guide/i18n#localization-folder).",
"translation": "根据[上面描述](guide/i18n#localization-folder)的名字和本土化的约定,它根据语言环境创建一个合约文件名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. The `getTranslationsWithSystemJs()` method reads the translation and returns the contents as a string.\nNotice that it appends `!text` to the filename, telling SystemJS to use the [text plugin](guide/i18n#text-plugin).",
"translation": "`getTranslationsWithSystemJs()`方法读取翻译并以字符串的形式返回其内容。\n注意它在文件名上附加`!text`告诉SystemJS使用[文本插件](guide/i18n#text-plugin)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. The callback composes a providers array with the three translation providers.",
"translation": "回调函数使用这三种翻译提供商创建一个提供商数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "1. Finally, `getTranslationProviders()` returns the entire effort as a promise.",
"translation": "最后,`getTranslationProviders()`返回以承诺的形式返回全部流程的结果。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Bootstrap with translation providers",
"translation": "### 使用翻译提供商引导应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The Angular `bootstrapModule()` method has a second _options_ parameter\nthat can influence the behavior of the compiler.",
"translation": "Angular的`bootstrapModule()`方法接受**可选的**第二参数,它可以影响编译器的行为。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "You'll create an _options_ object with the translation providers from `getTranslationProviders()`\nand pass it to `bootstrapModule`.\nOpen the `src/main.ts` and modify the bootstrap code as follows:",
"translation": "从`getTranslationProviders()`返回的翻译提供商创建_options_对象并将其传给`bootstrapModule`。\n打开`src/main.ts`并这样修改引导代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Notice that it waits for the `getTranslationProviders()` promise to resolve before\nbootstrapping the app.",
"translation": "注意,它等待`getTranslationProviders()`承诺的解析完成后,才引导应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The app is now _internationalized_ for English and Spanish and there is a clear path for adding\nmore languages.",
"translation": "现在,应用已经被国际化为英语版和西班牙语版,而且我们有了清晰的添加更多语言的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### _Internationalization_ with the AOT compiler",
"translation": "### 使用AoT编译器时的国际化",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The JIT compiler translates the application into the target language\nwhile compiling dynamically in the browser.\nThat's flexible but may not be fast enough for your users.",
"translation": "JiT编译器在浏览器中动态编译应用时将其翻译到目标语言。\n这样很灵活但是对用户来讲可能速度太慢。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "The AOT (_Ahead-of-Time_) compiler is part of a build process that\nproduces a small, fast, ready-to-run application package.\nWhen you internationalize with the AOT compiler, you pre-build\na separate application package for each\nlanguage. Then in the host web page, in this case `index.html`,\nyou determine which language the user needs\nand serve the appropriate application package.",
"translation": "AoT预先编译器是一种构建流程出产尺寸小、速度快和可执行的应用程序包。\n在使用Aot编译器的环境中国际化你为每种语言预先构建一个单独的应用程序包。然后在宿主网络页面`index.html`)中,你再决定用户需要哪种语言,并选择合适的应用程序包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "This guide doesn't cover how to build multiple application packages and\nserve them according to the user's language preference.\nIt does explain the few steps necessary to tell the AOT compiler to apply a translations file.",
"translation": "本烹饪书不介绍如何构建多种应用程序包和如何根据用户的语言设置推送它们。\n它介绍了一些必要的步骤来告诉AoT采用翻译文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Internationalization with the AOT compiler requires\nsome setup specifically for AOT compilation.\nStart with the application project as shown\n[just before merging the translation file](guide/i18n#app-pre-translation)\nand refer to the [AOT guide](guide/aot-compiler) to make it _AOT-ready_.",
"translation": "使用AoT编译器时的国际化需要一些针对AoT的设置。\n以[合并翻译文件之前](guide/i18n#app-pre-translation)的应用项目开始,并参见[AoT烹饪书](guide/aot-compiler)把它变成与AoT兼容的项目。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Next, issue an `ngc` compile command for each supported language, including English.\nThe result is a separate version of the application for each language.",
"translation": "接下来,为每种支持的语言(包括英语)运行一次`ngc`编译命令。\n结果是每种语言都有自己单独的应用版本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Tell AOT how to translate by adding three options to the `ngc` command:",
"translation": "通过添加下面三种选项到`ngc`命令来告诉AoT编译器如何翻译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* `--i18nFile`: the path to the translation file.",
"translation": "`--i18nFile`: 翻译文件的路径",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* `--locale`: the name of the locale.",
"translation": "`--locale`: 语言环境的名字",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* `--i18nFormat`: the format of the localization file.",
"translation": "`--i18nFormat`: 翻译文件的格式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "For this sample, the Spanish language command would be:",
"translation": "本西班牙语例子的命令为:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Windows users may have to quote the command:",
"translation": "Windows用户可能需要双引号这个命令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "### Report missing translations",
"translation": "### 汇报缺失的翻译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "If you forgot to provide a translation, the build will succeed with a warning that you might easily overlook.\nYou can configure the Angular compiler for different \"missing translation\" behaviors:",
"translation": "如果你忘了提供翻译,构建工具会给出警告,以便你更容易发现它们。\n我们可以把 Angular 编译器配置为发现\"缺少翻译\"时采取不同的行动:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* Error",
"translation": "报错",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* Warning (default)",
"translation": "警告(默认值)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "* Ignore",
"translation": "忽略",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "To change the behavior in JIT, you can use the following configuration:",
"translation": "要在 JIT 编译器中改变这种行为,我们可以使用下列配置:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "A good place to use it is the translation providers:",
"translation": "使用它的一个好地方是在 \"翻译服务提供商provider\" 中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "To change the behavior in AOT, add the `--missingTranslation` flag to the compilation command:",
"translation": "要在 AOT 编译器中改变这种行为,可以在编译命令行中添加 `--missingTranslation` 标志:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "## File maintenance and _id_ changes",
"translation": "## 文件维护与`id`的改变",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "As the application evolves, you will change the _i18n_ markup\nand re-run the `ng-xi18n` extraction tool many times.\nThe _new_ markup that you add is not a problem.\nBut the `id` _can be a serious problem!_",
"translation": "随着应用的成长,我们会修改 `i18n` 的页面脚本,并且多次重新运行 `ng-xi18n` 提取工具。\n你*新增的*脚本毫无问题,但是原有脚本的 `id` *可能会面临一系列问题!*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "If the `id` is generated by the tool, _most_ changes to _existing_ markup\ncause the tool to generate a _new_ `id` for the affected translation unit.",
"translation": "如果`id`是由工具生成的,*大部分*对*现有*脚本的改动会导致工具重新生成*新的* `id` ,从而影响到翻译单元。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "After an `id` changes, the translation files are no longer in sync.\nBecause of that, you get some warning messages during re-compilation.\nThe warning messages identify that some translations are missing, but they don't tell you which\nold `ids` are no longer valid.",
"translation": "在一个`id`变化之后,翻译结果文件将不再同步。\n因此我们会在重新编译的时候收到一些警告信息。\n这些警告信息标识出了哪些翻译结果被丢了但却不会告诉我们哪些原有的`id`失效了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "If you use a [custom id](#custom-id \"Set a custom id\"),\nthe tooling preserves the custom `id` as you make changes to the corresponding translation unit. **Use custom _ids_ unless you have a very good reason to do otherwise.**",
"translation": "如果我们使用[自定义 id](#custom-id \"Set a custom id\"),当你修改相应的翻译单元时,工具就会保留这些自定义`id`。**除非有特别好的理由,否则应该总是使用自定义`id`**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "Whether you use generated or custom `ids`, **always commit all translation message files to source control**,\nespecially the English source `messages.xlf`.\nThe difference between the old and the new `messages.xlf` file\nwill help you find and update `ids` and other changes across your translation files.",
"translation": "无论我们是所有自动生成的id还是自定义id**都总是要把所有的翻译结果文件提交到源码控制系统中**,特别是英语的源文件`messages.xlf`。\n比较新旧`messages.xlf`文件之间的不同,可以帮助你在多个翻译结果文件之间发现`id`的变化,以及其它更改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/i18n.md"
},
{
"original": "# Angular Language Service",
"translation": "# Angular 语言服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "## Autocompletion",
"translation": "## 自动完成",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "## Error checking",
"translation": "## 错误检查",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "## Navigation",
"translation": "## 导航",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "## Angular Language Service in your editor",
"translation": "## 编辑器中的 Angular 语言服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "### Visual Studio Code",
"translation": "### Visual Studio Code 中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "Then click the install button to install the Angular Language Service.",
"translation": "然后点击安装按钮来安装 Angular 语言服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"original": "### WebStorm",
"translation": "### WebStorm 中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "Here's the dev dependency \nyou need to have in `package.json`:",
"translation": "下面这个开发依赖需要添加到`package.json`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "*OR*",
"translation": "*或*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"original": "*OR*",
"translation": "*或*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"original": "### Sublime Text",
"translation": "### Sublime Text 编辑器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "Then install the Angular Language Service in the same location:",
"translation": "然后把 Angular 语言服务安装到同一位置:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "Next, in your user preferences (`Cmd+,` or `Ctrl+,`), add:",
"translation": "接下来,在你的用户首选项中(按`Cmd+,`或`Ctrl+,`)添加:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"original": "## Installing in your project",
"translation": "## 安装到工程中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"original": "You can also install Angular Language Service in your project with the \nfollowing `npm` command:",
"translation": "我们还可以使用下列`npm`命令来把 Angular 语言服务安装到工程中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"original": "```sh\nnpm install --save-dev @angular/language-service\n```\nAdditionally, add the following to the `\"compilerOptions\"` section of \nyour project's `tsconfig.json`.",
"translation": "另外,还要在工程的`tsconfig.json`中添加下列`\"compilerOptions\"`区域:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"original": "```json\n \"plugins\": [\n {\"name\": \"@angular/language-service\"}\n ]\n```\nNote 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/content-1/guide/language-service.md"
},
{
"original": "## How the Language Service works",
"translation": "## 语言服务的工作原理",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "## More on Information",
"translation": "## 更多信息",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/language-service.md"
},
{
"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/content-1/guide/language-service.md"
},
{
"original": "# Lifecycle Hooks",
"translation": "# 生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "A component has a lifecycle managed by Angular .",
"translation": "每个组件都有一个被Angular管理的生命周期。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "A directive has the same set of lifecycle hooks, minus the hooks that are specific to component content and views.",
"translation": "除了那些组件内容和视图相关的钩子外,指令有相同生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## Component lifecycle hooks overview",
"translation": "## 组件生命周期钩子概览",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "No directive or component will implement all of the lifecycle hooks and some of the hooks only make sense for components.\nAngular only calls a directive/component hook method *if it is defined*.",
"translation": "没有指令或者组件会实现所有这些接口,并且有些钩子只对组件有意义。只有在指令/组件中*定义过的*那些钩子方法才会被Angular调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## Lifecycle sequence",
"translation": "## 生命周期的顺序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Hook\n </p>",
"translation": "钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Purpose and Timing\n </p>",
"translation": "<p>\n 目的和时机\n </p></th>\n </tr>\n <tr style='vertical-align:top'>\n <td>\n <code>ngOnChanges()</code>\n </td>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Called before `ngOnInit()` and whenever one or more data-bound input properties change.",
"translation": "当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在`ngOnInit()`之前。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_, after the _first_ `ngOnChanges()`.",
"translation": "在第一轮`ngOnChanges()`完成之后调用,只调用**一次**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Detect and act upon changes that Angular can't or won't detect on its own.",
"translation": "检测并在发生Angular无法或不愿意自己检测的变化时作出反应。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Called during every change detection run, immediately after `ngOnChanges()` and `ngOnInit()`.",
"translation": "在每个Angular变更检测周期中调用`ngOnChanges()`和`ngOnInit()`之后。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular projects external content into the component's view.",
"translation": "当把内容投影进组件之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_ after the first `ngDoCheck()`.",
"translation": "第一次`ngDoCheck()`之后调用,只调用一次。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "_A component-only hook_.",
"translation": "**只适用于组件**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular checks the content projected into the component.",
"translation": "每次完成被投影组件内容的变更检测之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Called after the `ngAfterContentInit()` and every subsequent `ngDoCheck()`.",
"translation": "`ngAfterContentInit()`和每次`ngDoCheck()`之后调用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "_A component-only hook_.",
"translation": "**只适合组件**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular initializes the component's views and child views.",
"translation": "初始化完组件视图及其子视图之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Called _once_ after the first `ngAfterContentChecked()`.",
"translation": "第一次`ngAfterContentChecked()`之后调用,只调用一次。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "_A component-only hook_.",
"translation": "**只适合组件**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Respond after Angular checks the component's views and child views.",
"translation": "每次做完组件视图和子视图的变更检测之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Called after the `ngAfterViewInit` and every subsequent `ngAfterContentChecked()`.",
"translation": "`ngAfterViewInit()`和每次`ngAfterContentChecked()`之后调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "_A component-only hook_.",
"translation": "**只适合组件**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Called _just before_ Angular destroys the directive/component.",
"translation": "在Angular销毁指令/组件之前调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## Interfaces are optional (technically)",
"translation": "## 接口是可选的(理论上)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Fortunately, they aren't necessary.",
"translation": "幸运的是,它们并不是必须的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "You don't have to add the lifecycle hook interfaces to directives and components to benefit from the hooks themselves.",
"translation": "我们并不需要在指令和组件上添加生命周期钩子接口就能获得钩子带来的好处。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## Other Angular lifecycle hooks",
"translation": "## 其它生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Other Angular sub-systems may have their own lifecycle hooks apart from these component hooks.",
"translation": "Angular的其它子系统除了有这些组件钩子外还可能有它们自己的生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## Lifecycle examples",
"translation": "## 生命周期练习",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Here's a brief description of each exercise:",
"translation": "下面是每个练习简短的描述:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Component\n </p>",
"translation": "组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "<th>\n <p>Description\n </p>",
"translation": "<p>\n 描述\n </p></th>\n </tr>\n <tr style='vertical-align:top'>\n <td>\n <a href=\"#peek-a-boo\">Peek-a-boo</a>\n </td>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Demonstrates every lifecycle hook.\n Each hook method writes to the on-screen log.",
"translation": "展示每个生命周期钩子,每个钩子方法都会在屏幕上显示一条日志。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Counter",
"translation": "计数器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Demonstrates a combination of a component and a directive\n each with its own hooks.",
"translation": "演示了组件和指令的组合,它们各自有自己的钩子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The remainder of this page discusses selected exercises in further detail.",
"translation": "接下来,我们将详细讨论这些练习。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## Peek-a-boo: all hooks",
"translation": "## Peek-a-boo全部钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The `PeekABooComponent` demonstrates all of the hooks in one component.",
"translation": "`PeekABooComponent`组件演示了组件中所有可能存在的钩子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The sequence of log messages follows the prescribed hook calling order:\n`OnChanges`, `OnInit`, `DoCheck`&nbsp;(3x), `AfterContentInit`, `AfterContentChecked`&nbsp;(3x),\n`AfterViewInit`, `AfterViewChecked`&nbsp;(3x), and `OnDestroy`.",
"translation": "日志信息的日志和所规定的钩子调用顺序是一致的:\n`OnChanges`、`OnInit`、`DoCheck`&nbsp;(3x)、`AfterContentInit`、`AfterContentChecked`&nbsp;(3x)、\n`AfterViewInit`、`AfterViewChecked`&nbsp;(3x)和`OnDestroy`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The next examples focus on hook details.",
"translation": "下一个例子就聚焦于这些钩子的细节上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## Spying *OnInit* and *OnDestroy*",
"translation": "## 窥探*OnInit*和*OnDestroy*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Go undercover with these two spy hooks to discover when an element is initialized or destroyed.",
"translation": "潜入这两个spy钩子来发现一个元素是什么时候被初始化或者销毁的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Kidding aside, pay attention to two key points:",
"translation": "不开玩笑了,注意下面两个关键点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "1. Angular calls hook methods for *directives* as well as components.<br><br>",
"translation": "就像对组件一样Angular也会对*指令*调用这些钩子方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "2. A spy directive can provide insight into a DOM object that you cannot change directly.\nObviously you can't touch the implementation of a native `<div>`.\nYou can't modify a third party component either.\nBut you can watch both with a directive.",
"translation": "一个侦探(spy)指令可以让我们在无法直接修改DOM对象实现代码的情况下透视其内部细节。\n显然你不能修改一个原生`<div>`元素的实现代码。\n你同样不能修改第三方组件。\n但我们用一个指令就能监视它们了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The `ngOnInit()` and `ngOnDestroy()` methods have more vital roles to play in real applications.",
"translation": "在真实的应用程序中,`ngOnInit()`和`ngOnDestroy()`方法扮演着更重要的角色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "### _OnInit()_",
"translation": "### _OnInit()钩子_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Use `ngOnInit()` for two main reasons:",
"translation": "使用`ngOnInit()`有两个原因:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "1. To perform complex initializations shortly after construction.",
"translation": "在构造函数之后马上执行复杂的初始化逻辑",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "1. To set up the component after Angular sets the input properties.",
"translation": "在Angular设置完输入属性之后对该组件进行准备。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Experienced developers agree that components should be cheap and safe to construct.",
"translation": "有经验的开发者会认同组件的构建应该很便宜和安全。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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 HeveryAngular项目的头在[这里解释](http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/)了你为什么应该避免复杂的构造函数逻辑。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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) guideshows how.",
"translation": "`ngOnInit()`是组件获取初始数据的好地方。[指南](tutorial/toh-pt4#oninit)中讲解了如何这样做。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "### _OnDestroy()_",
"translation": "### _OnDestroy()钩子_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Put cleanup logic in `ngOnDestroy()`, the logic that *must* run before Angular destroys the directive.",
"translation": "一些清理逻辑*必须*在Angular销毁指令之前运行把它们放在`ngOnDestroy()`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "This is the time to notify another part of the application that the component is going away.",
"translation": "这是在该组件消失之前,可用来通知应用程序中其它部分的最后一个时间点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## _OnChanges()_",
"translation": "## _OnChanges()_ 钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive).",
"translation": "一旦检测到该组件(或指令)的***输入属性***发生了变化Angular就会调用它的`ngOnChanges()`方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "This example monitors the `OnChanges` hook.",
"translation": "本例监控`OnChanges`钩子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The example component, `OnChangesComponent`, has two input properties: `hero` and `power`.",
"translation": "这个例子中的`OnChangesComponent`组件有两个输入属性:`hero`和`power`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The host `OnChangesParentComponent` binds to them like this:",
"translation": "宿主`OnChangesParentComponent`绑定了它们,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Here's the sample in action as the user makes changes.",
"translation": "下面是此例子中的当用户做出更改时的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## _DoCheck()_",
"translation": "## _DoCheck()_ 钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Use this method to detect a change that Angular overlooked.",
"translation": "用这个方法来检测那些被Angular忽略的更改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck()` hook:",
"translation": "*DoCheck*范例通过下面的`ngDoCheck()`实现扩展了*OnChanges*范例:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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&mdash;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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## AfterView",
"translation": "## AfterView 钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Here's a child view that displays a hero's name in an `<input>`:",
"translation": "下面是一个子视图,它用来把英雄的名字显示在一个`<input>`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The `AfterViewComponent` displays this child view *within its template*:",
"translation": "`AfterViewComponent`把这个子视图显示*在它的模板中*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "### Abide by the unidirectional data flow rule",
"translation": "### 遵循单向数据流规则",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The `doSomething()` method updates the screen when the hero name exceeds 10 characters.",
"translation": "当英雄的名字超过10个字符时`doSomething()`方法就会更新屏幕。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Why does the `doSomething()` method wait a tick before updating `comment`?",
"translation": "为什么在更新`comment`属性之前,`doSomething()`方法要等上一拍(tick)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Here's *AfterView* in action:",
"translation": "这里是*AfterView*的操作演示:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "## AfterContent",
"translation": "## AfterContent 钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "### Content projection",
"translation": "### 内容投影",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "AngularJS developers know this technique as *transclusion*.",
"translation": "AngularJS的开发者大概知道一项叫做*transclusion*的技术,对,这就是它的马甲。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "Now look at the component's template:",
"translation": "现在来看下`<after-content>`组件的模板:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "The telltale signs of *content projection* are twofold:",
"translation": "下列迹象表明存在着*内容投影*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "* HTML between component element tags.",
"translation": "在组件的元素标签中有HTML",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "* The presence of `<ng-content>` tags in the component's template.",
"translation": "组件的模板中出现了`<ng-content>`标签",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"original": "### AfterContent hooks",
"translation": "### AfterContent钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "* The *AfterContent* hooks concern `ContentChildren`, the child components that Angular\nprojected into the component.",
"translation": "*AfterContent*钩子所关心的是`ContentChildren`这些子组件被Angular投影进该组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "### No unidirectional flow worries with _AfterContent_",
"translation": "### 使用**AfterContent**时,无需担心单向数据流规则",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"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/content-1/guide/lifecycle-hooks.md"
},
{
"original": "# NgModule FAQs",
"translation": "# Angular 模块常见问题",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "NgModules help organize an application into cohesive blocks of functionality.",
"translation": "**Angular模块**可以帮我们把应用组织成一些紧密相关的代码块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The [NgModules](guide/ngmodule) page guides you\nfrom the most elementary `@NgModule` to a multi-faceted sample with lazy-loaded modules.",
"translation": "[Angular模块](guide/ngmodule)章涵盖了此概念,并带你从最基本的`@NgModule`学到惰性加载模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "This page answers the questions many developers ask about NgModule design and implementation.",
"translation": "*这里*回答的是开发者常问起的关于Angular模块的设计与实现问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "These FAQs assume that you have read the [NgModules](guide/ngmodule) page.",
"translation": "本《Angular模块常见问题》假设你已经读完了[Angular模块](guide/ngmodule)章。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What classes should I add to _declarations_?",
"translation": "## 我应该把哪些类加到*declarations*中?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Add [declarable](guide/ngmodule-faq#q-declarable) classes&mdash;components, directives, and pipes&mdash;to a `declarations` list.",
"translation": "把[可声明](guide/ngmodule-faq#q-declarable)的类(组件、指令和管道)添加到`declarations`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Declare these classes in _exactly one_ module of the application.\nDeclare them in _this_ module if they _belong_ to this module.",
"translation": "这些类只能在应用程序的*一个并且只有一个*模块中声明。\n只有当它们*从属于*某个模块时,才能把在*此*模块中声明它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What is a _declarable_?",
"translation": "## 什么是*可声明的*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Declarables are the class types&mdash;components, directives, and pipes&mdash;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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What classes should I _not_ add to _declarations_?",
"translation": "## 哪些类*不*应该加到`declarations`中?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Add only [declarable](guide/ngmodule-faq#q-declarable) classes to a module's `declarations` list.",
"translation": "只有[可声明的](guide/ngmodule-faq#q-declarable)类才能加到模块的`declarations`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Do *not* declare the following:",
"translation": "*不要*声明:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "* An array of directives imported from another module.\nFor example, don't declare FORMS_DIRECTIVES from `@angular/forms`.",
"translation": "从其它模块中导入的指令。例如,不要声明来自`@angular/forms`的FORMS_DIRECTIVES。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Module classes.",
"translation": "模块类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Service classes.",
"translation": "服务类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Why list the same component in multiple _NgModule_ properties?",
"translation": "## 为什么要把同一个组件声明在不同的*NgModule*属性中?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "`AppComponent` is often listed in both `declarations` and `bootstrap`.\nYou might see `HeroComponent` listed in `declarations`, `exports`, and `entryComponents`.",
"translation": "我们经常看到`AppComponent`被同时列在`declarations`和`bootstrap`中。\n 我们还可能看到`HeroComponent`被同时列在`declarations`、`exports`和`entryComponent`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "* `AppComponent` could be declared in this module but not bootstrapped.",
"translation": "`AppComponent`可能被声明在此模块中,但可能不是引导组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* `AppComponent` could be bootstrapped in this module but declared in a different feature module.",
"translation": "`AppComponent`可能在此模块中引导,但可能是由另一个特性模块声明的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* `HeroComponent` 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/content-1/guide/ngmodule-faq.md"
},
{
"original": "* `HeroComponent` 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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "This error usually means that you haven't declared the directive \"x\"\nor haven't imported the module to which \"x\" belongs.",
"translation": "这个错误通常意味着你或者忘了声明指令“x”或者你没有导入“x”所属的模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "For example, if \"x\" is `ngModel`, you probably haven't imported the `FormsModule` from `@angular/forms`.",
"translation": "比如如果这个“x”是`ngModel`,你可能忘了从`@angular/forms`中导入`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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”但是忘了从那个模块导出它。\n除非你把这个“x”类加入了`exports`列表中,否则它对其它模块将是不可见的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What should I import?",
"translation": "## 我应该导入什么?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Import modules whose public (exported) [declarable classes](guide/ngmodule-faq#q-declarable)\nyou need to reference in this module's component templates.",
"translation": "一句话:导入你需要在当前模块的组件模板中使用的那些公开的(被导出的)[可声明类](guide/ngmodule-faq#q-declarable)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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 module 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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Import _shared_ and _feature_ modules when this module's components incorporate their\ncomponents, directives, and pipes.",
"translation": "如果当前模块中的组件包含了*共享*模块和*特性*模块中的组件、指令和管道,就导入这些模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Should I import _BrowserModule_ or _CommonModule_?",
"translation": "## 我应该导入*BrowserModule*还是*CommonModule*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "`BrowserModule` provides services that are essential to launch and run a browser app.",
"translation": "`BrowserModule`提供了启动和运行浏览器应用的那些基本的服务提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "`BrowserModule` throws an error if you try to lazy load a module that imports it.",
"translation": "如果你在惰性加载模块中导入`BrowserModule`Angular就会抛出一个错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Importing `CommonModule` also frees feature modules for use on _any_ target platform, not just browsers.",
"translation": "特性模块中导入`CommonModule`可以让它能用在任何目标平台上,不仅是浏览器。那些跨平台库的作者应该喜欢这种方式的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What if I import the same module twice?",
"translation": "## 如果我两次导入同一个模块会怎么样?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "That's true at whatever level `A` appears in a hierarchy of imported modules.\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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular doesn't like modules 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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What should I export?",
"translation": "## 我应该导出什么?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Export [declarable](guide/ngmodule-faq#q-declarable) classes that components in _other_ modules\nare able to reference in their templates. These are your _public_ classes.\nIf you don't export a class, it stays _private_, visible only to other component\ndeclared in this module.",
"translation": "导出那些*其它模块*希望在自己的模板中引用的[可声明类](guide/ngmodule-faq#q-declarable)。这些也是你的*公开*类。\n如果你不导出某个类它就是*私有的*,只对当前模块中声明的其它组件可见。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "You _can_ export any declarable class&mdash;components, directives, and pipes&mdash;whether\nit's declared in this module or in an imported module.",
"translation": "你*可以*导出任何可声明类(组件、指令和管道),而不用管它是声明在当前模块中还是某个导入的模块中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "You _can_ re-export entire imported modules, which effectively re-exports all of their exported classes.\nA module can even export a module that it doesn't import.",
"translation": "你*可以*重新导出整个导入过的模块,这将导致重新导出它们导出的所有类。模块甚至还可以导出它未曾导入过的模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What should I *not* export?",
"translation": "## 我*不应该*导出什么?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Don't export the following:",
"translation": "*不要*导出:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Private components, directives, and pipes that you need only within components declared in this module.\nIf you don't want another module to see it, don't export it.",
"translation": "那些你只想在当前模块中声明的那些组件中使用的私有组件、指令和管道。如果你不希望任何模块看到它,就不要导出。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Non-declarable objects such as services, functions, configurations, and entity models.",
"translation": "不可声明的对象,比如服务、函数、配置、实体模型等。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Pure service modules that don't have public (exported) declarations.\nFor example, there's no point in re-exporting `HttpModule` because it doesn't export anything.\nIt's only purpose is to add http service providers to the application as a whole.",
"translation": "纯服务模块没有公开(导出)的声明。\n 例如,没必要重新导出`HttpModule`,因为它不导出任何东西。\n 它唯一的用途是一起把http的那些服务提供商添加到应用中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Can I re-export classes and modules?",
"translation": "## 我可以重新导出类和模块吗?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Absolutely.",
"translation": "毫无疑问!",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Modules are a great way to selectively aggregate classes from other modules and\nre-export them in a consolidated, convenience module.",
"translation": "模块是从其它模块中选取类并把它们重新导出成统一、便利的新模块的最佳方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A module can re-export entire modules, which effectively re-exports all of their exported classes.\nAngular's own `BrowserModule` exports a couple of modules like this:",
"translation": "模块可以重新导出其它模块,这会导致重新导出它们导出的所有类。\nAngular自己的`BrowserModule`就重新导出了一组模块,例如:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A module can export a combination of its own declarations, selected imported classes, and imported modules.",
"translation": "模块还能导出一个组合,它可以包含自己的声明、某些导入的类以及导入的模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Don't bother re-exporting pure service modules.\nPure service modules don't export [declarable](guide/ngmodule-faq#q-declarable) classes that another module could use.\nFor example, there's no point in re-exporting `HttpModule` because it doesn't export anything.\nIt's only purpose is to add http service providers to the application as a whole.",
"translation": "不要费心去导出纯服务类。\n纯服务类的模块不会导出任何可供其它模块使用的[可声明类](guide/ngmodule-faq#q-declarable)。\n例如不用重新导出`HttpModule`,因为它没有导出任何东西。\n它唯一的用途是把那些http服务提供商一起添加到应用中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What is the _forRoot_ method?",
"translation": "## *forRoot*方法是什么?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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.",
"translation": "只能在应用的根模块`AppModule`中调用并导入`.forRoot`的结果。\n在其它模块中导入它特别是惰性加载模块中是违反设计目标的并会导致一个运行时错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "`RouterModule` also offers a `forChild` static method for configuring the routes of lazy-loaded modules.",
"translation": "`RouterModule`也提供了静态方法`forChild`,用于配置惰性加载模块的路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Why is a service provided in a feature module visible everywhere?",
"translation": "## 为什么服务提供商在特性模块中的任何地方都是可见的?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "When you import a module,\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/content-1/guide/ngmodule-faq.md"
},
{
"original": "This makes the provider visible to every class in the application that knows the provider's lookup token.",
"translation": "这会让该提供商对应用中所有知道该提供商令牌token的类都可见。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "This is by design.\nExtensibility through module imports is a primary goal of the NgModule system.\nMerging module providers into the application injector\nmakes it easy for a module library to enrich the entire application with new services.\nBy adding the `HttpModule` once, every application component can make http requests.",
"translation": "Angular就是如此设计的。\n通过模块导入来实现可扩展性是Angular模块系统的主要设计目标。\n把模块的提供商并入应用程序的注入器可以让库模块使用新的服务来强化应用程序变得更容易。\n只要添加一次`HttpModule`那么应用中的每个组件就都可以发起Http请求了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Why is a service provided in a _lazy-loaded_ module visible only to that module?",
"translation": "## 为什么在惰性加载模块中声明的服务提供商只对该模块自身可见?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Unlike providers of the modules loaded at launch,\nproviders of lazy-loaded modules are *module-scoped*.",
"translation": "和启动时就加载的模块中的提供商不同,惰性加载模块中的提供商是*局限于模块*的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "The router adds the lazy module's providers and the providers of its imported modules to this child injector.",
"translation": "路由器把该惰性加载模块的提供商和它导入的模块的提供商添加到这个子注入器中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What if two modules provide the same service?",
"translation": "## 如果两个模块提供了*同一个*服务会怎么样?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "If Module A provides a service for token 'X' and imports a module B\nthat also provides a service for token 'X', then Module A's service definition \"wins\".",
"translation": "如果模块A提供了一个使用令牌'X'的服务并且导入的模块B也用令牌'X'提供了一个服务那么模块A中定义的服务“获胜”了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The service provided by the root `AppModule` takes precedence over services provided by imported modules.\nThe `AppModule` always wins.",
"translation": "由根`AppModule`提供的服务相对于所导入模块中提供的服务有优先权。换句话说:`AppModule`总会获胜。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## How do I restrict service scope to a module?",
"translation": "## 我们应该如何把服务的范围限制到模块中?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Imported providers are easily replaced by providers from another imported module.\nSuch replacement might be by design. It could be unintentional and have adverse consequences.",
"translation": "导入的提供商很容易被由其它导入模块中的提供商替换掉。\n这虽然是故意这样设计的但是也可能引起意料之外的结果。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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 `HttpModule`, 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`或仅仅导入了`HttpModule`,它就会改写当前模块的`HttpBackend`提供商,丢掉了这个特别的请求头。\n 这样服务器就会拒绝来自该模块的请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "To avoid this problem, import the `HttpModule` only in the `AppModule`, the application _root module_.",
"translation": "要消除这个问题,就只能在应用的根模块`AppModule`中导入`HttpModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Be sure to create module components as children of this module's top component.",
"translation": "确保把模块中的组件都创建成这个顶级组件的子组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Should I add application-wide providers to the root _AppModule_ or the root _AppComponent_?",
"translation": "## 我应该把全应用级提供商添加到根模块`AppModule`中还是根组件`AppComponent`中?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Register application-wide providers in the root `AppModule`, not in the `AppComponent`.",
"translation": "在根模块`AppModule`中注册全应用级提供商,而不是`AppComponent`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "More generally, [prefer registering providers in modules](guide/ngmodule-faq#q-component-or-module) to registering in components.",
"translation": "更一般地说,[优先把提供商注册进模块中](guide/ngmodule-faq#q-component-or-module),而不是组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Discussion",
"translation": "讨论",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular registers all startup module providers with the application root injector.\nThe services created from root injector providers are available to the entire application.\nThey are _application-scoped_.",
"translation": "Angular把所有启动期模块的提供商都注册进了应用的根注入器中。\n这些服务是由根注入器中的提供商创建的并且在整个应用中都可用。\n它们具有*应用级作用域*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Certain services (such as the `Router`) only work when registered in the application root injector.",
"translation": "某些服务(比如`Router`)只有当注册进应用的根注入器时才能正常工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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 are _component-scoped_.",
"translation": "相反Angular使用`AppComponent`自己的注入器注册了`AppComponent`的提供商。\n`AppComponent`服务只在该组件及其子组件树中才能使用。\n它们具有*组件级作用域*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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 for routed applications, \"almost\" isn't good enough.",
"translation": "`AppComponent`的注入器是根注入器的*子级*,注入器层次中的下一级。\n这对于没有路由器的应用来说*几乎是*整个应用了。\n但这个“几乎”对于带路由的应用仍然是不够的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "`AppComponent` services don't exist at the root level where routing operates.\nLazy-loaded modules can't reach them.\nIn the NgModule page sample applications, if you had registered `UserService` in the `AppComponent`,\nthe `HeroComponent` couldn't inject it.\nThe application would fail the moment a user navigated to \"Heroes\".",
"translation": "当有路由时,`AppComponent`服务并不在根部。\n惰性加载的模块就不能用它们。\n在“Angular模块”章的范例应用中如果我们在`AppComponent`中注册`UserService`,那么`HeroComponent`就不能注入它。\n一旦用户导航到“Heroes”特性区该应用就会失败。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Should I add other providers to a module or a component?",
"translation": "## 我应该把其它提供商注册到模块中还是组件中?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "For example, a hero editing component that needs a private copy of a caching hero service should register\nthe `HeroService` with the `HeroEditorComponent`.\nThen each new instance of the `HeroEditorComponent` gets its own cached service instance.\nThe changes that editor makes to heroes in its service don't touch the hero instances elsewhere in the application.",
"translation": "例如,如果英雄编辑组件需要自己私有的缓存英雄服务实例,那么我们应该把`HeroService`注册进`HeroEditorComponent`中。\n这样每个新的`HeroEditorComponent`的实例都会得到一份自己的缓存服务实例。\n编辑器的改动只会作用于它自己的服务而不会影响到应用中其它地方的英雄实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Why is it bad if _SharedModule_ provides a service to a lazy-loaded module?",
"translation": "## 为什么*SharedModule*为惰性加载模块提供服务是个馊主意?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "This question is addressed in the [Why UserService isn't shared](guide/ngmodule#no-shared-module-providers)\nsection of the [NgModules](guide/ngmodule) page,\nwhich discusses the importance of keeping providers out of the `SharedModule`.",
"translation": "这个问题在[Angular模块](guide/ngmodule)一章的[为何UserService不是共享的](guide/ngmodule#no-shared-module-providers)部分出现过,\n那时我们在讨论不要把提供商放进`SharedModule`的重要性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Suppose the `UserService` was listed in the module's `providers` (which it isn't).\nSuppose every module imports this `SharedModule` (which they all do).",
"translation": "假设把`UserService`列在了模块的`providers`中(我们没有这么做)。\n假设每个模块都导入了这个`SharedModule`(我们是这么做的)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "When the app starts, Angular eagerly loads the `AppModule` and the `ContactModule`.",
"translation": "当应用启动时Angular主动加载了`AppModule`和`ContactModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Both instances of the imported `SharedModule` would provide the `UserService`.\nAngular registers one of them in the root app injector (see [What if I import the same module twice?](guide/ngmodule-faq#q-reimport)).\nThen some component injects `UserService`, Angular finds it in the app root injector,\nand delivers the app-wide singleton `UserService`. No problem.",
"translation": "导入的`SharedModule`的每个实例都会提供`UserService`。\nAngular把它们中的一个注册进了应用的根注入器中参见[如果同一个模块被导入两次会怎么样?](guide/ngmodule-faq#q-reimport))。\n然后某些组件要求注入`UserService`Angular就会在应用的根注入器中查找它并交付一个全应用级的单例对象`UserService`。这没问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Now consider the `HeroModule` _which is lazy loaded_.",
"translation": "现在,该考虑`HeroModule`了,*它是惰性加载的!*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "When the router lazy loads the `HeroModule`, 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/content-1/guide/ngmodule-faq.md"
},
{
"original": "When Angular creates a lazy `HeroComponent`, it must inject a `UserService`.\nThis time it 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/content-1/guide/ngmodule-faq.md"
},
{
"original": "That's almost certainly a mistake.",
"translation": "这绝对是一个错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "To demonstrate, run the <live-example name=\"ngmodule\">live example</live-example>.\nModify the `SharedModule` so that it provides the `UserService` rather than the `CoreModule`.\nThen toggle between the \"Contact\" and \"Heroes\" links a few times.\nThe username goes bonkers as the Angular creates a new `UserService` instance each time.\n<!-- CF: \"goes bonkers\" is jargon. Can you describe the behavior in plain English? -->",
"translation": "自己验证一下吧。\n运行这个<live-example name=\"ngmodule\">在线例子</live-example>。\n修改`SharedModule`,由它来提供`UserService`而不再由`CoreModule`。\n然后在“Contact”和“Heroes”链接之间切换几次。\n由于Angular每次都创建一个新的`UserService`实例,所以用户名变得不正常了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Why does lazy loading create a child injector?",
"translation": "## 为什么惰性加载模块会创建一个子注入器?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular adds `@NgModule.providers` to the application root injector, unless the module is lazy loaded.\nFor a lazy-loaded module, 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/content-1/guide/ngmodule-faq.md"
},
{
"original": "This means that a module 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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Why doesn't Angular add lazy-loaded providers to the app root injector as it does for eagerly loaded modules?",
"translation": "为什么Angular不能像主动加载模块那样把惰性加载模块的提供商也添加到应用程序的根注入器中呢为什么会出现这种不一致",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "When an applications starts, Angular first configures the root injector with the providers of all eagerly loaded modules\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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Time passes and application logic triggers lazy loading of a module.\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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## How can I tell if a module or service was previously loaded?",
"translation": "## 我要如何知道一个模块或服务是否已经加载过了?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Some modules 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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Certain NgModules (such as `BrowserModule`) implement such a guard,\nsuch as this `CoreModule` constructor from the NgModules page.",
"translation": "某些Angular模块例如`BrowserModule`)就实现了一个像 Angular 模块那一章的`CoreModule`构造函数那样的守卫。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What is an _entry component_?",
"translation": "## 什么是*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "An entry component is any component that Angular loads _imperatively_ by type.",
"translation": "Angular根据其类型*不可避免地*加载的组件是*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A component loaded _declaratively_ via its selector is _not_ an entry component.",
"translation": "而通过组件选择器*声明式*加载的组件则*不是*入口组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Most application components are loaded declaratively.\nAngular uses the component's selector to locate the element in the template.\nIt then creates the HTML representation of the component and inserts it into the DOM at the selected element.\nThese aren't entry components.",
"translation": "大多数应用组件都是声明式加载的。\nAngular使用该组件的选择器在模板中定位元素然后创建表现该组件的HTML并把它插入DOM中所选元素的内部。它们不是入口组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A few components are only loaded dynamically and are _never_ referenced in a component template.",
"translation": "也有少量组件只会被动态加载,并且*永远不会*被组件的模板所引用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular loads `AppComponent` dynamically because it's either listed _by type_ in `@NgModule.bootstrap`\nor boostrapped imperatively with the module's `ngDoBootstrap` method.",
"translation": "Angular总是会动态加载`AppComponent` —— 无论把它的*类型*列在了`@NgModule.bootstrap`函数中,还是命令式的调用该模块的`ngDoBootstrap`方法来引导它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "The compiler can't discover these _entry components_ by looking for them in other component templates.\nYou must tell it about them by adding them to the `entryComponents` list.",
"translation": "编译器无法通过在其它组件的模板中查找来发现这些*入口组件*。\n 我们必须通过把它们加入`entryComponents`列表中来让编译器知道它们的存在。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular automatically adds the following types of components to the module's `entryComponents`:",
"translation": "Angular会自动把下列类型的组件添加到模块的`entryComponents`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* The component in the `@NgModule.bootstrap` list.",
"translation": "那些出现在`@NgModule.bootstrap`列表中的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Components referenced in router configuration.",
"translation": "那些被路由定义引用的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "You don't have to mention these components explicitly, although doing so is harmless.",
"translation": "我们并不需要显式的引用这些组件 —— 虽然引用了也没坏处。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What's the difference between a _bootstrap_ component and an _entry component_?",
"translation": "### *引导组件*和*入口组件*有什么不同?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A bootstrapped component _is_ an [entry component](guide/ngmodule-faq#q-entry-component-defined)\nthat Angular loads into the DOM during the bootstrap (application launch) process.\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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "There's no need to list a component in both the `bootstrap` and `entryComponent` lists,\nalthough doing so is harmless.",
"translation": "不需要把组件同时列在`bootstrap`和`entryComponent`列表中 —— 虽然这样做也没坏处。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## When do I add components to _entryComponents_?",
"translation": "## 什么时候我应该把组件加到`entryComponents`中?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Most application developers won't need to add components to the `entryComponents`.",
"translation": "大多数应用开发者都不需要把组件添加到`entryComponents`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## Why does Angular need _entryComponents_?",
"translation": "## 为什么Angular需要*入口组件*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "_Entry components_ are also declared.\nWhy doesn't the Angular compiler generate code for every component in `@NgModule.declarations`?\nThen you wouldn't need entry components.",
"translation": "*入口组件*也是被声明的。\n为什么Angular编译器不为`@NgModule.declarations`中的每个组件都生成一份代码呢?那样就不需要入口组件了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The reason is _tree shaking_. For production apps you want to load the smallest, fastest code possible.\nThe 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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "If the [Angular compiler](guide/ngmodule-faq#q-angular-compiler) generated code for every declared component,\nit would defeat the purpose of the tree shaker.",
"translation": "如果[Angular编译器](guide/ngmodule-faq#q-angular-compiler)为每个声明的组件都生成了代码,那么摇树优化器的作用就没有了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Instead, the compiler adopts a recursive strategy that generates code only for the components you use.",
"translation": "所以,编译器转而采用一种递归策略,它只为我们用到的那些组件生成代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What kinds of modules should I have and how should I use them?",
"translation": "## 有哪些类型的模块?我应该如何使用它们?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "The following is preliminary guidance based on early experience using NgModules in a few applications.\nRead with appropriate caution and reflection.",
"translation": "下面这些初步的指南仅来自在少量应用中使用Angular模块时的早期体验。\n仅供参考。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "### _SharedModule_",
"translation": "### _SharedModule_ 共享模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Create a `SharedModule` 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/content-1/guide/ngmodule-faq.md"
},
{
"original": "The `SharedModule` may re-export other [widget modules](guide/ngmodule-faq#widget-feature-module), such as `CommonModule`,\n`FormsModule`, and modules with the UI controls that you use most widely.",
"translation": "`SharedModule`可以重新导出其它[小部件模块](guide/ngmodule-faq#widget-feature-module),比如`CommonModule`、`FormsModule`和提供你广泛使用的UI控件的那些模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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`.\nIf you deviate from this guideline, know what you're doing and why.",
"translation": "`SharedModule`***不应该***带有`providers`,原因[在前面解释过了](guide/ngmodule-faq#q-why-bad)。\n它的导入或重新导出的模块中也不应该有`providers`。\n如果你要违背这条指导原则请务必想清楚你在做什么并要有充分的理由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "### _CoreModule_",
"translation": "### _CoreModule_ 核心模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Create a `CoreModule` with `providers` for the singleton services you load when the application starts.",
"translation": "为你要在应用启动时加载的那些服务创建一个带`providers`的`CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Consider making `CoreModule` a [pure services module](guide/ngmodule-faq#service-feature-module) with no `declarations`.",
"translation": "考虑把`CoreModule`做成一个没有`declarations`的[纯服务模块](guide/ngmodule-faq#service-feature-module)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "This page sample departs from that advice by declaring and exporting two components that are\nonly used within the root `AppComponent` declared by `AppModule`.\nSomeone following this guideline strictly would have declared these components in the `AppModule` instead.",
"translation": "这里的范例违背了此建议,它声明和导出了两个只用在`AppModule`模块的`AppComponent`组件中的组件。\n如果你想严格遵循这条指南应该把这两个组件改为声明在`AppModule`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "### Feature Modules",
"translation": "### 特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Create feature modules around specific application business domains, user workflows, and utility collections.",
"translation": "围绕特定的业务领域、工作流和工具集来为应用创建*特性模块*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Feature modules tend to fall into one of the following groups:",
"translation": "特性模块一般可分成下面这几种:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* [Domain feature modules](guide/ngmodule-faq#domain-feature-module).",
"translation": "[领域特性模块](guide/ngmodule-faq#domain-feature-module)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* [Routed feature modules](guide/ngmodule-faq#routed-feature-module)",
"translation": "[带路由的特性模块](guide/ngmodule-faq#routed-feature-module)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* [Routing modules](guide/ngmodule-faq#routing-module)",
"translation": "[路由模块](guide/ngmodule-faq#routing-module)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* [Service feature modules](guide/ngmodule-faq#service-feature-module)",
"translation": "[服务特性模块](guide/ngmodule-faq#service-feature-module)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* [Widget feature modules](guide/ngmodule-faq#widget-feature-module).",
"translation": "[窗口部件特性模块](guide/ngmodule-faq#widget-feature-module)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Real-world modules are often hybrids that purposefully deviate from the following guidelines.\nThese guidelines are not laws;\nfollow them unless you have a good reason to do otherwise.",
"translation": "真实世界中的模块通常会偏离这些指导原则,而混杂多种不同的类型。\n这些只是指导原则不是硬性要求。\n但除非你有充分的理由不这么做最好还是遵循它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Feature Module",
"translation": "特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Guidelines",
"translation": "指导原则",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a domain-feature-module}\n <p>\n Domain\n </p>",
"translation": "领域",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Domain feature modules deliver a user experience *dedicated to a particular application domain*\n like editing a customer or placing an order.",
"translation": "领域特性模块**专注于一个特定的应用领域**来提供用户体验,比如编辑消费者信息或下订单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "They typically have a top component that acts as the feature root.\n Private, supporting sub-components descend from it.",
"translation": "它们通常有一个顶级组件,并作为该特性的根组件。\n 内部则是它的一些子组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Domain feature modules consist mostly of _declarations_.\n Only the top component is exported.",
"translation": "领域特性模块几乎总是由`declarations`构成。只有顶级组件会被导出。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Domain feature modules rarely have _providers_.\n When they do, the lifetime of the provided services\n should be the same as the lifetime of the module.",
"translation": "领域特性模块很少会有`providers`。\n 如果要这么做,那它们所提供服务的生命周期就应该与该模块的生命周期相同。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Don't provide application-wide singleton services in a domain feature module.",
"translation": "不要在领域特性模块中提供全应用级的单例服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Domain feature modules are typically imported _exactly once_ by a larger feature module.",
"translation": "领域特性模块的典型用法是*只被*更大的特性模块*导入一次*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "They might be imported by the root `AppModule` of a small application that lacks routing.",
"translation": "对于缺少路由的小型应用,它们可能只会被根模块`AppModule`导入一次。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "For an example, see the [Make _Contact_ a feature module](guide/ngmodule#contact-module-v1)\n section of the [NgModules](guide/ngmodule) page, before routing is introduced.",
"translation": "比如[Angular模块](guide/ngmodule)章的[_ContactModule_](guide/ngmodule#contact-module-v1)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a routed-feature-module}\n <p>\n Routed\n </p>",
"translation": "路由特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "_Routed feature modules_ are _domain feature modules_\n whose top components are the *targets of router navigation routes*.",
"translation": "*路由特性模块*属于*领域特性模块*的一种,它的顶层组件是**路由器导航时的路由目标**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "All lazy-loaded modules are routed feature modules by definition.",
"translation": "根据这个定义,所有惰性加载的模块都是路由特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "This page's `ContactModule`, `HeroModule`, and `CrisisModule` are routed feature modules.",
"translation": "这里的`ContactModule`、`HeroModule`和`CrisisModule`都是路由特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Routed feature modules _shouldn't export anything_.\n They don't have to because their components never appear in the template of an external component.",
"translation": "路由特性模块*不应该导出任何东西*,这是因为它们中的任何组件都不可能出现在外部组件的模板中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A lazy-loaded routed feature module should _not be imported_ by any module.\n Doing so would trigger an eager load, defeating the purpose of lazy loading.\n `HeroModule` and `CrisisModule` are lazy loaded. They aren't mentioned among the `AppModule` imports.",
"translation": "惰性加载的路由特性模块也不应该被任何模块*导出*。\n 那么做会触发一次主动加载,破坏了我们惰性加载的目的。\n `HeroModule`和`CrisisModule`是惰性加载的。它们没有出现在`AppModule`的`imports`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "But an eager loaded routed feature module must be imported by another module\n so that the compiler learns about its components.\n `ContactModule` is eager loaded and therefore listed among the `AppModule` imports.",
"translation": "而主动加载的路由特性模块必须被其它模块导入,以便编译器了解它有哪些组件。\n `ContactModule`就是主动加载的,因此它也被列在了`AppModule`的`imports`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Routed Feature Modules rarely have _providers_ for reasons [explained earlier](guide/ngmodule-faq#q-why-bad).\n When they do, the lifetime of the provided services\n should be the same as the lifetime of the module.",
"translation": "路由特性模块很少会有`providers`,理由[前面解释过](guide/ngmodule-faq#q-why-bad)。\n 如果要那么做,它所提供的服务就应该与模块具有相同的生命周期。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Don't provide application-wide singleton services in a routed feature module\n or in a module that the routed module imports.",
"translation": "不要在路由特性模块及其导入的模块中提供*全应用级*的单例服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a routing-module}\n <p>\n Routing\n </p>",
"translation": "路由模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A [routing module](guide/router#routing-module) *provides routing configuration* for another module.",
"translation": "[路由模块](guide/router#routing-module)为其它模块**提供路由配置**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A routing module separates routing concerns from its companion module.",
"translation": "路由模块将路由配置从它的关联模块分离开来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A routing module typically does the following:",
"translation": "路由模块通常会做这些:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Defines routes.",
"translation": "定义路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Adds router configuration to the module's `imports`.",
"translation": "添加路由配置到模块的`imports`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Re-exports `RouterModule`.",
"translation": "重新导出`RouterModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Adds guard and resolver service providers to the module's `providers`.",
"translation": "添加守卫和解析器服务提供商到模块的`providers`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The name of the routing module should parallel the name of its companion module, using the suffix \"Routing\".\n For example, `FooModule` in `foo.module.ts` has a routing module named `FooRoutingModule`\n in `foo-routing.module.ts`",
"translation": "路由模块的名字应该和它的关联模块平行比如使用“Routing”前缀\n `foo.module.ts`中的`FooModule`有名为`FooRoutingModule`的路由模块,所属文件名为`foo-routing.module.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "If the companion module is the _root_ `AppModule`, \n the `AppRoutingModule` adds router configuration to its `imports` with `RouterModule.forRoot(routes)`. \n All other routing modules are children that import `RouterModule.forChild(routes)`.",
"translation": "如果关联模块是**根**`AppModule`,那么在`AppRoutingModule`的`imports`中,添加`RouterModule.forRoot(routes)`来配置路由。\n 所有其它路由模块都是子级,导入`RouterModule.forChild(routes)`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A routing module re-exports the `RouterModule` as a convenience\n so that components of the companion module have access to\n router directives such as `RouterLink` and `RouterOutlet`.",
"translation": "路由模块顺便重新导出`RouterModule`,这样关联模块的组件可以访问路由指令,比如`RouterLink`和`RouterOutlet`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A routing module *should not have its own `declarations`*. \n Components, directives, and pipes are the *responsibility of the feature module*,\n not the _routing_ module.",
"translation": "路由模块**不应该有自己的`declarations`**。组件、指令和管道是**特性模块的责任**,不属于路由模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A routing module should _only_ be imported by its companion module.",
"translation": "路由模块应该**只**被它的关联模块导入。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The `AppRoutingModule`, `ContactRoutingModule`, and `HeroRoutingModule` are good examples.",
"translation": "`AppRoutingModule`、`ContactRoutingModule`和`HeroRoutingModule是很好的例子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "See also [Do you need a _Routing Module_?](guide/router#why-routing-module) on the\n [Routing & Navigation](guide/router) page.",
"translation": "参见[路由与导航](guide/router)一章的“[你需要**路由模块**吗?](guide/router#why-routing-module)”部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a service-feature-module}\n <p>\n Service\n </p>",
"translation": "服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Service modules *provide utility services* such as data access and messaging.",
"translation": "*服务模块*用于**提供工具类服务**,比如数据访问和消息等。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Ideally, they consist entirely of _providers_ and have no _declarations_.\n The `CoreModule` and Angular's `HttpModule` are good examples.",
"translation": "理想情况下,它们应该完全由`providers`组成,不应该包括`declarations`。\n `CoreModule`和Angular的`HttpModule`就是很好的例子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Service Modules should _only_ be imported by the root `AppModule`.",
"translation": "服务模块应该*只被*根模块`AppModule`导入。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Do *not* import service modules in other feature modules.\n If you deviate from this guideline, know what you're doing and why.",
"translation": "*不要*在任何特性模块中导入它们。\n 如果你要违背这条指导原则,请务必想清楚你在做什么,并要有充分的理由。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "<td style=\"vertical-align: top\">\n {@a widget-feature-module}\n <p>\n Widget\n </p>",
"translation": "窗口部件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A widget module makes *components, directives, and pipes* available to external modules.",
"translation": "*窗口部件*模块导出能用供外部模块使用的**组件、指令和管道**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "`CommonModule` and `SharedModule` are widget modules.\n Many third-party UI component libraries are widget modules.",
"translation": "`CommonModule`和`SharedModule`都是窗口部件模块。\n 很多第三方UI组件库都是窗口部件模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A widget module should consist entirely of _declarations_, most of them exported.",
"translation": "部件模块应该只有`declarations`,并导出里面的绝大多数声明。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A widget module should rarely have _providers_.\n If you deviate from this guideline, know what you're doing and why.",
"translation": "窗口部件模块很少会有`providers`。\n 如果你要违背这条指导原则,请务必想清楚你在做什么,并要有充分的理由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Import widget modules in any module whose component templates need the widgets.",
"translation": "如果任何模块的组件模板中需要用到这些窗口部件,就请导入相应的窗口部件模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The following table summarizes the key characteristics of each _feature module_ group.",
"translation": "下表是对各种*特性模块*的关键特征汇总。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Real-world modules are often hybrids that knowingly deviate from these guidelines.",
"translation": "真实世界中的模块可能会违背这些分类法,混杂使用它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Feature Module",
"translation": "特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Declarations",
"translation": "声明`declarations`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Providers",
"translation": "提供商`providers`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Exports",
"translation": "导出什么",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Imported By",
"translation": "被谁导入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Examples",
"translation": "范例",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Domain",
"translation": "领域",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Rare",
"translation": "罕见",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Top component",
"translation": "顶级组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Feature, <code>AppModule</code>",
"translation": "特性模块和<code>AppModule</code>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "<code>ContactModule</code> (before routing)",
"translation": "<code>ContactModule</code>(路由之前的那个例子)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Routed",
"translation": "路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Rare",
"translation": "罕见",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Nobody",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "ContactModule</code>, <code>HeroModule</code>, <code>CrisisModule",
"translation": "ContactModule</code>、<code>HeroModule</code>、<code>CrisisModule",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Routing",
"translation": "路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "HttpModule</code>, <code>CoreModule",
"translation": "HttpModule</code>、<code>CoreModule",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Service",
"translation": "服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "No",
"translation": "无",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "HttpModule</code>, <code>CoreModule",
"translation": "HttpModule</code>、<code>CoreModule",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Widget",
"translation": "窗口部件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Rare",
"translation": "罕见",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Yes",
"translation": "有",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Feature",
"translation": "特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "CommonModule</code>, <code>SharedModule",
"translation": "CommonModule</code>、<code>SharedModule",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What's the difference between Angular and JavaScript Modules?",
"translation": "## Angular模块和JavaScript模块有什么区别",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular and JavaScript are different yet complementary module systems.",
"translation": "Angular和JavaScript是两种不同但互补的模块体系。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "Then you `import` a part in another module:",
"translation": "然后,我们可以在其它模块中`import`那部分:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "This kind of modularity is a feature of the _JavaScript language_.",
"translation": "这种模块化方式是*JavaScript*语言中的特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "An _NgModule_ is a feature of _Angular_ itself.",
"translation": "而*Angular模块*是*Angular本身*的特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular's `NgModule` also has `imports` and `exports` and they serve a similar purpose.",
"translation": "Angular的`NgModule`也有自己的`imports`和`exports`来达到类似的目的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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_ modules.",
"translation": "我们可以*导入*其它Angular模块以便在当前模块的组件模板中使用它们导出的类。\n我们可以*导出*当前Angular模块中的类以便其它模块可以导入它们并用在自己的组件模板中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The NgModule classes differ from JavaScript module class in the following key ways:",
"translation": "Angular的模块类与JavaScript的模块类有三个主要的不同点",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Instead of defining all member classes in one giant file (as in a JavaScript module),\n you list the module's classes in the `@NgModule.declarations` list.",
"translation": "JavaScript模块把所有成员类都定义在一个巨型文件Angular模块则把自己的类都列在`@NgModule.declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* An NgModule can only export the [declarable classes](guide/ngmodule-faq#q-declarable)\nit owns or imports from other modules.\nIt doesn't declare or export any other kind of class.",
"translation": "Angular模块只能导出[_可声明的类_](guide/ngmodule-faq#q-declarable)。这可能是它自己拥有的也可能是从其它模块中导入的。它不会声明或导出任何其它类型的类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The NgModule is also special in another way.\nUnlike JavaScript modules, an NgModule can extend the _entire_ application with services\nby adding providers to the `@NgModule.providers` list.\n<!-- CF: Should this sentence be a bullet point in the list above? -->",
"translation": "Angular模块还有些别的特殊之处。\n不同于JavaScript模块Angular模块可以通过把服务提供商添加到`@NgModule.providers`数组中来扩展*整个*应用提供的服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The provided services don't belong to the module nor are they scoped to the declared classes.\nThey are available _everywhere_.",
"translation": "这些提供的服务不仅仅从属于当前模块,其作用范围也不局限于模块中声明的类。它们*在哪里*都能用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Here's an _NgModule_ class with imports, exports, and declarations.",
"translation": "这里是一个带有`imports`、`exports`和`declarations`的*Angular模块*类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Of course you use _JavaScript_ modules to write NgModules as seen in the complete `contact.module.ts` file:",
"translation": "当然,我们同样得用*JavaScript*模块来写*Angular模块*,就像在最终版`contact.module.ts`文件中所见到的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "The Angular compiler finds a component or directive in a template when it can match the *selector* of that\ncomponent or directive to some HTML in that template.",
"translation": "Angular编译器通过在一个模板的HTML中匹配组件或指令的**选择器selector**,来查找组件或指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## What is the Angular compiler?",
"translation": "## 什么是Angular编译器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The Angular compiler converts the application code you write into highly performant JavaScript code.\nThe `@NgModule` metadata play an important role in guiding the compilation process.",
"translation": "*Angular编译器*会把我们所写的应用代码转换成高性能的JavaScript代码。\n在编译过程中`@NgModule`的元数据扮演了很重要的角色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The code you write isn't immediately executable.\nConsider *components*.\nComponents 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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "## NgModule API",
"translation": "## NgModule 模块 API",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "The following table summarizes the `NgModule` metadata properties.",
"translation": "下面是`NgModule`元数据中属性的汇总表:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Property",
"translation": "属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A list of [declarable](guide/ngmodule-faq#q-declarable) classes,\n the *component*, *directive*, and *pipe* classes that _belong to this module_.",
"translation": "[可声明类](guide/ngmodule-faq#q-declarable)的列表,也就是属于当前模块的**组件**、**指令**和**管道**类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "These declared classes are visible within the module but invisible to\n components in a different module unless they are _exported_ from this module and\n the other module _imports_ this one.",
"translation": "这些声明的类对组件内部可见,但是对其它模块不可见,除非 (a) 这些类从当前模块中*导出过*,并且 (b) 其它模块导入了当前模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "*Do not re-declare a class imported from another module.*",
"translation": "**不要重新声明从其它模块中导入的类。**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A list of dependency-injection providers.",
"translation": "依赖注入提供商的列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular registers these providers with the root injector of the module's execution context.\n That's the application's root injector for all modules loaded when the application starts.",
"translation": "Angular会在当前模块执行环境的根注入器中注册这些提供商。\n 那是应用程序在启动时为其加载的所有模块提供的根注入器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular can inject one of these provider services into any component in the application.\n If this module or any module loaded at launch provides the `HeroService`,\n Angular can inject the same `HeroService` intance into any app component.",
"translation": "Angular可以把这些提供商提供的服务注入到应用中的任何组件中。\n 如果该模块提供了`HeroService`或启动时被加载的任何模块提供了`HeroService`那么Angular就会把同一个`HeroService`实例注入到应用中的任何组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A lazy-loaded module has its own sub-root injector which typically\n is a direct child of the application root injector.",
"translation": "惰性加载模块有自己的子注入器,通常它是应用的根注入器的直接子级。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Lazy-loaded services are scoped to the lazy module's injector.\n If a lazy-loaded module also provides the `HeroService`,\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 如果惰性加载的模块也提供了`HeroService`,那么在该模块的环境中创建的任何组件(比如通过路由器导航),都会得到该服务的一个局部实例,而不是来自应用程序根注入器的那个全局实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Components in external modules continue to receive the instance created for the application root.",
"translation": "外部模块中的组件仍然会取得由应用的根注入器创建的那个实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A list of supporting modules.",
"translation": "支撑模块的列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Specifically, the list of modules whose exported components, directives, or pipes\n are referenced by the component templates declared in this module.",
"translation": "特别是包含当前模块中的组件模板引用过的组件、指令或管道的那些模块的列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A component template can [reference](guide/ngmodule-faq#q-template-reference) another component, directive, or pipe\n when the referenced class is declared in this module\n or the class was imported from another module.",
"translation": "在两种情况下组件模板可以[引用](guide/ngmodule-faq#q-template-reference)其它组件、指令或管道:或者所引用的类是声明在当前模块中的,或者那个类已经从其它模块中导入进来了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A component can use the `NgIf` and `NgFor` directives only because its parent module\n imported the Angular `CommonModule` (perhaps indirectly by importing `BrowserModule`).",
"translation": "组件可以使用`NgIf`和`NgFor`指令只是因为它所在的模块导入了Angular的`CommonModule`(也可能是通过导入`BrowserModule`而间接导入的)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "You can import many standard directives with the `CommonModule`\n but some familiar directives belong to other modules.\n A component template can bind with `[(ngModel)]` only after importing the Angular `FormsModule`.",
"translation": "通过`CommonModule`,我们可以导入很多标准指令。\n 但是也有一些熟悉的指令是属于其它模块的。\n 比如组件只有导入了Angular的`FormsModule`才能在组件模板中用`[(ngModel)]`进行绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A list of declarations&mdash;*component*, *directive*, and *pipe* classes&mdash;that\n an importing module can use.",
"translation": "可供导入了自己的模块使用的可声明对象(**组件**、**指令**、**管道类**)的列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Exported declarations are the module's _public API_.\n A component in another module can [reference](guide/ngmodule-faq#q-template-reference) _this_ module's `HeroComponent`\n if it imports this module and this module exports `HeroComponent`.",
"translation": "这些导出的可声明对象就是模块的*公开API*。\n 如果 (a) 其它模块导入了当前模块,并且 (b) 当前模块导出了`HeroComponent`\n 那么其它模块中的组件就可以[引用](guide/ngmodule-faq#q-template-reference)来自当前模块的`HeroComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Declarations are private by default.\n If this module does _not_ export `HeroComponent`, no other module can see it.",
"translation": "可声明对象默认情况下是私有的。\n 如果当前模块*没有*导出`HeroComponent`,那么没有任何其它模块能看到它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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`。模块`B`必须自己导入`CommonModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "[Re-export](guide/ngmodule-faq#q-re-export) 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-re-export)可以让模块的传递性更加明确。\n 如果模块`A`重新导出了`CommonModule`,然后模块`B`导入了模块`A`,那么模块`B`中的组件就能使用`NgIf`了,虽然模块`B`本身并没有导入过`CommonModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A list of components that can be bootstrapped.",
"translation": "能被引导的组件列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Usually there's only one component in this list, the _root component_ of the application.",
"translation": "通常,在这个列表中只有一个组件,也就是应用的*根组件*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"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/content-1/guide/ngmodule-faq.md"
},
{
"original": "A bootstrap component is automatically an `entryComponent`.",
"translation": "引导组件会自动成为`entryComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "A list of components that are _not_ [referenced](guide/ngmodule-faq#q-template-reference) in a reachable component template.",
"translation": "那些*没有*在任何可访问的组件的模板中[引用过](guide/ngmodule-faq#q-template-reference)的组件列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Most developers never set this property.\n The [Angular compiler](guide/ngmodule-faq#q-angular-compiler) must know about every component actually used in the application.\n The compiler can discover most components by walking the tree of references\n from one component template to another.",
"translation": "大多数开发人员从来没有设置过该属性。[_Angular编译器_](guide/ngmodule-faq#q-angular-compiler)必须知道在应用中实际用过的每一个组件。\n 通过遍历组件模板中的引用树,编译器可以自动找出大多数的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "But there's always at least one component that's not referenced in any template:\n the root component, `AppComponent`, that you bootstrap to launch the app.\n That's why it's called an _entry component_.",
"translation": "但是至少有一个组件不会被任何模板引用:根组件`AppComponent`,因为我们就是用它来引导本应用程序的。\n 这也就是为什么它被称为*入口组件*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Routed components are also _entry components_ because they aren't referenced in a template either.\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/content-1/guide/ngmodule-faq.md"
},
{
"original": "While the bootstrapped and routed components are _entry components_,\n you usually don't have to add them to a module's `entryComponents` list.",
"translation": "*引导组件*和*路由组件*都是*入口组件*,我们一般不用再把它们添加到模块的`entryComponents`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Angular automatically adds components in the module's `bootstrap` list to the `entryComponents` list.\n The `RouterModule` adds routed components to that list.",
"translation": "Angular会自动把模块的`bootstrap`列表中的组件添加到`entryComponents`列表中。\n `RouterModule`同样会把路由组件添加到`entryComponents`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "That leaves only the following sources of undiscoverable components:",
"translation": "这样,那些无法自动发现的组件就只剩下这些来源了:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Components bootstrapped using one of the imperative techniques.",
"translation": "使用某种命令式技巧引导的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "* Components dynamically loaded into the DOM by some means other than the router.",
"translation": "使用路由器之外的手段动态加载到DOM中的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "Both are advanced techniques that few developers ever employ.\n If you are one of those few, you must add these components to the\n `entryComponents` list yourself, either programmatically or by hand.",
"translation": "所有这些高级技巧是只有极少数开发人员才会去用的。\n 如果你是其中的一位,那么你就不得不自行把这些组件添加到`entryComponents`列表中 —— 无论是用程序添加还是手动添加。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule-faq.md"
},
{
"original": "# NgModules",
"translation": "# Angular模块 (NgModule)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "**NgModules** help organize an application into cohesive blocks of functionality.\n<!-- CF: \"app\" and \"application\" are used interchangeably throughout this page.\nI'm not sure what's appropriate, so I left them as is for now. --",
"translation": "**Angular 模块**能帮你把应用组织成多个内聚的功能块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "An NgModule is a class adorned with the *@NgModule* decorator function.\n`@NgModule` takes a metadata object that tells Angular how to compile and run module code.\nIt identifies the module's own components, directives, and pipes,\nmaking some of them public so external components can use them.\n`@NgModule` may add service providers to the application dependency injectors.\nAnd there are many more options covered here.",
"translation": "Angular 模块是带有 **@NgModule** 装饰器函数的_类_。\n `@NgModule`接收一个元数据对象,该对象告诉 Angular 如何编译和运行模块代码。\n 它标记出该模块_拥有_的组件、指令和管道\n 并把它们的一部分公开出去,以便外部组件使用它们。\n 它可以向应用的依赖注入器中添加服务提供商。\n 本章还会涉及到更多选项。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Before reading this page, read the\n[The Root Module](guide/bootstrapping) page, which introduces NgModules and the essentials\nof creating and maintaining a single root `AppModule` for the entire application.",
"translation": "请先阅读[根模块](guide/bootstrapping)一章,那里介绍过 Angular 模块,以及如何为整个应用创建和维护单一的*根*`AppModule`类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This page covers NgModules in greater depth.",
"translation": "本章的解释更加详尽,正如下面的目录所示。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Angular modularity](guide/ngmodule#angular-modularity \"Add structure to the app with NgModule\")",
"translation": "[Angular 模块化](guide/ngmodule#angular-modularity \"用 NgModule 把结构添加到应用中\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [The application root module](guide/ngmodule#root-module \"The startup module that every app requires\")",
"translation": "[应用的根模块](guide/ngmodule#root-module \"任何应用都需要的启动模块\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Bootstrap the root module](guide/ngmodule#bootstrap \"Launch the app in a browser with the root module as the entry point\")",
"translation": "[引导根模块](guide/ngmodule#bootstrap \"在浏览器中把根模块作为入口点来启动应用\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Declarations](guide/ngmodule#declarations \"Declare the components, directives, and pipes that belong to a module\")",
"translation": "[声明](guide/ngmodule#declarations \"声明从属于模块的组件、指令和管道\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Providers](guide/ngmodule#providers \"Extend the app with additional services\")",
"translation": "[提供商](guide/ngmodule#providers \"使用更多服务来扩展该应用\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Imports](guide/ngmodule#imports \"Import components, directives, and pipes for use in component templates\")",
"translation": "[导入](guide/ngmodule#imports \"为组件模板导入组件、指令和管道\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Resolve conflicts](guide/ngmodule#resolve-conflicts \"When two directives have the same selector\")",
"translation": "[解决冲突](guide/ngmodule#resolve-conflicts \"当两指令具有相同的选择器时……\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Feature modules](guide/ngmodule#feature-modules \"Partition the app into feature modules\")",
"translation": "[特性模块](guide/ngmodule#feature-modules \"把应用分割成一些特性模块\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Lazy loaded modules with the router](guide/ngmodule#lazy-load \"Load modules asynchronously\")",
"translation": "[用路由器惰性加载模块](guide/ngmodule#lazy-load \"惰性加载模块\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Shared modules](guide/ngmodule#shared-module \"Create modules for commonly used components, directives, and pipes\")",
"translation": "[共享模块](guide/ngmodule#shared-module \"为公用的组件、指令和管道创建模块\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [The Core module](guide/ngmodule#core-module \"Create a core module with app-wide singleton services and single-use components\")",
"translation": "[核心模块](guide/ngmodule#core-module \"用应用级单例服务和一次性组件创建核心模块\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Configure core services with _forRoot_](guide/ngmodule#core-for-root \"Configure providers during module import\")",
"translation": "[用 _forRoot_ 配置核心服务](guide/ngmodule#core-for-root \"在导入模块时配置提供商\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [Prevent reimport of the _CoreModule_](guide/ngmodule#prevent-reimport \"because bad things happen if a lazy loaded module imports Core\")",
"translation": "[禁止重复导入 _CoreModule_](guide/ngmodule#prevent-reimport \"如果惰性加载模块导入了核心模块,就会出问题\")",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* [NgModule metadata properties](guide/ngmodule#ngmodule-properties \"A technical summary of the @NgModule metadata properties\")\n CF: This link goes to the top of this page. I would expect it to go to an \"NgModule metadata properties\"\n section at the end of this page, but that section doesn't exist. -->",
"translation": "<!--\n [NgModule 元数据的属性](guide/ngmodule#ngmodule-properties \"对@NgModule元数据属性的技术性总结\")\n-->",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "#### Live examples",
"translation": "#### 在线例子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This page explains NgModules through a progression of improvements to a sample with a \"Tour of Heroes\" theme. Here's an index to live examples at key moments in the evolution of the sample:",
"translation": "本章通过一个基于《英雄指南》的渐进式例子解释了 Angular 的模块。这里是例子演化过程中一些关键节点的在线例子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* <live-example plnkr=\"minimal.0\">A minimal NgModule app</live-example>",
"translation": "<live-example plnkr=\"minimal.0\">最小的 NgModule 应用</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* <live-example plnkr=\"contact.1b\">The first contact module</live-example>",
"translation": "<live-example plnkr=\"contact.1b\">第一个联系人模块</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* <live-example plnkr=\"contact.2\">The revised contact module</live-example>",
"translation": "<live-example plnkr=\"contact.2\">修改过的联系人模块</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* <live-example plnkr=\"pre-shared.3\">Just before adding SharedModule</live-example>",
"translation": "<live-example plnkr=\"pre-shared.3\">添加 _SharedModule_ 之前</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* <live-example>The final version</live-example>",
"translation": "<live-example>最终版</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "#### Frequently asked questions (FAQs)",
"translation": "### 常见问题",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This page covers NgModule concepts in a tutorial fashion.",
"translation": "本章涵盖了英雄指南下的 Angular 模块概念。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The companion [NgModule FAQs](guide/ngmodule-faq \"NgModule FAQs\") guide\noffers answers to specific design and implementation questions.\nRead this page before reading those FAQs.",
"translation": "烹饪宝典中的 [Angular 模块常见问题](guide/ngmodule-faq \"Angular 模块常见问题\")为一些与设计和实现有关的问题提供了答案。\n不过在阅读常见问题之前要先阅读本章。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Angular modularity",
"translation": "## Angular 模块化",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Modules are a great way to organize an application and extend it with capabilities from external libraries.",
"translation": "模块是组织应用和使用外部库扩展应用的最佳途径。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Many Angular libraries are modules (such as `FormsModule`, `HttpModule`, 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>,\n<a href=\"https://github.com/angular/angularfire2\">AngularFire2</a>).",
"translation": "很多 Angular 库都是模块,例如:`FormsModule`、`HttpModule`、`RouterModule`。\n 很多第三方库也封装成了 Angular 模块,例如:<a href=\"https://material.angular.io/\" target=\"_blank\">Material Design</a>、\n <a href=\"http://ionicframework.com/\" target=\"_blank\">Ionic</a>、\n <a href=\"https://github.com/angular/angularfire2\" target=\"_blank\">AngularFire2</a>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"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/content-1/guide/ngmodule.md"
},
{
"original": "Modules can also add services to the application.\nSuch services might be internally developed, such as the application logger.\nServices can come from outside sources, such as the Angular router and Http client.",
"translation": "模块还能用来把服务加到应用程序中。这些服务可能是内部研发的,例如应用日志服务;\n也可能是外部资源例如 Angular 路由和 Http 客户端。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Modules can be loaded eagerly when the application starts.\nThey can also be _lazy loaded_ asynchronously by the router.",
"translation": "模块可能在应用启动时主动加载也可能由路由器进行异步_惰性加载_。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "An NgModule is a class decorated with `@NgModule` metadata. The metadata do the following:",
"translation": "Angular 模块是一个由`@NgModule`装饰器提供元数据的类,元数据包括:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Declare which components, directives, and pipes belong to the module.",
"translation": "声明哪些组件、指令、管道_属于_该模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Make some of those classes public so that other component templates can use them.",
"translation": "公开某些类,以便其它的组件模板可以使用它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Import other modules with the components, directives, and pipes needed by the components in _this_ module.",
"translation": "导入其它模块从其它模块中获得_本_模块所需的组件、指令和管道。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Provide services at the application level that any application component can use.",
"translation": "在应用程序级提供服务,以便应用中的任何组件都能使用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Every Angular app has at least one module class, the _root module_.\nYou bootstrap that module to launch the application.",
"translation": "每个 Angular 应用至少有一个模块类 —— _根模块_我们将通过引导根模块来启动应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"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*\nthat represent collections of related functionality.\nYou then import these modules into the root module.",
"translation": "对于组件很少的简单应用来说只用一个_根模块_就足够了。\n 随着应用规模的增长我们逐步从_根模块_中重构出一些**特性模块**,来代表一组相关功能的集合。\n 然后我们在_根模块_中导入它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Later in this page, you'll read about this process. For now, you'll start with the root module.",
"translation": "稍后我们就会看到怎么做。不过还是先从_根模块_开始吧",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## The root _AppModule_",
"translation": "## _AppModule_ - 应用的根模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Every Angular app has a *root module* class.\nBy convention, the *root module* class is called `AppModule` and it exists in a file named `app.module.ts`.",
"translation": "每个 Angular 应用都有一个**根模块**类。\n按照约定它的类名叫做`AppModule`,被放在`app.module.ts`文件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `AppModule` from the QuickStart seed on the [Setup](guide/setup) page is as minimal as possible:",
"translation": "[快速起步种子库](guide/setup)中的`AppModule`是能找到的最小版本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `@NgModule` decorator defines the metadata for the module.\nThis page takes an intuitive approach to understanding the metadata and fills in details as it progresses.",
"translation": "`@NgModule`装饰器用来为模块定义元数据。\n 我们先凭直觉来理解一下元数据,接下来再逐步深入细节。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The metadata imports a single helper module, `BrowserModule`, which every browser app must import.",
"translation": "这个元数据只导入了一个辅助模块,`BrowserModule`,每个运行在浏览器中的应用都必须导入它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`BrowserModule` registers critical application service providers.\nIt also includes common directives like `NgIf` and `NgFor`, which become immediately visible and usable\nin any of this module's component templates.",
"translation": "`BrowserModule`注册了一些关键的应用服务提供商。\n它还包括了一些通用的指令例如`NgIf`和`NgFor`,所以这些指令在该模块的任何组件模板中都是可用的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `declarations` list identifies the application's only component,\nthe _root component_, the top of the app's rather bare component tree.",
"translation": "`declarations`列出了该应用程序中唯一的组件_根组件_它是应用的光秃秃的组件树的根。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The example `AppComponent` simply displays a data-bound title:",
"translation": "下面范例`AppComponent`显示被绑定的标题:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Lastly, the `@NgModule.bootstrap` property identifies this `AppComponent` as the _bootstrap component_.\nWhen Angular launches the app, it places the HTML rendering of `AppComponent` in the DOM,\ninside the `<my-app>` element tags of the `index.html`.",
"translation": "最后,`@NgModule.bootstrap`属性把这个`AppComponent`标记为_引导 (bootstrap) 组件_。\n当 Angular 引导应用时,它会在 DOM 中渲染`AppComponent`,并把结果放进`index.html`的`<my-app>`元素标记内部。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Bootstrapping in _main.ts_",
"translation": "## 在 _main.ts_ 中引导",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You launch the application by bootstrapping the `AppModule` in the `main.ts` file.",
"translation": "在`main.ts`文件中,我们通过引导`AppModule`来启动应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Angular offers a variety of bootstrapping options targeting multiple platforms.\nThis page describes two options, both targeting the browser.",
"translation": "针对不同的平台Angular 提供了很多引导选项。\n本章我们只讲两个选项都是针对浏览器平台的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Compile just-in-time (JIT)",
"translation": "### 即时 (JiT) 编译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "In the first, _dynamic_ option, the [Angular compiler](guide/ngmodule-faq#q-angular-compiler \"About the Angular Compiler\")\ncompiles the application in the browser and then launches the app.",
"translation": "先看看_动态_选项[Angular 编译器](guide/ngmodule-faq#q-angular-compiler \"关于 Angular 编译器\")在浏览器中编译并引导该应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The samples in this page demonstrate the dynamic bootstrapping approach.",
"translation": "这里的例子演示进行动态引导的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "<live-example embedded plnkr=\"minimal.0\" img=\"guide/ngmodule/minimal-plunker.png\">Try the live example.</live-example>",
"translation": "<live-example embedded plnkr=\"minimal.0\" img=\"devguide/ngmodule/minimal-plunker.png\">试试在线例子。</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Compile ahead-of-time (AOT)",
"translation": "### 使用预编译器 (AoT - Ahead-Of-Time) 进行静态引导",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Consider the static alternative which can produce a much smaller application that\nlaunches faster, especially on mobile devices and high latency networks.",
"translation": "静态方案可以生成更小、启动更快的应用,建议优先使用它,特别是在移动设备或高延迟网络下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "In the _static_ option, the Angular compiler runs ahead of time as part of the build process,\nproducing a collection of class factories in their own files.\nAmong them is the `AppModuleNgFactory`.",
"translation": "使用_静态_选项Angular 编译器作为构建流程的一部分提前运行,生成一组类工厂。它们的核心就是`AppModuleNgFactory`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The syntax for bootstrapping the pre-compiled `AppModuleNgFactory` is similar to\nthe dynamic version that bootstraps the `AppModule` class.",
"translation": "引导预编译的`AppModuleNgFactory`的语法和动态引导`AppModule`类的方式很相似。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Because the entire application was pre-compiled,\nAngular doesn't ship the Angular compiler to the browser and doesn't compile in the browser.",
"translation": "由于整个应用都是预编译的,所以我们不用把 _Angular 编译器_一起发到浏览器中也不用在浏览器中进行编译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The application code downloaded to the browser is much smaller than the dynamic equivalent\nand it's ready to execute immediately. The performance boost can be significant.",
"translation": "下载到浏览器中的应用代码比动态版本要小得多,并且能立即执行。引导的性能可以得到显著提升。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Both the JIT and AOT compilers generate an `AppModuleNgFactory` class from the same `AppModule`\n source code.\nThe JIT compiler creates that factory class on the fly, in memory, in the browser.\nThe AOT compiler outputs the factory to a physical file\nthat is imported here in the static version of `main.ts`.",
"translation": "无论是 JiT 还是 AoT 编译器都会从同一份`AppModule`源码中生成一个`AppModuleNgFactory`类。\nJiT 编译器动态地在浏览器的内存中创建这个工厂类。\nAoT 编译器把工厂输出成一个物理文件,也就是我们在静态版本`main.ts`中导入的那个。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "In general, the `AppModule` should neither know nor care how it is bootstrapped.",
"translation": "通常,`AppModule`不必关心它是如何被引导的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Although the `AppModule` evolves as the app grows, the bootstrap code in `main.ts` doesn't change.\nThis is the last time you'll look at `main.ts`.",
"translation": "虽然`AppModule`会随着应用而演化,但是`main.ts`中的引导代码不会变。\n这将是我们最后一次关注`main.ts`了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Declare directives and components",
"translation": "## 声明指令和组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "As the app evolves,\nthe first addition is a `HighlightDirective`, an [attribute directive](guide/attribute-directives)\nthat sets the background color of the attached element.",
"translation": "应用继续演进。\n首先加入的是`HighlightDirective`,一个[属性型指令](guide/attribute-directives),它会设置所在元素的背景色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Update the `AppComponent` template to attach the directive to the title:",
"translation": "我们更新`AppComponent`的模板,来把该指令附加到标题上:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "If you ran the app now, Angular wouldn't recognize the `highlight` attribute and would ignore it.\nYou must declare the directive in `AppModule`.",
"translation": "如果我们现在就运行该应用Angular 将无法识别`highlight`属性,并且忽略它。\n我们必须在`AppModule`中声明该指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Import the `HighlightDirective` class and add it to the module's `declarations` like this:",
"translation": "导入`HighlightDirective`类,并把它加入该模块的`declarations`数组中,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Refactor the title into its own `TitleComponent`.\nThe component's template binds to the component's `title` and `subtitle` properties like this:",
"translation": "接着把标题重构到独立的`TitleComponent`中。\n该组件的模板绑定到了组件的`title`和`subtitle`属性中,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Rewrite the `AppComponent` to display the new `TitleComponent` in the `<app-title>` element,\nusing an input binding to set the `subtitle`.",
"translation": "我们重写了`AppComponent`来把这个新的`TitleComponent`显示到`<app-title>`元素中,并使用一个输入型绑定来设置`subtitle`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Angular won't recognize the `<app-title>` tag until you declare it in `AppModule`.\nImport the `TitleComponent` class and add it to the module's `declarations`:",
"translation": "除非我们在`AppModule`中声明过,否则 Angular 无法识别`<app-title>`标签。\n导入`TitleComponent`类,并把它加到模块的`declarations`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Service providers",
"translation": "## 服务提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Modules are a great way to provide services for all of the module's components.",
"translation": "模块是为模块中的所有组件提供服务的最佳途径。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The [Dependency Injection](guide/dependency-injection) page describes\nthe Angular hierarchical dependency-injection system and how to configure that system\nwith [providers](guide/dependency-injection#providers) at different levels of the\napplication's component tree.",
"translation": "[依赖注入](guide/dependency-injection)一章中讲过 Angular 的层次化依赖注入系统,\n以及如何在组件树的不同层次上通过[提供商](guide/dependency-injection#providers)配置该系统。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "A module can add providers to the application's root dependency injector, making those services\navailable everywhere in the application.",
"translation": "模块可以往应用的“根依赖注入器”中添加提供商,让那些服务在应用中到处可用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Many applications capture information about the currently logged-in user and make that information\naccessible through a user service.\nThis sample application has a dummy implementation of such a `UserService`.",
"translation": "很多应用都需要获取当前登录的用户的信息,并且通过一个用户服务来访问它们。\n该范例中有一个`UserService`的伪实现。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The sample application should display a welcome message to the logged-in user just below the application title.\nUpdate the `TitleComponent` template to show the welcome message below the application title.",
"translation": "该范例应用会在标题下方为已登录用户显示一条欢迎信息。\n更新`TitleComponent`的模板来显示它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Update the `TitleComponent` class with a constructor that injects the `UserService`\nand sets the component's `user` property from the service.",
"translation": "更新`TitleComponent`,为它加入一个构造函数,注入`UserService`类,并把组件的`user`属性设置为它的实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You've defined and used the service. Now to _provide_ it for all components to use,\nadd it to a `providers` property in the `AppModule` metadata:",
"translation": "我们已经_定义_并_使用了_该服务。现在我们通过把它加入`AppModule`元数据的`providers`属性中来把它_提供_给所有组件使用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Import supporting modules",
"translation": "## 导入支持性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "In the revised `TitleComponent`, an `*ngIf` directive guards the message.\nThere is no message if there is no user.",
"translation": "注意,在修改过的`TitleComponent`中,有一个`*ngIf`指令在“守卫着”该消息。如果没有当前用户,就没有任何消息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Although `AppModule` doesn't declare `NgIf`, the application still compiles and runs.\nHow can that be? The Angular compiler should either ignore or complain about unrecognized HTML.",
"translation": "虽然`AppModule`没有声明过`NgIf`指令但该应用仍然能正常编译和运行。为什么这样没问题呢Angular 的编译器遇到不认识的 HTML 时应该不是忽略就是报错才对。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Angular does recognize `NgIf` because you imported it earlier.\nThe initial version of `AppModule` imports `BrowserModule`.",
"translation": "Angular 能识别`NgIf`指令,是因为我们以前导入过它。最初版本的`AppModule`就导入了`BrowserModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Importing `BrowserModule` made all of its public components, directives, and pipes visible\nto the component templates in `AppModule`.",
"translation": "导入`BrowserModule`会让该模块公开的所有组件、指令和管道在`AppModule`下的任何组件模板中可用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "More accurately, `NgIf` is declared in `CommonModule` from `@angular/common`.",
"translation": "更准确的说,`NgIf`是在来自`@angular/common`的`CommonModule`中声明的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`CommonModule` contributes many of the common directives that applications need, including `ngIf` and `ngFor`.",
"translation": "`CommonModule`提供了很多应用程序中常用的指令,包括`NgIf`和`NgFor`等。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`BrowserModule` imports `CommonModule` and [re-exports](guide/ngmodule-faq#q-re-export) it.\nThe net effect is that an importer of `BrowserModule` gets `CommonModule` directives automatically.",
"translation": "`BrowserModule`导入了`CommonModule`并且[_重新导出_](guide/ngmodule-faq#q-re-export)了它。\n最终的效果是只要导入`BrowserModule`就自动获得了`CommonModule`中的指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Many familiar Angular directives don't belong to `CommonModule`.\nFor example, `NgModel` and `RouterLink` belong to Angular's `FormsModule` and `RouterModule` respectively.\nYou must import those modules before you can use their directives.",
"translation": "很多熟悉的 Angular 指令并不属于`CommonModule`。\n例如`NgModel`和`RouterLink`分别属于 Angular 的`FormsModule`模块和`RouterModule`模块。\n在使用那些指令之前我们也必须_导入_那些模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "To illustrate this point, you'll extend the sample app with `ContactComponent`,\na form component that imports form support from the Angular `FormsModule`.",
"translation": "要解释这一点,我们可以再加入`ContactComponent`组件,它是一个表单组件,从 Angular 的`FormsModule`中导入了表单支持。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Add the _ContactComponent_",
"translation": "添加 _ContactComponent_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "[Angular forms](guide/forms) are a great way to manage user data entry.",
"translation": "[Angular 表单](guide/forms)是用来管理用户数据输入的最佳方式之一。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `ContactComponent` presents a \"contact editor,\"\nimplemented with Angular forms in the [template-driven form](guide/forms#template-driven) style.",
"translation": "`ContactComponnet`组件展现“联系人编辑器”,它是用[_模板驱动式表单_](guide/forms)实现的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Angular form styles",
"translation": "### Angular 表单的风格",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You can write Angular form components in\ntemplate-driven or\n[reactive](guide/dynamic-form) style.\n<!-- CF: this link goes to a page titled \"Dynamic Forms\". Should the link text be \"dynamic\" instead of \"reactive\"? -->",
"translation": "我们写 Angular 表单组件时,可以使用[_模板驱动式表单_](guide/forms)\n 也可以使用[_响应式表单_](guide/dynamic-form)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The following sample imports the `FormsModule` from `@angular/forms` because\nthe `ContactComponent` is written in _template-driven_ style.\nModules with components written in the _reactive_ style\nimport the `ReactiveFormsModule`.",
"translation": "该例子中从`@angular/forms`中导入了`FormsModule`,这是因为`ContactComponent`组件用的是_模板驱动式表单_。\n那些带有_响应式表单_组件的模块应该转而导入`ReactiveFormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `ContactComponent` selector matches an element named `<app-contact>`.\nAdd an element with that name to the `AppComponent` template, just below the `<app-title>`:",
"translation": "`ContactComponent`的选择器会去匹配名叫`<app-contact>`的元素。\n在`AppComponent`模板中`<app-title>`的下方添加一个具有此名字的元素:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Form components are often complex. The `ContactComponent` has its own `ContactService`\nand [custom pipe](guide/pipes#custom-pipes) (called `Awesome`),\nand an alternative version of the `HighlightDirective`.",
"translation": "`ContactComponent`还有很多事要做。\n表单组件通常都是很复杂的。本组件具有它自己的`ContactService`和[自定义管道](guide/pipes#custom-pipes) `Awesome`\n以及`HighlightDirective`的另一个版本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "To make it manageable, place all contact-related material in an `src/app/contact` folder\nand break the component into three constituent HTML, TypeScript, and css files:",
"translation": "为了方便管理,我们把所有与联系人相关的编程元素都放进`src/app/contact`目录,\n并把该组件分解成三个基本成分HTML、TypeScript 和 CSS 文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "In the middle of the component template,\nnotice the two-way data binding `[(ngModel)]`.\n`ngModel` is the selector for the `NgModel` directive.",
"translation": "先来看组件模板。\n注意模板中部的双向数据绑定`[(ngModel)]`。\n`ngModel`是`NgModel`指令的选择器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Although `NgModel` is an Angular directive, the _Angular compiler_ won't recognize it for the following reasons:",
"translation": "虽然`NgModel`是 Angular 指令,但 _Angular 编译器_并不会识别它因为",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* `AppModule` doesn't declare `NgModel`.",
"translation": "`AppModule`没有声明过这个`NgModel`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* `NgModel` wasn't imported via `BrowserModule`.",
"translation": "`NgModel`也没有通过`BrowserModule`被导入过。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Even if Angular somehow recognized `ngModel`,\n`ContactComponent` wouldn't behave like an Angular form because\nform features such as validation aren't yet available.",
"translation": "退一步说,即使 Angular 有办法识别`ngModel``ContactComponent`也不会表现的像 Angular 表单,\n因为本组件表单的表单相关的特性例如有效性验证还不可用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Import the FormsModule",
"translation": "导入 FormsModule",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Add the `FormsModule` to the `AppModule` metadata's `imports` list.",
"translation": "把`FormsModule`加到`AppModule`元数据中的`imports`列表中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Now `[(ngModel)]` binding will work and the user input will be validated by Angular forms,\nonce you declare the new component, pipe, and directive.",
"translation": "一旦我们声明了这些新组件、管道和指令,`[(ngModel)]`绑定就会正常工作,用户的输入也能被 Angular 表单验证了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "*Do not* add `NgModel`&mdash;or the `FORMS_DIRECTIVES`&mdash;to\nthe `AppModule` metadata's declarations.\nThese directives belong to the `FormsModule`.",
"translation": "**不要**把`NgModel`(或`FORMS_DIRECTIVES加到`AppModule`元数据的`declarations`数据中!这些指令属于`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Components, directives, and pipes belong to _one module only_.",
"translation": "组件、指令和管道_只能_属于一个模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "*Never re-declare classes that belong to another module.*",
"translation": "**永远不要再次声明属于其它模块的类。**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Declare the contact component, directive, and pipe",
"translation": "### 声明联系人的组件、指令和管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The application won't compile until you declare the contact component, directive, and pipe.\nUpdate the `declarations` in the `AppModule` accordingly:",
"translation": "如果我们没有声明该联系人模块的组件、指令和管道,该应用就会失败。\n更新`AppModule`中的`declarations`元数据,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "There are two directives with the same name, both called `HighlightDirective`.",
"translation": "如果有两个同名指令,都叫做`HighlightDirective`,该怎么办呢?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "To work around this, create an alias for the contact version using the `as` JavaScript import keyword.",
"translation": "我们只要在 import 时使用`as`关键字来为第二个指令创建个别名就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This solves the immediate issue of referencing both directive _types_ in the same file but\nleaves another issue unresolved.\nYou'll learn more about that issue later in this page, in [Resolve directive conflicts](guide/ngmodule#resolve-conflicts).",
"translation": "这解决了在文件中使用指令_类型_时的冲突问题但是还有另一个问题没有解决我们将在[后面](guide/ngmodule#resolve-conflicts)讨论它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Provide the _ContactService_",
"translation": "提供 _ContactService_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `ContactComponent` displays contacts retrieved by the `ContactService`,\nwhich Angular injects into its constructor.",
"translation": "`ContactComponent`显示从`ContactService`服务中获取的联系人信息,该服务是被 Angular 注入到组件的构造函数中的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You have to provide that service somewhere.\nThe `ContactComponent` could provide it,\nbut then the service would be scoped to this component only.\nYou want to share this service with other contact-related components that you'll surely add later.",
"translation": "我们必须在某个地方提供该服务。\n在`ContactComponent`中_可以_提供它。\n但是那样一来它的作用范围就会_仅_局限于该组件及其子组件。\n而我们希望让该服务与其它和联系人有关的组件中共享稍后我们就会添加那些组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "In this app, add `ContactService` to the `AppModule` metadata's `providers` list:",
"translation": "在此应用中,我们选择把`ContactSerivce`添加到`AppModule`元数据的`providers`列表中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Now you can inject `ContactService` (like `UserService`) into any component in the application.",
"translation": "现在,`ContactService`服务就能被注入进该应用中的任何组件了,就像`UserService`一样。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Application-scoped providers",
"translation": "全应用范围的提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `ContactService` provider is _application_-scoped because Angular\n registers a module's `providers` with the application's *root injector*.",
"translation": "`ContactService`的提供商是_全应用_范围的这是因为 Angular 使用该应用的**根注入器**注册模块的`providers`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Architecturally, the `ContactService` belongs to the Contact business domain.\nClasses in other domains don't need the `ContactService` and shouldn't inject it.",
"translation": "从架构上看,`ContactService`属于“联系人”这个业务领域。\n _其它_领域中的类并不需要知道`ContactService`,也不会要求注入它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You might expect Angular to offer a _module_-scoping mechanism to enforce this design.\nIt doesn't. NgModule instances, unlike components, don't have their own injectors\nso they can't have their own provider scopes.",
"translation": "我们可能会期待 Angular 提供一种_模块_范围内的机制来保障此设计。\n但它没有。与组件不同Angular的 模块实例并没有它们自己的注入器,所以它们也没有自己的供应商范围。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This omission is intentional.\nNgModules are designed primarily to extend an application,\nto enrich the entire app with the module's capabilities.",
"translation": "Angular是故意这么设计的。\n Angular的模块设计主要目的是扩展应用程序丰富其模块化能力。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "In practice, service scoping is rarely an issue.\nNon-contact components can't accidentally inject the `ContactService`.\nTo inject `ContactService`, you must first import its _type_.\nOnly Contact components should import the `ContactService` type.",
"translation": "在实践中,服务的范围很少会成为问题。\n 联系人之外的组件不会意外注入`ContactService`服务。\n 要想注入`ContactService`你得先导入它的_类型_。\n 而只有联系人组件才会导入`ContactService`_类型_。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Read more in the [How do I restrict service scope to a module?](guide/ngmodule-faq#q-component-scoped-providers) section\nof the [NgModule FAQs](guide/ngmodule-faq) page.",
"translation": "在[NgModule常见问题](guide/ngmodule-faq)页的[如何把服务的范围限制在一个模块中](guide/ngmodule-faq#q-component-scoped-providers)一节中可以了解更多。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Run the app",
"translation": "运行该应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Everything is in place to run the application with its contact editor.",
"translation": "一切就绪,可以运行该应用及其联系人编辑器了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The app file structure looks like this:",
"translation": "应用的文件结构是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "</div>",
"translation": "Try the example:\n试试这个例子<live-example embedded plnkr=\"contact.1b\" img=\"guide/ngmodule/contact-1b-plunker.png\"></live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Resolve directive conflicts",
"translation": "## 解决指令冲突",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "An issue arose [earlier](guide/ngmodule#import-name-conflict) when you declared the contact's `HighlightDirective` because\nyou already had a `HighlightDirective` class at the application level.",
"translation": "[以前](guide/ngmodule#import-name-conflict)我们在声明联系人的`HighlightDirective`指令时遇到了问题,因为在应用程序一级已经有了一个`HighlightDirective`类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The selectors of the two directives both highlight the attached element with a different color.",
"translation": "在查找它们的选择器时,它们都试图用不同的颜色来高亮所依附的元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Both directives are declared in this module so both directives are active.",
"translation": "Angular 会只用它们中的一个吗?不会。\n所有指令都声明在该模块中所以_这两个指令都会被激活_。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "When the two directives compete to color the same element,\nthe directive that's declared later wins because its DOM changes overwrite the first.\nIn this case, the contact's `HighlightDirective` makes the application title text blue\nwhen it should stay gold.",
"translation": "当两个指令在同一个元素上争相设置颜色时,后声明的那个会胜出,因为它对 DOM 的修改覆盖了前一个。\n在该例子中联系人的`HighlightDirective`把应用标题的文本染成了蓝色,而我们原本期望它保持金色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The issue is that two different classes are trying to do the same thing.",
"translation": "真正的问题在于有_两个不同的类_试图做同一件事。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "It's OK to import the same directive class multiple times.\nAngular removes duplicate classes and only registers one of them.",
"translation": "多次导入_同一个_指令是没问题的Angular 会移除重复的类,而只注册一次。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "But from Angular's perspective, two different classes, defined in different files, that have the same name\nare not duplicates. Angular keeps both directives and\nthey take turns modifying the same HTML element.",
"translation": "从 Angular 的角度看两个类并没有重复。Angular 会同时保留这两个指令,并让它们依次修改同一个 HTML 元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "At least the app still compiles.\nIf you define two different component classes with the same selector specifying the same element tag,\nthe compiler reports an error. It can't insert two components in the same DOM location.",
"translation": "至少,应用仍然编译通过了。\n 如果我们使用相同的选择器定义了两个不同的组件类,并指定了同一个元素标记,编译器就会报错说它无法在同一个 DOM 位置插入两个不同的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "To eliminate component and directive conflicts, create feature modules\nthat insulate the declarations in one module from the declarations in another.",
"translation": "我们可以通过创建特性模块来消除组件与指令的冲突。\n特性模块可以把来自一个模块中的声明和来自另一个的区隔开。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Feature modules",
"translation": "## 特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This application isn't big yet, but it's already experiencing structural issues.",
"translation": "该应用还不大,但是已经在受结构方面的问题困扰了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The root `AppModule` grows larger with each new application class.",
"translation": "随着一个个类被加入应用中,根模块`AppModule`变大了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* There are conflicting directives.\nThe `HighlightDirective` in the contact re-colors the work done by the `HighlightDirective` declared in `AppModule`.\nAlso, it colors the application title text when it should color only the `ContactComponent`.",
"translation": "我们遇到了指令冲突。\n 联系人模块的`HighlightDirective`在`AppModule`中声明的`HighlightDirective`的基础上进行了二次上色。\n 并且,它染了应用标题文字的颜色,而不仅仅是`ContactComponent`中的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The app lacks clear boundaries between contact functionality and other application features.\nThat lack of clarity makes it harder to assign development responsibilities to different teams.",
"translation": "该应用在联系人和其它特性区之间缺乏清晰的边界。\n 这种缺失,导致难以在不同的开发组之间分配职责。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You can resolve these issues with _feature modules_.",
"translation": "我们用_特性模块_技术来缓解此问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "A feature module is a class adorned by the `@NgModule` decorator and its metadata,\njust like a root module.\nFeature module metadata have the same properties as the metadata for a root module.",
"translation": "_特性模块_是带有`@NgModule`装饰器及其元数据的类,就像根模块一样。\n特性模块的元数据和根模块的元数据的属性是一样的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The root module and the feature module share the same execution context.\nThey share the same dependency injector, which means the services in one module\nare available to all.",
"translation": "根模块和特性模块还共享着相同的执行环境。\n 它们共享着同一个依赖注入器,这意味着某个模块中定义的服务在所有模块中也都能用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The modules have the following significant technical differences:",
"translation": "它们在技术上有两个显著的不同点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* You _boot_ the root module to _launch_ the app;\nyou _import_ a feature module to _extend_ the app.",
"translation": "我们_引导_根模块来_启动_应用但_导入_特性模块来_扩展_应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* A feature module can expose or hide its implementation from other modules.",
"translation": "特性模块可以对其它模块暴露或隐藏自己的实现。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Otherwise, a feature module is distinguished primarily by its intent.",
"translation": "此外,特性模块主要还是从它的设计意图上来区分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "A feature module delivers a cohesive set of functionality\nfocused on an application business domain, user workflow, facility (forms, http, routing),\nor collection of related utilities.",
"translation": "特性模块用来提供了内聚的功能集合。\n聚焦于应用的某个业务领域、用户工作流、某个基础设施表单、HTTP、路由或一组相关的工具集合。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "While you can do everything within the root module,\nfeature modules help you partition the app into areas of specific interest and purpose.\n<!-- CF: Is this paragraph just restating the previous paragraph?\nIf so, I recommend removing it or merging the two -->",
"translation": "虽然这些都能在根模块中做,但特性模块可以帮助我们把应用切分成具有特定关注点和目标的不同区域。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "A feature module collaborates with the root module and with other modules\nthrough the services it provides and\nthe components, directives, and pipes that it shares.",
"translation": "特性模块通过自己提供的服务和它决定对外共享的那些组件、指令、管道来与根模块等其它模块协同工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "In the next section, you'll carve the contact functionality out of the root module\nand into a dedicated feature module.",
"translation": "下一节,我们从根模块中把与联系人有关的功能切分到专门的特性模块中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Make _Contact_ a feature module\n<!-- CF: Is \"Contact\" a proper noun in this context? -->",
"translation": "### 把_联系人_做成特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "It's easy to refactor the contact material into a contact feature module.",
"translation": "把与联系人有关的这些元素重构到“联系人”特性模块中很简单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Create the `ContactModule` in the `src/app/contact` folder.",
"translation": "在`src/app/contact`目录下创建`ContactModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Move the contact material from `AppModule` to `ContactModule`.",
"translation": "把联系人相关的元素从`AppModule`移到`ContactModule`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Replace the imported `BrowserModule` with `CommonModule`.",
"translation": "把导入`BrowserModule`改为导入`CommonModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Import the `ContactModule` into the `AppModule`.",
"translation": "在`AppModule`中导入`ContactModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`AppModule` is the only existing class that changes. But you do add one new file.",
"translation": "`AppModule`是唯一有改变的_已经存在_的类不过我们还会添加一个新文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Add the _ContactModule_",
"translation": "### 添加 _ContactModule_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Here's the new `ContactModule`:",
"translation": "下面是新的`ContactModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You copy from `AppModule` the contact-related import statements and `@NgModule` properties\nthat concern the contact, and paste them into `ContactModule`.",
"translation": "把`AppModule`中的相关联系人的 import 语句和`@NgModule`的相关属性复制到`ContactModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You _import_ the `FormsModule` because the contact component needs it.",
"translation": "_导入_`FormsModule`,因为联系人组件需要它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Modules don't inherit access to the components, directives, or pipes that are declared in other modules.\nWhat `AppModule` imports is irrelevant to `ContactModule` and vice versa.\nBefore `ContactComponent` can bind with `[(ngModel)]`, its `ContactModule` must import `FormsModule`.",
"translation": "当前模块不会继承其它模块中对组件、指令或管道的访问权。\n`AppModule`中的 imports 与`ContatModule`的 imports 互不相干。\n如果`ContactComponent`要绑定到`[(ngModel)]`,它所在的`ContactModule`必需导入`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You also replaced `BrowserModule` by `CommonModule`, for reasons explained in the\n[Should I import BrowserModule or CommonModule?](guide/ngmodule-faq#q-browser-vs-common-module)\nsection of the [NgModule FAQs](guide/ngmodule-faq) page.",
"translation": "我们还用`CommonModule`替换了`BrowserModule`,其中缘由参见[这条常见问题](guide/ngmodule-faq#q-browser-vs-common-module)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You _declare_ the contact component, directive, and pipe in the module `declarations`.",
"translation": "我们在该模块的`declarations`中*声明*了联系人组件、指令和管道。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You _export_ the `ContactComponent` so\nother modules that import the `ContactModule` can include it in their component templates.",
"translation": "我们*导出*了`ContactComponent`,这样其它模块只要导入了`ContactModule`,就可以在它们的组件模板中使用`ContactComponent`了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "All other declared contact classes are private by default.\nThe `AwesomePipe` and `HighlightDirective` are hidden from the rest of the application.\nThe `HighlightDirective` can no longer color the `AppComponent` title text.",
"translation": "声明的所有其它联系人类默认都是私有的。\n`AwesomePipe`和`HighlightDirective`对应用的其它部分是不可见的。\n所以`HighlightDirective`不能把`AppComponent`的标题文字染色。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Refactor the _AppModule_",
"translation": "### 重构 *AppModule*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Return to the `AppModule` and remove everything specific to the contact feature set.",
"translation": "返回`AppModule`并移除专属于联系人特性下的任何东西。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Delete the contact import statements.",
"translation": "删除属于联系人的`import`语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Delete the contact declarations and contact providers.",
"translation": "删除联系人的`declarations`和`providers`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Delete the `FormsModule` from the `imports` list (`AppComponent` doesn't need it).",
"translation": "从`imports`列表中移除`FormsModule``AppComponent`并不需要它)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Leave only the classes required at the application root level.",
"translation": "只保留本应用的根一级需要的那些类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Then import the `ContactModule` so the app can continue to display the exported `ContactComponent`.",
"translation": "然后,导入`ContactModule`,以便应用能够继续显示导出的`ContactComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Here's the refactored version of the `AppModule` along with the previous version.",
"translation": "下面是`AppModule`重构完的版本与之前版本的对比。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Improvements",
"translation": "### 改进之处",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "There's a lot to like in the revised `AppModule`.",
"translation": "修改后的`AppModule`有一些很棒的特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* It does not change as the _Contact_ domain grows.",
"translation": "它不会再随着_联系人_的领域扩张而修改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* It only changes when you add new modules.",
"translation": "只有当添加新模块时才需要修改它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* It's simpler:",
"translation": "它也变得简单了:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Fewer import statements.",
"translation": "更少的`import`语句",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* No `FormsModule` import.",
"translation": "不再导入`FormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* No contact-specific declarations.",
"translation": "没有与联系人有关的声明",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* No `ContactService` provider.",
"translation": "没有`ContactService`提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* No `HighlightDirective` conflict.",
"translation": "没有`HighlightDirective`冲突",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Try this `ContactModule` version of the sample.",
"translation": "试试范例的`ContactModule`版。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "<live-example embedded plnkr=\"contact.2\" img=\"guide/ngmodule/contact-2-plunker.png\">Try the live example.</live-example>",
"translation": "<live-example embedded plnkr=\"contact.2\" img=\"devguide/ngmodule/contact-2-plunker.png\">试试在线例子</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Lazy-loading modules with the router",
"translation": "## 用路由器实现惰性 (lazy) 加载",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The Heroic Staffing Agency sample app has evolved.\nIt has two more modules, one for managing the heroes on staff and another for matching crises to the heroes.\nBoth modules are in the early stages of development.\nTheir specifics aren't important to the story and this page doesn't discuss every line of code.",
"translation": "英雄职介所这个例子应用继续成长。\n它又增加了两个模块一个用来管理雇佣的英雄另一个用来匹配英雄与危机。\n这两个模块都还处于前期开发阶段。\n它们对于整个故事来说无关紧要这里我们就不逐行讨论了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Examine and download the complete source for this version from the\n<live-example plnkr=\"pre-shared.3\" img=\"guide/ngmodule/v3-plunker.png\">live example.</live-example>",
"translation": "到<live-example plnkr=\"pre-shared.3\" img=\"devguide/ngmodule/v3-plunker.png\">在线例子</live-example>\n试用并下载当前版本的完整代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Some facets of the current application merit discussion are as follows:",
"translation": "当前应用中还有一些方面值得深入探讨。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The app has three feature modules: Contact, Hero, and Crisis.",
"translation": "该应用有三个特性模块:联系人 (Contact) 、英雄 (Hero) 和危机 (Crisis) 。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The Angular router helps users navigate among these modules.",
"translation": "Angular 路由器帮助用户在这些模块之间导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The `ContactComponent` is the default destination when the app starts.",
"translation": "`ContactComponent`组件是应用启动时的默认页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The `ContactModule` continues to be \"eagerly\" loaded when the application starts.",
"translation": "`ContactModule`仍然会在应用启动时被主动加载。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* `HeroModule` and the `CrisisModule` are lazy loaded.",
"translation": "`HeroModule`和`CrisisModule`会被惰性加载。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The new `AppComponent` templatehas\na title, three links, and a `<router-outlet>`.",
"translation": "我们从这个`AppComponent`新模板的顶部看起:标题、三个链接和`<router-outlet>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `<app-contact>` element is gone; you're routing to the _Contact_ page now.",
"translation": "`<app-contact>`元素不见了改成了路由到_联系人_页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `AppModule` has changed modestly:",
"translation": "对`AppModule`进行适度的修改:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Some file names bear a `.3` extension that indicates\na difference with prior or future versions.\nThe significant differences will be explained in due course.\n<!-- CF: Can you be more specific here? Are the differences explained later in this page or in another page? -->",
"translation": "有些文件名带有`.3`扩展名,用来和以前/以后的版本区分开。\n我们会在适当的时机解释它们的差异。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The module still imports `ContactModule` so that its routes and components are mounted when the app starts.",
"translation": "该模块仍然要导入`ContactModule`模块,以便在应用启动时加载它的路由和组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The module does _not_ import `HeroModule` or `CrisisModule`.\nThey'll be fetched and mounted asynchronously when the user navigates to one of their routes.",
"translation": "该模块_不_导入`HeroModule`或`CrisisModule`。\n它们将在用户导航到其中的某个路由时被异步获取并加载。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The significant change from version 2 is the addition of the *AppRoutingModule* to the module `imports`.\nThe `AppRoutingModule` is a [routing module](guide/router#routing-module)\nthat handles the app's routing concerns.",
"translation": "与第二版相比,最值得注意的修改是`imports`中那个额外的***AppRoutingModule***模块。\n`AppRoutingModule`是一个[**路由模块**](guide/router#routing-module)\n用来处理应用的路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### App routing",
"translation": "### 应用路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The router is the subject of the [Routing & Navigation](guide/router) page, so this section skips many of the details and\nconcentrates on the intersection of NgModules and routing.",
"translation": "路由器有[专门的章节](guide/router)做深入讲解,所以这里我们跳过细节,而是专注于它和 Angular 模块的协作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `app-routing.module.ts` file defines three routes.",
"translation": "`app-routing.module.ts`文件定义了三个路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The first route redirects the empty URL (such as `http://host.com/`)\nto another route whose path is `contact` (such as `http://host.com/contact`).",
"translation": "第一个路由把空白 URL例如`http://host.com/`)重定向到了另一个路径为`contact`的路由(例如`http://host.com/contact`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `contact` route isn't defined here.\nIt's defined in the _Contact_ feature's _own_ routing module, `contact-routing.module.ts`.\nIt's standard practice for feature modules with routing components to define their own routes.\nYou'll get to that file in a moment.",
"translation": "`contact`路由并不是在这里定义的,而是定义在*联系人*特性区自己的路由文件`contact.routing.ts`中。\n对于带有路由组件的特性模块其标准做法就是让它们定义自己的路由。\n稍后我们就会看到这些。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The remaining two routes use lazy loading syntax to tell the router where to find the modules:",
"translation": "另外两个路由使用惰性加载语法来告诉路由器要到哪里去找这些模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "A lazy-loaded module location is a _string_, not a _type_.\nIn this app, the string identifies both the module _file_ and the module _class_,\nthe latter separated from the former by a `#`.",
"translation": "惰性加载模块的位置是*字符串*而不是*类型*。\n在本应用中该字符串同时标记出了模块*文件*和模块*类*,两者用`#`分隔开。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### RouterModule.forRoot",
"translation": "### RouterModule.forRoot 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `forRoot` static class method of the `RouterModule` with the provided configuration and\nadded to the `imports` array provides the routing concerns for the module.",
"translation": "`RouterModule`类的`forRoot`静态方法和提供的配置,被添加到`imports`数组中,提供该模块的路由信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The returned `AppRoutingModule` class is a `Routing Module` containing both the `RouterModule` directives\nand the dependency-injection providers that produce a configured `Router`.",
"translation": "该方法返回的`AppRoutingModule`类是一个`路由模块`,它同时包含了`RouterModule`指令和用来生成配置好的`Router`的依赖注入提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This `AppRoutingModule` is intended for the app _root_ module only.",
"translation": "这个`AppRoutingModule`_仅_用于应用的_根_模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Never call `RouterModule.forRoot` in a feature-routing module.",
"translation": "永远不要在特性路由模块中调用`RouterModule.forRoot`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Back in the root `AppModule`, add the `AppRoutingModule` to its `imports` list,\nand the app is ready to navigate.",
"translation": "回到根模块`AppModule`,把这个`AppRoutingModule`添加到根模块的`imports`列表中,该应用就可以正常导航了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "</code-example>",
"translation": "### Routing to a feature module\n### 路由到特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `src/app/contact` folder holds a new file, `contact-routing.module.ts`.\nIt defines the `contact` route mentioned earlier and provides a `ContactRoutingModule` as follows:",
"translation": "`src/app/contact`目录中也有一个新文件`contact-routing.module.ts`。\n它定义了我们前面提到过的`联系人`路由,并提供了`ContactRoutingModule`,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This time you pass the route list to the `forChild` method of the `RouterModule`.\nThe route list is only responsible for providing additional routes and is intended for feature modules.",
"translation": "这次我们要把路由列表传给`RouterModule`的`forChild`方法。\n该方法会为特性模块生成另一种对象。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Always call `RouterModule.forChild` in a feature-routing module.",
"translation": "总是在特性路由模块中调用`RouterModule.forChild`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "_forRoot_ and _forChild_ are conventional names for methods that\ndeliver different `import` values to root and feature modules.\nAngular doesn't recognize them but Angular developers do.",
"translation": "当需要为根模块和特性模块分别提供不同的`导入`值时,***forRoot***和***forChild***是约定俗成的方法名。\n虽然 Angular 无法识别它们,但是 Angular 开发人员可以。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "[Follow this convention](guide/ngmodule-faq#q-for-root) if you write a similar module\nthat has both shared [declarables](guide/ngmodule-faq#q-declarable) and services.",
"translation": "当你要写类似的模块,来为根模块和特性模块分别导出一些[_声明_](guide/ngmodule-faq#q-declarable)和服务时,请[遵循这个约定](guide/ngmodule-faq#q-for-root)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`ContactModule` has changed in two small but important ways.",
"translation": "`ContactModule`已经做了两个微小但重要的细节改动:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* It imports the `ContactRoutingModule` object from `contact-routing.module.ts`.",
"translation": "它从`contact-routing.module.ts`中导入了`ContactRoutingModule`对象",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* It no longer exports `ContactComponent`.",
"translation": "它不再导出`ContactComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Now that you navigate to `ContactComponent` with the router, there's no reason to make it public.\nAlso, `ContactComponent` doesn't need a selector.\nNo template will ever again reference this `ContactComponent`.\nIt's gone from the [AppComponent template](guide/ngmodule#app-component-template).",
"translation": "现在我们通过路由器导航到`ContactComponent`,所以也就没有理由公开它了。它也不再需要选择器 (selector)。\n也没有模板会再引用`ContactComponent`。它从 [_AppComponent_ 模板](guide/ngmodule#app-component-template)中彻底消失了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Lazy-loaded routing to a module",
"translation": "### 路由到惰性加载的模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The lazy-loaded `HeroModule` and `CrisisModule` follow the same principles as any feature module.\nThey don't look different from the eagerly loaded `ContactModule`.",
"translation": "惰性加载的`HeroModule`和`CrisisModule`与其它特性模块遵循同样的规则。它们和主动加载的`ContactModule`看上去没有任何区别。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `HeroModule` is a bit more complex than the `CrisisModule`, which makes it\na more interesting and useful example. Its file structure is as follows:",
"translation": "`HeroModule`比`CrisisModule`略复杂一些,因此更适合用作范例。它的文件结构如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This is the child routing scenario familiar to readers of the\n[Child routing component](guide/router#child-routing-component) section of the\n[Routing & Navigation](guide/router#child-routing-component) page.\nThe `HeroComponent` is the feature's top component and routing host.\nIts template has a `<router-outlet>` that displays either a list of heroes (`HeroList`)\nor an editor of a selected hero (`HeroDetail`).\nBoth components delegate to the `HeroService` to fetch and save data.",
"translation": "如果你读过[路由](guide/router#child-routing-component)那章,那么对这个子路由的场景应该觉得很熟悉。\n `HeroComponent`是本特性区的顶级组件和路由宿主。\n 模板带有`<router-outlet>`指令,它或者显示英雄列表(`HeroList`)或者显示所选英雄的编辑器(`HeroDetail`)。\n 这两个组件都把获取和保存数据的任务委托给`HeroService`执行。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Yet another `HighlightDirective` colors elements in yet a different shade.\nIn the next section, [Shared modules](guide/ngmodule#shared-module \"Shared modules\"), you'll resolve the repetition and inconsistencies.",
"translation": "还有*另一个*`HighlightDirective`指令,它用另一种方式为元素染色。\n在下一节的[共享模块](guide/ngmodule#shared-module \"共享模块\")中,我们会解决这种不必要的重复和不一致性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `HeroModule` is a feature module like any other.",
"translation": "`HeroModule`是特性模块,与其它的没什么不同。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "It imports the `FormsModule` because the `HeroDetailComponent` template binds with `[(ngModel)]`.\nIt imports the `HeroRoutingModule` from `hero-routing.module.ts` just as `ContactModule` and `CrisisModule` do.",
"translation": "它导入了`FormsModule`,因为`HeroDetailComponent`的模板中绑定到了`[(ngModel)]`。\n像`ContactModule`和`CrisisModule`中一样,它还从`hero-routing.module.ts`中导入了`HeroRoutingModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `CrisisModule` is much the same.",
"translation": "`CrisisModule`和本模块非常像,我们不再赘述。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Shared modules",
"translation": "## 共享模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The app is shaping up.\nBut it carries three different versions of the `HighlightDirective`.\nAnd the many files cluttering the app folder level could be better organized.",
"translation": "本应用在继续演进中。\n 让我们感到不爽的是:这里有`HighlightDirective`的三个不同版本。\n 还有一大堆其它乱七八糟的东西堆在 app 目录这一级,我们得把它们清出去。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Add a `SharedModule` to hold the common components, directives, and pipes\nand share them with the modules that need them.",
"translation": "我们添加`SharedModule`来存放这些公共组件、指令和管道,并且共享给那些需要它们的模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Create an `src/app/shared` folder.",
"translation": "创建`src/app/shared`目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Move the `AwesomePipe` and `HighlightDirective` from `src/app/contact` to `src/app/shared`.",
"translation": "把`AwesomePipe`和`HighlightDirective`从`src/app/contact`移到`src/app/shared`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Delete the `HighlightDirective` classes from `src/app/` and `src/app/hero`.",
"translation": "从`src/app/`和`src/app/hero`目录中删除`HighlightDirective`类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Create a `SharedModule` class to own the shared material.",
"translation": "创建`SharedModule`类来管理这些共享的素材",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Update other feature modules to import `SharedModule`.",
"translation": "更新其它特性模块,导入`SharedModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Here is the `SharedModule`:",
"translation": "下面就是这个`SharedModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Note the following:",
"translation": "值得注意的有:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* It imports the `CommonModule` because its component needs common directives.",
"translation": "它导入了`CommonModule`,这是因为它的组件需要这些公共指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* It declares and exports the utility pipe, directive, and component classes as expected.",
"translation": "正如我们所期待的,它声明并导出了工具性的管道、指令和组件类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* It re-exports the `CommonModule` and `FormsModule`",
"translation": "它重新导出了`CommonModule`和`FormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Re-exporting other modules",
"translation": "### 重新导出其它模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "If you review the application, you may notice that many components requiring `SharedModule` directives\nalso use `NgIf` and `NgFor` from `CommonModule`\nand bind to component properties with `[(ngModel)]`, a directive in the `FormsModule`.\nModules that declare these components would have to import `CommonModule`, `FormsModule`, and `SharedModule`.",
"translation": "当回顾应用程序时,我们注意到很多需要`SharedModule`的组件也同时用到了来自`CommonModule`的`NgIf`和`NgFor`指令,\n 并且还通过来自`FormsModule`的`[(ngModel)]`指令绑定到了组件的属性。\n 那些声明这些组件的模块将不得不同时导入`CommonModule`、`FormsModule`和`SharedModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You can reduce the repetition by having `SharedModule` re-export `CommonModule` and `FormsModule`\nso that importers of `SharedModule` get `CommonModule` and `FormsModule` for free.",
"translation": "通过让`SharedModule`重新导出`CommonModule`和`FormsModule`模块,我们可以消除这种重复。\n于是导入`SharedModule`的模块也同时*免费*获得了`CommonModule`和`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "As it happens, the components declared by `SharedModule` itself don't bind with `[(ngModel)]`.\nTechnically, there is no need for `SharedModule` to import `FormsModule`.",
"translation": "实际上,`SharedModule`本身所声明的组件没绑定过`[(ngModel)]`,那么,严格来说`SharedModule`并不需要导入`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`SharedModule` can still export `FormsModule` without listing it among its `imports`.",
"translation": "这时`SharedModule`仍然可以导出`FormsModule`,而不需要先把它列在`imports`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Why _TitleComponent_ isn't shared",
"translation": "### 为什么 *TitleComponent* 没有被共享",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`SharedModule` exists to make commonly used components, directives, and pipes available\nfor use in the templates of components in many other modules.",
"translation": "设计`SharedModule`的目的在于让常用的组件、指令和管道可以被用在*很多*其它模块的组件模板中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `TitleComponent` is used only once by the `AppComponent`.\nThere's no point in sharing it.",
"translation": "而`TitleComponent`*只被*`AppComponent`用了一次,因此没必要共享它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### Why _UserService_ isn't shared",
"translation": "### 为什么 *UserService* 没有被共享",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "While many components share the same service instances,\nthey rely on Angular dependency injection to do this kind of sharing, not the module system.",
"translation": "虽然很多组件都共享着同一个服务*实例*,但它们是靠 Angular 的依赖注入体系实现的,而不是模块体系。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Several components of the sample inject the `UserService`.\nThere should be only one instance of the `UserService` in the entire application\nand only one provider of it.",
"translation": "例子中的很多组件都注入了`UserService`。\n在整个应用程序中*只应该有一个*`UserService`的实例,并且它*只应该有一个*提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`UserService` is an application-wide singleton.\nYou don't want each module to have its own separate instance.\nYet there is [a real danger](guide/ngmodule-faq#q-why-bad) of that happening\n<!-- CF: This link goes to the top of the NgModule FAQs page.\nIt looks like it is supposed to go to a specific question/section within the page. -->\nif the `SharedModule` provides the `UserService`.",
"translation": "`UserService`是全应用级单例。\n我们不希望每个模块都各自有它的实例。\n而如果由`SharedModule`提供`UserService`,就会导致[铁板钉钉的危险](guide/ngmodule-faq#q-why-bad)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Do *not* specify app-wide singleton `providers` in a shared module.\nA lazy-loaded module that imports that shared module makes its own copy of the service.",
"translation": "**不要**在共享模块中把应用级单例添加到`providers`中。\n否则如果一个惰性加载模块导入了此共享模块就会导致它自己也生成一份此服务的实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## The Core module",
"translation": "## 核心 (Core) 模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "At the moment, the root folder is cluttered with the `UserService`\nand `TitleComponent` that only appear in the root `AppComponent`.\nYou didn't include them in the `SharedModule` for reasons just explained.",
"translation": "现在,我们的根目录下只剩下`UserService`和`TitleComponent`这两个被根组件`AppComponent`用到的类没有清理了。\n但正如我们已经解释过的它们无法被包含在`SharedModule`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Instead, gather them in a single `CoreModule` that you import once when the app starts\nand never import anywhere else.",
"translation": "不过,我们可以把它们收集到单独的`CoreModule`中,并且**只在应用启动时导入它*一次*****而不会在其它地方导入它**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Perform the following steps:",
"translation": "执行下列步骤:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Create an `src/app/core` folder.",
"translation": "创建`src/app/core`文件夹",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Move the `UserService` and `TitleComponent` from `src/app/` to `src/app/core`.",
"translation": "把`UserService`和`TitleComponent`从`src/app`移到`src/app/core`中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Create a `CoreModule` class to own the core material.",
"translation": "创建`CoreModule`类来管理这些核心素材",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "1. Update the `AppRoot` module to import `CoreModule`.",
"translation": "修改`AppRoot`模块,使其导入`CoreModule`模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Most of this work is familiar. The interesting part is the `CoreModule`.",
"translation": "这些都是一些熟悉的普通任务。令人感兴趣的是`CoreModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You're importing some extra symbols from the Angular core library that you're not using yet.\nThey'll become relevant later in this page.",
"translation": "我们正在从 Angular 核心库中导入一些从未用到的符号,稍后我们会接触它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The `@NgModule` metadata should be familiar.\nYou declare the `TitleComponent` because this module owns it and you export it\nbecause `AppComponent` (which is in `AppModule`) displays the title in its template.\n`TitleComponent` needs the Angular `NgIf` directive that you import from `CommonModule`.",
"translation": "我们对`@NgModule`的元数据应该很熟悉。\n由于该模块_拥有_`TitleComponent`,所以我们声明了它。由于`AppComponent`(位于`AppModule`模块)在模板中显示了这个标题,所以我们导出了它。\n由于`TitleComponent`需要用到 Angular 的`NgIf`指令,所以我们导入了`CommonModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`CoreModule` provides the `UserService`. Angular registers that provider with the app root injector,\nmaking a singleton instance of the `UserService` available to any component that needs it,\nwhether that component is eagerly or lazily loaded.",
"translation": "`CoreModule`_提供_了`UserService`。Angular 在该应用的根注入器中注册了它的提供商,\n导致这份`UserService`的实例在每个需要它的组件中都是可用的,无论那个组件时主动加载的还是惰性加载的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Why bother?",
"translation": "没必要?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "This scenario is clearly contrived.\nThe app is too small to worry about a single service file and a tiny, one-time component.",
"translation": "这个场景设计的是有点生硬。\n该应用太小了所以其实并不需要拆分出单独的服务文件和小型的、一次性的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "A `TitleComponent` sitting in the root folder isn't bothering anyone.\nThe root `AppModule` can register the `UserService` itself,\nas it does currently, even if you decide to relocate the `UserService` file to the `src/app/core` folder.",
"translation": "把`TitleComponent`放在根目录中其实也无所谓。\n即使我们决定把`UserService`文件挪到`app/core`目录中,根`AppModule`也仍然可以自己注册`UserService`(就像现在这样)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Real-world apps have more to worry about.\nThey can have several single-use components (such as spinners, message toasts, and modal dialogs)\nthat appear only in the `AppComponent` template.\nYou don't import them elsewhere so they're not shared in that sense.\nYet they're too big and messy to leave loose in the root folder.",
"translation": "但真实的应用要考虑很多。\n它们有一些只用于`AppComponent`的模板的一次性的组件(例如:加载动画、消息浮层和模态对话框等)。\n我们不用在其它地方导入它们因此没必要*共享*它们。\n然而如果把它们留在根目录还是显得太大、太乱了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Apps often have many singleton services like this sample's `UserService`.\nEach must be registered exactly once, in the app root injector, when the application starts.",
"translation": "应用通常还有很多像这里的`UserService`这样的单例服务。\n当程序启动时每个服务都只能在应用的“根注入器”中*注册一次*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "While many components inject such services in their constructors&mdash;and\ntherefore require JavaScript `import` statements to import their symbols&mdash;no\nother component or module should define or re-create the services themselves.\nTheir _providers_ aren't shared.",
"translation": "当很多组件在它们的构造函数中注入这些服务时 &mdash;\n因此也需要用 JavaScript 的`import`语句来导入它们的符号 &mdash;\n任何组件或模块自身都不应该定义或重新创建这些服务。\n因为它们的*提供商*不是共享的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "We recommend collecting such single-use classes and hiding their details inside a `CoreModule`.\nA simplified root `AppModule` imports `CoreModule` in its capacity as orchestrator of the application as a whole.",
"translation": "因此我们建议把这些一次性的类收集到`CoreModule`中,并且隐藏它们的实现细节。\n简化之后的根模块`AppModule`导入`CoreModule`来获取其能力。记住,根模块是整个应用的总指挥,不应该插手过多细节。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Cleanup",
"translation": "## 清理",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Having refactored to a `CoreModule` and a `SharedModule`, it's time to clean up the other modules.",
"translation": "我们已经重构完`CoreModule`和`SharedModule`,现在开始清理其它模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### A trimmer _AppModule_",
"translation": "### 清理 *AppModule*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Here is the updated `AppModule` paired with version 3 for comparison:",
"translation": "这里是更新后的`AppModule`与其第三版本的对比:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "`AppModule` now has the following qualities:",
"translation": "`AppModule`现在变得:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* A little smaller because many `src/app/root` classes have moved to other modules.",
"translation": "更小了。因为很多`src/app/root`下的类被移到了其它模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Stable because you'll add future components and providers to other modules, not this one.",
"translation": "更稳定了。因为我们以后会在其它模块中添加组件和服务提供商,而不是这里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Delegated to imported modules rather than doing work.",
"translation": "导入其它模块并把任务委托给它们,而不是亲力亲为。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* Focused on its main task, orchestrating the app as a whole.",
"translation": "聚焦于自己的主要任务:总指挥整个应用程序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "### A trimmer _ContactModule_",
"translation": "### 清理*ContactModule*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Here is the new `ContactModule` paired with the prior version:",
"translation": "这里是新的`ContactModule`与以前版本的对比:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Notice the following:",
"translation": "注意:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The `AwesomePipe` and `HighlightDirective` are gone.",
"translation": "`AwesomePipe`和`HighlightDirective`不见了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The imports include `SharedModule` instead of `CommonModule` and `FormsModule`.",
"translation": "导入`SharedModule`,不再导入`CommonModule`和`FormsModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* The new version is leaner and cleaner.",
"translation": "这个新版本更加精简和干净了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Configure core services with _CoreModule.forRoot_",
"translation": "## 用 *CoreModule.forRoot* 配置核心服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "A module that adds providers to the application can offer a facility for configuring those providers as well.",
"translation": "为应用添加服务提供商的模块也可以同时提供配置那些提供商的功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "By convention, the `forRoot` static method both provides and configures services at the same time.\nIt takes a service configuration object and returns a\n[ModuleWithProviders](api/core/ModuleWithProviders), which is\na simple object with the following properties:",
"translation": "按照约定,模块的静态方法***forRoot***可以同时提供并配置服务。\n它接收一个服务配置对象并返回一个[ModuleWithProviders](api/core/ModuleWithProviders)。这个简单对象具有两个属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* `ngModule`: the `CoreModule` class",
"translation": "`ngModule` - `CoreModule`类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "* `providers`: the configured providers",
"translation": "`providers` - 配置好的服务提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The root `AppModule` imports the `CoreModule` and adds the `providers` to the `AppModule` providers.",
"translation": "根模块`AppModule`会导入`CoreModule`类并把它的`providers`添加到`AppModule`的服务提供商中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "More precisely, Angular accumulates all imported providers before appending the items listed in `@NgModule.providers`.\nThis sequence ensures that whatever you add explicitly to the `AppModule` providers takes precedence\nover the providers of imported modules.",
"translation": "更精确的说法是Angular 会先累加所有导入的提供商,*然后才*把它们追加到`@NgModule.providers`中。\n这样可以确保我们显式添加到`AppModule`中的那些提供商总是优先于从其它模块中导入的提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Add a `CoreModule.forRoot` method that configures the core `UserService`.",
"translation": "现在添加`CoreModule.forRoot`方法,以便配置核心中的`UserService`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You've extended the core `UserService` with an optional, injected `UserServiceConfig`.\nIf a `UserServiceConfig` exists, the `UserService` sets the user name from that config.",
"translation": "我们曾经用一个可选的、被注入的`UserServiceConfig`服务扩展过核心的`UserService`服务。\n如果有`UserServiceConfig``UserService`就会据此设置用户名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Here's `CoreModule.forRoot` that takes a `UserServiceConfig` object:",
"translation": "这里的`CoreModule.forRoot`接收`UserServiceConfig`对象:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Lastly, call it within the `imports` list of the `AppModule`.",
"translation": "最后,我们在`AppModule`的`imports`*列表*中调用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"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/content-1/guide/ngmodule.md"
},
{
"original": "Call `forRoot` only in the root application module, `AppModule`.\nCalling it in any other module, particularly in a lazy-loaded module,\nis contrary to the intent and can produce a runtime error.",
"translation": "只在应用的根模块`AppModule`中调用`forRoot`。\n如果在其它模块特别是惰性加载模块中调用它则违反了设计意图并会导致运行时错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Remember to _import_ the result; don't add it to any other `@NgModule` list.",
"translation": "别忘了_导入_其返回结果而且不要把它添加到`@NgModule`的其它任何列表中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Prevent reimport of the _CoreModule_",
"translation": "## 禁止多次导入*CoreModule*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Only the root `AppModule` should import the `CoreModule`.\n[Bad things happen](guide/ngmodule-faq#q-why-bad) if a lazy-loaded module imports it.\n<!-- CF: Again, this link goes to the top of the NgModule FAQs page.\nIt looks like it is supposed to go to a specific question/section within the page. -->",
"translation": "只有根模块`AppModule`才能导入`CoreModule`。\n 如果惰性加载模块导入了它,就会[出问题](guide/ngmodule-faq#q-why-bad)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You could hope that no developer makes that mistake.\nOr you can guard against it and fail fast by adding the following `CoreModule` constructor.",
"translation": "我们可以*祈祷*任何开发人员都不会犯错。\n 但是最好还是对它进行一些保护,以便让它“尽快出错”。只要把下列代码添加到`CoreModule`的构造函数中就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The constructor tells Angular to inject the `CoreModule` into itself.\nThat seems dangerously circular.",
"translation": "这个构造函数会要求 Angular 把`CoreModule`注入自身。这看起来像一个危险的循环注入。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "The injection would be circular if Angular looked for `CoreModule` in the _current_ injector.\nThe `@SkipSelf` decorator means \"look for `CoreModule` in an ancestor injector, above me in the injector hierarchy.\"",
"translation": "确实,如果 Angular 在*当前*注入器中查阅`CoreModule`,这确实会是一个循环引用。\n不过`@SkipSelf`装饰器意味着“在当前注入器的所有祖先注入器中寻找`CoreModule`。”",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "If the constructor executes as intended in the `AppModule`,\nthere is no ancestor injector that could provide an instance of `CoreModule`.\nThe injector should give up.",
"translation": "如果该构造函数在我们所期望的`AppModule`中运行,就没有任何祖先注入器能够提供`CoreModule`的实例,于是注入器会放弃查找。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "By default, the injector throws an error when it can't find 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/content-1/guide/ngmodule.md"
},
{
"original": "It's a different story if you improperly import `CoreModule` into a lazy-loaded module such as `HeroModule` (try it).",
"translation": "如果我们错误的把`CoreModule`导入了一个惰性加载模块(例如`HeroModule`)中,那就不一样了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Angular creates a lazy-loaded module with its own injector, a _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/content-1/guide/ngmodule.md"
},
{
"original": "## Conclusion",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "You made it! You can examine and download the complete source for this final version from the live example.",
"translation": "完工!你可以到下面的在线例子中试验它,并下载最终版本的全部源码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "## Frequently asked questions",
"translation": "## 常见问题 (FAQ)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "Now that you understand NgModules, you may be interested\nin the companion [NgModule FAQs](guide/ngmodule-faq \"NgModule FAQs\") page\nwith its ready answers to specific design and implementation questions.",
"translation": "现在,你已经理解了 Angular 的模块。可能你还会对烹饪宝典中的\n[Angular 模块常见问题](guide/ngmodule-faq \"Angular 模块常见问题\")感兴趣,\n它解答了很多关于设计和实现方面的问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/ngmodule.md"
},
{
"original": "# Npm Packages",
"translation": "# npm 包",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "Angular applications and Angular itself depend upon features and functionality provided by a variety of third-party packages.\nThese packages are maintained and installed with the Node Package Manager (<a href=\"https://docs.npmjs.com/\">npm</a>).",
"translation": "Angular应用程序以及Angular本身都依赖于很多第三方包(包括Angular自己)提供的特性和功能。\n这些包由Node包管理器(<a href=\"https://docs.npmjs.com/\" target=\"_blank\">npm</a>)负责安装和维护。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "Node.js and npm are essential to Angular development.",
"translation": "Node.js和npm是做Angular开发的基础。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "<a href=\"https://docs.npmjs.com/getting-started/installing-node\" title=\"Installing Node.js and updating npm\">\nGet 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=\"Installing Node.js and updating npm\">立即获取它</a>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"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/content-1/guide/npm-packages.md"
},
{
"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/content-1/guide/npm-packages.md"
},
{
"original": "During [Setup](guide/setup), a <a href=\"https://docs.npmjs.com/files/package.json\">package.json</a>\nfile is installed with a comprehensive starter set of\npackages as specified in the `dependencies` and `devDependencies` sections.",
"translation": "我们在[搭建本地开发环境](guide/setup)一章中安装并解释了<a href=\"https://docs.npmjs.com/files/package.json\" target=\"_blank\">package.json</a>文件的\n `dependencies`和`devDependencies`区中指定了一组适用于新手的综合依赖包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "You can use other packages but the packages in _this particular set_ work well together and include\neverything you need to build and run the sample applications in this series.",
"translation": "你当然可以使用其它包,不过这一组可以很好的协同工作,而且包含了我们在个系列文档中构建和运行范例应用时所需的一切。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "Note: A cookbook or guide page may require an additional library such as *jQuery*.",
"translation": "注意:烹饪宝典或开发指南中的页面可能需要其它库,比如*jQuery*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "You'll install more than you need for the QuickStart guide.\nNo worries!\nYou only serve to the client those packages that the application actually requests.",
"translation": "它们远远超过了我们将在“快速上手”中所需要用到的。\n实际上它比我们在大多数应用中需要的还多。\n安装的包比我们实际需要的包多其实并没有什么坏处。\n我们最终只会往客户端发送程序中实际用到的那些包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "This page explains what each package does. You can make substitutions later to suit your tastes and experience.",
"translation": "本页面会解释每一个包是干什么的,以后你就可以根据自己的喜好和经验,随意替换它们了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "## *dependencies* and *devDependencies*",
"translation": "## *dependencies*和*devDependencies*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"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/content-1/guide/npm-packages.md"
},
{
"original": "The *dependencies* are essential to *running* the application. \nThe *devDependencies* are only necessary to *develop* the application. \nYou can exclude them from production installations by adding `--production` to the install command, as follows:",
"translation": "*dependencies*下的这些包是*运行*本应用的基础,而*devDependencies*下的只在*开发*此应用时才用得到。\n通过为`install`命令添加`--production`参数,你在产品环境下安装时排除*devDependencies*下的包,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "## *dependencies*",
"translation": "## *dependencies* 依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "The `dependencies` section of `package.json` contains:",
"translation": "应用程序的`package.json`文件中,`dependencies`区下有三类包:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "* ***Features*** : Feature packages give the application framework and utility capabilities.",
"translation": "**特性*** - 特性包为应用程序提供了框架和工具方面的能力。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "* ***Polyfills*** : Polyfills plug gaps in the browser's JavaScript implementation.",
"translation": "***填充(Polyfills)*** - 填充包弥合了不同浏览器上的JavaScript实现方面的差异。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "* ***Other*** : Other libraries that support the application such as `bootstrap` for HTML widgets and styling.",
"translation": "***其它*** - 其它库对本应用提供支持,比如`bootstrap`包提供了HTML中的小部件和样式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "### Feature Packages",
"translation": "### 特性包",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"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*** - 框架中关键的运行期部件,每一个应用都需要它。\n包括所有的元数据装饰器`Component`、`Directive`,依赖注入系统,以及组件生命周期钩子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***@angular/common*** : The commonly needed services, pipes, and directives provided by the Angular team.",
"translation": "***@angular/common*** - 常用的那些由Angular开发组提供的服务、管道和指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"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 dont interact with the compiler directly; rather, you use it indirectly via `platform-browser-dynamic` or the offline template compiler.",
"translation": "***@angular/compiler*** - Angular的*模板编译器*。\n它会理解模板并且把模板转化成代码以供应用程序运行和渲染。\n开发人员通常不会直接跟这个编译器打交道而是通过`platform-browser-dynamic`或离线模板编译器间接使用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***@angular/platform-browser*** : Everything DOM and browser related, especially the pieces that help render into theDOM.\nThis package also includes the `bootstrapStatic()` method for bootstrapping applications for production builds that pre-compile templates offline.",
"translation": "***@angular/platform-browser*** - 与DOM和浏览器相关的每样东西特别是帮助往DOM中渲染的那部分。\n这个包还包含bootstrapStatic方法用来引导那些在产品构建时需要离线预编译模板的应用程序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***@angular/platform-browser-dynamic*** : Includes [Providers](api/core/Provider) and a [bootstrap](guide/ngmodule#bootstrap) method for applications that\ncompile templates on the client. Dont use offline compilation.\nUse this package for bootstrapping during development and for bootstrapping plunker samples.",
"translation": "***@angular/platform-browser-dynamic*** - 为应用程序提供一些[提供商](api/core/Provider)和[bootstrap](guide/ngmodule#bootstrap)方法,以便在客户端编译模板。不要用于离线编译。\n我们使用这个包在开发期间引导应用以及引导plunker中的范例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***@angular/http*** : Angular's HTTP client.",
"translation": "***@angular/http*** - Angular的HTTP客户端。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***@angular/router*** : Component router.",
"translation": "***@angular/router*** - 路由器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***@angular/upgrade*** : Set of utilities for upgrading AngularJS applications to Angular.",
"translation": "***@angular/upgrade*** - 一组用于升级AngularJS应用的工具。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***[system.js](https://github.com/systemjs/systemjs)*** : A dynamic module loader compatible with the \n[ES2015 module](http://www.2ality.com/2014/09/es6-modules-final.html) specification.\nOther viable choices include the well-regarded [webpack](https://webpack.github.io/).",
"translation": "***[system.js](https://github.com/systemjs/systemjs)*** - 是一个动态的模块加载器,\n与[ES2015模块](http://www.2ality.com/2014/09/es6-modules-final.html)规范兼容。\n还有很多其它选择比如广受欢迎的[webpack](https://webpack.github.io/)。\nSystemJS被用在了我们的文档范例中。因为它能工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "Your future applications are likely to require additional packages that provide\nHTML controls, themes, data access, and various utilities.",
"translation": "今后应用程序很可能还会需要更多的包比如HTML控件、主题、数据访问以及其它多种工具。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "### Polyfill packages",
"translation": "### 填充(Polyfill)包",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "Angular requires certain [polyfills](https://en.wikipedia.org/wiki/Polyfill) in the application environment.\nInstall these polyfills using the npm packages that Angular lists in the *peerDependencies* section of its `package.json`.",
"translation": "在应用程序的运行环境中Angular需要某些[填充库](https://en.wikipedia.org/wiki/Polyfill)。\n我们通过特定的npm包来安装这些填充库Angular本身把它列在了`package.json`中的*peerDependencies*区。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "You must list these packages in the `dependencies` section of your own `package.json`.",
"translation": "但我们必须把它列在我们`package.json`文件的`dependencies`区。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "For background on this requirement, see [Why peerDependencies?](guide/npm-packages#why-peer-dependencies).",
"translation": "查看下面的“[为什么用peerDependencies?](guide/npm-packages#why-peer-dependencies)”,以了解这项需求的背景。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***core-js***: Patches the global context (window) with essential features of ES2015 (ES6).\n You may substitute an alternative polyfill that provides the same core APIs.\n When these APIs are implemented by the major browsers, this dependency will become unnecessary.",
"translation": "***core-js*** - 为全局上下文(window)打的补丁提供了ES2015(ES6)的很多基础特性。\n我们也可以把它换成提供了相同内核API的其它填充库。\n一旦所有的“主流浏览器”都实现了这些API这个依赖就可以去掉了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***rxjs*** : A polyfill for the [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.\nYou can pick a preferred version of *rxjs* (within a compatible version range)\nwithout waiting for Angular updates.",
"translation": "***rxjs*** - 一个为[可观察对象(Observable)规范](https://github.com/zenparsing/es-observable)提供的填充库,该规范已经提交给了\n[TC39](http://www.ecma-international.org/memento/TC39.htm)委员会以决定是否要在JavaScript语言中进行标准化。\n开发人员应该能在兼容的版本中选择一个喜欢的*rxjs*版本而不用等Angular升级。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***zone.js*** : A polyfill for the [Zone 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.\nYou can pick a preferred version of *zone.js* to use (within a compatible version range)\nwithout waiting for Angular updates.",
"translation": "***zone.js*** - 一个为[Zone规范](https://gist.github.com/mhevery/63fdcdf7c65886051d55)提供的填充库,该规范已经提交给了\n[TC39](http://www.ecma-international.org/memento/TC39.htm)委员会以决定是否要在JavaScript语言中进行标准化。\n开发人员应该能在兼容的版本中选择一个喜欢的*zone.js*版本而不用等Angular升级。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "### Other helper libraries",
"translation": "### 其它辅助库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***angular-in-memory-web-api*** : An Angular-supported library that simulates a remote server's web api \nwithout requiring an actual server or real HTTP calls. \nGood for demos, samples, and early stage development (before you even have a server).",
"translation": "***angular-in-memory-web-api*** - 一个Angular的支持库它能模拟一个远端服务器的Web API而不需要依赖一个真实的服务器或发起真实的HTTP调用。\n对演示、文档范例和开发的早期阶段(那时候我们可能还没有服务器呢)非常有用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***bootstrap*** : [Bootstrap](http://getbootstrap.com/) is a popular HTML and CSS framework for designing responsive web apps.\nSome of the samples improve their appearance with *bootstrap*.",
"translation": "***bootstrap*** - [bootstrap](http://getbootstrap.com/)是一个广受欢迎的HTML和CSS框架可用来设计响应式网络应用。\n有些文档中的范例使用了*bootstrap*来强化它们的外观。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "## *devDependencies*",
"translation": "## *devDependencies* 依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "The packages listed in the *devDependencies* section of the `package.json` help you develop the application.\nYou don't have to deploy them with the production application although there is no harm in doing so.",
"translation": "列在`package.json`文件中*devDependencies*区的包会帮助我们开发该应用程序。\n我们不用把它们部署到产品环境的应用程序中 —— 虽然这样做也没什么坏处。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "***[concurrently](https://www.npmjs.com/package/concurrently)*** : \nA utility to run multiple *npm* commands concurrently on OS/X, Windows, and Linux operating systems.",
"translation": "***[concurrently](https://www.npmjs.com/package/concurrently)*** - 一个用来在OS/X、Windows和Linux操作系统上同时运行多个*npm*命令的工具\n***[lite-server](https://www.npmjs.com/package/lite-server)*** : \nA light-weight, static file server, by [John Papa](http://johnpapa.net/) \nwith excellent support for Angular apps that use routing.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"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/content-1/guide/npm-packages.md"
},
{
"original": "***@types/\\* *** : TypeScript definition files.\nLearn more about it in the [TypeScript Configuration](guide/typescript-configuration#typings) guide.",
"translation": "***@types/\\**** - “TypeScript定义”文件管理器。\n要了解更多请参见[TypeScript配置](guide/typescript-configuration#typings)页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "## Why *peerDependencies*?",
"translation": "## 为什么使用*peerDependencies*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "There isn't a [*peerDependencies*](https://nodejs.org/en/blog/npm/peer-dependencies/) section in the QuickStart `package.json`. \nBut Angular has a *peerDependencies* section in \n*its* `package.json`, which has important consequences for your application.",
"translation": "在“快速上手”的`package.json`文件中,并没有[*peerDependencies*](https://nodejs.org/en/blog/npm/peer-dependencies/)区。\n但是Angular本身在*它自己的* `package.json` 中有,\n它对我们的应用程序有重要的影响。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "This section explains why you load the [polyfill](guide/npm-packages#polyfills) *dependency* packages in the QuickStart application's`package.json`,\nand why you'll need those packages in your own applications.",
"translation": "它解释了为什么我们要在“快速上手”的`package.json`文件中加载这些[填充库(polyfill)](guide/npm-packages#polyfills)依赖包,\n以及为什么我们在自己的应用中会需要它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "An explanation of [peer dependencies](https://nodejs.org/en/blog/npm/peer-dependencies/) follows.",
"translation": "然后是对[平级依赖(peer dependencies)](https://nodejs.org/en/blog/npm/peer-dependencies/)的简短解释。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "Packages depend on other packages. For example, your application depends on the Angular package.",
"translation": "每个包都依赖其它的包比如我们的应用程序就依赖于Angular包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "Two packages, \"A\" and \"B\", could depend on the same third package \"C\". \n\"A\" and \"B\" might both list \"C\" among their *dependencies*.",
"translation": "两个包“A”和“B”可能依赖共同的第三个包“C”。\n\"A\"和“B”可能都在它们的*dependencies*中列出了“C”。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "What if \"A\" and \"B\" depend on different versions of \"C\" (\"C1\" and \"C2\"). The npm package system supports that. \nIt installs \"C1\" in the `node_modules` folder for \"A\" and \"C2\" in the `node_modules` folder for \"B\".\nNow \"A\" and \"B\" have their own copies of \"C\" and they run without interferring with one another.",
"translation": "如果“A”和“B”依赖于“C”的不同版本(\"C1\"和“C2”)。npm包管理系统也能支持\n它会把“C1”安装到“A”的`node_modules`目录下给“A”用把“C2”安装到“B”的`node_modules`目录下给“B”用。\n现在“A”和“B”都有了它们自己的一份“C”的复本它们运行起来也互不干扰。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "But there is a problem. Package \"A\" may require the presence of \"C1\" without actually calling upon it directly.\n\"A\" may only work if *everyone is using \"C1\"*. It falls down if any part of the application relies on \"C2\".",
"translation": "但是有一个问题。包“A”可能只需要“C1”出现就行而实际上并不会直接调用它。\n\"A\"可能只有当*每个人都使用“C1”时*才能正常工作。如果程序中的任何一个部分依赖了“C2”它就会失败。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "The solution is for \"A\" to declare that \"C1\" is a *peer dependency*.",
"translation": "要想解决这个问题“A”就需要把“C1”定义为它的*平级依赖*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "The difference between a `dependency` and a `peerDependency` is roughly this:",
"translation": "在`dependencies`和`peerDependencies`之间的区别大致是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "The Angular `package.json` specifies several *peer dependency* packages, \neach pinned to a particular version of a third-party package.",
"translation": "Angular就存在这个问题。\n因此Angular的`package.json`中指定了一系列*平级依赖*包,\n把每个第三方包都固定在一个特定的版本上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "### You must install Angular's *peerDependencies* yourself.",
"translation": "### 我们必须自己安装Angular的*peerDependencies*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "When *npm* installs packages listed in *your* `dependencies` section,\nit also installs the packages listed within *their* packages `dependencies` sections.\nThe process is recursive.",
"translation": "当*npm*安装那些在*我们的*`dependencies`区指定的包时,\n它也会同时安装上在*那些包*的`dependencies`区所指定的那些包。\n这个安装过程是递归的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "However, as of version 3, *npm* does *not* install packages listed in *peerDependencies* sections.",
"translation": "但是在npm的第三版中*它不会*安装列在*peerDependencies*区的那些包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "This means that when your application installs Angular, ***npm* doesn't automatically install\nthe packages listed in Angular's *peerDependencies* section**.",
"translation": "这意味着当我们的应用程序安装Angular时***npm*将不会自动安装列在Angular的*peerDependencies*区的那些包**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "Fortunately, *npm* issues a warning (a) When any *peer dependencies* are missing, or (b)\nWhen the application or any of its other dependencies\ninstalls a different version of a *peer dependency*.",
"translation": "幸运的是,*npm*会在下列情况下给我们警告:(a) 当任何*平级依赖*缺失时 或(b) 当应用程序或它的任何其它依赖安装了与*平级依赖*不同版本的包时。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "These warnings guard against accidental failures due to version mismatches.\nThey leave you in control of package and version resolution.",
"translation": "这些警告可以避免因为版本不匹配而导致的意外错误。\n它们让我们可以控制包和版本的解析过程。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "It is your responsibility to list all *peer dependency* packages **among your own *devDependencies***.",
"translation": "我们的责任是,把所有*平级依赖*包都**列在我们自己的*devDependencies*中**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "#### The future of *peerDependencies*",
"translation": "#### *peerDependencies*的未来",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "The Angular polyfill dependencies are hard requirements. Currently, there is no way to make them optional.",
"translation": "Angular的填充库依赖只是一个给开发人员的建议或提示以便它们知道Angular期望用什么。\n它们不应该像现在一样是硬需求但目前我们也不知道该如何把它们设置为可选的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "However, there is an npm feature request for \"optional peerDependencies,\" which would allow you to model this relationship better. \nWhen this feature request is implemented, Angular will switch from *peerDependencies* to *optionalPeerDependencies* for all polyfills.",
"translation": "不过有一个npm的新特性申请叫做“可选的peerDependencies”它将会允许我们更好的对这种关系建模。\n一旦它被实现了Angular将把所有填充库从*peerDependencies*区切换到*optionalPeerDependencies*去。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/npm-packages.md"
},
{
"original": "# Pipes",
"translation": "# 管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "You can run the <live-example></live-example> in Plunker and download the code from there.",
"translation": "试试<live-example>在线例子</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "## Using pipes",
"translation": "## 使用管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "Focus on the component's template.",
"translation": "重点看下组件的模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "## Built-in pipes",
"translation": "## 内置的管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "## Parameterizing a pipe",
"translation": "## 对管道进行参数化",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "</div>",
"translation": "## Chaining pipes\n## 链式管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "This example&mdash;which displays **<samp>FRIDAY, APRIL 15, 1988</samp>**&mdash;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/content-1/guide/pipes.md"
},
{
"original": "## Custom pipes",
"translation": "## 自定义管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "This pipe definition reveals the following key points:",
"translation": "在这个管道的定义中体现了几个关键点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "* A pipe is a class decorated with pipe metadata.",
"translation": "管道是一个带有“管道元数据(pipe metadata)”装饰器的类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "## The *PipeTransform* interface",
"translation": "### *PipeTransform*接口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "Now you need a component to demonstrate the pipe.",
"translation": "现在,我们需要一个组件来演示这个管道。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "Note the following:",
"translation": "要注意的有两点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "* You use your custom pipe the same way you use built-in pipes.",
"translation": "我们使用自定义管道的方式和内置管道完全相同。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "* You must include your pipe in the `declarations` array of the `AppModule`.",
"translation": "我们必须在`AppModule`的`declarations`数组中包含这个管道。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "Remember the declarations array",
"translation": "别忘了`declarations`数组",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "You must manually register custom pipes.\nIf you don't, Angular reports an error.\nIn the previous example, you didn't list the `DatePipe` because all\nAngular built-in pipes are pre-registered.",
"translation": "我们必须手动注册自定义管道。如果忘了Angular就会报告一个错误。\n在前一个例子中我们没有把`DatePipe`列进去这是因为Angular所有的内置管道都已经预注册过了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "## Power Boost Calculator",
"translation": "## 能力倍增计算器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "## Pipes and change detection",
"translation": "## 管道与变更检测",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "No pipe",
"translation": "无管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "The companion component class provides heroes, adds heroes into the array, and can reset the array.",
"translation": "和模板相伴的组件类可以提供英雄数组,能把新的英雄添加到数组中,还能重置英雄数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "FlyingHeroesPipe",
"translation": "“会飞的英雄”管道FlyingHeroesPipe",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "Here's the `FlyingHeroesPipe` implementation, which follows the pattern for custom pipes described earlier.",
"translation": "下面是`FlyingHeroesPipe`的实现,它遵循了我们以前见过的那些写自定义管道的模式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "Notice how a hero is added:",
"translation": "来看看我们是如何添加新英雄的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "For filtering flying heroes, consider an *impure pipe*.",
"translation": "为了过滤会飞的英雄,我们要使用*非纯(impure)管道*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "## Pure and impure pipes",
"translation": "## 纯(pure)管道与非纯(impure)管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "Before doing that, understand the difference between pure and impure, starting with a pure pipe.",
"translation": "在继续往下走之前,我们先理解一下*纯*和*非纯*之间的区别,从*纯*管道开始。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "Pure pipes",
"translation": "纯管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "This may seem restrictive but it's also fast.\nAn object reference check is fast&mdash;much faster than a deep check for\ndifferences&mdash;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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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 laterin this page.",
"translation": "或者我们也可以完全不用管道。\n有时候使用组件的属性能比用管道更好的达到目的这一点我们等后面会再提起。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "Impure pipes",
"translation": "### 非纯管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "An impure <i>FlyingHeroesPipe</i>",
"translation": "### 非纯版本的*FlyingHeroesPipe*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`.",
"translation": "我们可以从`FlyingHeroesComponent`派生出一个`FlyingHeroesImpureComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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>中确认,当我们输入新的英雄甚至修改#[code heroes]数组时,这个#[i 会飞的英雄]的显示也跟着更新了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "{@a async-pipe}\n<h3 class=\"no-toc\">The impure <i>AsyncPipe</i></h3>",
"translation": "非纯 <i>AsyncPipe</i>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "An impure caching pipe",
"translation": "一个非纯而且带缓存的管道",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "Write one more impure pipe, a pipe that makes an HTTP request.",
"translation": "我们来写更多的非纯管道一个向服务器发起HTTP请求的管道。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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</span>:",
"translation": "我们确实得小心点。\n这个管道只有当所请求的URL发生变化时才会向服务器发起请求。它会缓存服务器的响应。\n代码如下它使用[Angular http](guide/http)客户端来接收数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "The component renders as the following:",
"translation": "组件渲染起来是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "A breakpoint on the pipe's request for data shows the following:",
"translation": "这个管道上的断点请求数据的过程显示:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "* Each binding gets its own pipe instance.",
"translation": "每个绑定都有它自己的管道实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "* Each pipe instance caches its own URL and data.",
"translation": "每个管道实例都缓存了它自己的URL和数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"original": "* Each pipe instance only calls the server once.",
"translation": "每个管道实例都只调用一次服务器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "Debugging with the json pipe",
"translation": "借助json管道进行调试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "Pure pipes and pure functions",
"translation": "### 纯管道与纯函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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`&mdash;an impure pipe with a pure function.",
"translation": "我们在本章前面见过的管道都是用纯函数实现的。\n内置的`DatePipe`就是一个用纯函数实现的纯管道。\n`ExponentialStrengthPipe`是如此,\n`FlyingHeroesComponent`也是如此。\n不久前我们刚看过的`FlyingHeroesImpurePipe`,是一个*用纯函数实现的非纯管道*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "## Next steps",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "## Appendix: No *FilterPipe* or *OrderByPipe*",
"translation": "## 附录:没有*FilterPipe*或者*OrderByPipe*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"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/content-1/guide/pipes.md"
},
{
"original": "# QuickStart",
"translation": "# 快速上手",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Good tools make application development quicker and easier to maintain than\nif you did everything by hand.",
"translation": "好的工具能让开发更加简单快捷。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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": "在这一章CLI快速起步中我们的目标是构建并运行一个超级简单的Angular应用。我们会使用Angular-CLI来让每个Angular应用从[风格指南](guide/styleguide)中获益。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "Step 1. Set up the Development Environment",
"translation": "步骤1. 设置开发环境",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "You need to set up your development environment before you can do anything.",
"translation": "在开始工作之前,我们必须设置好开发环境。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "Step 2. Create a new project",
"translation": "步骤2. 创建新项目",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Open a terminal window.",
"translation": "打开终端窗口。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Generate a new project and skeleton application by running the following commands:",
"translation": "运行下列命令来生成一个新项目以及应用的骨架代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Patience please.\nIt takes time to set up a new project, most of it spent installing npm packages.",
"translation": "请耐心等待。\n创建新项目需要花费很多时间大多数时候都是在安装那些npm包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Step 3: Serve the application",
"translation": "步骤3. 启动开发服务器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Go to the project directory and launch the server.",
"translation": "进入项目目录,并启动服务器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "Your app greets you with a message:",
"translation": "本应用会用一条消息来跟你打招呼:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Step 4: Edit your first Angular component",
"translation": "步骤4. 编辑我们的第一个Angular组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/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!!_ ",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "The browser reloads automatically with the revised title. That's nice, but it could look better.",
"translation": "浏览器会自动刷新,而我们会看到修改之后的标题。不错,不过它还可以更好看一点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Open `src/app/app.component.css` and give the component some style.",
"translation": "打开 `src/app/app.component.css` 并给这个组件设置一些样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Looking good!",
"translation": "漂亮!",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "## What's next?",
"translation": "## 接下来呢?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "That's about all you'd expect to do in a \"Hello, World\" app.",
"translation": "如你所愿我们完成了这个“Hello, World”应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "## Project file review",
"translation": "## 项目文件概览",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "An Angular CLI project is the foundation for both quick experiments and enterprise solutions.",
"translation": "Angular CLI项目是做快速试验和开发企业解决方案的基础。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "Some of the generated files might be unfamiliar to you.",
"translation": "有些生成的文件你可能觉得陌生。接下来我们就讲讲它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "### The `src` folder",
"translation": "### `src`文件夹",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "<table width=\"100%\">\n <col width=\"20%\">\n </col>\n <col width=\"80%\">\n </col>\n <tr>\n <th>\n File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "</th>\n <th>\n Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "A folder where you can put images and anything else to be copied wholesale\n when you build your application.",
"translation": "这个文件夹下你可以放图片等任何东西,在构建应用时,它们全都会拷贝到发布包中。\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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都替你考虑到了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "Every site wants to look good on the bookmark bar.\n Get started with your very own Angular icon.",
"translation": "每个网站都希望自己在书签栏中能好看一点。\n 请把它换成你自己的图标。\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/glossary#ahead-of-time-aot-compilation)\n without changing any code by passing in `--aot` to `ng build` or `ng serve`.",
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "### The root folder",
"translation": "### 根目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "<table width=\"100%\">\n <col width=\"20%\">\n </col>\n <col width=\"80%\">\n </col>\n <tr>\n <th>\n File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"original": "</th>\n <th>\n Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "Git configuration to make sure autogenerated files are not commited to source control.",
"translation": "一个Git的配置文件用来确保某些自动生成的文件不会被提交到源码控制系统中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "TypeScript compiler configuration for your IDE to pick up and give you helpful tooling.",
"translation": "TypeScript编译器的配置你的IDE会借助它来给你提供更好的帮助。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "### Next Step",
"translation": "### 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/quickstart.md"
},
{
"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/content-1/guide/quickstart.md"
},
{
"original": "# Reactive Forms",
"translation": "# 响应式表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "Try the <live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\">Reactive Forms live-example</live-example>.",
"translation": "试试<live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\">响应式表单的在线例子</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "You can also run the <live-example title=\"Reactive Forms Demo in Plunker\">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 Plunker\">响应式表单的演示程序</live-example>,并从顶部选取一个中间步骤。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Introduction to Reactive Forms",
"translation": "## 响应式表单简介",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### _Reactive_ forms",
"translation": "### *响应式*表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### _Template-driven_ forms",
"translation": "### *模板驱动*表单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "_Template-driven_ forms, introduced in the [Template guide](guide/forms), take a completely different approach.",
"translation": "在[模板](guide/forms)一章我们介绍过的*模板驱动*表单,是一种完全不同的方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "For this reason, the `ngModel` directive is not part of the ReactiveFormsModule.",
"translation": "因此,`ngModel`并不是`ReactiveFormsModule`模块的一部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### Async vs. sync",
"translation": "### 异步 vs. 同步",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Reactive forms are synchronous. Template-driven forms are asynchronous. It's a difference that matters.",
"translation": "响应式表单是同步的。模板驱动表单是异步的。这个不同点很重要。",
"sourceFile": "/Users/twer/private/GDE/content-1/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.",
"translation": "使用响应式表单,我们会在代码中创建整个表单控件树。\n我们可以立即更新一个值或者深入到表单中的任意节点因为所有的控件都始终是可用的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### Which is better, reactive or template-driven?",
"translation": "### 哪一个更好?响应式还是模板驱动?",
"sourceFile": "/Users/twer/private/GDE/content-1/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请自行选择更合适的方法甚至可以在同一个应用中同时使用它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/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": "在这章*响应式表单*中,我们只专注于*响应式*范式以及响应式表单技术的详情。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "## Setup",
"translation": "## 准备工作",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Follow the steps in the [_Setup_ guide](guide/setup \"Setup guide\")\nfor creating a new project folder (perhaps called `reactive-forms`)\nbased on the _QuickStart seed_.",
"translation": "遵循[*准备工作*一章](guide/setup \"Setup guide\")中的步骤基于*快速起步种子工程*创建一个新的项目目录(比如叫`reactive-forms`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Create a data model",
"translation": "## 创建数据模型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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.\nCreate a new `data-model.ts` file in the `app` directory and copy the content below into it.",
"translation": "本章的焦点是响应式表单组件以及编辑一个英雄。\n我们需要一个`Hero`类和一些英雄数据。\n在`app`目录下创建一个`data-model.ts`文件,并粘贴进下列内容:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "## Create a _reactive forms_ component",
"translation": "## 创建*响应式表单*组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Make a new file called\n`hero-detail.component.ts` in the `app` directory and import these symbols:",
"translation": "在`app`目录下创建一个名叫`hero-detail.component.ts`的新文件,并且导入下列符号:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Now enter the `@Component` decorator that specifies the `HeroDetailComponent` metadata:",
"translation": "然后输入这个`@Component`来为`HeroDetailComponent`指定元数据:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Next, create an exported `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/content-1/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`框,表示英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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/content-1/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)一章。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Create the template",
"translation": "## 创建模板",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Now create the component's template, `src/app/hero-detail.component.html`, with the following markup.",
"translation": "现在,在创建组件的模板文件`src/app/hero-detail.component.html`,内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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.",
"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/content-1/guide/reactive-forms.md"
},
{
"original": "## Import the _ReactiveFormsModule_",
"translation": "## 导入`ReactiveFormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "The HeroDetailComponent template uses `formControlName`\ndirective from the `ReactiveFormsModule`.",
"translation": "`HeroDetailComponent`的模板中使用了来自`ReactiveFormsModule`的`formControlName`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "In this sample, you declare the `HeroDetailComponent` in the `AppModule`.\nTherefore, do the following three things in `app.module.ts`:",
"translation": "在这个例子中,我们在`AppModule`中声明了`HeroDetailComponent`。因此现在`app.module.ts`中做了三件事:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "1. Use a JavaScript `import` statement to access\nthe `ReactiveFormsModule` and the `HeroDetailComponent`.",
"translation": "使用JavaScript的`import`语句访问`ReactiveFormsModule`和`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "1. Add `ReactiveFormsModule` to the `AppModule`'s `imports` list.",
"translation": "把`ReactiveFormsModule`添加到`AppModule`的`imports`列表中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "1. Add `HeroDetailComponent` to the declarations array.",
"translation": "把`HeroDetailComponent`添加到声明数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Display the _HeroDetailComponent_",
"translation": "## 显示`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Revise the `AppComponent` template so it displays the `HeroDetailComponent`.",
"translation": "修改`AppComponent`的模板,以便显示`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### Essential form classes",
"translation": "### 基础的表单类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "It may be helpful to read a brief description of the core form classes.",
"translation": "阅读一下这些核心表单类的简短描述也许会有用。",
"sourceFile": "/Users/twer/private/GDE/content-1/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*。",
"sourceFile": "/Users/twer/private/GDE/content-1/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表单控件比如输入框和下拉框。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`实例组成的有序数组的值和有效性状态。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "You'll learn more about these classes as you work through this guide.",
"translation": "随着本章的深入,我们将学到关于这三个类的更多知识。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### Style the app",
"translation": "### 为应用添加样式",
"sourceFile": "/Users/twer/private/GDE/content-1/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 `index.html`:",
"translation": "我们在`AppComponent`和`HeroDetailComponent`的模板中使用Bootstrap中的CSS类。请把`bootstrap`的*CSS样式表文件*添加到`index.html`的`head`区。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Now that everything is wired up, the browser should display something like this:",
"translation": "这些做好之后,浏览器中应该显示成这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Add a FormGroup",
"translation": "## 添加FormGroup",
"sourceFile": "/Users/twer/private/GDE/content-1/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`区就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "In the class, wrap the `FormControl` in a `FormGroup` called `heroForm` as follows:",
"translation": "在这个类中,把`FormControl`包裹进了一个名叫`heroForm`的`FormGroup`中,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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中的表单验证器。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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当用户输入名字时它的值去了哪里",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Taking a look at the form model",
"translation": "## 表单模型概览",
"sourceFile": "/Users/twer/private/GDE/content-1/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`标签紧后面添加如下代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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/content-1/guide/reactive-forms.md"
},
{
"original": "Great! You have the basics of a form.",
"translation": "真棒!我们有了一个基本版表单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "## Introduction to _FormBuilder_",
"translation": "## `FormBuilder`简介",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "The `FormBuilder` class helps reduce repetition and\nclutter by handling details of control creation for you.",
"translation": "`FormBuilder`类能通过处理控件创建的细节问题来帮我们减少重复劳动。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "To use `FormBuilder`, you need to import it into `hero-detail.component.ts`:",
"translation": "要使用`FormBuilder`,我们就要先把它导入到`hero-detail.component.ts`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/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`重构得更加容易读写。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "* Inject a `FormBuilder` into the constructor.",
"translation": "把`FormBuilder`注入到构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "* Call `createForm` in the constructor.",
"translation": "在构造函数中调用`createForm`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "The revised `HeroDetailComponent` looks like this:",
"translation": "修改过的`HeroDetailComponent`代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "`FormBuilder.group` is a factory method that creates a `FormGroup`. &nbsp;\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/content-1/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/content-1/guide/reactive-forms.md"
},
{
"original": "### Validators.required",
"translation": "### Validators.required 验证器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "First, import the `Validators` symbol.",
"translation": "首先,导入`Validators`符号。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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.",
"translation": "响应式验证器是一些简单、可组合的函数。\n在模板驱动表单中配置验证器有些困难因为我们必须把验证器包装进指令中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Update the diagnostic message at the bottom of the template to display the form's validity status.",
"translation": "修改模板底部的诊断信息,以显示表单的有效性状态。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "The browser displays the following:",
"translation": "浏览器会显示下列内容:",
"sourceFile": "/Users/twer/private/GDE/content-1/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`.",
"translation": "`Validators.required`生效了,但状态还是`INVALID`,因为输入框中还没有值。\n在输入框中输入就会看到这个状态从`INVALID`变成了`VALID`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "In a real app, you'd replace the diagnosic message with a user-friendly experience.",
"translation": "在真实的应用中,我们要把这些诊断信息替换成用户友好的信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### More FormControls",
"translation": "### 更多的表单控件FormControl",
"sourceFile": "/Users/twer/private/GDE/content-1/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": "每个英雄可以有多个名字,还有一个住址、一项超能力,有时还会有一个副手。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`(州列表)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Declare the `states` property and add some address `FormControls` to the `heroForm` as follows.",
"translation": "声明`states`属性并往`heroForm`中添加一些表示住址的`FormControl`,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Then add corresponding markup in `hero-detail.component.html`\nwithin the `form` element.",
"translation": "然后在`hero-detail.component.html`文件中把对应的脚本添加到`form`元素中。",
"sourceFile": "/Users/twer/private/GDE/content-1/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 `formGroupName` 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/content-1/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`.",
"translation": "修改过的模板包含更多文本输入框,一个`state`选择框,`power`(超能力)的单选按钮和一个`sidekick`检查框。",
"sourceFile": "/Users/twer/private/GDE/content-1/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如果不绑定这个值这个选择框就会显示来自数据模型中的第一个选项。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### Nested FormGroups",
"translation": "### 多级`FormGroup`",
"sourceFile": "/Users/twer/private/GDE/content-1/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": "这个表单变得越来越大、越来越笨重。我们可以把一些相关的`FormControl`组织到多级`FormGroup`中。\n`street`、`city`、`state`和`zip`属性就可以作为一个名叫`address`的`FormGroup`。\n用这种方式多级表单组和控件可以让我们轻松地映射多层结构的数据模型以便帮助我们跟踪这组相关控件的有效性和状态。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`.",
"translation": "我们用`FormBuilder`在这个名叫`heroForm`的组件中创建一个`FormGroup`,并把它用作父`FormGroup`。\n再次使用`FormBuilder`创建一个子级`FormGroup`,其中包括这些住址控件。把结果赋值给父`FormGroup`中新的`address`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Youve changed 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/content-1/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`。",
"sourceFile": "/Users/twer/private/GDE/content-1/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如下",
"sourceFile": "/Users/twer/private/GDE/content-1/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`的住址。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Great! Youve made a group and you can see that the template\nand the form model are talking to one another.",
"translation": "真棒!我们制作了一个控件组,并且可以看到模板和表单模型已经能彼此通讯了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Inspect _FormControl_ Properties",
"translation": "## 查看`FormControl`的属性",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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:",
"translation": "我们可以使用`.get()`方法来提取表单中一个单独`FormControl`的状态。\n我们可以在组件类中这么做或者通过往模板中添加下列代码来把它显示在页面中就添加在`{{form.value | json}}`插值表达式的紧后面:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "To get the state of a `FormControl` thats inside a `FormGroup`, use dot notation to path to the control.",
"translation": "要点取得`FormGroup`中的`FormControl`的状态,使用点语法来指定到控件的路径。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`的*任意*属性,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Property",
"translation": "属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Description",
"translation": "说明",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "the value of a `FormControl`.",
"translation": "`FormControl`的值。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "the validity of a `FormControl`. Possible values: `VALID`,\n `INVALID`, `PENDING`, or `DISABLED`.",
"translation": "`FormControl`的有效性。可能的值有`VALID`、`INVALID`、`PENDING`或`DISABLED`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "`true` if the user has _not_ changed the value in the UI.\n Its opposite is `myControl.dirty`.",
"translation": "如果用户*尚未*改变过这个控件的值,则为`true`。它总是与`myControl.dirty`相反。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Learn 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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "## The _data model_ and the _form model_",
"translation": "## *数据模型*与*表单模型*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "In this app, the `HeroDetailComponent` gets its hero from a parent `HeroListComponent`",
"translation": "在这个应用中,`HeroDetailComponent`从它的父组件`HeroListComponent`中取得一个英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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": "组件必须把*数据模型*中的英雄值复制到*表单模型*中。这里隐含着两个非常重要的点。",
"sourceFile": "/Users/twer/private/GDE/content-1/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": "开发人员必须理解*数据模型*是如何映射到*表单模型*中的属性的。",
"sourceFile": "/Users/twer/private/GDE/content-1/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元素流向*表单模型*的,而不是*数据模型*。表单控件永远不会修改*数据模型*。",
"sourceFile": "/Users/twer/private/GDE/content-1/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但是*表单模型*的形态越接近*数据模型*,事情就会越简单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "In this `HeroDetailComponent`, the two models are quite close.",
"translation": "在`HeroDetailComponent`中,这两个模型是非常接近的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Recall the definition of `Hero` in `data-model.ts`:",
"translation": "回忆一下`data-model.ts`中的`Hero`定义:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Here, again, is the component's `FormGroup` definition.",
"translation": "这里又是组件的`FormGroup`定义。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "There are two significant differences between these models:",
"translation": "在这些模型中有两点显著的差异:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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\")则可以表示多个。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`方法来把*数据模型*拷贝到*表单模型*中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Take a moment to refactor the _address_ `FormGroup` definition for brevity and clarity as follows:",
"translation": "花一点时间来重构一下`address`这个`FormGroup`定义,来让它更简洁清晰,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "## Populate the form model with _setValue_ and _patchValue_",
"translation": "## 使用`setValue`和`patchValue`来操纵表单模型",
"sourceFile": "/Users/twer/private/GDE/content-1/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`来初始化或重置这些值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### _setValue_",
"translation": "### _setValue_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/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`**,我们可以*立即*设置*每个*表单控件的值,只要把与*表单模型*的属性精确匹配的数据模型传进去就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "The `setValue` method checks the data object thoroughly before assigning any form control values.",
"translation": "`setValue`方法会在赋值给任何表单控件之前先检查数据对象的值。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`会默默地失败。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "On the other hand,`setValue` will catch\nthe error and report it clearly.",
"translation": "而`setValue`会捕获错误,并清晰的报告它。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`结构是非常像的。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/guide/reactive-forms.md"
},
{
"original": "### _patchValue_",
"translation": "### _patchValue_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/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`中的指定控件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "This example sets only the form's `name` control.",
"translation": "这个例子只会设置表单的`name`控件。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`不会检查缺失的控件值,并且不会抛出有用的错误信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### When to set form model values (_ngOnChanges_)",
"translation": "### 什么时候设置表单的模型值(`ngOnChanges`",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/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/content-1/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/content-1/guide/reactive-forms.md"
},
{
"original": "Add the `hero` input property.",
"translation": "添加输入属性`hero`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Add the `ngOnChanges` method to the class as follows:",
"translation": "向该类中添加`ngOnChanges`方法,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### _reset_ the form flags",
"translation": "### *重置*表单的标识。",
"sourceFile": "/Users/twer/private/GDE/content-1/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/content-1/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/content-1/guide/reactive-forms.md"
},
{
"original": "### Create the _HeroListComponent_ and _HeroService_",
"translation": "### 创建`HeroListComponent`和`HeroService`",
"sourceFile": "/Users/twer/private/GDE/content-1/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:",
"translation": "`HeroDetalComponent`是一个嵌套在`HeroListComponent`的*主从*视图中的子组件。如果把它们放在一起就是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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`检测到英雄的变化,并使用当前英雄的值重置此表单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "A \"Refresh\" button clears the hero list and the current selected hero before refetching the heroes.",
"translation": "\"刷新\"按钮清除英雄列表和当前选中的英雄,然后重新获取英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/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\")。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "If you're coding along with the steps in this reactive forms tutorial,\ncreate 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接下来我们回到正轨继续学习*表单数组*属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Use _FormArray_ to present an array of _FormGroups_",
"translation": "## 使用`FormArray`来表示`FormGroup`数组",
"sourceFile": "/Users/twer/private/GDE/content-1/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`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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`的数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "To _work_ with a `FormArray` you do the following:",
"translation": "要想使用`FormArray`,我们要这么做:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "1. Define the items (`FormControls` or `FormGroups`) in the array.",
"translation": "在数组中定义条目(`FormControl`或`FormGroup`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "1. Initialize the array with items created from data in the _data model_.",
"translation": "把这个数组初始化微一组从*数据模型*中的数据创建的条目。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "1. Add and remove items as the user requires.",
"translation": "根据用户的需求添加或移除这些条目。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`,并且让用户添加或修改这些住址(移除住址功能请课后自行实现)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Youll 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`显示第一个英雄住址。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### From _address_ to _secret lairs_",
"translation": "### 从*住址*到*秘密小屋*Secret Lair",
"sourceFile": "/Users/twer/private/GDE/content-1/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`定义:",
"sourceFile": "/Users/twer/private/GDE/content-1/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`让我们遇到了一个重要问题:*表单模型*与*数据模型*不再匹配了。",
"sourceFile": "/Users/twer/private/GDE/content-1/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.",
"translation": "显然,必须在两者之间建立关联。但它在应用领域中的意义不限于此,它可以用于任何东西。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### Initialize the \"secretLairs\" _FormArray_",
"translation": "### 初始化`FormArray`型的`secretLairs`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "The default form displays a nameless hero with no addresses.",
"translation": "默认的表单显示一个无地址的无名英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`来进行初始化。",
"sourceFile": "/Users/twer/private/GDE/content-1/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我们所要替换的是*控件*,而不是控件的*值*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Notice also that the _secretLairs_ `FormArray` contains **`FormGroups`**, not `Addresses`.",
"translation": "还要注意,`secretLairs`数组中包含的是**`FormGroup`,而不是`Address`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### Get the _FormArray_",
"translation": "### 获取`FormArray`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "The `HeroDetailComponent` should be able to display, add, and remove items from the _secretLairs_ `FormArray`.",
"translation": "`HeroDetailComponent`应该能从`secretLairs`中显示、添加和删除条目。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`的便捷属性中来让它更清晰,并供复用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### Display the _FormArray_",
"translation": "### 显示`FormArray`",
"sourceFile": "/Users/twer/private/GDE/content-1/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`.",
"translation": "当前HTML模板显示单个的地址`FormGroup`。\n我们要把它修改成能显示0、1或更多个表示英雄地址的`FormGroup`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "The trick lies in knowing how to write the `*ngFor`. There are three key points:",
"translation": "诀窍在于要知道如何编写`*ngFor`。主要有三点:",
"sourceFile": "/Users/twer/private/GDE/content-1/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.",
"translation": "在`*ngFor`的`<div>`之外套上另一个包装`<div>`,并且把它的`formArrayName`指令设为`\"secretLairs\"`。\n 这一步为内部的表单控件建立了一个`FormArray`型的`secretLairs`作为上下文以便重复渲染HTML模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/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.",
"translation": "这些重复条目的数据源是`FormArray.controls`而不是`FormArray`本身。\n 每个控件都是一个`FormGroup`型的地址对象与以前的模板HTML所期望的格式完全一样。",
"sourceFile": "/Users/twer/private/GDE/content-1/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.",
"translation": "每个被重复渲染的`FormGroup`都需要一个独一无二的`formGroupName`,它必须是`FormGroup`在这个`FormArray`中的索引。\n 我们将复用这个索引,以便为每个地址组合出一个独一无二的标签。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Here's the skeleton for the _secret lairs_ section of the HTML template:",
"translation": "下面是HTML模板中*秘密小屋*部分的代码骨架:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Here's the complete template for the _secret lairs_ section:",
"translation": "这里是*秘密小屋*部分的完整模板:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### Add a new lair to the _FormArray_",
"translation": "### 把新的小屋添加到`FormArray`中",
"sourceFile": "/Users/twer/private/GDE/content-1/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`添加到其中。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/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”按钮时就保存一次。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### Try it!",
"translation": "### 试试看!",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### Remove a lair",
"translation": "### 移除一个小屋",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "## Observe control changes",
"translation": "## 监视控件的变化",
"sourceFile": "/Users/twer/private/GDE/content-1/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`。",
"sourceFile": "/Users/twer/private/GDE/content-1/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幸运的是我们可以通过订阅表单控件的属性之一来了解这些变化此属性会发出变更通知。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "Add the following method to log changes to the value of the _name_ `FormControl`.",
"translation": "添加下列方法,以监听姓名这个`FormControl`中值的变化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Call it in the constructor, after creating the form.",
"translation": "在构造函数中调用它,就在创建表单的代码之后:",
"sourceFile": "/Users/twer/private/GDE/content-1/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`绑定在组件模板的底部显示这个数组:",
"sourceFile": "/Users/twer/private/GDE/content-1/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我们会看到每次按键都会记录一个新名字。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### When to use it",
"translation": "### 什么时候用它",
"sourceFile": "/Users/twer/private/GDE/content-1/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*在组件类中*订阅表单控件属性变化的可观察对象以触发应用逻辑则是比较难的方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Save form data",
"translation": "## 保存表单数据",
"sourceFile": "/Users/twer/private/GDE/content-1/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:",
"translation": "`HeroDetailComponent`捕获了用户输入,但没有用它做任何事。\n在真实的应用中我们可能要保存这些英雄的变化。\n在真实的应用中我们还要能丢弃未保存的变更然后继续编辑。\n在实现完本节的这些特性之后表单是这样的",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### Save",
"translation": "### 保存",
"sourceFile": "/Users/twer/private/GDE/content-1/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`的一个方法来进行保存。",
"sourceFile": "/Users/twer/private/GDE/content-1/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`助手来深层复制变化后的模型值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "**Address deep copy**",
"translation": "**地址的深层复制**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "### Revert (cancel changes)",
"translation": "### 丢弃(撤销修改)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/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`数据模型来构建出*表单模型*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "### Buttons",
"translation": "### 按钮",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "Add the \"Save\" and \"Revert\" buttons near the top of the component's template:",
"translation": "把“Save”和“Revert”按钮添加到组件模板的顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"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/content-1/guide/reactive-forms.md"
},
{
"original": "This is the final step in the demo.\nTry the <live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\"></live-example>.",
"translation": "这是本演示的最后一步。\n去试试<live-example plnkr=\"final\" title=\"Reactive Forms (final) in Plunker\"></live-example>吧。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "## Conclusion",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "This page covered:",
"translation": "本章包括:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "* How to create a reactive form component and its corresponding template.",
"translation": "如何创建一个响应式表单控件及其对应的模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "* How to use `FormBuilder` to simplify coding a reactive form.",
"translation": "如何使用`FormBuilder`来简化响应式表单的编码工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "* Grouping `FormControls`.",
"translation": "分组`FormControl`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "* Inspecting `FormControl` properties.",
"translation": "审查`FormControl`的属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "* Setting data with `patchValue` and `setValue`.",
"translation": "使用`patchValue`和`setValue`设置数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "* Adding groups dynamically with `FormArray`.",
"translation": "使用`FormArray`动态添加控件组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "* Observing changes to the value of a `FormControl`.",
"translation": "监听`FormControl`中值的变化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "* Saving form changes.",
"translation": "保存表单中的更改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "The key files of the final version are as follows:",
"translation": "最终版中的核心文件如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "You can download the complete source for all steps in this guide\nfrom the <live-example title=\"Reactive Forms Demo in Plunker\">Reactive Forms Demo</live-example> live example.",
"translation": "你可以到<live-example title=\"Reactive Forms Demo in Plunker\">响应式表单在线例子</live-example>中下载本章所有步骤的完整代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/reactive-forms.md"
},
{
"original": "# Routing & Navigation",
"translation": "# 路由与导航",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "## Overview",
"translation": "## 概览",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The browser is a familiar model of application navigation:",
"translation": "浏览器具有我们熟悉的导航模式:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Enter a URL in the address bar and the browser navigates to a corresponding page.",
"translation": "在地址栏输入URL浏览器就会导航到相应的页面。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Click links on the page and the browser navigates to a new page.",
"translation": "在页面中点击链接,浏览器就会导航到一个新页面。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "## The Basics",
"translation": "## 基础知识",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "An introduction to a few core router concepts will help orient you to the details that follow.",
"translation": "在接触细节之前,我们先来介绍关于路由的一些核心概念。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### *&lt;base href>*",
"translation": "### *&lt;base href>* 元素",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Router imports",
"translation": "### 从路由库中导入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Configuration",
"translation": "### 配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Router outlet",
"translation": "### 路由出口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Router links",
"translation": "### 路由器链接",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Consider the following template:",
"translation": "考虑下列模板:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Router state",
"translation": "### 路由器状态",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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": "路由器状态为我们提供了从任意激活路由开始向上或向下遍历路由树的一种方式,以获得关于父、子、兄弟路由的信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Activated route",
"translation": "### 激活的路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Property",
"translation": "属性\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述\n </th>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "An `Observable` of the route path(s), represented as an array of strings for each part of the route path.",
"translation": "路由路径的`Observable`对象,是一个由路由路径中的各个部分组成的字符串数组。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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)解析而来的值。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The name of the `RouterOutlet` used to render the route. For an unnamed outlet, the outlet name is _primary_.",
"translation": "要把该路由渲染到的`RouterOutlet`的名字。对于无名路由,它的路由名是`primary`,而不是空串。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The route configuration used for the route that contains the origin path.",
"translation": "用于该路由的路由配置信息,其中包含原始路径。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The route's parent `ActivatedRoute` when this route is a [child route](#child-routing-component).",
"translation": "当该路由是一个[子路由](#child-routing-component)时,表示该路由的父级`ActivatedRoute`。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Contains the first `ActivatedRoute` in the list of this route's child routes.",
"translation": "包含该路由的子路由列表中的第一个`ActivatedRoute`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Contains all the [child routes](#child-routing-component) activated under the current route.",
"translation": "包含当前路由下所有已激活的[子路由](#child-routing-component)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "**`params`** &mdash; 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/content-1/guide/router.md"
},
{
"original": "**`queryParams`** &mdash; 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/content-1/guide/router.md"
},
{
"original": "### Router events",
"translation": "### 路由事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Router Event",
"translation": "路由器事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "An [event](api/router/NavigationStart) triggered when navigation starts.",
"translation": "本[事件](api/router/NavigationStart)会在导航开始时触发。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "An [event](api/router/RouteConfigLoadEnd) triggered after a route has been lazy loaded.",
"translation": "本[事件](api/router/RouteConfigLoadEnd)会在路由被惰性加载之后触发。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "An [event](api/router/NavigationEnd) triggered when navigation ends successfully.",
"translation": "本[事件](api/router/NavigationEnd)会在导航成功结束之后触发。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "An [event](api/router/NavigationError) triggered when navigation fails due to an unexpected error.",
"translation": "这个[事件](api/router/NavigationError)会在导航由于意料之外的错误而失败时触发。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Summary",
"translation": "### 总结一下",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Here are the key `Router` terms and their meanings:",
"translation": "下面是一些*路由器*中的关键词汇及其含义:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Router Part",
"translation": "路由器部件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Meaning",
"translation": "含义",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Router",
"translation": "<code>Router</code>(路由器)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "RouterModule",
"translation": "<code>RouterModule</code>(路由器模块)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "A separate NgModule that provides the necessary service providers\n and directives for navigating through application views.",
"translation": "<p>\n 一个独立的Angular模块用于提供所需的服务提供商以及用来在应用视图之间进行导航的指令。\n </p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Routes",
"translation": "<code>Routes</code>(路由数组)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Defines an array of Routes, each mapping a URL path to a component.",
"translation": "定义了一个路由数组每一个都会把一个URL路径映射到一个组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Route",
"translation": "<code>Route</code>(路由)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "RouterOutlet",
"translation": "<code>RouterOutlet</code>(路由出口)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The directive (<code>&lt;router-outlet></code>) that marks where the router displays a view.",
"translation": "该指令(<code>&lt;router-outlet></code>)用来标记出路由器该在哪里显示视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "RouterLink",
"translation": "<code>RouterLink</code>(路由链接)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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>link parameters array</i> triggers a navigation.",
"translation": "该指令用来把一个可点击的HTML元素绑定到路由。\n 点击带有绑定到<i>字符串</i>或<i>链接参数数组</i>的<code>routerLink</code>指令的元素就会触发一次导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "RouterLinkActive",
"translation": "<code>RouterLinkActive</code>(活动路由链接)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "ActivatedRoute",
"translation": "<code>ActivatedRoute</code>(激活的路由)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "RouterState",
"translation": "<code>RouterState</code>(路由器状态)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "<i>Link parameters array</i>",
"translation": "链接参数数组",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "An array that the router interprets as a routing instruction.\n You can bind that array toa <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/content-1/guide/router.md"
},
{
"original": "<i>Routing component</i>",
"translation": "<i>路由组件</i>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "<td>\n<p> An Angular component with a <code>RouterOutlet</code> that displays views based on router navigations.\n</p>",
"translation": "<p>\n 一个带有<code>RouterOutlet</code>的Angular组件它根据路由器的导航来显示相应的视图。\n </p>\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "## The sample application",
"translation": "## 范例应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* Organizing the application features into modules.",
"translation": "把应用的各个特性组织成模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Navigating to a component (*Heroes* link to \"Heroes List\").",
"translation": "导航到组件(*Heroes*链接到“英雄列表”组件)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Including a route parameter (passing the Hero `id` while routing to the \"Hero Detail\").",
"translation": "包含一个路由参数(当路由到“英雄详情”时,把该英雄的`id`传进去)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Child routes (the *Crisis Center* has its own routes).",
"translation": "子路由(*危机中心*特性有一组自己的路由)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The `CanActivate` guard (checking route access).",
"translation": "`CanActivate`守卫(检查路由的访问权限)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The `CanActivateChild` guard (checking child route access).",
"translation": "`CanActivateChild`守卫(检查子路由的访问权限)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The `CanDeactivate` guard (ask permission to discard unsaved changes).",
"translation": "`CanDeactivate`守卫(询问是否丢弃未保存的更改)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The `Resolve` guard (pre-fetching route data).",
"translation": "`Resolve`守卫(预先获取路由数据)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Lazy loading feature modules.",
"translation": "惰性加载特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The `CanLoad` guard (check before loading feature module assets).",
"translation": "`CanLoad`守卫(在加载特性模块之前进行检查)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### The sample application in action",
"translation": "### 范例程序的动图",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The application has three main feature areas:",
"translation": "本应用具有三个主要的特性区:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. A *Crisis Center* for maintaining the list of crises for assignment to heroes.",
"translation": "*危机中心*用于维护要指派给英雄的危机列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. A *Heroes* area for maintaining the list of heroes employed by the agency.",
"translation": "*英雄*区用于维护管理局雇佣的英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. An *Admin* area to manage the list of crises and heroes.",
"translation": "*管理*区会管理危机和英雄的列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Try it by clicking on this <live-example title=\"Hero Employment Agency Live Example\">live example link</live-example>.",
"translation": "点击<live-example title=\"Hero Employment Agency Live Example\"></live-example>试用一下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Select one hero and the app takes you to a hero editing screen.",
"translation": "选择其中之一,该应用就会把我们带到此英雄的编辑页面。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Now click the *Crisis Center* link for a list of ongoing crises.",
"translation": "现在,点击*危机中心*链接,前往*危机*列表页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Up pops a dialog box.",
"translation": "我们会看到弹出了一个对话框。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You can say \"OK\" and lose your changes or click \"Cancel\" and continue editing.",
"translation": "我们可以回答“确定”以放弃这些更改,或者回答“取消”来继续编辑。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Proceed to the first application milestone.",
"translation": "我们这就开始本应用的第一个里程碑。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "## Milestone 1: Getting started with the router",
"translation": "## 里程碑1从路由器开始",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Begin with a simple version of the app that navigates between two empty views.",
"translation": "开始本应用的一个简版,它在两个空路由之间导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Set the *&lt;base href>*",
"translation": "### 设置*&lt;base href>*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "You must **add a\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base\" title=\"base href\">&lt;base href&gt; 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\">&lt;base href&gt; 元素</a>**,这样`pushState`才能正常工作。\n当引用CSS文件、脚本和图片时浏览器会用`<base href>`的值作为*相对*URL的前缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "A live coding environment like Plunker 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": "像Plunker这样的在线编程环境会动态设置应用的基地址base href因此我们没办法指定固定的地址。\n这就是为什么我们要用一个脚本动态写入`<base>`标签,而不是直接写`<base href...>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You only need this trick for the live example, not production code.",
"translation": "我们只应该在在线例子这种情况下使用这种小花招,不要把它用到产品的正式代码中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Importing from the router library",
"translation": "### 从路由库中导入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "You teach the router how to navigate by configuring it with routes.",
"translation": "通过一些路由来配置路由器,我们可以教它如何进行导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### Define routes",
"translation": "#### 定义路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "A router must be configured with a list of route definitions.",
"translation": "路由器必须用“路由定义”的列表进行配置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "In simpler terms, you might say this of the first route:",
"translation": "直白的说,我们可以这样解释第一个路由:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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随着应用的成长我们将需要将路由配置重构到单独的文件并创建**[路由模块](guide/router#routing-module)** - 一种特别的、专门为特性模块的路由器服务的**服务模块**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Providing the `RouterModule` in the `AppModule` makes the Router available everywhere in the application.",
"translation": "在`AppModule`中提供`RouterModule`,让该路由器在应用的任何地方都能被使用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### The *AppComponent* shell",
"translation": "### *AppComponent*外壳组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The corresponding component template looks like this:",
"translation": "该组件所对应的模板是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### *RouterOutlet*",
"translation": "### *RouterOutlet* 指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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>`。\n但路由器可以支持多个*命名的*出口outlet将来我们会涉及到这部分特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### *RouterLink* binding",
"translation": "### `routerLink` 绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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=\"...\"`。我们从路由库中导入了`RouterLink`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### *RouterLinkActive* binding",
"translation": "### `routerLinkActive`绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### *Router directives*",
"translation": "### *路由器指令集*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The current state of `app.component.ts` looks like this:",
"translation": "`app.component.ts`目前是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Wildcard route",
"translation": "### 通配符路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Create the `PageNotFoundComponent` to display when users visit invalid URLs.",
"translation": "创建`PageNotFoundComponent`,以便在用户访问无效网址时显示它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "As with the other components, add the `PageNotFoundComponent` to the `AppModule` declarations.",
"translation": "像其它组件一样,把`PageNotFoundComponent`添加到`AppModule`的声明中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### The _default_ route to heroes",
"translation": "### 把*默认*路由设置为英雄列表",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "When the application launches, the initial URL in the browser bar is something like:",
"translation": "应用启动时浏览器地址栏中的初始URL是这样的",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Redirecting routes",
"translation": "### 重定向路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Basics wrap up",
"translation": "### “起步阶段”总结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "You've learned how to do the following:",
"translation": "我们已经学会了如何:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Load the router library.",
"translation": "加载路由库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* Add a `router-outlet` to the shell template where views will be displayed.",
"translation": "往壳组件的模板中添加一个`router-outlet`指令,视图将会被显示在那里",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Configure the router module with `RouterModule.forRoot`.",
"translation": "用`RouterModule.forRoot`配置路由器模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Set the router to compose HTML5 browser URLs.",
"translation": "设置路由器使其合成HTML5模式的浏览器URL。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* handle invalid routes with a `wildcard` route.",
"translation": "使用通配符路由来处理无效路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* navigate to the default route when the app launches with an empty path.",
"translation": "当应用在空路径下启动时,导航到默认路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The starter app's structure looks like this:",
"translation": "这个初学者应用的结构是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Here are the files discussed in this milestone.",
"translation": "下面是当前里程碑中讨论过的文件列表:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "## Milestone 2: *Routing module*",
"translation": "## 里程碑 #2**路由模块**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The **Routing Module** has several characteristics:",
"translation": "**路由模块**有一系列特性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Separates routing concerns from other application concerns.",
"translation": "把路由这个关注点从其它应用类关注点中分离出去",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Provides a module to replace or remove when testing the application.",
"translation": "测试特性模块时,可以替换或移除路由模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Provides a well-known location for routing service providers including guards and resolvers.",
"translation": "为路由服务提供商(包括守卫和解析器等)提供一个共同的地方",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Does **not** [declare components](guide/ngmodule-faq#routing-module).",
"translation": "**不要**[声明组件](guide/ngmodule-faq#routing-module)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Refactor the routing configuration into a _routing module_",
"translation": "### 将路由配置重构为*路由模块*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "After these steps, the file should look like this.",
"translation": "做完这些之后,该文件变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Do you need a _Routing Module_?",
"translation": "### 你需要**路由模块**吗?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Choose one pattern or the other and follow that pattern consistently.",
"translation": "我们建议你选择其中一种模式,并坚持模式的一致性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Most developers should always implement a Routing Module for the sake of consistency.",
"translation": "大多数开发者应该采用路由模块,以保持一致性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "It 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开发者可以很自然的从路由模块中查找和扩展路由配置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "## Milestone 3: Heroes feature",
"translation": "## 里程碑 #2 英雄特征区",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You've seen how to navigate using the `RouterLink` directive.\nNow you'll learn the following:",
"translation": "我们刚刚学习了如何用`RouterLink`指令进行导航。接下来我们将到:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Organize the app and routes into *feature areas* using modules.",
"translation": "用模块把应用和路由组织为一些*特性区*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Navigate imperatively from one component to another.",
"translation": "命令式地从一个组件导航到另一个组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Pass required and optional information in route parameters.",
"translation": "通过路由传递必要信息和可选信息",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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=\"Tour of Heroes: Services example code\"></live-example>中赋值大部分代码过来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Here's how the user will experience this version of the app:",
"translation": "下面是用户将看到的版本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "A typical application has multiple *feature areas*,\neach dedicated to a particular business purpose.",
"translation": "典型的应用具有多个*特性区*,每个特性区都专注于特定的业务用途。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Add heroes functionality",
"translation": "### 添加英雄管理功能",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Follow these steps:",
"translation": "按照下列步骤:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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=\"Tour of Heroes: Services example code\">教程中的“服务”部分</live-example>的代码复制到`app.component.ts`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Make a few minor but necessary changes:",
"translation": "做一些微小但必要的修改:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Delete the `selector` (routed components don't need them).",
"translation": "删除`selector`(路由组件不需要它们)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Delete the `<h1>`.",
"translation": "删除`<h1>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Relabel the `<h2>` to `<h2>HEROES</h2>`.",
"translation": "给`<h2>`加文字,改成`<h2>HEROES</h2>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Delete the `<hero-detail>` at the bottom of the template.",
"translation": "删除模板底部的`<hero-detail>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Rename the `AppComponent` class to `HeroListComponent`.",
"translation": "把`AppComponent`类改名为`HeroListComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "When you're done, you'll have these *hero management* files:",
"translation": "安排完这些,我们就有了四个*英雄管理*特性区的文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### *Hero* feature routing requirements",
"translation": "### *英雄*特性区的路由需求",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### *Hero* feature route configuration",
"translation": "### *英雄*特性区的路由配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Add the routing module to the _HeroesModule_",
"translation": "### 把路由模块添加到`HeroesModule`中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Add the `HeroRoutingModule` to the `HeroModule`\njust as you added `AppRoutingModule` to the `AppModule`.",
"translation": "我们在`Heroes`模块中从`heroes-routing.module.ts`中导入`HeroRoutingModule`,并注册其路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Remove duplicate hero routes",
"translation": "### 移除重复的“英雄管理”路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Import hero module into AppModule",
"translation": "### 把“英雄管理”模块导入到AppModule",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "After these steps, the `AppModule` should look like this:",
"translation": "经过这些步骤,`AppModule`变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Module import order matters",
"translation": "### 导入模块的顺序很重要",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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 &mdash; which matches _every_ URL &mdash;\nwill intercept the attempt to navigate to a hero route.",
"translation": "每个路由模块都会根据*导入的顺序*把自己的路由配置追加进去。\n如果我们先列出了`AppRoutingModule`,那么通配符路由就会被注册在“英雄管理”路由*之前*。\n通配符路由它匹配*任意*URL将会拦截住每一个到“英雄管理”路由的导航因此事实上屏蔽了所有“英雄管理”路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Route definition with a parameter",
"translation": "### 带参数的路由定义",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Setting the route parameters in the list view",
"translation": "### 在列表视图中设置路由参数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### _Activated Route_ in action",
"translation": "#### _Activated Route_ 实战",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Import the `Router`, `ActivatedRoute`, and `ParamMap` tokens from the router package.",
"translation": "我们要从路由器(`router`)包中导入`Router`、`ActivatedRoute`和`Params`类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Import the `switchMap` operator because you need it later to process the `Observable` route parameters.",
"translation": "这里导入`switchMap`操作符是因为我们稍后将会处理路由参数的可观察对象`Observable`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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": "由于参数是作为`Observable`提供的,所以我们得用`switchMap`操作符来根据名字取得`id`参数,并告诉`HeroService`来获取带有那个`id`的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "#### _ParamMap_ API",
"translation": "#### _ParamMap_ 参数 API",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "<table>\n <tr>\n <th>\n Member",
"translation": "成员\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "<th>\n Description",
"translation": "描述\n </th>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Returns `true` if the parameter name is in the map of parameters.",
"translation": "如果参数名位于参数列表中,就返回 `true` 。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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`。如果参数值实际上是一个数组,就返回它的*第一个*元素。\n </td>\n </tr>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Returns a `string array` of all parameter names in the map.",
"translation": "返回这个map中的所有参数名组成的字符串数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### Observable <i>paramMap</i> and component reuse",
"translation": "#### <i>参数</i>的可观察对象Observable与组件复用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Feel free to unsubscribe anyway. It is harmless and never a bad practice.",
"translation": "不过,我们仍然可以随意取消订阅,这不会造成任何损害,而且也不是一项坏的实践。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### _Snapshot_: the _no-observable_ alternative",
"translation": "#### *Snapshot*快照当不需要Observable时的替代品",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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如果有可能连续多次导航到此组件那么就该用`params`可观察对象的方式。\n我们在这里选择使用`params`可观察对象策略,以防万一。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Navigating back to the list component",
"translation": "### 导航回列表组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "{@a optional-route-parameters}",
"translation": "### Route Parameters: Required or optional?\n### 路由参数:必须还是可选?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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`返回时在URL中带上英雄Magneta的`id`,不就可以了吗?接下来我们就尝试实现这个场景。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Optional information takes other forms. Search criteria are often loosely structured, e.g., `name='wind*'`.\nMultiple values are common&mdash;`after='12/31/2015' & before='1/1/2017'`&mdash;in no\nparticular order&mdash;`before='1/1/2017' & after='12/31/2015'`&mdash; in a\nvariety of formats&mdash;`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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Heroes list: optionally selecting a hero",
"translation": "### 英雄列表:选定一个英雄(也可不选)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The application still works. Clicking \"back\" returns to the hero list view.",
"translation": "该应用仍然能工作。点击“back”按钮返回英雄列表视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Look at the browser address bar.",
"translation": "注意浏览器的地址栏。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "It should look something like this, depending on where you run it:",
"translation": "它应该是这样的,不过也取决于你在哪里运行它:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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 &mdash; something you may not have seen before.",
"translation": "可选的路由参数没有使用“?”和“&”符号分隔因为它们将用在URL查询字符串中。\n它们是**用“;”分隔的**。\n这是*矩阵URL*标记法 —— 我们以前可能从未见过。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Route parameters in the *ActivatedRoute* service",
"translation": "### *ActivatedRoute*服务中的路由参数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The list of heroes is unchanged. No hero row is highlighted.",
"translation": "英雄列表仍没有改变,没有哪个英雄列被加亮显示。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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`中。我们把该服务注入到了`HeroDetailComponent`的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "First you extend the router import statement to include the `ActivatedRoute` service symbol:",
"translation": "首先,我们扩展该路由的导入语句,以包含进`ActivatedRoute`服务的类;",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Import the `switchMap` operator to perform an operation on the `Observable` of route parameter map.",
"translation": "我们将导入`switchMap`操作符,在路由参数的`Observable`对象上执行操作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Then you inject the `ActivatedRoute` in the `HeroListComponent` constructor.",
"translation": "接着,我们注入`ActivatedRoute`到`HeroListComponent`的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The optional `foo` route parameter is harmless and continues to be ignored.",
"translation": "这儿可选的`foo`路由参数人畜无害,并继续被忽略。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Adding animations to the routed component",
"translation": "### 为路由组件添加动画",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The heroes feature module is almost complete, but what is a feature without some smooth transitions?",
"translation": "这个“英雄”特性模块就要完成了,但这个特性还没有平滑的转场效果。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "This section shows you how to add some [animations](guide/animations)\nto the `HeroDetailComponent`.",
"translation": "在这一节,我们将为*英雄详情*组件添加一些[动画](guide/animations)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "First import `BrowserAnimationsModule`:",
"translation": "首先导入`BrowserAnimationsModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "This file does the following:",
"translation": "该文件做了如下工作:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Imports the animation symbols that build the animation triggers, control state, and manage transitions between states.",
"translation": "导入动画符号以构建动画触发器、控制状态并管理状态之间的过渡。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* Specifies the _wildcard state_ , `*`, that matches any animation state that the route component is in.",
"translation": "指定了一个*通配符状态* —— `*`,它匹配该路由组件存在时的任何动画状态。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Add an `animations` array to the `@Component` metadata's that contains the `slideInDownAnimation`.",
"translation": "把一个包含`slideInDownAnimation`的`animations`数组添加到`@Component`的元数据中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The other two `@HostBinding` properties style the display and position of the component.",
"translation": "另外两个`@HostBinding`属性指定组件的外观和位置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Milestone 3 wrap up",
"translation": "### 里程碑#3的总结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You've learned how to do the following:",
"translation": "我们学到了如何:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Organize the app into *feature areas*.",
"translation": "把应用组织成*特性区*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Navigate imperatively from one component to another.",
"translation": "命令式的从一个组件导航到另一个",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Pass information along in route parameters and subscribe to them in the component.",
"translation": "通过路由参数传递信息,并在组件中订阅它们",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Import the feature area NgModule into the `AppModule`.",
"translation": "把这个特性分区模块导入根模块`AppModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Apply animations to the route component.",
"translation": "把动画应用到路由组件上",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "After these changes, the folder structure looks like this:",
"translation": "做完这些修改之后,目录结构是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Here are the relevant files for this version of the sample application.",
"translation": "这里是当前版本的范例程序相关文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "## Milestone 4: Crisis center feature",
"translation": "## 里程碑#4危机中心",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "It's time to add real features to the app's current placeholder crisis center.",
"translation": "是时候往该应用的危机中心(现在是占位符)中添加一些真实的特性了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Begin by imitating the heroes feature:",
"translation": "我们先从模仿“英雄管理”中的特性开始:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Delete the placeholder crisis center file.",
"translation": "删除危机中心的占位文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Create an `app/crisis-center` folder.",
"translation": "创建`app/crisis-center`文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Copy the files from `app/heroes` into the new crisis center folder.",
"translation": "把`app/heroes`中的文件复制到新的危机中心文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "You'll turn the `CrisisService` into a purveyor of mock crises instead of mock heroes:",
"translation": "我们将会把`CrisisService`转换成模拟的危机列表,而不再是模拟的英雄列表:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The resulting crisis center is a foundation for introducing a new concept&mdash;**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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### A crisis center with child routes",
"translation": "### 带有子路由的危机中心",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "This section shows you how to organize the crisis center\nto conform to the following recommended pattern for Angular applications:",
"translation": "本节会展示如何组织危机中心来满足Angular应用所推荐的模式* Each feature area resides in its own folder. 把每个特性放在自己的目录中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Each feature has its own Angular feature module.",
"translation": "每个特性都有自己的Angular特性模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Each area has its own area root component.",
"translation": "每个特性区都有自己的根组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Each area root component has its own router outlet and child routes.",
"translation": "每个特性区的根组件中都有自己的路由出口及其子路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Feature area routes rarely (if ever) cross with routes of other features.",
"translation": "特性区的路由很少(或完全不)与其它特性区的路由交叉。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "If your app had many feature areas, the app component trees might look like this:",
"translation": "如果我们有更多特性区,它们的组件树是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Child routing component",
"translation": "### 子路由组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The `CrisisCenterComponent` has the following in common with the `AppComponent`:",
"translation": "`CrisisCenterComponent`和`AppComponent`有下列共同点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Child route configuration",
"translation": "### 子路由配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "These two routes navigate to the crisis center child components,\n`CrisisCenterHomeComponent` and `CrisisDetailComponent`, respectively.",
"translation": "这两个路由导航到了*危机中心*的两个子组件:`CrisisCenterHomeComponent`和`CrisisDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "There are *important differences* in the way the router treats these _child routes_.",
"translation": "对这些路由的处理中有一些*重要的不同*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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.",
"translation": "`Crisis Detail`路由是`Crisis List`的子路由。由于路由器默认会[复用组件](guide/router#reuse),因此当我们选择了另一个危机时,`CrisisDetailComponent`会被复用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "In contrast, back in the `Hero Detail` route, the component was recreated each time you selected a different hero.",
"translation": "作为对比,回到`Hero Detail`路由时,每当我们选择了不同的英雄时,该组件都会被重新创建。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The absolute URL for the latter example, including the `localhost` origin, is",
"translation": "本例子中包含站点部分的绝对URL就是",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Here's the complete `crisis-center-routing.module.ts` file with its imports.",
"translation": "这里是完整的`crisis-center.routing.ts`及其导入语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Import crisis center module into the *AppModule* routes",
"translation": "### 把危机中心模块导入到`AppModule`的路由中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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`中移除了危机中心的初始路由。我们的路由现在是由`HeroesModule`和`CrisisCenter`特性模块提供的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The `app-routing.module.ts` file retains the top-level application routes such as the default and wildcard routes.",
"translation": "我们将保持`app.routing.ts`文件中只有通用路由,本章稍后会讲解它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Relative navigation",
"translation": "### 相对导航",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The router matches such _absolute_ paths to routes starting from the top of the route configuration.",
"translation": "路由器会从路由配置的顶层来匹配像这样的*绝对路径*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Here's an example:",
"translation": "例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The router supports directory-like syntax in a _link parameters list_ to help guide route name lookup:",
"translation": "在*链接参数数组*中,路由器支持“目录式”语法来指导我们如何查询路由名:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "`./` or `no leading slash` is relative to the current level.",
"translation": "`./`或`无前导斜线`形式是相对于当前级别的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "`../` to go up one level in the route path.",
"translation": "`../`会回到当前路由路径的上一级。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "**Always** specify the complete _absolute_ path when calling router's `navigateByUrl` method.",
"translation": "当调用路由器的`navigateByUrl`时,**总是**要指定完整的*绝对路径*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Navigate to crisis list with a relative URL",
"translation": "把*危机列表*的`onSelect`方法改成使用相对导航,以便我们不用每次都从路由配置的顶层开始。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You've already injected the `ActivatedRoute` that you need to compose the relative navigation path.",
"translation": "我们已经注入过了`ActivatedRoute`,我们需要它来和相对导航路径组合在一起。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Displaying multiple routes in named outlets",
"translation": "### 用命名出口outlet显示多重路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Add an outlet named \"popup\" in the `AppComponent`, directly below the unnamed outlet.",
"translation": "在`AppComponent`中添加一个名叫“popup”的出口就在无名出口的下方。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "#### Secondary routes",
"translation": "#### 第二路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Named outlets are the targets of _secondary routes_.",
"translation": "命名出口是*第二路由*的目标。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* They are displayed in named outlets.",
"translation": "它们显示在命名出口中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Here's the component and its template:",
"translation": "下面是该组件及其模板:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "#### Add a secondary route",
"translation": "#### 添加第二路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Open the `AppRoutingModule` and add a new `compose` route to the `appRoutes`.",
"translation": "打开`AppRoutingModule`,并把一个新的`compose`路由添加到`appRoutes`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "#### Secondary route navigation: merging routes during navigation",
"translation": "#### 第二路由导航:在导航期间合并路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The interesting part of the URL follows the `...`:",
"translation": "这个URL中有意思的部分是`...`后面的这些:* The `crisis-center` is the primary navigation. `crisis-center`是主导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Parentheses surround the secondary route.",
"translation": "圆括号包裹的部分是第二路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Click the _Heroes_ link and look at the URL again.",
"translation": "点击*Heroes*链接并再次查看URL",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The primary navigation part has changed; the secondary route is the same.",
"translation": "主导航的部分变化了,而第二路由没有变。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Experiment with these possibilities at your leisure.",
"translation": "有空的时候你可以自行试验这些可能性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### Clearing secondary routes",
"translation": "#### 清除第二路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "## Milestone 5: Route guards",
"translation": "## 里程碑5路由守卫",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* Perhaps the user is not authorized to navigate to the target component.",
"translation": "该用户可能无权导航到目标组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Maybe the user must login (*authenticate*) first.",
"translation": "可能用户得先登录(认证)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Maybe you should fetch some data before you display the target component.",
"translation": "在显示目标组件前,我们可能得先获取某些数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* You might want to save pending changes before leaving a component.",
"translation": "在离开组件前,我们可能要先保存修改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* You might ask the user if it's OK to discard pending changes rather than save them.",
"translation": "我们可能要询问用户:你是否要放弃本次更改,而不用保存它们?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You can add _guards_ to the route configuration to handle these scenarios.",
"translation": "我们可以往路由配置中添加***守卫***,来处理这些场景。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "A guard's return value controls the router's behavior:",
"translation": "守卫返回一个值,以控制路由器的行为:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* If it returns `true`, the navigation process continues.",
"translation": "如果它返回`true`,导航过程会继续",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* If it returns `false`, the navigation process stops and the user stays put.",
"translation": "如果它返回`false`,导航过程会终止,且用户会留在原地。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation.",
"translation": "守卫还可以告诉路由器导航到别处,这样也取消当前的导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* [`CanActivate`](api/router/CanActivate) to mediate navigation *to* a route.",
"translation": "用[`CanActivate`](api/router/CanActivate)来处理导航*到*某路由的情况。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* [`CanActivateChild`](api/router/CanActivateChild) to mediate navigation *to* a child route.",
"translation": "用[`CanActivateChild`](api/router/CanActivateChild)来处理导航*到*某子路由的情况。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* [`CanDeactivate`](api/router/CanDeactivate) to mediate navigation *away* from the current route.",
"translation": "用[`CanDeactivate`](api/router/CanDeactivate)来处理从当前路由*离开*的情况.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* [`Resolve`](api/router/Resolve) to perform route data retrieval *before* route activation.",
"translation": "用[`Resolve`](api/router/Resolve)在路由激活*之前*获取路由数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* [`CanLoad`](api/router/CanLoad) to mediate navigation *to* a feature module loaded _asynchronously_.",
"translation": "用[`CanLoad`](api/router/CanLoad)来处理*异步*导航到某特性模块的情况。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "There are several examples over the next few sections.",
"translation": "我们会在接下来的小节中看到一些例子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### _CanActivate_: requiring authentication",
"translation": "### *CanActivate*: 要求认证",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The `CanActivate` guard is the tool to manage these navigation business rules.",
"translation": "`CanActivate`守卫是一个管理这些导航类业务规则的工具。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### Add an admin feature module",
"translation": "#### 添加一个“管理”特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Create an `admin` folder with a feature module file, a routing configuration file, and supporting components.",
"translation": "创建一个`admin`目录,它带有一个特性模块文件、一个路由配置文件和一些支持性组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The admin feature file structure looks like this:",
"translation": "管理特性区的文件是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The initial admin routing configuration:",
"translation": "我们的初始管理路由配置如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Component-less route: grouping routes without a component",
"translation": "### 无组件路由: 不借助组件对路由进行分组",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Add an \"Admin\" link to the `AppComponent` shell so that users can get to this feature.",
"translation": "然后我们往壳组件`AppComponent`中添加一个链接,让用户能点击它,以访问该特性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### Guard the admin feature",
"translation": "#### 守护“管理特性”区",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "This is a general purpose guard&mdash;you can imagine other features\nthat require authenticated users&mdash;so you create an\n`auth-guard.service.ts` in the application root folder.",
"translation": "这是一种具有通用性的守护目标(通常会有其它特性需要登录用户才能访问),所以我们在应用的根目录下创建一个`auth-guard.ts`文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The admin feature is now protected by the guard, albeit protected poorly.",
"translation": "我们的管理特性区现在受此守卫保护了,不过这样的保护还不够。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### Teach *AuthGuard* to authenticate",
"translation": "#### 教*AuthGuard*进行认证",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Make the `AuthGuard` at least pretend to authenticate.",
"translation": "我们先让`AuthGuard`至少能“假装”进行认证。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Revise the `AuthGuard` to call it.",
"translation": "我们这就修改`AuthGuard`来调用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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&mdash;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/content-1/guide/router.md"
},
{
"original": "#### Add the *LoginComponent*",
"translation": "#### 添加*LoginComponent*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You need a `LoginComponent` for the user to log in to the app. After logging in, you'll redirect\n to the stored URL if available, or use the default URL.\n There 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/content-1/guide/router.md"
},
{
"original": "Register a `/login` route in the `login-routing.module.ts` and add the necessary providers to the `providers`\n array. In `app.module.ts`, import the `LoginComponent` and add it to the `AppModule` `declarations`.\n Import 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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### _CanActivateChild_: guarding child routes",
"translation": "### `CanAcitvateChild`:保护子路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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`守卫和`CanAcitvate`守卫很像。\n它们的区别在于`CanActivateChild`会在*任何子路由*被激活之前运行。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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": "接下来,实现`CanAcitvateChild`方法,它所接收的参数与`CanAcitvate`方法一样:一个`ActivatedRouteSnapshot`和一个`RouterStateSnapshot`。\n`CanAcitvateChild`方法可以返回`Observable<boolean>`或`Promise<boolean>`来支持异步检查,或`boolean`来支持同步检查。\n这里返回的是`boolean`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### _CanDeactivate_: handling unsaved changes",
"translation": "### *CanDeactivate*:处理未保存的更改",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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": "我们应该暂停,并让用户决定该怎么做。如果用户选择了取消,我们就留下来,并允许更多改动。如果用户选择了确认,那就进行保存。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "You can't block while waiting for the server&mdash;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/content-1/guide/router.md"
},
{
"original": "You need the `CanDeactivate` guard.",
"translation": "我们需要`CanDeactivate`守卫。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Cancel and save",
"translation": "### 取消与保存",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Both buttons navigate back to the crisis list after save or cancel.",
"translation": "这两个按钮都会在保存或取消之后导航回危机列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "You could wait for the user's answer with synchronous, blocking code.\nThe app will be more responsive&mdash;and can do other work&mdash;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/content-1/guide/router.md"
},
{
"original": "The `DialogService`, provided in the `AppModule` for app-wide use, does the asking.",
"translation": "`DialogService`(为了在应用级使用,已经注入到了`AppModule`)就可以做到这些。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Create a _guard_ that checks for the presence of a `canDeactivate()` method in a component&mdash;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`函数的工作现场,在这里,它就是`CrisisDetailComponent`。我们并不需要知道`CrisisDetailComponent`确认退出激活状态的详情。这让我们的守卫可以被复用,这是一次轻而易举的胜利。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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`守卫。在需要访问外部信息时,`canDeactivate()`方法为提供了组件、`ActivatedRoute`和`RouterStateSnapshot`的当前实例。如果只想为这个组件使用该守卫,并且需要使用该组件属性、或者需要路由器确认是否允许从该组件导航出去时,这个守卫就非常有用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Looking back at the `CrisisDetailComponent`, it implements the confirmation workflow for unsaved changes.",
"translation": "看看`CrisisDetailComponent`组件,我们已经实现了对未保存的更改进行确认的工作流。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Add the `Guard` to the crisis detail route in `crisis-center-routing.module.ts` using the `canDeactivate` array property.",
"translation": "我们往`crisis-center.routing.ts`的危机详情路由中用`canDeactivate`数组添加一个`Guard`(守卫)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Now you have given the user a safeguard against unsaved changes.",
"translation": "现在,我们已经给了用户一个能保护未保存更改的安全守卫。\n{@a Resolve}",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### _Resolve_: pre-fetching component data",
"translation": "### _Resolve_: 预先获取组件数据",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "In summary, you want to delay rendering the routed component until all necessary data have been fetched.",
"translation": "总之,你希望的是只有当所有必要数据都已经拿到之后,才渲染这个路由组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You need a *resolver*.",
"translation": "我们需要`Resolve`守卫。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Fetch data before navigating",
"translation": "### 导航前预先加载路由信息",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Be explicit. Implement the `Resolve` interface with a type of `Crisis`.",
"translation": "为了更明确一点,可以实现一个带有`Crisis`类型的`Resolve`接口。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Remember to add the `CrisisDetailResolver` service to the `CrisisCenterRoutingModule`'s `providers` array.",
"translation": "别忘了把`CrisisDetailResolver`服务添加到`CrisisCenterRoutingModule`的`providers`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "**Two critical points**",
"translation": "**两个关键点**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The relevant *Crisis Center* code for this milestone follows.",
"translation": "本里程碑中与*危机中心*有关的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Query parameters and fragments",
"translation": "### 查询参数及片段",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Add an `anchor` element so you can jump to a certain point on the page.",
"translation": "再添加一个锚点(`A`)元素,来让你能跳转到页面中的正确位置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Add the `NavigationExtras` object to the `router.navigate` method that navigates you to the `/login` route.",
"translation": "我们还将为`router.nativate`方法传入一个`NavigationExtras`对象,用来导航到`/login`路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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 在更新过的*英雄管理*组件中,我们将直接把`Observable`传给模板,借助`AsyncPipe`在组件被销毁时自动_取消_对`Observable`的订阅。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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*按钮,它会带着我们提供的“查询参数”和“片段”跳转到登录页。\n 点击登录按钮,我们就会被带到`Crisis Admin`页,仍然带着上一步提供的“查询参数”和“片段”。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "## Milestone 6: Asynchronous routing",
"translation": "## 里程碑6异步路由",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "How do you combat this problem? With asynchronous routing, which loads feature modules _lazily_, on request.\nLazy loading has multiple benefits.",
"translation": "如何才能解决这个问题呢?我们引进了异步路由到应用程序中,并获得在请求时才**惰性**加载特性模块的能力。这样给我们带来了下列好处:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* You can load feature areas only when requested by the user.",
"translation": "我们可以只在用户请求时才加载某些特性区。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* You can speed up load time for users that only visit certain areas of the application.",
"translation": "对于那些只访问应用程序某些区域的用户,这样能加快加载速度。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* You can continue expanding lazy loaded feature areas without increasing the size of the initial load bundle.",
"translation": "我们可以持续扩充惰性加载特性区的功能,而不用增加初始加载的包体积。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You're already made part way there.\nBy organizing the application into modules&mdash;`AppModule`,\n`HeroesModule`, `AdminModule` and `CrisisCenterModule`&mdash;you\nhave natural candidates for lazy loading.",
"translation": "我们已经完成了一部分。通过把应用组织成一些模块:`AppModule`、`HeroesModule`、`AdminModule`和`CrisisCenterModule`\n我们已经有了可用于实现惰性加载的候选者。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Lazy Loading route configuration",
"translation": "### 惰性加载路由配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Open the `AppRoutingModule` and add a new `admin` route to its `appRoutes` array.",
"translation": "打开`AppRoutingModule`,并把一个新的`admin`路由添加到它的`appRoutes`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### _CanLoad_ Guard: guarding unauthorized loading of feature modules",
"translation": "### `CanLoad`守卫:保护对特性模块的未授权加载",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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": "我们已经使用`CanAcitvate`保护`AdminModule`了,它会阻止未授权用户访问管理特性区。如果用户未登录,它就会跳转到登录页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Preloading: background loading of feature areas",
"translation": "### 预加载:特性区的后台加载",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You've learned how to load modules on-demand.\nYou can also load modules asynchronously with _preloading_.",
"translation": "我们已经学会了如何按需加载模块,接下来再看看如何使用*预加载*技术异步加载模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "That's _preloading_.",
"translation": "这就是*预加载*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### How preloading works",
"translation": "#### 预加载的工作原理",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The `Router` offers two preloading strategies out of the box:",
"translation": "`Router`内置了两种预加载策略:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* No preloading at all which is the default. Lazy loaded feature areas are still loaded on demand.",
"translation": "完全不预加载,这是默认值。惰性加载的特性区仍然会按需加载。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Preloading of all lazy loaded feature areas.",
"translation": "预加载所有惰性加载的特性区。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "#### Lazy load the _crisis center_",
"translation": "#### 惰性加载*危机中心*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "1. Change the `crisis-center` path in the `CrisisCenterRoutingModule` to an empty string.",
"translation": "把`CrisisCenterRoutingModule`中的路径从`crisis-center`改为空字符串。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. Add a `crisis-center` route to the `AppRoutingModule`.",
"translation": "往`AppRoutingModule`中添加一个`crisis-center`路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. Set the `loadChildren` string to load the `CrisisCenterModule`.",
"translation": "设置`loadChildren`字符串来加载`CrisisCenterModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. Remove all mention of the `CrisisCenterModule` from `app.module.ts`.",
"translation": "从`app.module.ts`中移除所有对`CrisisCenterModule`的引用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "Here are the updated modules _before enabling preload_:",
"translation": "下面是打开预加载之前的模块修改版:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Surprisingly, the `AdminModule` does _not_ preload. Something is blocking it.",
"translation": "意外的是,`AdminModule`*没有*预加载,有什么东西阻塞了它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "#### CanLoad blocks preload",
"translation": "#### CanLoad会阻塞预加载",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Custom Preloading Strategy",
"translation": "### 自定义预加载策略",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "You can control what and how the router preloads with a custom preloading strategy.",
"translation": "使用自定义预加载策略,我们可以控制路由器预加载哪些路由以及如何加载。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "`SelectivePreloadingStrategy` implements the `PreloadingStrategy`, which has one method, `preload`.",
"translation": "`SelectivePreloadingStrategy`实现了`PreloadingStrategy`,它只有一个方法`preload`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "The router calls the `preload` method with two arguments:",
"translation": "路由器会用两个参数调用调用`preload`方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. The route to consider.",
"translation": "要加载的路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. A loader function that can load the routed module asynchronously.",
"translation": "一个加载器loader函数它能异步加载带路由的模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Shortly, you'll extend the `AdminDashboardComponent` to inject this service and display its `preloadedModules` array.",
"translation": "很快,我们就会扩展`AdminDashboardComponent`来注入该服务,并且显示它的`preloadedModules`数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "But first, make a few changes to the `AppRoutingModule`.",
"translation": "但是首先,要对`AppRoutingModule`做少量修改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Now edit the `AdminDashboardComponent` to display the log of preloaded routes.",
"translation": "现在,编辑`AdminDashboardComponent`以显示这些预加载路由的日志。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. Import the `SelectivePreloadingStrategy` (it's a service).",
"translation": "导入`SelectivePreloadingStrategy`(它是一个服务)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. Inject it into the dashboard's constructor.",
"translation": "把它注入到仪表盘的构造函数中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. Update the template to display the strategy service's `preloadedModules` array.",
"translation": "修改模板来显示这个策略服务的`preloadedModules`数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "When you're done it looks like this.",
"translation": "当完成时,代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "## Migrating URLs with Redirects",
"translation": "## 使用重定向迁移 URL",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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": "我们已经设置好了路由,并且用命令式和声明式的方式导航到了很多不同的路由。但是,任何应用的需求都会随着时间而改变。我们把链接`/heroes`和`hero/:id`指向了`HeroListComponent`和`HeroDetailComponent`组件。如果有这样一个需求,要把链接`heroes`变成`superheroes`我们希望以前的URL仍然能正常导航。但我们也不想在应用中找到并修改每一个链接这时候重定向就可以省去这些琐碎的重构工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Changing /heroes to /superheroes",
"translation": "### 把`/heroes`修改为`/superheros`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* When using relative redirects, the `Router` use the query params and the fragment from the source URL.",
"translation": "当使用相对地址重定向时,路由器将会使用源地址(跳转前的地址)中的查询参数和片段。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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`。这样*不行*,从设计上就不行。因为路由器在每一层的路由配置中只会处理一次重定向。这样可以防止出现无限循环的重定向。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "## Inspect the router's configuration",
"translation": "## 审查路由器配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "## Wrap up and final app",
"translation": "## 总结与最终的应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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 Plunker\"></live-example>\nwhere you can download the final source code.",
"translation": "本章中涉及到了很多背景知识,而且本应用程序也太大了,所以没法在这里显示。请访问<live-example title=\"Router Sample in Plunker\"></live-example>,在那里你可以下载最终的源码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "## Appendices",
"translation": "## 附录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The appendix material isn't essential. Continued reading is for the curious.",
"translation": "该附件中的内容不是必须的,感兴趣的人才需要阅读它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "### Appendix: link parameters array",
"translation": "### 附录:链接参数数组",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "A link parameters array holds the following ingredients for router navigation:",
"translation": "链接参数数组保存路由导航时所需的成分:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The *path* of the route to the destination component.",
"translation": "指向目标组件的那个路由的*路径path*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* Required and optional route parameters that go into the route URL.",
"translation": "必备路由参数和可选路由参数它们将进入该路由的URL",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You can bind the `RouterLink` directive to such an array like this:",
"translation": "我们可以把`RouterLink`指令绑定到一个数组,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You've written a two element array when specifying a route parameter like this:",
"translation": "在指定路由参数时,我们写过一个双元素的数组,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "You can provide optional route parameters in an object like this:",
"translation": "我们可以在对象中提供可选的路由参数,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Parse it out.",
"translation": "分解一下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The first item in the array identifies the parent route (`/crisis-center`).",
"translation": "数组中的第一个条目标记出了父路由(`/crisis-center`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* There are no parameters for this parent route so you're done with it.",
"translation": "这个父路由没有参数,因此这步已经完成了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* There is no default for the child route so you need to pick one.",
"translation": "没有默认的子路由,因此我们得选取一个。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* Voilà! `['/crisis-center']`.",
"translation": "哇!`['/crisis-center']`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* The first item in the array identifies the parent route (`/crisis-center`).",
"translation": "数组中的第一个条目用来标记出父路由('/crisis-center')。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* There are no parameters for this parent route so you're done with it.",
"translation": "这个父路由没有参数,因此这步已经完成了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The second item identifies the child route details about a particular crisis (`/:id`).",
"translation": "数组中的第二个条目('/:id')用来标记出到指定危机的详情页的子路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "* The details child route requires an `id` route parameter.",
"translation": "详细的子路由需要一个`id`路由参数。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "* The resulting path is `/crisis-center/1`.",
"translation": "最终生成的路径是`/crisis-center/1`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "If you wanted to, you could redefine the `AppComponent` template with *Crisis Center* routes exclusively:",
"translation": "只要想,我们也可以用*危机中心*路由单独重定义`AppComponent`的模板:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "### Appendix: *LocationStrategy* and browser URL styles",
"translation": "### 附录:*LocationStrategy*以及浏览器URL样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Here's the *Crisis Center* URL in this \"HTML5 pushState\" style:",
"translation": "下面是*危机中心*的URL在“HTML 5 pushState”风格下的样子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "The router supports both styles with two `LocationStrategy` providers:",
"translation": "路由器通过两种`LocationStrategy`提供商来支持所有这些风格:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. `PathLocationStrategy`&mdash;the default \"HTML5 pushState\" style.",
"translation": "`PathLocationStrategy` - 默认的策略支持“HTML 5 pushState”风格。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. `HashLocationStrategy`&mdash;the \"hash URL\" style.",
"translation": "`HashLocationStrategy` - 支持“hash URL”风格。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "#### Which strategy is best?",
"translation": "#### 哪种策略更好?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "#### HTML5 URLs and the *&lt;base href>*",
"translation": "#### HTML 5 URL与*&lt;base href>*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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\">&lt;base href&gt; element</a>\ntag in the `<head>` of the `index.html`.",
"translation": "配置该策略的首选方式是往`index.html`的`<head>`中添加一个[&lt;base href> element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)标签。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "Those developers may still use HTML5 URLs by taking two remedial steps:",
"translation": "它们仍然可以使用HTML 5格式的URL但要采取两个步骤进行补救",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"original": "1. Provide the router with an appropriate [APP_BASE_HREF][] value.",
"translation": "用适当的[APP_BASE_HREF][]值提供provide路由器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "#### *HashLocationStrategy*",
"translation": "#### *HashLocationStrategy* 策略",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/router.md"
},
{
"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/content-1/guide/router.md"
},
{
"original": "# Security",
"translation": "# 安全",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "You can run the <live-example></live-example> in Plunker and download the code from there.",
"translation": "运行<live-example></live-example>来试用本页的代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"original": "<h2 id='report-issues'>\nReporting vulnerabilities\n</h2",
"translation": "举报漏洞",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "Best practices",
"translation": "最佳实践",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "## Preventing cross-site scripting (XSS)",
"translation": "## 防范跨站脚本(XSS)攻击",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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&mdash;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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "### Sanitization and security contexts",
"translation": "### 无害化处理与安全环境",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "Angular defines the following security contexts:",
"translation": "Angular定义了四个安全环境 - HTML样式URL和资源URL",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "* **Style** is used when binding CSS into the `style` property.",
"translation": "**样式**值需要作为CSS绑定到`style`属性时使用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"original": "* **URL** is used for URL properties such as `<a href>`.",
"translation": "**URL**值需要被用作URL属性时使用比如`<a href>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "### Sanitization example",
"translation": "### 无害化示例",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "Interpolated content is always escaped&mdash;the HTML isn't interpreted and the browser displays\nangle brackets in the element's text content.",
"translation": "插值表达式的内容总会被编码 - 其中的HTML不会被解释所以浏览器会在元素的文本内容中显示尖括号。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "### Avoid direct use of the DOM APIs",
"translation": "### 避免直接使用DOM API",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "### Content security policy",
"translation": "### 内容安全策略",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "### Use the offline template compiler",
"translation": "### 使用离线模板编译器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "### Server-side XSS protection",
"translation": "### 服务器端XSS保护",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "Trusting safe values",
"translation": "信任安全值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "To mark a value as trusted, inject `DomSanitizer` and call one of the\nfollowing methods:",
"translation": "注入`DomSanitizer`服务,然后调用下面的方法之一,你就可以把一个值标记为可信任的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "HTTP-level vulnerabilities",
"translation": "HTTP级别的漏洞",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "Cross-site request forgery",
"translation": "跨站请求伪造XSRF",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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。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`.如果`example-bank.com`服务器缺乏XSRF保护就无法辨识请求是从应用程序发来的合法请求还是从`evil.com`来的假请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "Cross-site script inclusion (XSSI)",
"translation": "跨站脚本包含(XSSI)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "Auditing Angular applications",
"translation": "审计Angular应用程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/security.md"
},
{
"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/content-1/guide/security.md"
},
{
"original": "# Set the Document Title",
"translation": "# 设置文档标题",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"original": "To see the browser title bar change in the live example,\n open it again in the Plunker editor by clicking the icon in the upper right,\n then pop out the preview window by clicking the blue 'X' button in the upper right corner.",
"translation": "要在在线例子中看到浏览器标题的变化请点击右上角的图标在Plunker编辑器中打开它然后点击预览窗口右上角的蓝色'X'按钮,弹出窗口。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"original": "## The problem with *&lt;title&gt;*",
"translation": "## *&lt;title&gt;*的问题",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"original": "## Use the `Title` service",
"translation": "## 使用 `Title` 服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"original": "* `getTitle() : string`&mdash;Gets the title of the current HTML document.",
"translation": "`getTitle(): string` —— 获取当前HTML文档的标题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"original": "* `setTitle( newTitle : string )`&mdash;Sets the title of the current HTML document.",
"translation": "`setTitle( newTitle: string)` —— 设置当前HTML文档的标题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"original": "Bind that method to three anchor tags and voilà!",
"translation": "我们把这个方法绑定到三个A标签瞧瞧",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"original": "Here's the complete solution:",
"translation": "这里是完整的方案(代码)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"original": "## Why provide the `Title` service in `bootstrap`",
"translation": "## 为什么要在*bootstrap*里面提供这个*Title*服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"original": "Generally you want to provide application-wide services in the root application component, `AppComponent`.",
"translation": "我们通常会推荐在应用程序的根组件`AppComponent`中提供应用程序级的服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"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/content-1/guide/set-document-title.md"
},
{
"original": "# Anatomy of the Setup Project",
"translation": "# 搭建项目环境",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Application files _inside the_ **`src/`** and **`e2e/`** folders matter most to developers.",
"translation": "对程序员来讲最重要的是在 *`src/`* 和 *`e2e/`* 文件夹*之内*的应用文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "File",
"translation": "文件\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Purpose",
"translation": "用途\n </th>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Angular application files go here.",
"translation": "你的 Angular 应用文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Try the <live-example name=\"setup\">sample application</live-example> \n and the <live-example name=\"setup\" plnkr=\"quickstart-specs\">unit test</live-example>\n as _live examples_.",
"translation": "在live example中试试<live-example name=\"setup\">范例程序</live-example>和<live-example name=\"setup\" plnkr=\"quickstart-specs\">单元测试</live-example>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Initialized with an e2e test for the \"Hello Angular\" sample.",
"translation": "初始化后有个“Hello Angular” 的例子的端对端测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "The _npm_ packages installed with the `npm install` command.",
"translation": "用 `npm install` 命令安装的 *npm* 包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Tooling configuration files and folders.",
"translation": "配置文件和文件夹的工具。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Ignore them until you have a compelling reason to do otherwise.",
"translation": "除非非常必要,否则可以忽略。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "The history of changes to the _QuickStart_ repository.",
"translation": "*快速上手*库的更新历史。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Delete or ignore.",
"translation": "删除或忽略。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "The application icon that appears in the browser tab.",
"translation": "出现在浏览器标签上的应用图标。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "The same `index.html` satisfies all documentation application samples.",
"translation": "同一个 `index.html`满足所有文档应用例子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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配置*\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "The open source MIT license to use this setup code in your application.",
"translation": "应用的搭建代码中用到的开源 MIT 许可证。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Identifies `npm `package dependencies for the project.",
"translation": "为项目指定`npm`依赖包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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>阅读更多关于它们的说明。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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) 测试器运行器的配置。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Instruction for using this git repository in your project.\n Worth reading before deleting.",
"translation": "项目中使用这个 git 库的说明。\n 在删除前值得阅读。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Global styles for the application. Initialized with an `<h1>` style for the QuickStart demo.",
"translation": "应用的全局样式。初始化后,有个为《快速上手》演示准备的`<h1>`样式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "Don't touch this file unless you are fully versed in SystemJS configuration.",
"translation": "除非你完全理解 SystemJS 的配置,不要修改它。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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/content-1/guide/setup-systemjs-anatomy.md"
},
{
"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)与本文档站作者喜爱的语法检查规则。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup-systemjs-anatomy.md"
},
{
"original": "# Setup for local development",
"translation": "# 搭建本地开发环境",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"original": "## Clone",
"translation": "## 克隆",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "Perform the _clone-to-launch_ steps with these terminal commands.",
"translation": "运行下列命令来执行*克隆并启动*步骤。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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-04为止它还不支持访问网络上的服务器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "## Download",
"translation": "## 下载\n<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.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"original": "## Delete _non-essential_ files (optional)",
"translation": "## 删除*非必需*文件(可选)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"original": "Do this only in the beginning to avoid accidentally deleting your own tests and git setup!",
"translation": "请只在开始时执行此删除操作以防你自己的测试和git文件被意外删除",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "Open a terminal window in the project folder and enter the following commands for your environment:",
"translation": "在项目目录下打开一个终端窗口,并根据你的操作系统执行以下命令:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "### OS/X (bash)",
"translation": "### OS/X (bash) 命令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "### Windows",
"translation": "### Windows 命令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "## What's in the QuickStart seed?",
"translation": "## 《快速上手》种子库里都有什么?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"original": "Focus on the following three TypeScript (`.ts`) files in the **`/src`** folder.",
"translation": "注意**`/src`**目录中以下三个 TypeScript (`.ts`) 文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"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除非明确指出否则教程中添加的 TypeScriptHTML和CSS文件都在`src/`目录下,\n大多数在`src/app`目录中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "The following are all in `src/`",
"translation": "`src/`目录文件详情如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "Purpose",
"translation": "用途",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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 不久,它将声明更多组件。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "Compiles the application with the [JIT compiler](guide/glossary#jit) and\n [bootstraps](guide/bootstrapping#main \"bootstrap the application\")\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 Plunker.\n You'll learn about alternative compiling and [deployment](guide/deployment) options later in the documentation.",
"translation": "使[即时 (JiT) 编译器](guide/glossary#jit)用编译应用并且在浏览器中[启动](guide/bootstrapping#main \"启动应用\")并运行应用。\n 对于大多数项目的开发,这都是合理的选择。而且它是在像 Plunker 这样的*在线编程*环境中运行例子的唯一选择。\n 你将在本文档中学习其他编译和开发选择。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "### Next Step",
"translation": "### 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"original": "## Appendix: node and npm",
"translation": "## 附录node 与 npm",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"original": "<a href=\"https://docs.npmjs.com/getting-started/installing-node\" target=\"_blank\" title=\"Installing Node.js and updating npm\">\n</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\">\n立刻安装它们</a>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"original": "## Appendix: Why develop locally",
"translation": "## 附录:为何在本地开发",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "<live-example title=\"QuickStart Seed in Plunker\">Live coding</live-example> in the browser is a great way to explore Angular.",
"translation": "在浏览器中<live-example title=\"QuickStart Seed in Plunker\">在线编程</live-example>是很好的探索 Angular 的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"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/content-1/guide/setup.md"
},
{
"original": "As much fun as this is ...",
"translation": "虽然有这么多的乐趣,但是...",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "* you can't ship your app in plunker",
"translation": "你不能在 plunker 里面发布你的应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "* you aren't always online when writing code",
"translation": "编程时你不可能总是在线",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "* transpiling TypeScript in the browser is slow",
"translation": "在浏览器中编译 TypeScript 很慢",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "* the type support, refactoring, and code completion only work in your local IDE",
"translation": "只有本地 IDE 有类型支持、代码重构和代码自动完成",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "Use the <live-example title=\"QuickStart Seed in Plunker\">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 Plunker\">在线编程</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/content-1/guide/setup.md"
},
{
"original": "For real development, we strongly recommend [developing locally](guide/setup#develop-locally).",
"translation": "对于现实项目开发,我们强烈推荐在[本地开发](guide/setup#develop-locally)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/setup.md"
},
{
"original": "# Structural Directives",
"translation": "# 结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Try the <live-example></live-example>.",
"translation": "试试<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "## What are structural directives?",
"translation": "## 什么是结构型指令?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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 descendents.",
"translation": "像其它指令一样,你可以把结构型指令应用到一个*宿主元素*上。\n然后它就可以对宿主元素及其子元素做点什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "No brackets. No parentheses. Just `*ngIf` set to a string.",
"translation": "没有方括号,没有圆括号,只是把`*ngIf`设置为一个字符串。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "You'll learn in this guide that the [asterisk (*) is a convenience notation](guide/structural-directives#asterisk)\nand the string isa [_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/content-1/guide/structural-directives.md"
},
{
"original": "Three of the common, built-in structural directives&mdash;[NgIf](guide/template-syntax#ngIf),\n[NgFor](guide/template-syntax#ngFor), and [NgSwitch...](guide/template-syntax#ngSwitch)&mdash;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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Directive spelling",
"translation": "指令的拼写形式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "There are two other kinds of Angular directives, described extensively elsewhere:\n(1)&nbsp;components and (2)&nbsp;attribute directives.",
"translation": "还有另外两种Angular指令在本开发指南的其它地方有讲解(1) 组件 (2) 属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## NgIf case study",
"translation": "## NgIf案例分析",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "### Why *remove* rather than *hide*?",
"translation": "### 为什么*移除*而不是*隐藏*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "A directive could hide the unwanted paragraph instead by setting its `display` style to `none`.",
"translation": "指令也可以通过把它的`display`风格设置为`none`而隐藏不需要的段落。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "While invisible, the element remains in the DOM.",
"translation": "当不可见时这个元素仍然留在DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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": "对于简单的段落,隐藏和移除之间的差异影响不大,但对于资源占用较多的组件是不一样的。当我们隐藏掉一个元素时,组件的行为还在继续 —— 它仍然附加在它所属的DOM元素上\n它也仍在监听事件。Angular会继续检查哪些能影响数据绑定的变更。\n组件原本要做的那些事情仍在继续。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "Although invisible, the component&mdash;and all of its descendant components&mdash;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/content-1/guide/structural-directives.md"
},
{
"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&mdash;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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## The asterisk (*) prefix",
"translation": "## 星号(*)前缀",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Here is `*ngIf` displaying the hero's name if `hero` exists.",
"translation": "这里的`*ngIf`会在`hero`存在时显示英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## Inside _*ngFor_",
"translation": "## `*ngFor`内幕",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Here's a full-featured application of `NgFor`, written both ways:",
"translation": "这里有一个`NgFor`的全特性应用,同时用了这三种写法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "### Microsyntax",
"translation": "### 微语法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "* The context property for `let-hero` wasn't specified.\nIt's 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`属性,`NgFor`会用当前迭代中的英雄初始化它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "### Template input variable",
"translation": "### 模板输入变量",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "### One structural directive per host element",
"translation": "### 每个宿主元素上只能有一个结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## Inside _NgSwitch_ directives",
"translation": "## `NgSwitch` 内幕",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Here's an example.",
"translation": "例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "*Design thought*: minimize initialization effort and consider caching state in a \ncompanion service.",
"translation": "*设计思路*:要最小化初始化的成本,并考虑把状态缓存在一个伴生的服务中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## Prefer the asterisk (*) syntax.",
"translation": "## 优先使用星号(`*`)语法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "The asterisk (*) syntax is more clear than the desugared form.\nUse [&lt;ng-container&gt;](guide/structural-directives#ng-container) when there's no single element\nto host the directive.",
"translation": "星号(`*`)语法比不带语法糖的形式更加清晰。\n如果找不到单一的元素来应用该指令可以使用[&lt;ng-container&gt;](guide/structural-directives#ng-container)作为该指令的容器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## The *&lt;ng-template&gt;*",
"translation": "## *&lt;ng-template&gt;*指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "The &lt;ng-template&gt; 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": "&lt;ng-template&gt;是一个 Angular 元素用来渲染HTML。\n它永远不会直接显示出来。\n事实上在渲染视图之前Angular 会把`<ng-template>`及其内容*替换为*一个注释。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Angular erases the middle \"Hip!\", leaving the cheer a bit less enthusiastic.",
"translation": "Angular 抹掉了中间的那个 \"Hip!\" ,让欢呼声显得不再那么热烈了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## Group sibling elements with &lt;ng-container&gt;",
"translation": "## 使用&lt;ng-container&gt;把一些兄弟元素归为一组",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Introducing another container element&mdash;typically a `<span>` or `<div>`&mdash;to\ngroup the elements under a single _root_ is usually harmless.\n_Usually_ ... but not _always_.",
"translation": "但引入另一个容器元素(通常是`<span>`或`<div>`)来把一些元素归到一个单一的*根元素*下,通常也会带来问题。注意,是\"通常\"而不是\"总会\"。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "The constructed paragraph renders strangely.",
"translation": "这样渲染出来的段落就会非常奇怪。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "The `p span` style, intended for use elsewhere, was inadvertently applied here.",
"translation": "本来为其它地方准备的`p span`样式,被意外的应用到了这里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "When you try this,",
"translation": "如果这样做:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "the drop down is empty.",
"translation": "下拉列表就是空的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "The browser won't display an `<option>` within a `<span>`.",
"translation": "浏览器不会显示`<span>`中的`<option>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "### &lt;ng-container&gt; to the rescue",
"translation": "### &lt;ng-container&gt; 的救赎",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Here's the conditional paragraph again, this time using `<ng-container>`.",
"translation": "下面是重新实现的条件化段落,这次我们使用`<ng-container>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "It renders properly.",
"translation": "这次就渲染对了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "Now conditionally exclude a _select_ `<option>` with `<ng-container>`.",
"translation": "我们再用`<ng-container>`来根据条件排除选择框中的某个`<option>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "The drop down works properly.",
"translation": "下拉框也工作正常。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## Write a structural directive",
"translation": "## 写一个结构型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Creating a directive is similar to creating a component.",
"translation": "创建指令很像创建组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "* Import the `Directive` decorator (instead of the `Component` decorator).",
"translation": "导入`Directive`装饰器(而不再是`Component`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "* Apply the decorator to the directive class.",
"translation": "给指令类添加装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Here's how you might begin:",
"translation": "这里是起点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "The directive's _selector_ is typically the directive's **attribute name** in square brackets, `[myUnless]`.\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": "指令的*选择器*通常是把指令的属性名括在方括号中,如`[myUnless]`。\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/content-1/guide/structural-directives.md"
},
{
"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 `my`.",
"translation": "该指令的*属性名*应该拼写成*小驼峰*形式,并且带有一个前缀。\n但是这个前缀不能用`ng`,因为它只属于 Angular 本身。\n请选择一些简短的适合你自己或公司的前缀。\n在这个例子中前缀是`my`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "### _TemplateRef_ and _ViewContainerRef_",
"translation": "### _TemplateRef_ 和 _ViewContainerRef_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "You inject both in the directive constructor as private variables of the class.",
"translation": "我们可以把它们都注入到指令的构造函数中,作为该类的私有属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "### The _myUnless_ property",
"translation": "### *myUnless* 属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "The directive consumer expects to bind a true/false condition to `[myUnless]`.\nThat means the directive needs a `myUnless` property, decorated with `@Input`",
"translation": "该指令的使用者会把一个true/false条件绑定到`[myUnless]`属性上。\n也就是说该指令需要一个带有`@Input`的`myUnless`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Angular sets the `myUnless` property whenever the value of the condition changes.\nBecause the `myUnless` property does work, it needs a setter.",
"translation": "一旦该值的条件发生了变化Angular 就会去设置 `myUnless` 属性这时候我们就需要为它定义一个设置器setter。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Nobody reads the `myUnless` property so it doesn't need a getter.",
"translation": "没有人会读取`myUnless`属性因此它不需要定义设置器getter。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "The completed directive code looks like this:",
"translation": "完整的指令代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "Add this directive to the `declarations` array of the AppModule.",
"translation": "把这个指令添加到AppModule的`declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "Then create some HTML to try it.",
"translation": "然后创建一些 HTML 来试用一下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "## Summary",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "Here is the source from the `src/app/` folder.",
"translation": "本章相关的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "You learned",
"translation": "我们学到了",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "* that structural directives manipulate HTML layout.",
"translation": "结构型指令可以操纵 HTML 的元素布局。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "* how that works for the `NgIf`, `NgFor` and `NgSwitch` built-in directives.",
"translation": "内置指令`NgIf`、`NgFor`和`NgSwitch`的工作原理。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"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/content-1/guide/structural-directives.md"
},
{
"original": "* to write a [custom structural directive](guide/structural-directives#unless), `UnlessDirective`.",
"translation": "写了一个[自定义结构型指令](guide/structural-directives#unless) —— `UnlessDirective`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/structural-directives.md"
},
{
"original": "# Style Guide",
"translation": "# 风格指南",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "## Style vocabulary",
"translation": "## 风格词汇",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Each guideline describes either a good or bad practice, and all have a consistent presentation.",
"translation": "每个指导原则都会描述好的或者坏的做法,所有指导原则风格一致。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "The wording of each guideline indicates how strong the recommendation is.",
"translation": "指导原则中使用的词汇表明推荐的程度。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Consider** guidelines should generally be followed.",
"translation": "**考虑**标志着通常应该遵循的指导原则。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "If you fully understand the meaning behind the guideline and have a good reason to deviate, then do so. Please strive to be consistent.",
"translation": "如果能完全理解指导原则背后的含义,并且很好的理由背离它,那就可以那么做。但是请保持一致。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Avoid** indicates something you should almost never do. Code examples to *avoid* have an unmistakeable red header.",
"translation": "**避免**标志着我们决不应该做的事。需要*避免*的代码范例会有明显的红色标题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** gives reasons for following the previous recommendations.",
"translation": "**为何?**会给出随后的建议的理由。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## File structure conventions",
"translation": "## 文件结构约定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "## Single responsibility",
"translation": "## 单一职责",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "### Rule of One",
"translation": "### 单一规则",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 01-01",
"translation": "#### 风格 01-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** define one thing, such as a service or component, per file.",
"translation": "**坚持**每个文件只定义一样东西(例如服务或组件)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** limiting files to 400 lines of code.",
"translation": "**考虑**把文件大小限制在 400 行代码以内。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "The key is to make the code more reusable, easier to read, and less mistake prone.",
"translation": "最关键的是,可以增强代码可重用性和阅读性,减少出错的可能性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "As the app grows, this rule becomes even more important.",
"translation": "随着应用程序的成长,本法则会变得越来越重要。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Small functions",
"translation": "### 小函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 01-02",
"translation": "#### 风格 01-02",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** define small functions",
"translation": "**坚持**定义简单函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** limiting to no more than 75 lines.",
"translation": "**考虑**限制在 75 行之内。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to test, especially when they do one thing and serve one purpose.",
"translation": "**为何?**简单函数更易于测试,特别是当它们只做一件事,只为一个目的服务时。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Small functions promote reuse.",
"translation": "**为何?**简单函数促进代码重用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to read.",
"translation": "**为何?**简单函数更易于阅读。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Small functions are easier to maintain.",
"translation": "**为何?**简单函数更易于维护。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## Naming",
"translation": "## 命名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "### General Naming Guidelines",
"translation": "### 总体命名原则",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-01",
"translation": "#### 风格 02-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all symbols.",
"translation": "**坚持**所有符号使用一致的命名规则。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** The naming conventions should simply help find desired code faster and make it easier to understand.",
"translation": "**为何?**命名约定帮助我们更快得找到不在手头的代码,更容易理解它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Separate file names with dots and dashes",
"translation": "### 使用点和横杠来分隔文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-02",
"translation": "#### 风格 02-02",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use dashes to separate words in the descriptive name.",
"translation": "**坚持** 在描述性名字中,用横杠来分隔单词。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use dots to separate the descriptive name from the type.",
"translation": "**坚持**使用点来分隔描述性名字和类型。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Type names provide a consistent way to quickly identify what is in the file.",
"translation": "**为何?**类型名字提供一致的方式来快速的识别文件中有什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Type names provide pattern matching for any automated tasks.",
"translation": "**为何?**为自动化任务提供模式匹配。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Symbols and file names",
"translation": "### 符号名与文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-03",
"translation": "#### 风格 02-03",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all assets named after what they represent.",
"translation": "**坚持**为所有东西使用一致的命名约定,以它们所代表的东西命名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use upper camel case for class names.",
"translation": "**坚持**使用大写驼峰命名法来命名类。符号名匹配它所在的文件名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Consistent conventions make it easy to quickly identify\nand reference assets of different types.",
"translation": "**为何?**遵循一致的约定可以快速识别和引用不同类型的资产。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Service names",
"translation": "### 服务名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-04",
"translation": "#### 风格 02-04",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all services named after their feature.",
"translation": "**坚持**使用一致的规则命名服务,以它们的特性来命名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference services.",
"translation": "**为何?**提供一致的方式来快速识别和引用服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Clear service names such as `Logger` do not require a suffix.",
"translation": "**为何?**像`Logger`这样的清楚的服务名不需要后缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Bootstrapping",
"translation": "### 引导",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-05",
"translation": "#### 风格 02-05",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** put bootstrapping and platform logic for the app in a file named `main.ts`.",
"translation": "**坚持**把应用的引导程序和平台相关的逻辑放到名为`main.ts`的文件里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** include error handling in the bootstrapping logic.",
"translation": "**坚持**在引导逻辑中包含错误处理代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Follows a consistent convention for the startup logic of an app.",
"translation": "**为何?**应用的启动逻辑遵循一致的约定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Follows a familiar convention from other technology platforms.",
"translation": "**为何?**这是从其它技术平台借鉴的常用约定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Directive selectors",
"translation": "### 指令选择器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-06",
"translation": "#### 风格 02-06",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** Use lower camel case for naming the selectors of directives.",
"translation": "**坚持**使用小驼峰命名法来命名指令的选择器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.",
"translation": "**为何?**Angular HTML 解析器是大小写敏感的,它识别小写驼峰写法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Custom prefix for components",
"translation": "### 为组件添加自定义前缀",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-07",
"translation": "#### 风格 02-07",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use a hyphenated, lowercase element selector value (e.g. `admin-users`).",
"translation": "**坚持**使用带连字符的小写元素选择器值(例如`admin-users`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Do** use a prefix that identifies the feature area or the app itself.",
"translation": "**坚持**使用前缀来识别特性区或者应用程序本身。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Prevents element name collisions with components in other apps and with native HTML elements.",
"translation": "**为何?**防止与其它应用中的组件和原生 HTML 元素发生命名冲突。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Makes it easier to promote and share the component in other apps.",
"translation": "**为何?**更容易在其它应用中推广和共享组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Components are easy to identify in the DOM.",
"translation": "**为何?**组件在 DOM 中更容易被区分出来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Custom prefix for directives",
"translation": "### 为指令添加自定义前缀",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-08",
"translation": "#### 风格 02-08",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Prevents name collisions.",
"translation": "**为何?**防止名字冲突。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Directives are easily identified.",
"translation": "**为何?**指令更加容易被识别。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Pipe names",
"translation": "### 管道名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-09",
"translation": "#### 风格 02-09",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use consistent names for all pipes, named after their feature.",
"translation": "**坚持**为所有管道使用一致的命名约定,用它们的特性来命名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference pipes.",
"translation": "**为何?**提供一致方式快速识别和引用管道。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Symbol Name",
"translation": "符号名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "File Name",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Unit test file names",
"translation": "### 单元测试文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-10",
"translation": "#### 风格 02-10",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** name test specification files the same as the component they test.",
"translation": "**坚持**测试规格文件名与被测试组件文件名相同。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** name test specification files with a suffix of `.spec`.",
"translation": "**坚持**测试规格文件名添加`.spec`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify tests.",
"translation": "**为何?**提供一致的方式来快速识别测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "<th>\n Test Type",
"translation": "测试类型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "<th>\n File Names",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Components",
"translation": "组件\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Services",
"translation": "服务\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Pipes",
"translation": "管道\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### _End-to-End_ (E2E) test file names",
"translation": "### *端到端*E2E测试的文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-11",
"translation": "#### 风格 02-11",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify end-to-end tests.",
"translation": "**为何?**提供一致的方式快速识别端到端测试文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Provides pattern matching for test runners and build automation.",
"translation": "**为何?**提供一个与测试运行器和构建自动化匹配的模式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "<th>\n Test Type",
"translation": "测试类型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "<th>\n File Names",
"translation": "文件名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "End-to-End Tests",
"translation": "端到端测试\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Angular _NgModule_ names",
"translation": "### Angular *NgModule* 命名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 02-12",
"translation": "#### 风格 02-12",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** append the symbol name with the suffix `Module`.",
"translation": "**坚持**为符号名添加`Module`后缀",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** give the file name the `.module.ts` extension.",
"translation": "**坚持**为文件名添加`.module.ts`扩展名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** name the module after the feature and folder it resides in.",
"translation": "**坚持**用特性名和所在目录命名模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Provides a consistent way to quickly identify and reference modules.",
"translation": "**为何?**提供一致的方式来快速标识和引用模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Upper camel case is conventional for identifying objects that can be instantiated using a constructor.",
"translation": "**为何?**大驼峰命名法是一种命名约定,用来标识可用构造函数实例化的对象。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Easily identifies the module as the root of the same named feature.",
"translation": "**为何?**很容易就能看出这个模块是同名特性的根模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** suffix a _RoutingModule_ class name with `RoutingModule`.",
"translation": "**坚持**为 *RoutingModule* 类名添加`RoutingModule`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** end the filename of a _RoutingModule_ with `-routing.module.ts`.",
"translation": "**坚持**为 *RoutingModule* 的文件名添加`-routing.module.ts`后缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## Coding conventions",
"translation": "## 编程约定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Have a consistent set of coding, naming, and whitespace conventions.",
"translation": "坚持一致的编程、命名和空格的约定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Classes",
"translation": "### 类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 03-01",
"translation": "#### 风格 03-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use upper camel case when naming classes.",
"translation": "**坚持**使用大写驼峰命名法来命名类。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Follows conventional thinking for class names.",
"translation": "**为何?**遵循类命名传统约定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Constants",
"translation": "### 常量",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 03-02",
"translation": "#### 风格 03-02",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** declare variables with `const` if their values should not change during the application lifetime.",
"translation": "**坚持**用`const`声明变量,除非它们的值在应用的生命周期内会发生变化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Conveys to readers that the value is invariant.",
"translation": "**为何?**告诉读者这个值是不可变的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** TypeScript helps enforce that intent by requiring immediate initialization and by\npreventing subsequent re-assignment.",
"translation": "**为何?** TypeScript 会要求在声明时立即初始化,并阻止再次赋值,以确保达成我们的意图。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** spelling `const` variables in lower camel case.",
"translation": "**考虑** 把常量名拼写为小驼峰格式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Do** tolerate _existing_ `const` variables that are spelled in UPPER_SNAKE_CASE.",
"translation": "**坚持**容许_现存的_`const`常量沿用大写蛇形命名法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Interfaces",
"translation": "### 接口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 03-03",
"translation": "#### 风格 03-03",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** name an interface using upper camel case.",
"translation": "**坚持**使用大写驼峰命名法来命名接口。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** naming an interface without an `I` prefix.",
"translation": "**考虑**不要在接口名字前面加`I`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** using a class instead of an interface.",
"translation": "**考虑**用类代替接口。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** A class alone is less code than a _class-plus-interface_.",
"translation": "**为何?**单独一个类的代码量小于*类+接口*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** A class can act as an interface (use `implements` instead of `extends`).",
"translation": "**为何?**类可以作为接口使用(只是用`implements`代替`extends`而已)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** An interface-class can be a provider lookup token in Angular dependency injection.",
"translation": "**为何?**在 Angular 依赖注入系统中,接口类可以作为服务提供商的查找令牌。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Properties and methods",
"translation": "### 属性和方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 03-04",
"translation": "#### 样式 03-04",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use lower camel case to name properties and methods.",
"translation": "**坚持**使用小写驼峰命名法来命名属性和方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Avoid** prefixing private properties and methods with an underscore.",
"translation": "**避免**为私有属性和方法添加下划线前缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Follows conventional thinking for properties and methods.",
"translation": "**为何?**遵循传统属性和方法的命名约定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** JavaScript lacks a true private property or method.",
"translation": "**为何?** JavaScript 不支持真正的私有属性和方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** TypeScript tooling makes it easy to identify private vs. public properties and methods.",
"translation": "**为何?** TypeScript 工具让识别私有或公有属性和方法变得很简单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Import line spacing",
"translation": "### 导入语句中的空行",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 03-06",
"translation": "#### 风格 03-06",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** leaving one empty line between third party imports and application imports.",
"translation": "**坚持**在第三方导入和应用导入之间留一个空行。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** listing import lines alphabetized by the module.",
"translation": "**考虑**按模块名字的字母顺排列导入行。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** listing destructured imported symbols alphabetically.",
"translation": "**考虑**在解构表达式中按字母顺序排列导入的东西。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** The empty line separates _your_ stuff from _their_ stuff.",
"translation": "**为何?**空行可以让阅读和定位本地导入更加容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Alphabetizing makes it easier to read and locate symbols.",
"translation": "**为何?**按字母顺序排列可以让阅读和定位本地导入更加容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## Application structure and NgModules",
"translation": "## 应用程序结构与 Angular 模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-01",
"translation": "#### 风格 04-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Do** define the structure to follow these four basic guidelines, listed in order of importance.",
"translation": "**坚持**四项基本原则定义文件结构,上面的原则是按重要顺序排列的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Locate",
"translation": "### 定位",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-02",
"translation": "#### 风格04-02",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** make locating code intuitive, simple and fast.",
"translation": "**坚持**直观、简单和快速地定位代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Identify",
"translation": "### 识别",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-03",
"translation": "#### 风格 04-03",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** name the file such that you instantly know what it contains and represents.",
"translation": "**坚持**命名文件到这个程度:看到名字立刻知道它包含了什么,代表了什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** be descriptive with file names and keep the contents of the file to exactly one component.",
"translation": "**坚持**文件名要具有说明性,确保文件中只包含一个组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Avoid** files with multiple components, multiple services, or a mixture.",
"translation": "**避免**创建包含多个组件、服务或者混合体的文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Flat",
"translation": "### 扁平",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-04",
"translation": "#### 风格 04-04",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** keep a flat folder structure as long as possible.",
"translation": "**坚持**尽可能保持扁平的目录结构。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** creating sub-folders when a folder reaches seven or more files.",
"translation": "**考虑**当同一目录下达到 7 个或更多个文件时创建子目录。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### _T-DRY_ (Try to be _DRY_)",
"translation": "### *T-DRY*(尽量不重复自己)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-05",
"translation": "#### 风格 04-05",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** be DRY (Don't Repeat Yourself).",
"translation": "**坚持** DRYDon't Repeat Yourself不重复自己。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Avoid** being so DRY that you sacrifice readability.",
"translation": "**避免**过度 DRY以致牺牲了阅读性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Overall structural guidelines",
"translation": "### 总体结构的指导原则",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-06",
"translation": "#### 风格 04-06",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** start small but keep in mind where the app is heading down the road.",
"translation": "**坚持**从零开始,但要考虑应用程序接下来的路往哪儿走。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** have a near term view of implementation and a long term vision.",
"translation": "**坚持**有一个近期实施方案和一个长期的愿景。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** put all of the app's code in a folder named `src`.",
"translation": "**坚持**把所有源代码都放到名为`src`的目录里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Here is a compliant folder and file structure:",
"translation": "下面是符合规范的目录和文件结构",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### _Folders-by-feature_ structure",
"translation": "### 按特性组织的目录结构",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-07",
"translation": "#### 风格 04-07",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** create folders named for the feature area they represent.",
"translation": "**坚持**根据特性区命名目录。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** The LIFT guidelines are all covered.",
"translation": "**为何?** LIFT 原则中包含了所有这些。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Do** create an NgModule for each feature area.",
"translation": "**坚持**为每个特性区创建一个 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** NgModules make it easy to lazy load routable features.",
"translation": "**为何?** Angular 模块使惰性加载可路由的特性变得更容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** NgModules make it easier to isolate, test, and re-use features.",
"translation": "**为何?**Angular 模块隔离、测试和复用特性更容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "</div>",
"translation": "Refer to this _folder and file structure_ example.</a> <a href=\"#file-tree\">点这里查看目录和文件结构的范例",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### App _root module_",
"translation": "### 应用的*根模块*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-08",
"translation": "#### 风格 04-08",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Every app requires at least one root NgModule.",
"translation": "**为何?**每个应用都至少需要一个根 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Consider** naming the root module `app.module.ts`.",
"translation": "**考虑**把根模块命名为`app.module.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Makes it easier to locate and identify the root module.",
"translation": "**为何?**能让定位和识别根模块变得更容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Feature modules",
"translation": "### 特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-09",
"translation": "#### 风格 04-09",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** create an NgModule for all distinct features in an application;\nfor example, a `Heroes` feature.",
"translation": "**坚持**为应用中每个明显的特性创建一个 Angular 模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can expose or hide its implementation from other modules.",
"translation": "**为何?**特性模块可以对其它模块暴露或隐藏自己的实现。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** A feature module identifies distinct sets of related components that comprise the feature area.",
"translation": "**为何?**特性模块标记出组成该特性分区的相关组件集合。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can easily be routed to both eagerly and lazily.",
"translation": "**为何?**方便路由到特性模块 —— 无论是用主动加载还是惰性加载的方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** A feature module defines clear boundaries between specific functionality and other application features.",
"translation": "**为何?**特性模块在特定的功能和其它应用特性之间定义了清晰的边界。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** A feature module helps clarify and make it easier to assign development responsibilities to different teams.",
"translation": "**为何?**特性模块帮助澄清开发职责,以便于把这些职责指派给不同的项目组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** A feature module can easily be isolated for testing.",
"translation": "**为何?**特性模块易于隔离,以便测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Shared feature module",
"translation": "### 共享特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-10",
"translation": "#### 风格 04-10",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Do** declare all components, directives, and pipes in the `SharedModule`.",
"translation": "**坚持**在`SharedModule`中声明所有组件、指令和管道。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** export all symbols from the `SharedModule` that other feature modules need to use.",
"translation": "**坚持**从`SharedModule`中导出其它特性模块所需的全部符号。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Avoid** specifying app-wide singleton providers in a `SharedModule`. Intentional singletons are OK. Take care.",
"translation": "**避免**在`SharedModule`中指定应用级的单例服务提供商。如果是刻意要得到多个服务单例也行,不过还是要小心。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Core feature module",
"translation": "### 核心特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-11",
"translation": "#### 风格04-11",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Avoid** importing the `CoreModule` anywhere except in the `AppModule`.",
"translation": "**避免**在`AppModule`之外的任何地方导入`CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Prevent re-import of the core module",
"translation": "### 防止多次导入`CoreModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-12",
"translation": "#### 风格 04-12",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Only the root `AppModule` should import the `CoreModule`.",
"translation": "应该只有`AppModule`才允许导入`CoreModule`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** guard against reimporting of `CoreModule` and fail fast by adding guard logic.",
"translation": "**坚持**防范多次导入`CoreModule`,并通过添加守卫逻辑来尽快失败。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Guards against reimporting of the `CoreModule`.",
"translation": "**为何?**守卫可以阻止对`CoreModule`的多次导入。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Guards against creating multiple instances of assets intended to be singletons.",
"translation": "**为何?**守卫会禁止创建单例服务的多个实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Lazy Loaded folders",
"translation": "### 惰性加载的目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-13",
"translation": "#### 样式 04-13",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** The folder makes it easy to identify and isolate the feature content.",
"translation": "**为何?**这种目录让标识和隔离这些特性内容变得更轻松。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Never directly import lazy loaded folders",
"translation": "### 永远不要直接导入惰性加载的目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 04-14",
"translation": "#### 样式 04-14",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## Components",
"translation": "## 组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Component selector names",
"translation": "### 组件选择器命名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-02",
"translation": "#### 风格05-02",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.",
"translation": "**坚持**使用*中线 (dashed) 命名法*或*烤串 (kebab) 命名法*来命名组件中的元素选择器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Components as elements",
"translation": "### 把组件当做元素",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-03",
"translation": "#### 风格 05-03",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** give components an _element_ selector, as opposed to _attribute_ or _class_ selectors.",
"translation": "**坚持**给组件一个*元素*选择器,而不是*属性*或*类*选择器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Extract templates and styles to their own files",
"translation": "### 把模板和样式提取到它们自己的文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-04",
"translation": "#### 风格 05-04",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** extract templates and styles into a separate file, when more than 3 lines.",
"translation": "**坚持**当超过 3 行时,把模板和样式提取到一个单独的文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Do** specify _component-relative_ URLs, prefixed with `./`.",
"translation": "**坚持**指定*相对于模块的* URL ,给它加上`./`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Large, inline templates and styles obscure the component's purpose and implementation, reducing readability and maintainability.",
"translation": "**为何?**巨大的、内联的模板和样式表会遮盖组件的意图和实现方式,削弱可读性和可维护性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Decorate _input_ and _output_ properties",
"translation": "### 内联输入和输出属性装饰器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-12",
"translation": "#### 风格 05-12",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Consider** placing `@Input()` or `@Output()` on the same line as the property it decorates.",
"translation": "**坚持**把`@Input()`或者`@Output()`放到所装饰的属性的同一行。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** The metadata declaration attached to the directive is shorter and thus more readable.",
"translation": "**为何?**依附到指令的元数据声明会比较简短,更易于阅读。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Avoid aliasing _inputs_ and _outputs_",
"translation": "### 避免为输入和输出属性指定别名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-13",
"translation": "#### 风格 05-13",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Avoid** _input_ and _output_ aliases except when it serves an important purpose.",
"translation": "**避免**除非有重要目的,否则不要为输入和输出指定别名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Two names for the same property (one private, one public) is inherently confusing.",
"translation": "**为何?**同一个属性有两个名字(一个对内一个对外)很容易导致混淆。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Member sequence",
"translation": "### 成员顺序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-14",
"translation": "#### 风格 05-14",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** place properties up top followed by methods.",
"translation": "**坚持**把属性成员放在前面,方法成员放在后面。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** place private members after public members, alphabetized.",
"translation": "**坚持**先放公共成员,再放私有成员,并按照字母顺序排列。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Delegate complex component logic to services",
"translation": "### 把逻辑放到服务里",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-15",
"translation": "#### 风格 05-15",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Do** move reusable logic to services and keep components simple and focused on their intended purpose.",
"translation": "**坚持**把可重用的逻辑放到服务中,保持组件简单,聚焦于它们预期目的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Removes dependencies and hides implementation details from the component.",
"translation": "**为何?**从组件移除依赖并隐藏实施细节。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Keeps the component slim, trim, and focused.",
"translation": "**为何?**保持组件苗条、精简和聚焦。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Don't prefix _output_ properties",
"translation": "### 不要给输出属性加前缀",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-16",
"translation": "#### 风格 05-16",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** name events without the prefix `on`.",
"translation": "**坚持**命名事件时,不要带前缀`on`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** name event handler methods with the prefix `on` followed by the event name.",
"translation": "**坚持**把事件处理器方法命名为`on`前缀之后紧跟着事件名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** This is consistent with built-in events such as button clicks.",
"translation": "**为何?**与内置事件命名一致,例如按钮点击。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Put presentation logic in the component class",
"translation": "### 把表现层逻辑放到组件类里",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 05-17",
"translation": "#### 风格 05-17",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** put presentation logic in the component class, and not in the template.",
"translation": "**坚持**把表现层逻辑放进组件类中,而不要放在模板里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Use directives to enhance an element",
"translation": "### 使用指令来增强已有元素",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 06-01",
"translation": "#### 风格 06-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use attribute directives when you have presentation logic without a template.",
"translation": "**坚持**当你需要有表现层逻辑,但没有模板时,使用属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Attribute directives don't have an associated template.",
"translation": "**为何?**属性型指令没有模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** An element may have more than one attribute directive applied.",
"translation": "**为何?**一个元素可以使用多个属性型指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### _HostListener_/_HostBinding_ decorators versus _host_ metadata",
"translation": "### *HostListener* 和 *HostBinding* 装饰器 vs. 组件元数据 *host*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 06-03",
"translation": "#### 风格 06-03",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Do** be consistent in your choice.",
"translation": "**坚持**让你的选择保持一致。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** The property associated with `@HostBinding` or the method associated with `@HostListener`\ncan be modified only in a single place&mdash;in the directive's class.\nIf you use the `host` metadata property, you must modify both the property declaration inside the controller,\nand the metadata associated with the directive.",
"translation": "**为何?**对于关联到`@HostBinding`的属性或关联到`@HostListener`的方法,要修改时,只需在指令类中的一个地方修改。\n如果使用元数据属性`host`,你就得在组件类中修改属性声明的同时修改相关的元数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Compare with the less preferred `host` metadata alternative.",
"translation": "与不推荐的方式(`host`元数据)比较一下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## Services",
"translation": "## 服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Services are singletons",
"translation": "### 服务总是单例的",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 07-01",
"translation": "#### 风格 07-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** use services as singletons within the same injector. Use them for sharing data and functionality.",
"translation": "**坚持**在同一个注入器内,把服务当做单例使用。用它们来共享数据和功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Services are ideal for sharing methods across a feature area or an app.",
"translation": "**为何?**服务是在特性范围或应用内共享方法的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Services are ideal for sharing stateful in-memory data.",
"translation": "**为何?**服务是共享状态性内存数据的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Single responsibility",
"translation": "### 单一职责",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 07-02",
"translation": "#### 风格 07-02",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** create services with a single responsibility that is encapsulated by its context.",
"translation": "**坚持**创建单一职责的服务,用职责封装在它的上下文中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** create a new service once the service begins to exceed that singular purpose.",
"translation": "**坚持**当服务成长到超出单一用途时,创建一个新服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** When a service has multiple responsibilities, it becomes difficult to test.",
"translation": "**为何?**当服务有多个职责时,它很难被测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Providing a service",
"translation": "### 提供一个服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 07-03",
"translation": "#### 风格 07-03",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Why?** The Angular injector is hierarchical.",
"translation": "**为何?** Angular 注入器是层次化的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** This is ideal when a service is sharing methods or state.",
"translation": "**为何?**服务是共享方法或状态的理想载体。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Use the @Injectable() class decorator",
"translation": "### 使用 @Injectable() 类装饰器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 07-04",
"translation": "#### 风格 07-04",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## Data Services",
"translation": "## 数据服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Talk to the server through a service",
"translation": "### 通过服务与 Web 服务器通讯",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 08-01",
"translation": "#### 风格 08-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** refactor logic for making data operations and interacting with data to a service.",
"translation": "**坚持**把数据操作和与数据交互的逻辑重构到服务里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## Lifecycle hooks",
"translation": "## 生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Use Lifecycle hooks to tap into important events exposed by Angular.",
"translation": "使用生命周期钩子来介入到 Angular 暴露的重要事件里。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### Implement lifecycle hook interfaces",
"translation": "### 实现生命周期钩子接口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style 09-01",
"translation": "#### 风格 09-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Do** implement the lifecycle hook interfaces.",
"translation": "**坚持**实现生命周期钩子接口。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "**Why?** Lifecycle interfaces prescribe typed method\nsignatures. use those signatures to flag spelling and syntax mistakes.",
"translation": "**为何?**如果使用强类型的方法签名,编译器和编辑器可以帮你揪出拼写错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "## Appendix",
"translation": "## 附录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Useful tools and tips for Angular.",
"translation": "有用的 Angular 工具和小提示",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style A-01",
"translation": "#### 风格 A-01",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "**Consider** adjusting the rules in codelyzer to suit your needs.",
"translation": "**考虑**调整 codelyzer 的规则来满足你的需求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "### File templates and snippets",
"translation": "### 文档模板和代码片段",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "#### Style A-02",
"translation": "#### 风格 A-02",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"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/content-1/guide/styleguide.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/styleguide.md"
},
{
"original": "# Template Syntax",
"translation": "# 模板语法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "{@a html}\n## HTML in templates",
"translation": "## 模板中的HTML",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Begin with the first form of data binding&mdash;interpolation&mdash;to see how much richer template HTML can be.",
"translation": "我们首先看看数据绑定的第一种形式 —— 插值表达式,它展示了模板的 HTML 可以有多丰富。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "## Interpolation ( <span class=\"syntax\">{&#xfeff;{...}}</span> )",
"translation": "## 插值表达式 ( <span class=\"syntax\">{&#xfeff;{...}}</span> )",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "You met the double-curly braces of interpolation, `{{` and `}}`, early in your Angular education.",
"translation": "在以前的 Angular 教程中,我们遇到过由双花括号括起来的插值表达式,`{{`和`}}`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "The expression can invoke methods of the host component such as `getVal()`, seen here:",
"translation": "这个表达式可以调用宿主组件的方法,就像下面用的`getVal()`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "But first, let's take a closer look at template expressions and statements.",
"translation": "讲解属性绑定之前,先深入了解一下模板表达式和模板语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "## Template expressions",
"translation": "## 模板表达式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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&nbsp;`=` symbol as in `[property]=\"expression\"`.",
"translation": "`{{1 + 1}}`中所包含的模板表达式是`1 + 1`。\n 在[属性绑定](guide/template-syntax#property-binding)中会再次看到模板表达式,它出现在`=`右侧的引号中,就像这样:`[property]=\"expression\"`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "JavaScript expressions that have or promote side effects are prohibited,\nincluding:",
"translation": "JavaScript 中那些具有或可能引发副作用的表达式是被禁止的,包括:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* assignments (`=`, `+=`, `-=`, ...)",
"translation": "赋值 (`=`, `+=`, `-=`, ...)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* <code>new</code>",
"translation": "`new`运算符",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* chaining expressions with <code>;</code> or <code>,</code>",
"translation": "使用`;`或`,`的链式表达式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* increment and decrement operators (`++` and `--`)",
"translation": "自增或自减操作符 (`++`和`--`)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Other notable differences from JavaScript syntax include:",
"translation": "和 JavaScript语 法的其它显著不同包括:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* no support for the bitwise operators `|` and `&`",
"translation": "不支持位运算`|`和`&`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* new [template expression operators](guide/template-syntax#expression-operators), such as `|`, `?.` and `!`.",
"translation": "具有新的[模板表达式运算符](guide/template-syntax#expression-operators),比如`|`、`?.`和`!`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### Expression context",
"translation": "### 表达式上下文",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Template expressions cannot refer to anything in\nthe global namespace. 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/content-1/guide/template-syntax.md"
},
{
"original": "### Expression guidelines",
"translation": "### 表达式指南",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Template expressions can make or break an application.\nPlease follow these guidelines:",
"translation": "模板表达式能成就或毁掉一个应用。请遵循下列指南:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "* [Quick execution](guide/template-syntax#quick-execution)",
"translation": "[执行迅速](guide/template-syntax#quick-execution)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* [Simplicity](guide/template-syntax#simplicity)",
"translation": "[非常简单](guide/template-syntax#simplicity)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* [Idempotence](guide/template-syntax#idempotence)",
"translation": "[幂等性](guide/template-syntax#idempotence)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "The only exceptions to these guidelines should be in specific circumstances that you thoroughly understand.",
"translation": "超出上面指南外的情况应该只出现在那些你确信自己已经彻底理解的特定场景中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "#### No visible side effects",
"translation": "#### 没有可见的副作用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "A template expression should not change any application state other than the value of the\ntarget property.",
"translation": "模板表达式除了目标属性的值以外,不应该改变应用的任何状态。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "#### Quick execution",
"translation": "#### 执行迅速",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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.\nExpressions should finish quickly or the user experience may drag, especially on slower devices.\nConsider caching values when their computation is expensive.",
"translation": "Angular 执行模板表达式比我们想象的频繁。\n它们可能在每一次按键或鼠标移动后被调用。\n表达式应该快速结束否则用户就会感到拖沓特别是在较慢的设备上。\n当计算代价较高时应该考虑缓存那些从其它值计算得出的值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "#### Simplicity",
"translation": "#### 非常简单",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Although it's possible to write quite complex template expressions, you should avoid them.",
"translation": "虽然也可以写出相当复杂的模板表达式,但不要那么写。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "#### Idempotence",
"translation": "#### 幂等性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "## Template statements",
"translation": "## 模板语句",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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 `=`&nbsp;symbol as in `(event)=\"statement\"`.",
"translation": "模板**语句**用来响应由绑定目标(如 HTML 元素、组件或指令)触发的**事件**。\n模板语句将在[事件绑定](guide/template-syntax#event-binding)一节看到,它出现在`=`号右侧的引号中,就像这样:`(event)=\"statement\"`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "However, certain JavaScript syntax is not allowed:",
"translation": "然而,某些 JavaScript 语法仍然是不允许的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* <code>new</code>",
"translation": "`new`运算符",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* increment and decrement operators, `++` and `--`",
"translation": "自增和自减运算符:`++`和`--`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* operator assignment, such as `+=` and `-=`",
"translation": "操作并赋值,例如`+=`和`-=`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* the bitwise operators `|` and `&`",
"translation": "位操作符`|`和`&`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* the [template expression operators](guide/template-syntax#expression-operators)",
"translation": "[模板表达式运算符](guide/template-syntax#expression-operators)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### Statement context",
"translation": "### 语句上下文",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Statement guidelines",
"translation": "### 语句指南",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "## Binding syntax: An overview",
"translation": "## 绑定语法:概览",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Data binding is a mechanism for coordinating what users see, with application data values.\n While you could push values to and pull values from HTML,\n the application is easier to write, read, and maintain if you turn these chores over to a binding framework.\n You 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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Data direction",
"translation": "数据方向",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Syntax",
"translation": "语法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Type",
"translation": "绑定类型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "One-way",
"translation": "单向",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "from data source",
"translation": "从数据源",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "to view target",
"translation": "到视图目标",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Interpolation",
"translation": "插值表达式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Class",
"translation": "类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Style",
"translation": "样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "<td>\n<p> One-way</p>",
"translation": "单向",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "from view target",
"translation": "从视图目标",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "to data source",
"translation": "到数据源",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "<td><p>\n Event\n </p>",
"translation": "事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "<td><p>\n Two-way\n </p>",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "<td><p>\n Two-way\n </p>",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### A new mental model",
"translation": "### 新的思维模型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "You still create a structure and initialize attribute values this way in Angular templates.",
"translation": "在 Angular 模板中,我们仍使用同样的方式来创建结构和初始化 attribute 值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "That's HTML Plus.",
"translation": "这就是HTML+。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Then you learn about data binding. The first binding you meet might look like this:",
"translation": "现在开始学习数据绑定。我们碰到的第一种数据绑定是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### HTML attribute vs. DOM property",
"translation": "### HTML attribute 与 DOM property 的对比",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "* Some HTML attributes don't have corresponding properties. `colspan` is one example.",
"translation": "有些 HTML attribute 没有对应的 property如`colspan`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* Some DOM properties don't have corresponding attributes. `textContent` is one example.",
"translation": "有些 DOM property 没有对应的 attribute如`textContent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "That last category is confusing until you grasp this general rule:",
"translation": "最后一类尤其让人困惑…… 除非我们能理解这个普遍原则:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.",
"translation": "HTML attribute `value`指定了*初始*值DOM `value` property 是*当前*值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "This fact bears repeating:",
"translation": "这句话值得再强调一次:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "**Template binding works with *properties* and *events*, not *attributes*.**",
"translation": "**模板绑定是通过 *property* 和*事件*来工作的,而不是 *attribute*。**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "A world without attributes",
"translation": "没有 attribute 的世界",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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 eventsof the target object.\nHTML attributes effectively disappear.",
"translation": "在 Angular 的世界中attribute 唯一的作用是用来初始化元素和指令的状态。\n当进行数据绑定时只是在与元素和指令的 property 和事件打交道,而 attribute 就完全靠边站了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "With this model firmly in mind, read on to learn about binding targets.",
"translation": "把这个思维模型牢牢的印在脑子里,接下来,学习什么是绑定目标。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### Binding targets",
"translation": "### 绑定目标",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Type",
"translation": "绑定类型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Target",
"translation": "目标",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Examples",
"translation": "范例",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Element&nbsp;property",
"translation": "元素的 property",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Component&nbsp;property",
"translation": "组件的 property",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Directive&nbsp;property",
"translation": "指令的 property",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Event",
"translation": "事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Element&nbsp;event",
"translation": "元素的事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Component&nbsp;event",
"translation": "组件的事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Directive&nbsp;event",
"translation": "指令的事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Two-way",
"translation": "双向",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Event and property",
"translation": "事件与 property",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Attribute (the&nbsp;exception)",
"translation": "attribute例外情况",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Class",
"translation": "CSS 类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Style",
"translation": "样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "With this broad view in mind, you're ready to look at binding types in detail.",
"translation": "放开眼界,我们来看看每种绑定类型的具体情况。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "## Property binding ( <span class=\"syntax\">[property]</span> )",
"translation": "## 属性绑定 ( <span class=\"syntax\">[属性名]</span> )",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Another example is disabling a button when the component says that it `isUnchanged`:",
"translation": "另一个例子是当组件说它`isUnchanged`(未改变)时禁用按钮:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Another is setting a property of a directive:",
"translation": "另一个例子是设置指令的属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### One-way *in*",
"translation": "### 单向*输入*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Similarly, you cannot use property binding to *call* a method on the target element.",
"translation": "也不能使用属性 绑定 来*调用*目标元素上的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Binding target",
"translation": "### 绑定目标",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "An element property between enclosing square brackets identifies the target property. The target property in the following code is the image element's `src` property.",
"translation": "包裹在方括号中的元素属性名标记着目标属性。下列代码中的目标属性是 image 元素的`src`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Some people prefer the `bind-` prefix alternative, known as the *canonical form*:",
"translation": "有些人喜欢用`bind-`前缀的可选形式,并称之为*规范形式*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Avoid side effects",
"translation": "### 消除副作用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Of course, the expression might invoke a property or method that has side effects.\n Angular has no way of knowing that or stopping you.",
"translation": "当然,表达式可能会调用具有副作用的属性或方法。但 Angular 没法知道这一点,也没法阻止我们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Return the proper type",
"translation": "### 返回恰当的类型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Remember the brackets",
"translation": "### 别忘了方括号",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Don't make the following mistake:",
"translation": "不要出现这样的失误:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### One-time string initialization",
"translation": "### 一次性字符串初始化",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "You *should* omit the brackets when all of the following are true:",
"translation": "当满足下列条件时,*应该*省略括号:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* The target property accepts a string value.",
"translation": "目标属性接受字符串值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* The string is a fixed value that you can bake into the template.",
"translation": "字符串是个固定值,可以直接合并到模块中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* This initial value never changes.",
"translation": "这个初始值永不改变。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Property binding or interpolation?",
"translation": "### 属性绑定还是插值表达式?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "_Interpolation_ is a convenient alternative to _property binding_ in many cases.",
"translation": "在多数情况下,插值表达式是更方便的备选项。\n实际上在渲染视图之前Angular 把这些插值表达式翻译成相应的属性绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "When setting an element property to a non-string data value, you must use _property binding_.",
"translation": "但数据类型不是字符串时,就必须使用*属性绑定*了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "#### Content security",
"translation": "#### 内容安全",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Imagine the following *malicious content*.",
"translation": "假设下面的*恶意内容*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Interpolation handles the script tags differently than property binding but both approaches render the\ncontent harmlessly.",
"translation": "插值表达式处理 script 标签与属性绑定有所不同,但是二者都只渲染没有危害的内容。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "<img src='generated/images/guide/template-syntax/evil-title.png' alt=\"evil title made safe\">",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "## Attribute, class, and style bindings",
"translation": "## attribute、class 和 style 绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "The template syntax provides specialized one-way bindings for scenarios less well suited to property binding.",
"translation": "模板语法为那些不太适合使用属性绑定的场景提供了专门的单向数据绑定形式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### Attribute binding",
"translation": "### attribute 绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "You can set the value of an attribute directly with an **attribute binding**.",
"translation": "可以通过**attribute 绑定**来直接设置 attribute 的值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "**You must use attribute binding when there is no element property to bind.**",
"translation": "**因为当元素没有属性可绑的时候,就必须使用 attribute 绑定。**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "This fact becomes painfully obvious when you write something like this.",
"translation": "如果想写出类似下面这样的东西,现状会令我们痛苦:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "And you get this error:",
"translation": "会得到这个错误:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "You need attribute bindings to create and bind to such attributes.",
"translation": "我们需要 attribute 绑定来创建和绑定到这样的 attribute。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Bind `[attr.colspan]` to a calculated value:",
"translation": "这里把`[attr.colspan]`绑定到一个计算值:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Here's how the table renders:",
"translation": "这里是表格渲染出来的样子:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Class binding",
"translation": "### CSS 类绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Style binding",
"translation": "### 样式绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "You can set inline styles with a **style binding**.",
"translation": "通过**样式绑定**,可以设置内联样式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Some style binding styles have a unit extension. The following example conditionally sets the font size in “em” and “%” units.",
"translation": "有些样式绑定中的样式带有单位。在这里,以根据条件用 “em” 和 “%” 来设置字体大小的单位。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "{@a event-binding}",
"translation": "## Event binding ( <span class=\"syntax\">(event)</span> )\n## 事件绑定 ( <span class=\"syntax\">(事件名)</span> )",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Target event",
"translation": "### 目标事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "A **name between parentheses** &mdash; for example, `(click)` &mdash;\nidentifies the target event. In the following example, the target is the button's click event.",
"translation": "**圆括号中的名称** —— 比如`(click)` —— 标记出目标事件。在下面例子中,目标是按钮的 click 事件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Some people prefer the `on-` prefix alternative, known as the **canonical form**:",
"translation": "有些人更喜欢带`on-`前缀的备选形式,称之为**规范形式**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### *$event* and event handling statements",
"translation": "### *$event* 和事件处理语句",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "In an event binding, Angular sets up an event handler for the target event.",
"translation": "在事件绑定中Angular 会为目标事件设置事件处理器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "The binding conveys information about the event, including data values, through\nan **event object named `$event`**.",
"translation": "绑定会通过**名叫`$event`的事件对象**传递关于此事件的信息(包括数据值)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Consider this example:",
"translation": "考虑这个范例:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Custom events with <span class=\"syntax\">EventEmitter</span>",
"translation": "### 使用 <span class=\"syntax\">EventEmitter</span> 实现自定义事件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Here are the pertinent excerpts from that `HeroDetailComponent`:",
"translation": "下面的代码节选自`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Now imagine a hosting parent component that binds to the `HeroDetailComponent`'s `deleteRequest` event.",
"translation": "现在,假设有个宿主的父组件,它绑定了`HeroDetailComponent`的`deleteRequest`事件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### Template statements have side effects",
"translation": "### 模板语句有副作用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "## Two-way binding ( <span class=\"syntax\">[(...)]</span> )",
"translation": "## 双向数据绑定 ( <span class=\"syntax\">[(...)]</span> )",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "[( )] = banana in a box",
"translation": "[( )] = 盒子里的香蕉",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Visualize a *banana in a box* to remember that the parentheses go _inside_ the brackets.",
"translation": "想象*盒子里的香蕉*来记住方括号套圆括号。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Clearly the two-way binding syntax is a great convenience compared to separate property and event bindings.",
"translation": "显然,比起单独绑定属性和事件,双向数据绑定语法显得非常方便。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "## Built-in directives",
"translation": "## 内置指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "## Built-in _attribute_ directives",
"translation": "## 内置*属性型*指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### NgClass",
"translation": "### NgClass 指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Adding an `ngClass` property binding to `currentClasses` sets the element's classes accordingly:",
"translation": "把`NgClass`属性绑定到`currentClasses`根据它来设置此元素的CSS类",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "It's up to you to call `setCurrentClassess()`, both initially and when the dependent properties change.",
"translation": "你既可以在初始化时调用`setCurrentClassess()`,也可以在所依赖的属性变化时调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### NgStyle",
"translation": "### NgStyle 指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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 propertes:",
"translation": "来看看组件的`setCurrentStyles`方法,它会根据另外三个属性的状态把组件的`currentStyles`属性设置为一个定义了三个样式的对象:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Adding an `ngStyle` property binding to `currentStyles` sets the element's styles accordingly:",
"translation": "把`NgStyle`属性绑定到`currentStyles`,以据此设置此元素的样式:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "It's up to you to call `setCurrentStyles()`, both initially and when the dependent properties change.",
"translation": "你既可以在初始化时调用`setCurrentStyles()`,也可以在所依赖的属性变化时调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Two-way data binding with the `NgModel` directive makes that easy. Here's an example:",
"translation": "使用`NgModel`指令进行双向数据绑定可以简化这种工作。例子如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "#### _FormsModule_ is required to use _ngModel_",
"translation": "#### 使用 `ngModel` 时需要 `FormsModule`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Here's how to import the `FormsModule` to make `[(ngModel)]` available.",
"translation": "导入`FormsModule`并让`[(ngModel)]`可用的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "#### Inside <span class=\"syntax\">[(ngModel)]</span>",
"translation": "#### <span class=\"syntax\">[(ngModel)]</span>内幕",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "The following contrived example forces the input value to uppercase:",
"translation": "下面这个生造的例子强制输入框的内容变成大写:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Here are all variations in action, including the uppercase version:",
"translation": "这里是所有这些变体的动画,包括这个大写转换的版本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "## Built-in _structural_ directives",
"translation": "## 内置*结构型*指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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>`](structural-directives.html#ngcontainer \"<ng-container>对元素进行分组。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* how to write your own structural directive.",
"translation": "如何写自己的结构型指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "_This_ section is an introduction to the common structural directives:",
"translation": "*本节*是对常见结构型指令的简介:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "* [NgForOf](guide/template-syntax#ngFor) - repeat a template for each item in a list",
"translation": "[`NgSwitch`](guide/template-syntax#ngSwitch) - 一组指令,用于切换一组视图",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### NgIf",
"translation": "### NgIf 指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Don't forget the asterisk (`*`) in front of `ngIf`.",
"translation": "别忘了`ngIf`前面的星号(`*`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "#### Show/hide is not the same thing",
"translation": "#### 这和显示/隐藏不是一回事",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Hiding an element is quite different from removing an element with `NgIf`.",
"translation": "但隐藏子树和用`NgIf`排除子树是截然不同的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "#### Guard against null",
"translation": "#### 防范空指针错误",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "See also the\n[_safe navigation operator_](guide/template-syntax#safe-navigation-operator \"Safe naviation operator (?.)\")\ndescribed below.",
"translation": "参见稍后的[_安全导航操作符_](guide/template-syntax#safe-navigation-operator \"Safe naviation operator (?.)\")部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### NgForOf",
"translation": "### NgFor 指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "`NgForOf` is a _repeater_ directive &mdash; 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/content-1/guide/template-syntax.md"
},
{
"original": "Here is an example of `NgForOf` applied to a simple `<div>`:",
"translation": "下例中,`NgFor`应用在一个简单的`<div>`上:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "You can also apply an `NgForOf` to a component element, as in this example:",
"translation": "也可以把`NgFor`应用在一个组件元素上,就下例这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Don't forget the asterisk (`*`) in front of `ngFor`.",
"translation": "不要忘了`ngFor`前面的星号 (`*`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "The text assigned to `*ngFor` is the instruction that guides the repeater process.",
"translation": "赋值给`*ngFor`的文本是用于指导重复器如何工作的指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "#### *ngFor microsyntax",
"translation": "#### NgFor 微语法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "The string assigned to `*ngFor` is not a [template expression](guide/template-syntax#template-expressions).\nIt's a *microsyntax* &mdash; 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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Learn about the _microsyntax_ in the [_Structural Directives_](guide/structural-directives#microsyntax) guide.",
"translation": "要了解*微语法*的更多知识,参见[_结构型指令_](guide/structural-directives#microsyntax)一章。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### Template input variables",
"translation": "### 模板输入变量",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "You reference the `hero` input variable within the `NgForOf` host element\n(and within its descendents) 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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "#### *ngFor with _index_",
"translation": "#### 带索引的`*ngFor`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "#### *ngFor with _trackBy_",
"translation": "#### 带`trackBy`的`*ngFor`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "For example, re-querying the server could reset the list with all new hero objects.",
"translation": "例如,我们可以通过重新从服务器查询来刷新英雄列表。\n 刷新后的列表可能包含很多(如果不是全部的话)以前显示过的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "In the microsyntax expression, set `trackBy` to this method.",
"translation": "在微语法中,把`trackBy`设置为该方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "* With no `trackBy`, both buttons trigger complete DOM element replacement.",
"translation": "如果没有`trackBy`这些按钮都会触发完全的DOM元素替换。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* With `trackBy`, only changing the `id` triggers element replacement.",
"translation": "有了`trackBy`,则只有修改了`id`的按钮才会触发元素替换。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "<img src=\"generated/images/guide/template-syntax/ng-for-track-by-anim.gif\" alt=\"trackBy\">",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### The _NgSwitch_ directives",
"translation": "### `NgSwitch`指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "* `NgSwitchCase` adds its element to the DOM when its bound value equals the switch value.",
"translation": "`NgSwitchCase`会在它绑定到的值等于候选值时把它所在的元素加入到DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "* `NgSwitchDefault` adds its element to the DOM when there is no selected `NgSwitchCase`.",
"translation": "`NgSwitchDefault`会在没有任何一个`NgSwitchCase`被选中时把它所在的元素加入DOM中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "## Template reference variables ( <span class=\"syntax\">#var</span> )",
"translation": "## 模板引用变量 ( <span class=\"syntax\">#var</span> )",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "How a reference variable gets its value",
"translation": "### 模板引用变量怎么得到它的值?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Template reference variable warning notes",
"translation": "关于模板引用变量的提醒",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "## Input and output properties ( <span class=\"syntax\">@Input</span> and <span class=\"syntax\">@Output</span> )",
"translation": "## 输入输出属性 ( <span class=\"syntax\">@Input</span> 和 <span class=\"syntax\">@Output</span> )",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "So far, you've focused mainly on binding to component members within template expressions and statements\nthat appear on the *right side of the binding declaration*.\nA member in that position is a data binding **source**.",
"translation": "迄今为止,我们主要聚焦在*绑定声明的右侧*,学习如何在模板表达式和模板语句中绑定到组件成员。\n当成员出现在这个位置上则称之为数据绑定的**源**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "This section concentrates on binding to **targets**, which are directive\nproperties on the *left side of the binding declaration*.\nThese directive properties must be declared as **inputs** or **outputs**.",
"translation": "本节则专注于绑定到的**目标**,它位于*绑定声明中的左侧*。\n这些指令的属性必须被声明成**输入**或**输出**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Remember: All **components** are **directives**.",
"translation": "记住:所有**组件**皆为**指令**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Note the important distinction between a data binding **target** and a data binding **source**.",
"translation": "我们要重点突出下绑定**目标**和绑定**源**的区别。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "The *target* of a binding is to the *left* of the `=`.\nThe *source* is on the *right* of the `=`.",
"translation": "绑定的*目标*是在`=`*左侧*的部分,\n*源*则是在`=`*右侧*的部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "The *target* of a binding is the property or event inside the binding punctuation: `[]`, `()` or `[()]`.\nThe *source* is either inside quotes (`\" \"`) or within an interpolation (`{{}}`).",
"translation": "绑定的*目标*是绑定符:`[]`、`()`或`[()]`中的属性或事件名,\n*源*则是引号 (`\" \"`) 中的部分或插值符号 (`{{}}`) 中的部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Every member of a **source** directive is automatically available for binding.\nYou don't have to do anything special to access a directive member in a template expression or statement.",
"translation": "**源**指令中的每个成员都会自动在绑定中可用。\n 不需要特别做什么,就能在模板表达式或语句中访问指令的成员。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "You have *limited* access to members of a **target** directive.\nYou can only bind to properties that are explicitly identified as *inputs* and *outputs*.",
"translation": "访问**目标**指令中的成员则*受到限制*。\n 只能绑定到那些显式标记为*输入*或*输出*的属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "In the following snippet, `iconUrl` and `onSave` are data-bound members of the `AppComponent`\nand are referenced within quoted syntax to the _right_ of the equals&nbsp;(`=`).",
"translation": "在下面的例子中,`iconUrl`和`onSave`是组件的成员,它们在`=`右侧引号语法中被引用了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "They are *neither inputs nor outputs* of the component. They are **sources** for their bindings.\nThe targets are the native `<img>` and `<button>` elements.",
"translation": "它们既不是组件的*输入*也不是*输出*。它们是绑定的数据源。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Now look at a another snippet in which the `HeroDetailComponent`\nis the **target** of a binding on the _left_ of the equals&nbsp;(`=`).",
"translation": "现在,看看`HeroDetailComponent`中的另一个片段,等号(`=`*左侧*的是绑定的**目标**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Both `HeroDetailComponent.hero` and `HeroDetailComponent.deleteRequest` are on the **left side** of binding declarations.\n`HeroDetailComponent.hero` is inside brackets; it is the target of a property binding.\n`HeroDetailComponent.deleteRequest` is inside parentheses; it is the target of an event binding.",
"translation": "`HeroDetailComponent.hero`和`HeroDetailComponent.deleteRequest`都在绑定声明的**左侧**。\n`HeroDetailComponent.hero`在方括号中,它是属性绑定的目标。\n`HeroDetailComponent.deleteRequest`在圆括号中,它是事件绑定的目标。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### Declaring input and output properties",
"translation": "### 声明输入和输出属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Target properties must be explicitly marked as inputs or outputs.",
"translation": "目标属性必须被显式的标记为输入或输出。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "In the `HeroDetailComponent`, such properties are marked as input or output properties using decorators.",
"translation": "在`HeroDetailComponent`内部,这些属性被装饰器标记成了输入和输出属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "You can specify an input/output property either with a decorator or in a metadata array.\nDon't do both!",
"translation": "既可以通过装饰器,也可以通过元数据数组来指定输入/输出属性。但别同时用!",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### Input or output?",
"translation": "### 输入还是输出?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "The terms _input_ and _output_ reflect the perspective of the target directive.",
"translation": "_输入_和_输出_这两个词是从目标指令的角度来说的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Aliasing input/output properties",
"translation": "给输入/输出属性起别名",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Sometimes the public name of an input/output property should be different from the internal name.",
"translation": "有时需要让输入/输出属性的公开名字不同于内部名字。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "## Template expression operators",
"translation": "## 模板表达式操作符",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### The pipe operator ( <span class=\"syntax\">|</span> )",
"translation": "### 管道操作符 ( | )",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "You can chain expressions through multiple pipes:",
"translation": "还可以通过多个管道串联表达式:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "And you can also [apply parameters](guide/pipes#parameterizing-a-pipe) to a pipe:",
"translation": "还能对它们使用参数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "The `json` pipe is particularly helpful for debugging bindings:",
"translation": "`json`管道对调试绑定特别有用:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "The generated output would look something like this",
"translation": "它生成的输出是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "### The safe navigation operator ( <span class=\"syntax\">?.</span> ) and null property paths",
"translation": "### 安全导航操作符 ( ?. ) 和空属性路径",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "What happens when the following data bound `title` property is null?",
"translation": "如果下列数据绑定中`title`属性为空,会发生什么?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "JavaScript throws a null reference error, and so does Angular:",
"translation": "JavaScript 抛出了空引用错误Angular 也是如此:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "Worse, the *entire view disappears*.",
"translation": "晕,*整个视图都不见了*。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Unfortunately, the app crashes when the `currentHero` is null.",
"translation": "不幸的是,当`currentHero`为空的时候,应用崩溃了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "You could code around that problem with [*ngIf](guide/template-syntax#ngIf).",
"translation": "可以通过用[NgIf](guide/template-syntax#ngIf)代码环绕它来解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "### The non-null assertion operator ( <span class=\"syntax\">!</span> )",
"translation": "### 非空断言操作符(<span class=\"syntax\">!</span>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "The _Angular_ **non-null assertion operator (`!`)** serves the same purpose in an Angular template.",
"translation": "*Angular* 模板中的**非空断言操作符(`!`)也是同样的用途。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "Unlike the [_safe navigation operator_](guide/template-syntax#safe-navigation-operator \"Safe naviation 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/content-1/guide/template-syntax.md"
},
{
"original": "You'll need this template operator when you turn on strict null checks. It's optional otherwise.",
"translation": "如果我们打开了严格控制检测,那就要用到这个模板操作符,而其它情况下则是可选的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/template-syntax.md"
},
{
"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/content-1/guide/template-syntax.md"
},
{
"original": "# Testing",
"translation": "# 测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This guide offers tips and techniques for testing Angular applications.\nThough this page includes some general testing principles and techniques,\nthe focus is on testing applications written with Angular.",
"translation": "本章提供了一些测试Angular应用的提示和技巧。虽然这里讲述了一些常规测试理念和技巧但是其重点是测试用Angular编写的应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Live examples",
"translation": "## 在线例子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This guide presents tests of a sample application that is much like the [_Tour of Heroes_ tutorial](tutorial).\nThe sample application and all tests in this guide are available as live examples for inspection, experiment, and download:",
"translation": "这篇指南会展示一个范例应用的所有测试,这个范例应用和[《英雄指南》教程](tutorial)非常像。\n本章中的这个范例应用及其所有测试都有在线例子以供查看、试验和下载。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"1st-specs\" embedded-style>A spec to verify the test environment</live-example>.",
"translation": "<live-example plnkr=\"1st-specs\" embedded-style>用于验证测试环境的规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"banner-inline-specs\" embedded-style>The first component spec with inline template</live-example>.",
"translation": "<live-example plnkr=\"banner-inline-specs\" embedded-style>第一个带内联模板的组件规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"banner-specs\" embedded-style>A component spec with external template</live-example>.",
"translation": "<live-example plnkr=\"banner-specs\" embedded-style>带外部模板的组件规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* <live-example name=\"setup\" plnkr=\"quickstart-specs\" embedded-style>The QuickStart seed's AppComponent spec</live-example>.",
"translation": "<live-example name=\"setup\" plnkr=\"quickstart-specs\" embedded-style>快速起步种子工程的`AppComponent`规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* <live-example embedded-style>The sample application to be tested</live-example>.",
"translation": "<live-example embedded-style>所要测试的范例应用</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"app-specs\" embedded-style>All specs that test the sample application</live-example>.",
"translation": "<live-example plnkr=\"app-specs\" embedded-style>本范例应用的所有规约</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* <live-example plnkr=\"bag-specs\" embedded-style>A grab bag of additional specs</live-example>.",
"translation": "<live-example plnkr=\"bag-specs\" embedded-style>其它规约汇总</live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Introduction to Angular Testing",
"translation": "## Angular测试入门",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This page guides you through writing tests to explore\nand confirm the behavior of the application. Testing\ndoes the following:",
"translation": "本章教你如何编写测试程序来探索和确认应用的行为。测试的作用有:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. Guards against changes that break existing code (“regressions”).",
"translation": "测试**守护**由于代码变化而打破已有代码(“回归”)的情况。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. Clarifies what the code does both when used as intended and when faced with deviant conditions.",
"translation": "不管代码被正确使用还是错误使用,测试程序起到**澄清**代码的作用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. Reveals mistakes in design and implementation.\nTests shine a harsh light on the code from many angles.\nWhen a part of the application seems hard to test, the root cause is often a design flaw,\nsomething to cure now rather than later when it becomes expensive to fix.",
"translation": "测试程序**暴露**设计和实现可能出现的错误。测试程序从很多角度为代码亮出警报灯。当应用程序很难被测试时,\n其根本原因一般都是设计缺陷这种缺陷最好立刻被修正不要等到它变得很难被修复的时候才行动。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This chapter assumes that you know something about testing. Don't worry if you don't.\nThere are plenty of books and online resources to get up to speed.",
"translation": "本章假设你熟悉测试。但是如果你不熟悉也没有关系。有很多书本和在线资源可以帮助你。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Tools and technologies",
"translation": "### 工具与技术",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "You can write and run Angular tests with a variety of tools and technologies.\nThis guide describes specific choices that are known to work well.",
"translation": "你可以用多种工具和技术来编写和运行Angular测试程序。本章介绍了一些大家已经知道能良好工作的选择。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Technology",
"translation": "技术",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Purpose",
"translation": "目的",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [Jasmine test framework](http://jasmine.github.io/2.4/introduction.html)\n provides everything needed to write basic tests.\n It ships with an HTML test runner that executes tests in the browser.",
"translation": "[Jasmine测试框架](http://jasmine.github.io/2.4/introduction.html)提供了所有编写基本测试的工具。\n 它自带HTML测试运行器用来在浏览器中执行测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Angular testing utilities",
"translation": "Angular测试工具",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Angular testing utilities create a test environment\n for the Angular application code under test.\n Use them to condition and control parts of the application as they\n interact _within_ the Angular environment.",
"translation": "Angular测试工具为被测试的Angular应用代码创建测试环境。在应用代码与Angular环境互动时使用Angular测试工具来限制和控制应用的部分代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [karma test runner](https://karma-runner.github.io/1.0/index.html)\n is ideal for writing and running unit tests while developing the application.\n It can be an integral part of the project's development and continuous integration processes.\n This guide describes how to set up and run tests with karma.",
"translation": "[karma测试运行器](https://karma-runner.github.io/1.0/index.html)是在开发应用的过程中\n 编写和运行单元测试的理想工具。\n 它能成为项目开发和连续一体化进程的不可分割的一部分。本章讲述了如何用Karma设置和运行测试程序。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Use protractor to write and run _end-to-end_ (e2e) tests.\n End-to-end tests explore the application _as users experience it_.\n In e2e testing, one process runs the real application\n and a second process runs protractor tests that simulate user behavior\n and assert that the application respond in the browser as expected.",
"translation": "使用`Protractor`来编写和运行_端对端(e2e)_测试程序。端对端测试程序**像用户体验应用程序那样**探索它。\n 在端对端测试中一条进程运行真正的应用另一条进程运行Protractor测试程序模拟用户行为判断应用在浏览器中的反应是否正确。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Setup",
"translation": "### 环境设置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "There are two fast paths to getting started with unit testing.",
"translation": "要开始单元测试,有两条捷径:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. Start a new project following the instructions in [Setup](guide/setup \"Setup\").",
"translation": "遵循[环境设置](guide/setup \"环境设置\")中给出的步骤开始一个新项目。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. Start a new project with the\n<a href=\"https://github.com/angular/angular-cli/blob/master/README.md\" title=\"Angular CLI\">Angular CLI</a>.",
"translation": "使用[Angular CLI](https://github.com/angular/angular-cli/blob/master/README.md)创建新的项目。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Both approaches install npm packages, files, and scripts pre-configured for applications\nbuilt in their respective modalities.\nTheir artifacts and procedures differ slightly but their essentials are the same\nand there are no differences in the test code.",
"translation": "以上两种方法都安装在各自的模式下为应用预先配置的**npm包、文件和脚本**。它们的文件和规程有一点不同,但是它们的核心部分是一样的,并且在测试代码方面没有任何区别。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "In this guide, the application and its tests are based on the [setup instructions](guide/setup \"Setup\").\nFor a discussion of the unit testing setup files, [see below](guide/testing#setup-files).",
"translation": "本章中,该应用及其测试都是基于[环境设置步骤](guide/setup \"Setup\")的。\n对单元测试的环境设置文件的讨论[参见后面](guide/testing#setup-files)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Isolated unit tests vs. the Angular testing utilities",
"translation": "### 独立单元测试 vs. Angular测试工具集",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "[Isolated unit tests](guide/testing#isolated-unit-tests \"Unit testing without the Angular testing utilities\")\nexamine an instance of a class all by itself without any dependence on Angular or any injected values.\nThe tester creates a test instance of the class with `new`, supplying test doubles for the constructor parameters as needed, and\nthen probes the test instance API surface.",
"translation": "[独立单元测试](guide/testing#isolated-unit-tests \"不使用Angular测试工具集的单元测试\")用于测试那些完全不依赖Angular或不需要注入值的类实例。\n测试程序会`new`出一个测试类的实例为构造函数参数提供所需的测试替身然后测试该实例的API接口。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "*You should write isolated unit tests for pipes and services.*",
"translation": "*我们应该为管道和服务书写独立单元测试。*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "You can test components in isolation as well.\nHowever, isolated unit tests don't reveal how components interact with Angular.\nIn particular, they can't reveal how a component class interacts with its own template or with other components.",
"translation": "我们也同样可以对组件写独立单元测试。\n不过独立单元测试无法体现组件与Angular的交互。\n具体来说就是不能发现组件类如何与它的模板或其它组件交互。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Such tests require the **Angular testing utilities**.\nThe Angular testing utilities include the `TestBed` class and several helper functions from `@angular/core/testing`.\nThey are the main focus of this guide and you'll learn about them\nwhen you write your [first component test](guide/testing#simple-component-test).\nA comprehensive review of the Angular testing utilities appears [later in this guide](guide/testing#atu-apis).",
"translation": "这时你需要*Angular测试工具集*。\nAngular测试工具集包括`TestBed`类和一些来自`@angular/core/testing`的助手函数。\n本章将会重点讲解它们通过[第一个组件测试](guide/testing#simple-component-test)来讲解。\n[本章稍后的部分](guide/testing#atu-apis)将展示Angular测试工具集的全貌。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "But first you should write a dummy test to verify that your test environment is set up properly\nand to lock in a few basic testing skills.",
"translation": "但首先,我们要先随便写一个测试来验证测试环境是否已经就绪了,并掌握一些基础的测试技术。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## The first karma test",
"translation": "## 第一个`karma`测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Start with a simple test to make sure that the setup works properly.",
"translation": "编写简单的测试程序,来确认以上的配置是否工作正常。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Create a new file called `1st.spec.ts` in the application root folder, `src/app/`",
"translation": "在应用的根目录`app/`创建新文件,名叫`1st.spec.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Tests written in Jasmine are called _specs_ .\n**The filename extension must be `.spec.ts`**,\nthe convention adhered to by `karma.conf.js` and other tooling.",
"translation": "用Jasmine编写的测试程序都被叫做**specs**。**文件名后缀必须是`.spec.ts`**,这是`karma.conf.js`和其它工具所坚持和遵守的规约。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "**Put spec files somewhere within the `src/app/` folder.**\nThe `karma.conf.js` tells karma to look for spec files there,\nfor reasons explained [below](guide/testing#q-spec-file-location).",
"translation": "**将测试程序spec放到`app/`文件夹下的任何位置。**\n`karma.conf.js`告诉`Karma`在这个文件夹中寻找测试程序spec文件原因在 [这里](guide/testing#q-spec-file-location) 有所解释。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Add the following code to `src/app/1st.spec.ts`.",
"translation": "添加下面的代码到`app/1st.spec.ts`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Run with karma",
"translation": "### 运行Karma",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Compile and run it in karma from the command line using the following command:",
"translation": "使用下面的命令从命令行中编译并在`Karma`中运行上面的测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The command compiles the application and test code and starts karma.\nBoth processes watch pertinent files, write messages to the console, and re-run when they detect changes.",
"translation": "该命令编译应用及其测试代码并启动Karma。\n两个进程都监视相关文件往控制台输入信息和检测到变化时自动重新运行。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The documentation setup defines the `test` command in the `scripts` section of npm's `package.json`.\nThe Angular CLI has different commands to do the same thing. Adjust accordingly.",
"translation": "《快速上手》在npm的`package.json`中的`scripts`里定义了`test`命令。\nAngular CLI使用不同的命令来做同样的事情。对不同的环境采取不同的方案。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "After a few moments, karma opens a browser and starts writing to the console.",
"translation": "等一小段时间后Karma便打开浏览器并开始向控制台输出。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Hide (don't close!) the browser and focus on the console output, which\nshould look something like this:",
"translation": "隐藏(不要关闭)浏览器,查看控制台的输出,应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Both the compiler and karma continue to run. The compiler output is preceded by `[0]`;\nthe karma output by `[1]`.",
"translation": "编译器和`Karma`都会持续运行。编译器的输入信息前面有`[0]``Karma`的输出前面有`[1]`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Change the expectation from `true` to `false`.",
"translation": "将期望从`true`变换为`false`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The _compiler_ watcher detects the change and recompiles.",
"translation": "**编译器**监视器检测到这个变化并重新编译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The _karma_ watcher detects the change to the compilation output and re-runs the test.",
"translation": "**`Karma`**监视器检测到编译器输出的变化,并重新运行测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It fails of course.",
"translation": "正如所料,测试结果是**失败**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Restore the expectation from `false` back to `true`.\nBoth processes detect the change, re-run, and karma reports complete success.",
"translation": "将期望从`false`恢复为`true`。两个进程都检测到这个变化,自动重新运行,`Karma`报告测试成功。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The console log can be quite long. Keep your eye on the last line.\nWhen all is well, it reads `SUCCESS`.",
"translation": "控制台的日志可能会非常长。注意最后一样。当一切正常时,它会显示`SUCCESS`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Test debugging",
"translation": "### 调试测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Debug specs in the browser in the same way thatyou debug an application.",
"translation": "在浏览器中像调试应用一样调试测试程序spec。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. Reveal the karma browser window (hidden earlier).",
"translation": "显示`Karma`的浏览器窗口(之前被隐藏了)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests.",
"translation": "点击“DEBUG”按钮它打开一页新浏览器标签并重新开始运行测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "1. Pick the \"sources\" section.",
"translation": "选择“sources”页",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "1. Set a breakpoint in the test.",
"translation": "在测试程序中设置断点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. Refresh the browser, and it stops at the breakpoint.",
"translation": "刷新浏览器...然后它就会停在断点上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Try the live example",
"translation": "### 试试这个在线例子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "You can also try this test as a <live-example plnkr=\"1st-specs\" title=\"First spec\" embedded-style></live-example> in plunker.\nAll of the tests in this guide are available as [live examples](guide/testing#live-examples \"Live examples of these tests\").",
"translation": "你还可以在plunker的<live-example plnkr=\"1st-specs\" title=\"First spec\" embedded-style></live-example>中试运行这个测试。\n本章的所有测试都有相应的[在线例子](guide/testing#live-examples \"Live examples of these tests\")。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Test a component",
"translation": "## 测试一个组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "An Angular component is the first thing most developers want to test.\nThe `BannerComponent` in `src/app/banner-inline.component.ts` is the simplest component in this application and\na good place to start.\nIt presents the application title at the top of the screen within an `<h1>` tag.",
"translation": "大多数开发人员首先要测试的就是Angular组件。\n`src/app/banner-inline.component.ts`中的`BannerComponent`是这个应用中最简单的组件,也是一个好的起点。\n它所表示的是屏幕顶部`<h1>`标签中的应用标题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This version of the `BannerComponent` has an inline template and an interpolation binding.\nThe component is probably too simple to be worth testing in real life but\nit's perfect for a first encounter with the Angular testing utilities.",
"translation": "这个版本的`BannerComponent`有一个内联模板和一个插值表达式绑定。\n这个组件可能太简单以至于在真实的项目中都不值得测试但它却是首次接触Angular测试工具集时的完美例子。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The corresponding `src/app/banner-inline.component.spec.ts` sits in the same folder as the component,\nfor reasons explained in the [FAQ](guide/testing#faq) answer to\n[\"Why put specs next to the things they test?\"](guide/testing#q-spec-file-location).",
"translation": "组件对应的`src/app/banner-inline.component.spec.ts`文件与该组件位于同一个目录中,原因详见[FAQ](guide/testing#faq)中的\n[为什么要把测试规约文件放在被测试对象旁边?](guide/testing#q-spec-file-location)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Start with ES6 import statements to get access to symbols referenced in the spec.",
"translation": "在测试文件中我们先用ES6的`import`语句来引入测试所需的符号。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here's the `describe` and the `beforeEach` that precedes the tests:",
"translation": "测试前面的`describe`和`beforeEach`如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _TestBed_",
"translation": "### _TestBed_ 测试台",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "`TestBed` is the first and most important of the Angular testing utilities.\nIt creates an Angular testing module&mdash;an `@NgModule` class&mdash;that\nyou configure with the `configureTestingModule` method to produce the module environment for the class you want to test.\nIn effect, you detach the tested component from its own application module\nand re-attach it to a dynamically-constructed Angular test module\ntailored specifically for this battery of tests.",
"translation": "`TestBed`测试台是Angular测试工具集中的首要概念。\n它创建Angular测试模块一个`@NgModule`类),我们可以通过调用它的`configureTestingModule`方法来为要测试的类生成模块环境。\n其效果是你可以把被测试的组件从原有的应用模块中剥离出来把它附加到一个动态生成的Angular测试模块上而该测试模块可以为这些测试进行特殊裁剪。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `configureTestingModule` method takes an `@NgModule`-like metadata object.\nThe metadata object can have most of the properties of a normal [NgModule](guide/ngmodule).",
"translation": "`configureTestingModule`方法接受一个类似`@NgModule`的元数据对象。这个元数据对象具有标准[Angular模块](guide/ngmodule)的大多数属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "_This metadata object_ simply declares the component to test, `BannerComponent`.\nThe metadata lack `imports` because (a) the default testing module configuration already has what `BannerComponent` needs\nand (b) `BannerComponent` doesn't interact with any other components.",
"translation": "*这里的元数据对象*只是声明了要测试的组件`BannerComponent`。\n这个元数据中没有`imports`属性,这是因为:(a) 默认的测试模块配置中已经有了`BannerComponent`所需的一切,(b) `BannerComponent`不需要与任何其它组件交互。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Call `configureTestingModule` within a `beforeEach` so that\n`TestBed` can reset itself to a base state before each test runs.",
"translation": "在`beforeEach`中调用`configureTestingModule`,以便`TestBed`可以在运行每个测试之前都把自己重置回它的基础状态。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The base state includes a default testing module configuration consisting of the\ndeclarables (components, directives, and pipes) and providers (some of them mocked)\nthat almost everyone needs.",
"translation": "基础状态中包含一个默认的测试模块配置它包含每个测试都需要的那些声明组件、指令和管道以及服务提供商有些是Mock版。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The testing shims mentioned [later](guide/testing#testbed-methods) initialize the testing module configuration\nto something like the `BrowserModule` from `@angular/platform-browser`.",
"translation": "[之前](guide/testing#setup)提到的测试垫片初始化测试模块配置到一个模块,这个模块和`@angular/platform-browser`中的`BrowserModule`类似。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This default configuration is merely a _foundation_ for testing an app.\nLater you'll call `TestBed.configureTestingModule` with more metadata that define additional\nimports, declarations, providers, and schemas to fit your application tests.\nOptional `override` methods can fine-tune aspects of the configuration.",
"translation": "这个默认的配置只是测试的*基础性*工作。稍后我们会调用`TestBed.configureTestingModule`来传入更多元数据,这些元数据定义了额外的\n`imports`、`declarations`、`providers`和试用于这些测试的概要Schema。\n可选的`override`方法可以微调配置的各个方面。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _createComponent_",
"translation": "### _createComponent_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "After configuring `TestBed`, you tell it to create an instance of the _component-under-test_.\nIn this example, `TestBed.createComponent` creates an instance of `BannerComponent` and\nreturns a [_component test fixture_](guide/testing#component-fixture).",
"translation": "在配置好`TestBed`之后,我们可以告诉它创建一个*待测组件*的实例。\n在这个例子中`TestBed.createComponent`创建了一个`BannerComponent`的实例,并返回一个[*组件测试夹具*](guide/testing#component-fixture)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Do not re-configure `TestBed` after calling `createComponent`.",
"translation": "在调用了`createComponent`之后就不要再重新配置`TestBed`了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `createComponent` method closes the current `TestBed` instance to further configuration.\nYou cannot call any more `TestBed` configuration methods, not `configureTestingModule`\nnor any of the `override...` methods. If you try, `TestBed` throws an error.",
"translation": "`createComponent`方法封闭了当前的`TestBed`实例,以免将来再配置它。\n我们不能再调用任何`TestBed`的方法修改配置:不能调用`configureTestingModule`或任何`override...`方法。如果这么做,`TestBed`就会抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _ComponentFixture_, _DebugElement_, and _query(By.css)_",
"translation": "### `ComponentFixture`、`DebugElement` 和 `query(By.css)`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `createComponent` method returns a **`ComponentFixture`**, a handle on the test environment surrounding the created component.\nThe fixture provides access to the component instance itself and\nto the **`DebugElement`**, which is a handle on the component's DOM element.",
"translation": "`createComponent`方法返回**`ComponentFixture`**,用来控制和访问已创建的组件所在的测试环境。\n 这个fixture提供了对组件实例自身的访问同时还提供了用来访问组件的DOM元素的**`DebugElement`**对象。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `title` property value is interpolated into the DOM within `<h1>` tags.\nUse the fixture's `DebugElement` to `query` for the `<h1>` element by CSS selector.",
"translation": "`title`属性被插值到DOM的`<h1>`标签中。\n用CSS选择器从fixture的`DebugElement`中`query``<h1>`元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The **`query`** method takes a predicate function and searches the fixture's entire DOM tree for the \n_first_ element that satisfies the predicate. \nThe result is a _different_ `DebugElement`, one associated with the matching DOM element.",
"translation": "**`query`**方法接受predicate函数并搜索fixture的整个DOM树试图寻找**第一个**满足predicate函数的元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `queryAll` method returns an array of _all_ `DebugElements` that satisfy the predicate.",
"translation": "`queryAll`方法返回一列数组,包含所有`DebugElement`中满足predicate的元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "A _predicate_ is a function that returns a boolean. \nA query predicate receives a `DebugElement` and returns `true` if the element meets the selection criteria.",
"translation": "**predicate**是返回布尔值的函数。\npredicate查询接受`DebugElement`参数,如果元素符合选择条件便返回`true`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The **`By`** class is an Angular testing utility that produces useful predicates.\nIts `By.css` static method produces a\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors\">standard CSS selector</a>\npredicate that filters the same way as a jQuery selector.",
"translation": "**`By`**类是Angular测试工具之一它生成有用的predicate。\n它的`By.css`静态方法产生<a href=\"https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors\" target=\"_blank\">标准CSS选择器</a>\npredicate与JQuery选择器相同的方式过滤。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Finally, the setup assigns the DOM element from the `DebugElement` **`nativeElement`** property to `el`.\nThe tests assert that `el` contains the expected title text.",
"translation": "最后,这个配置把`DebugElement`中的**`nativeElement`**DOM元素赋值给`el`属性。\n测试程序将判断`el`是否包含期待的标题文本。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### The tests",
"translation": "### 测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Jasmine runs the `beforeEach` function before each of these tests",
"translation": "再每个测试程序之前Jasmin都一次运行`beforeEach`函数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "These tests ask the `DebugElement` for the native HTML element to satisfy their expectations.",
"translation": "这些测试程序向`DebugElement`获取原生HTML元素来满足自己的期望。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _detectChanges_: Angular change detection within a test",
"translation": "### **detectChanges**在测试中的Angular变更检测",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Each test tells Angular when to perform change detection by calling `fixture.detectChanges()`.\nThe first test does so immediately, triggering data binding and propagation of the `title` property\nto the DOM element.",
"translation": "每个测试程序都通过调用`fixture.detectChanges()`来通知Angular执行变更检测。第一个测试程序立刻这么做触发数据绑定和并将`title`属性发送到DOM元素中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The second test changes the component's `title` property _and only then_ calls `fixture.detectChanges()`;\nthe new value appears in the DOM element.",
"translation": "第二个测试程序在更改组件的`title`属性**之后**才调用`fixture.detectChanges()`。新值出现在DOM元素中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The `TestBed.createComponent` does _not_ trigger change detection.\nThe fixture does not automatically push the component's `title` property value into the data bound element,\na fact demonstrated in the following test:",
"translation": "`TestBed.createComponent`**不会**触发变更检测。该工具不会自动将组件的`title`属性值推送到数据绑定的元素,下面的测试程序展示了这个事实:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This behavior (or lack of it) is intentional.\nIt gives the tester an opportunity to inspect or change the state of\nthe component _before Angular initiates data binding or calls lifecycle hooks_.",
"translation": "这种行为(或者缺乏的行为)是有意为之。**在Angular初始化数据绑定或者调用生命周期钩子**之前,它给测试者机会来查看或者改变组件的状态。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Try the live example",
"translation": "### 试试在线例子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Take a moment to explore this component spec as a <live-example plnkr=\"banner-inline-specs\" title=\"Spec for component with inline template\" embedded-style></live-example> and\nlock in these fundamentals of component unit testing.",
"translation": "花点时间来浏览一下该组件的规约,比如<live-example plnkr=\"banner-inline-specs\" title=\"Spec for component with inline template\" embedded-style></live-example>,深入理解组件单元测试的这些基本原理。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Automatic change detection",
"translation": "### 自动变更检测",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `BannerComponent` tests frequently call `detectChanges`.\nSome testers prefer that the Angular test environment run change detection automatically.\nThat's possible by configuring the `TestBed` with the `ComponentFixtureAutoDetect` provider .\nFirst import it from the testing utility library :",
"translation": "`BannerComponent`的测试频繁调用`detectChanges`。\n有些测试人员更希望Angular的测试环境自动进行变更检测。\n这可以通过为`TestBed`配置上`ComponentFixtureAutoDetect`提供商来做到。首先从测试工具库中导入它:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Then add it to the `providers` array of the testing module configuration:",
"translation": "然后把它添加到测试模块配置的`providers`数组中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here are three tests that illustrate how automatic change detection works.",
"translation": "下列测试阐明了自动变更检测的工作原理。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The first test shows the benefit of automatic change detection.",
"translation": "第一个测试程序展示了自动检测的好处。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "</div>",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Test a component with an external template",
"translation": "## 测试带有外部模板的组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The application's actual `BannerComponent` behaves the same as the version above but is implemented differently.\nIt has _external_ template and css files, specified in `templateUrl` and `styleUrls` properties.",
"translation": "在实际应用中,`BannerComponent`的行为和刚才的版本相同,但是实现方式不同。\n它有一个*外部*模板和CSS文件通过`templateUrl`和`styleUrls`属性来指定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "That's a problem for the tests.\nThe `TestBed.createComponent` method is synchronous.\nBut the Angular template compiler must read the external files from the file system before it can create a component instance.\nThat's an asynchronous activity.\nThe previous setup for testing the inline component won't work for a component with an external template.",
"translation": "这些测试有一个问题。\n`TestBed.createComponent`方法是同步的。\n但是Angular模板编译器必须在创建组件实例之前先从文件系统中读取这些值而这是异步的。\n以前测试内联模板时使用的设置方式不适用于外部模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### The first asynchronous _beforeEach_",
"translation": "### 第一个异步的`beforeEach`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The test setup for `BannerComponent` must give the Angular template compiler time to read the files.\nThe logic in the `beforeEach` of the previous spec is split into two `beforeEach` calls.\nThe first `beforeEach` handles asynchronous compilation.",
"translation": "`BannerComponent`测试的设置方式必须给Angular模板编译器一些时间来读取文件。\n以前放在`beforeEach`中的逻辑被拆分成了两个`beforeEach`调用。\n第一个`beforeEach`处理异步编译工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Notice the `async` function called as the argument to `beforeEach`.\nThe `async` function is one of the Angular testing utilities and\nhas to be imported.",
"translation": "注意`async`函数被用作调用`beforeEach`的参数。\n`async`函数是Angular测试工具集的一部分这里必须引入它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It takes a parameterless function and _returns a function_\nwhich becomes the true argument to the `beforeEach`.",
"translation": "它接收一个无参数的函数,并*返回一个函数*,这个函数会作为实参传给`beforeEach`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The body of the `async` argument looks much like the body of a synchronous `beforeEach`.\nThere is nothing obviously asynchronous about it.\nFor example, it doesn't return a promise and\nthere is no `done` function to call as there would be in standard Jasmine asynchronous tests.\nInternally, `async` arranges for the body of the `beforeEach` to run in a special _async test zone_\nthat hides the mechanics of asynchronous execution.",
"translation": "`async`参数的内容看起来非常像同步版`beforeEach`的函数体。\n它并不能很明显的看出来这是异步函数。\n比如它不返回承诺Promise并且也没有标准Jasmine异步测试时常用的`done`函数作为参数。\n内部实现上`async`会把`beforeEach`的函数体放进一个特殊的*异步测试区async test zone*,它隐藏了异步执行的内部机制。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "All this is necessary in order to call the asynchronous `TestBed.compileComponents` method.",
"translation": "这就是为了调用异步的`TestBed.compileComponents`方法所要做的一切。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _compileComponents_",
"translation": "### _compileComponents_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The `TestBed.compileComponents` method asynchronously compiles all the components configured in the testing module.\nIn this example, the `BannerComponent` is the only component to compile.\nWhen `compileComponents` completes, the external templates and css files have been \"inlined\"\nand `TestBed.createComponent` can create new instances of `BannerComponent` synchronously.",
"translation": "`TestBed.compileComponents`方法会异步编译这个测试模块中配置的所有组件。\n在这个例子中`BannerComponent`是唯一要编译的组件。\n当`compileComponents`完成时外部组件和css文件会被“内联”而`TestBed.createComponent`会用同步的方式创建一个`BannerComponent`的新实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "WebPack developers need not call `compileComponents` because it inlines templates and css\nas part of the automated build process that precedes running the test.",
"translation": "WebPack用户不用调用`compileComponents`因为它会在构建过程中自动内联模板和css然后执行测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "In this example, `TestBed.compileComponents` only compiles the `BannerComponent`.\nTests later in the guide declare multiple components and\na few specs import entire application modules that hold yet more components.\nAny of these components might have external templates and css files.\n`TestBed.compileComponents` compiles all of the declared components asynchronously at one time.",
"translation": "在这个例子中,`TestBed.compileComponents`只会编译`BannerComponent`。\n本章稍后的测试中会声明多个组件并且少量规约中会导入包含多个组件的应用模块。所有这些组件都可能含有外部模板和css文件。\n`TestBed.compileComponents`会同时异步编译所有这些声明的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Do not configure the `TestBed` after calling `compileComponents`.\nMake `compileComponents` the last step\nbefore calling `TestBed.createComponent` to instantiate the _component-under-test_.",
"translation": "调用了`compileComponents`之后就不能再配置`TestBed`了。\n务必确保`compileComponents`是调用`TestBed.createComponent`来实例化*待测组件*之前的最后一步。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### The second synchronous _beforeEach_",
"translation": "### 第二个同步`beforeEach`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "A _synchronous_ `beforeEach` containing the remaining setup steps follows the asynchronous `beforeEach`.",
"translation": "这个同步的`beforeEach`包含异步`beforeEach`之后的其余步骤。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "These are the same steps as in the original `beforeEach`.\nThey include creating an instance of the `BannerComponent` and querying for the elements to inspect.",
"translation": "这些步骤和原来的`beforeEach`中相同。\n包括创建`BannerComponent`实例和查询要审查的元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### Waiting for _compileComponents_",
"translation": "### 等待`compileComponents`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `compileComponents` method returns a promise so you can perform additional tasks _immediately after_ it finishes.\nFor example, you could move the synchronous code in the second `beforeEach`\ninto a `compileComponents().then(...)` callback and write only one `beforeEach`.",
"translation": "`compileComponents`方法返回一个承诺,来让我们可以在它完成之后*立即*执行额外的任务。\n比如我们可以把第二个`beforeEach`中的同步代码移到一个`compileComponents().then(...)`回调中,从而只需要写一个`beforeEach`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Most developers find that hard to read.\nThe two `beforeEach` calls are widely preferred.",
"translation": "大多数开发人员会觉得这样不易读,因此,更多采用的还是写两个`beforeEach`调用的方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Try the live example",
"translation": "### 试试在线例子",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Take a moment to explore this component spec as a <live-example plnkr=\"banner-specs\" title=\"Spec for component with external template\" embedded-style></live-example>.",
"translation": "稍微花点时间,在<live-example plnkr=\"banner-specs\" title=\"Spec for component with external template\" embedded-style></live-example>中看看该组件的规约。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [Quickstart seed](guide/setup) provides a similar test of its `AppComponent`\nas you can see in _this_ <live-example name=\"setup\" plnkr=\"quickstart-specs\" title=\"QuickStart seed spec\" embedded-style></live-example>.\nIt too calls `compileComponents` although it doesn't have to because the `AppComponent`'s template is inline.",
"translation": "[“快速上手” 种子工程](guide/setup)为其`AppComponent`提供了简单的测试,在<live-example name=\"setup\" plnkr=\"quickstart-specs\" title=\"QuickStart seed spec\" embedded-style></live-example>中可以看到。\n它也调用了`compileComponents`,不过它并不是必须这么做,因为`AppComponent`的模板是内联的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "There's no harm in it and you might call `compileComponents` anyway\nin case you decide later to re-factor the template into a separate file.\nThe tests in this guide only call `compileComponents` when necessary.",
"translation": "这样做也没坏处,如果你将来可能会把模板重构到独立的文件中去,那就可以调用`compileComponents`。\n不过本章中的这些测试只会在必要时才调用`compileComponents`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "</div>",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Test a component with a dependency",
"translation": "## 测试有依赖的组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Components often have service dependencies.",
"translation": "组件经常依赖其他服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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, `src/app/welcome.component.spec.ts`:",
"translation": "`WelcomeComponent`有与服务进行交互的决策逻辑这样的逻辑让这个组件值得测试。下面是spec文件的测试模块配置`src/app/welcome.component.spec.ts`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### Provide service test doubles",
"translation": "### 提供服务替身",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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": "被测试的组件不一定要注入真正的服务。实际上服务的替身stubs, fakes, spies或者mocks通常会更加合适。\nspec的主要目的是测试组件而不是服务。真实的服务可能自身有问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "This particular test suite supplies a minimal `UserService` stub that satisfies the needs of the `WelcomeComponent`\nand its tests:",
"translation": "这个测试套件提供了最小化的`UserService`stub类用来满足`WelcomeComponent`和它的测试的需求:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Get injected services",
"translation": "### 获取注入的服务\nThe tests need access to the (stub) `UserService` injected into the `WelcomeComponent`.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### _TestBed.get_",
"translation": "### _TestBed.get_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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.\nFortunately, 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": "你**可以**通过`TestBed.get`方法来从根注入器中获取服务。\n它更容易被记住也更加简介。\n但是只有在Angular使用测试的根注入器中的那个服务实例来注入到组件时它才有效。\n幸运的是在这个测试套件中**唯一**的`UserService`提供商就是根测试模块,所以像下面这样调用`TestBed.get`很安全:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [`inject`](guide/testing#inject) utility function is another way to get one or more services from the test root injector.",
"translation": "[`inject`](guide/testing#inject)辅助函数方法是另外一种从测试的根注入器注入一个或多个服务到测试的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "For a use case in which `inject` and `TestBed.get` do not work,\nsee the section [_Override a component's providers_](guide/testing#component-override), which\nexplains why you must get the service from the component's injector instead.",
"translation": "如果遇到了`inject`和`TestBed.get`无效,的情况,请到“[**重载组件提供商**](guide/testing#component-override)”一节。那里会解释为什么要改用组件的注入器来获取服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Always get the service from an injector",
"translation": "### 总是从注入器获取服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### Final setup and tests",
"translation": "### 最后的设置和测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here's the complete `beforeEach` using `TestBed.get`:",
"translation": "这里是使用`TestBed.get`的完整`beforeEach`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "And here are some tests:",
"translation": "下面是一些测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The first is a sanity test; it confirms that the stubbed `UserService` is called and working.",
"translation": "第一个测试程序是合法测试程序,它确认这个被模拟的`UserService`是否被调用和工作正常。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The second parameter to the Jasmine matcher (e.g., `'expected name'`) is an optional addendum.\nIf the expectation fails, Jasmine displays this addendum after the expectation failure message.\nIn a spec with multiple expectations, it can help clarify what went wrong and which expectation failed .",
"translation": "Jasmine的`it`方法的第二个参数(比如`'expected name'`)是可选附加参数。\n如果这个期待失败了Jasmine在期待失败信息后面显示这个附加参数。\n在拥有多个期待的spec中它可以帮助澄清发生了什么错误哪个期待失败了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "## Test a component with an async service",
"translation": "## 测试有异步服务的组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Many services return values asynchronously.\nMost data services make an HTTP request to a remote server and the response is necessarily asynchronous.",
"translation": "许多服务异步返回值。大部分数据服务向远程服务器发起HTTP请求响应必然是异步的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The \"About\" view in this sample displays Mark Twain quotes.\nThe `TwainComponent` handles the display, delegating the server request to the `TwainService`.",
"translation": "本例的`About`视图显示马克吐温的名言。\n`TwainComponent`组件处理视图,并委派`TwainService`向服务器发起请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Both are in the `src/app/shared` folder because the author intends to display Twain quotes on other pages someday.\nHere is the `TwainComponent`.",
"translation": "两者都在`app/shared`目录里,因为作者计划将来在其它页面也显示马克吐温的名言。\n下面是`TwainComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `TwainService` implementation is irrelevant for this particular test.\nIt is sufficient to see within `ngOnInit` that `twainService.getQuote` returns a promise, which means it is asynchronous.",
"translation": "`TwainService`的实现细节现在并不重要。\n`ngOnInit`的`twainService.getQuote`返回承诺,所以显然它是异步的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "In general, tests should not make calls to remote servers. \nThey should emulate such calls. The setup in this `src/app/shared/twain.component.spec.ts` shows one way to do that:",
"translation": "一般来讲,测试程序不应该向远程服务器发请求。\n它们应该仿真这样的请求。`src/app/shared/twain.component.spec.ts`里的配置是其中一种伪造方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Spying on the real service",
"translation": "### 刺探(Spy)真实服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This setup is similar to the [`welcome.component.spec` setup](guide/testing#welcome-spec-setup).\nBut instead of creating a stubbed service object, it injects the _real_ service (see the testing module `providers`) and\nreplaces the critical `getQuote` method with a Jasmine spy.",
"translation": "本配置与[`welcome.component.spec`配置](guide/testing#welcome-spec-setup)类似。\n但是与其伪造服务对象它注入了真实的服务参见测试模块的`providers`并用Jasmine的`spy`替换关键的`getQuote`方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The spy is designed such that any call to `getQuote` receives an immediately resolved promise with a test quote.\nThe spy bypasses the actual `getQuote` method and therefore does not contact the server.",
"translation": "这个Spy的设计是所有调用`getQuote`的方法都会收到立刻解析的承诺得到一条预设的名言。Spy拦截了实际`getQuote`方法,所以它不会联系服务端。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Faking a service instance and spying on the real service are _both_ great options.\nPick the one that seems easiest for the current test suite.\nDon't be afraid to change your mind.",
"translation": "伪造服务实例和刺探真实服务都是好方法。挑选一种对当前测试套件最简单的方法。你可以随时改变主意。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Spying on the real service isn't always easy, especially when the real service has injected dependencies.\nYou can _stub and spy_ at the same time, as shown in [an example below](guide/testing#spy-stub).",
"translation": "刺探真实的服务往往并不容易,特别是真实的服务依赖其它服务时。\n我们可以同时*打桩和刺探*,就像[后面的例子](guide/testing#spy-stub)那样。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here are the tests with commentary to follow:",
"translation": "下面是接下来带有注解的测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Synchronous tests",
"translation": "### 同步测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The first two tests are synchronous.\nThanks to the spy, they verify that `getQuote` is called _after_\nthe first change detection cycle during which Angular calls `ngOnInit`.",
"translation": "前两个测试程序是同步的。\n在Spy的帮助下它们验证了在Angular调用`ngOnInit`期间发生的第一次变更检测后,`getQuote`被调用了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Neither test can prove that a value from the service is displayed.\nThe quote itself has not arrived, despite the fact that the spy returns a resolved promise.",
"translation": "两者都不能证明被显示的值是服务提供的。\n虽然spy返回了解析的承诺名言本身还没有到来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This test must wait at least one full turn of the JavaScript engine before the\nvalue becomes available. The test must become _asynchronous_.",
"translation": "这个测试程序必须等待JavaScript引擎一整个回合返回值才会有效。该测试程序必须要变成**异步的**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### The _async_ function in _it_",
"translation": "### **it**里的**async**函数方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Notice the `async` in the third test.",
"translation": "注意第三个测试程序的`async`方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `async` function is one of the Angular testing utilities.\nIt simplifies coding of asynchronous tests by arranging for the tester's code to run in a special _async test zone_\nas [discussed earlier](guide/testing#async-in-before-each) when it was called in a `beforeEach`.",
"translation": "`async`函数是**Angular TestBed**的一部分。通过将测试代码放到特殊的**异步测试区域**来运行,`async`函数简化了异步测试程序的代码。就像[以前讨论过的](guide/testing#async-in-before-each),它会在`beforeEach`中被调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Although `async` does a great job of hiding asynchronous boilerplate,\nsome functions called within a test (such as `fixture.whenStable`) continue to reveal their asynchronous behavior.",
"translation": "虽然`async`做了很多工作来尽量隐藏异步特性,但在测试程序(比如`fixture.whenStable`)里面调用函数时,有时还是会体现它们的异步行为。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `fakeAsync` alternative, [covered below](guide/testing#fake-async), removes this artifact and affords a more linear coding experience.",
"translation": "`fakeAsync`可选方法,[正如下面解释的](guide/testing#fake-async),进一步移除了异步行为,提供了更加直观的代码经验。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _whenStable_",
"translation": "### _whenStable_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The test must wait for the `getQuote` promise to resolve in the next turn of the JavaScript engine.",
"translation": "测试程序必须等待`getQuote`在JavaScript引擎的下一回合中被解析。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This test has no direct access to the promise returned by the call to `twainService.getQuote`\nbecause it is buried inside `TwainComponent.ngOnInit` and therefore inaccessible to a test that\nprobes only the component API surface.",
"translation": "本测试对`twainService.getQuote`返回的承诺没有直接的访问,因为它被埋没在`TwainComponent.ngOnInit`里,\n所以对于只测试组件API表面的测试来说它是无法被访问的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Fortunately, the `getQuote` promise is accessible to the _async test zone_ ,\nwhich intercepts all promises issued within the _async_ method call _no matter where they occur_.",
"translation": "幸运的是,**异步测试区域**可以访问`getQuote`承诺,因为它拦截所有调用**异步**方法所发出的承诺,不管它们在哪儿。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `ComponentFixture.whenStable` method returns its own promise, which resolves when the `getQuote` promise finishes.\nIn fact, the _whenStable_ promise resolves when _all pending asynchronous activities within this test_ complete &mdash; the definition of \"stable.\"",
"translation": "`ComponentFixture.whenStable`方法返回它自己的承诺,它在`getQuote`承诺完成时被解析。实际上“stable”的意思是当**所有待处理异步行为**完成时的状态在“stable”后**whenStable**承诺被解析。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Then the test resumes and kicks off another round of change detection (`fixture.detectChanges`),\nwhich tells Angular to update the DOM with the quote.\nThe `getQuote` helper method extracts the display element text and the expectation confirms that the text matches the test quote.",
"translation": "然后测试程序继续运行,并开始另一轮的变更检测(`fixture.detectChanges`,通知Angular使用名言来更新DOM。\n`getQuote`辅助方法提取出显示元素文本然后expect语句确认这个文本与预备的名言相符。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### The _fakeAsync_ function",
"translation": "### **fakeAsync**函数方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The fourth test verifies the same component behavior in a different way.",
"translation": "第四个测试程序用不同的方法验证同样的组件行为。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Notice that `fakeAsync` replaces `async` as the `it` argument.\nThe `fakeAsync` function is another of the Angular testing utilities.",
"translation": "注意,在`it`的参数中,`async`被`fakeAsync`替换。\n`fakeAsync`是另一种Angular测试工具。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Like [async](guide/testing#async), it _takes_ a parameterless function and _returns_ a function\nthat becomes the argument to the Jasmine `it` call.",
"translation": "和[async](guide/testing#async)一样,它也**接受**无参数函数并**返回**一个函数变成Jasmine的`it`函数的参数。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `fakeAsync` function enables a linear coding style by running the test body in a special _fakeAsync test zone_.",
"translation": "`fakeAsync`函数通过在特殊的**fakeAsync测试区域**运行测试程序,让测试代码更加简单直观。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The principle advantage of `fakeAsync` over `async` is that the test appears to be synchronous.\nThere is no `then(...)` to disrupt the visible flow of control.\nThe promise-returning `fixture.whenStable` is gone, replaced by `tick()`.",
"translation": "对于`async`来说,`fakeAsync`最重要的好处是测试程序看起来像同步的。里面没有任何承诺。\n没有`then(...)`链来打断控制流。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "There _are_ limitations. For example, you cannot make an XHR call from within a `fakeAsync`.",
"translation": "但是`fakeAsync`有局限性。比如,你不能从`fakeAsync`发起XHR请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### The _tick_ function",
"translation": "### **tick**函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `tick` function is one of the Angular testing utilities and a companion to `fakeAsync`.\nYou can only call it within a `fakeAsync` body.",
"translation": "`tick`函数是Angular测试工具之一是`fakeAsync`的同伴。\n它只能在`fakeAsync`的主体中被调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Calling `tick()` simulates the passage of time until all pending asynchronous activities finish,\nincluding the resolution of the `getQuote` promise in this test case.",
"translation": "调用`tick()`模拟时间的推移,直到全部待处理的异步任务都已完成,在这个测试案例中,包含`getQuote`承诺的解析。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It returns nothing. There is no promise to wait for.\nProceed with the same test code that appeared in the `whenStable.then()` callback.",
"translation": "它不返回任何结果。没有任何承诺需要等待。\n直接执行与之前在`whenStable.then()`的回调函数里相同的代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Even this simple example is easier to read than the third test.\nTo more fully appreciate the improvement, imagine a succession of asynchronous operations,\nchained in a long sequence of promise callbacks.",
"translation": "虽然这个例子非常简单,但是它已经比第三个测试程序更易阅读。\n为了更充分的体会`fakeAsync`的好处,试想一下一连串的异步操作,被一长串的承诺回调链在一起。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _jasmine.done_",
"translation": "### _jasmine.done_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "While the `async` and `fakeAsync` functions greatly\nsimplify Angular asynchronous testing,\nyou can still fall back to the traditional Jasmine asynchronous testing technique.",
"translation": "虽然`async`和`fakeAsync`函数大大的简化了异步测试你仍然可以回退到传统的Jasmine异步测试技术上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "You can still pass `it` a function that takes a\n[`done` callback](http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support).\nNow you are responsible for chaining promises, handling errors, and calling `done` at the appropriate moment.",
"translation": "你仍然可以将接受 [`done`回调](http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support)的函数传给`it`。\n但是你必须链接承诺、处理错误并在适当的时候调用`done`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here is a `done` version of the previous two tests:",
"translation": "下面是上面两个测试程序的`done`版本:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Although there is no direct access to the `getQuote` promise inside `TwainComponent`,\nthe spy has direct access, which makes it possible to wait for `getQuote` to finish.",
"translation": "虽然我们对`TwainComponent`里的`getQuote`承诺没有直接访问但是Spy有所以才可能等待`getQuote`完成。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Writing test functions with `done`, while more cumbersome than `async`\nand `fakeAsync`, is a viable and occasionally necessary technique.\nFor example, you can't call `async` or `fakeAsync` when testing\ncode that involves the `intervalTimer`, as is common when\ntesting async `Observable` methods.",
"translation": "写带有`done`回调的测试函数,虽然比`async`和`fakeAsync`函数笨拙,但是在少数偶然情况下却是很有必要的技巧。比如,当测试涉及`intervalTimer`的代码时,你就没法调用`async`和`fakeAsync`函数,在测试异步`Observable`函数时也一样。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Test a component with inputs and outputs",
"translation": "## 测试带有导入inputs和导出outputs的组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The `DashboardHeroComponent` is embedded in the `DashboardComponent` template like this:",
"translation": "`DashboardHeroComponent`是这样内嵌在`DashboardCompoent`的模板中的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Here's the component's definition:",
"translation": "下面是组件的定义:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "* Test it as used by `DashboardComponent`.",
"translation": "把它当作被`DashbaordComponent`使用的组件来测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Test it as a stand-alone component.",
"translation": "把它当作独立的组件来测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Test it as used by a substitute for `DashboardComponent`.",
"translation": "把它当作被`DashbaordComponent`的替代组件使用的组件来测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "A quick look at the `DashboardComponent` constructor discourages the first approach:",
"translation": "简单看看`DashbaordComponent`的构造函数就否决了第一种方案:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The [discussion below](guide/testing#routed-component) covers testing components that require the router.",
"translation": "[下面](guide/testing#routed-component) 涵盖了如何测试带有路由器的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### Test _DashboardHeroComponent_ stand-alone",
"translation": "### 独立测试_DashboardHeroComponent_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here's the spec file setup.",
"translation": "下面是spec文件的设置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The async `beforeEach` was discussed [above](guide/testing#component-with-external-template).\nHaving compiled the components asynchronously with `compileComponents`, the rest of the setup\nproceeds _synchronously_ in a _second_ `beforeEach`, using the basic techniques described [earlier](guide/testing#simple-component-test).",
"translation": "异步`beforeEach`已经在[上面](guide/testing#component-with-external-template)讨论过。\n在使用`compileComponents`异步编译完组件后,接下来的设置执行另一个**同步**的`beforeEach`,使用[之前](guide/testing#simple-component-test)解释过的基本知识。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Note how the setup code assigns a test hero (`expectedHero`) to the component's `hero` property, emulating\nthe way the `DashboardComponent` would set it via the property binding in its repeater.",
"translation": "注意代码是如何将模拟英雄(`expectedHero`)赋值给组件的`hero`属性的,模拟了`DashbaordComponent`在它的迭代器中通过属性绑定的赋值方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The first test follows:",
"translation": "紧接着第一个测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It verifies that the hero name is propagated to template with a binding.\nBecause the template passes the hero name through the Angular `UpperCasePipe`,\nthe test must match the element value with the uppercased name:",
"translation": "它验证了英雄名字通过绑定被传递到模板了。这里有个额外步骤。模板将英雄名字传给Angular的`UpperCasePipe`\n所以测试程序必须使用大写名字来匹配元素的值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This small test demonstrates how Angular tests can verify a component's visual\nrepresentation&mdash;something not possible with\n[isolated unit tests](guide/testing#isolated-component-tests)&mdash;at\nlow cost and without resorting to much slower and more complicated end-to-end tests.",
"translation": "这个小测试演示了Angular测试是如何验证组件的视图表现的 —— 这是[孤立的单元测试](guide/testing#isolated-component-tests)无法实现的\n—— 它成本低,而且无需依靠更慢、更复杂的端对端测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The second test verifies click behavior. Clicking the hero should raise a `selected` event that the\nhost component (`DashboardComponent` presumably) can hear:",
"translation": "第二个测试程序验证点击行为。点击英雄应该出发`selected`事件,可供宿主组件(`DashbaordComponent`)监听:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The component exposes an `EventEmitter` property. The test subscribes to it just as the host component would do.",
"translation": "这个组件公开`EventEmitter`属性。测试程序像宿主组件那样来描述它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `heroEl` is a `DebugElement` that represents the hero `<div>`.\nThe test calls `triggerEventHandler` with the \"click\" event name.\nThe \"click\" event binding responds by calling `DashboardHeroComponent.click()`.",
"translation": "`heroEl`是个`DebugElement`,它代表了英雄所在的`<div>`。\n测试程序用“click”事件名字来调用`triggerEventHandler`。\n调用`DashboardHeroComponent.click()`时“click”事件绑定作出响应。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "If the component behaves as expected, `click()` tells the component's `selected` property to emit the `hero` object,\nthe test detects that value through its subscription to `selected`, and the test should pass.",
"translation": "如果组件像期待的那样工作,`click()`通知组件的`selected`属性就会发出`hero`对象,测试程序通过订阅`selected`事件而检测到这个值,所以测试应该成功。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _triggerEventHandler_",
"translation": "### _triggerEventHandler_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "In this example, the test triggers a \"click\" event with a null event object.",
"translation": "本例中测试程序用null事件对象触发“click”事件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The test assumes (correctly in this case) that the runtime\nevent handler&mdash;the component's `click()` method&mdash;doesn't\ncare about the event object.",
"translation": "测试程序假设(在这里应该这样)运行时间的事件处理器——组件的`click()`方法——不关心事件对象。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Other handlers are less forgiving. For example, the `RouterLink`\ndirective expects an object with a `button` property\nthat identifies which mouse button was pressed.\nThis directive throws an error if the event object doesn't do this correctly.",
"translation": "其它处理器将会更加严格。\n比如`RouterLink`指令期待事件对象,并且该对象具有`button`属性,代表了已被按下的鼠标按钮。\n如果该事件对象不具备上面的条件指令便会抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Clicking a button, an anchor, or an arbitrary HTML element is a common test task.",
"translation": "点击按钮、链接或者任意HTML元素是很常见的测试任务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Make that easy by encapsulating the _click-triggering_ process in a helper such as the `click` function below:",
"translation": "把**click触发**过程封装到辅助方法中可以简化这个任务,比如下面的`click`辅助方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "click() is not an Angular testing utility",
"translation": "click()不是Angular测试工具",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Here's the previous test, rewritten using this click helper.",
"translation": "下面是使用了click辅助函数重新编写的上一个测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Test a component inside a test host component",
"translation": "## 在测试宿主组件中测试组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "In the previous approach, the tests themselves played the role of the host `DashboardComponent`.\nBut does the `DashboardHeroComponent` work correctly when properly data-bound to a host component?",
"translation": "在前面的方法中,测试本身扮演了宿主组件`DashbaordComponent`的角色。\n一种挥之不去的疑虑仍然存在当正常数据绑定到宿主组件时`DashboardHeroComponent`还会正常工作吗?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Testing with the actual `DashboardComponent` host is doable but seems more trouble than its worth.\nIt's easier to emulate the `DashboardComponent` host with a _test host_ like this one:",
"translation": "使用实际的`DashbaordComponent`宿主来测试是可行的,但是这么做似乎不合算。\n像下面这样使用**测试宿主组件**来模拟`DashbaordComponent`显得更加容易:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The test host binds to `DashboardHeroComponent` as the `DashboardComponent` would but without\nthe distraction of the `Router`, the `HeroService`, or even the `*ngFor` repeater.",
"translation": "测试宿主组件和`DashboardComponent`一样绑定`DashboardHeroComponent`,但是不用理会`Router`、`HeroService`服务,甚至`*ngFor`循环。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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\nin its `selectedHero` property. Later, the tests check that property to verify that the\n`DashboardHeroComponent.selected` event emitted the right hero.",
"translation": "测试宿主将组件的`hero`导入属性设置为它的模拟英雄。\n它将组件的`selected`事件绑定到它的`onSelected`处理器,使用`selectedHero`属性来记录发送来的英雄。\n然后测试检查这个属性来验证`DashboardHeroComponent.selected`事件确实发送了正确的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The setup for the test-host tests is similar to the setup for the stand-alone tests:",
"translation": "配置使用测试宿主的测试程序与配置孤立测试相似:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This testing module configuration shows two important differences:",
"translation": "这个测试模块配置展示了两个非常重要的区别:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. It _declares_ both the `DashboardHeroComponent` and the `TestHostComponent`.",
"translation": "它同时**声明**了`DashboardHeroComponent`和`TestHostComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. It _creates_ the `TestHostComponent` instead of the `DashboardHeroComponent`.",
"translation": "它**创建**了`TestHostComponent`,而非`DashboardHeroComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The tests themselves are almost identical to the stand-alone version:",
"translation": "这些测试本身和它们的孤立版本几乎相同:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "## Test a routed component",
"translation": "## 测试带路由器的组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Testing the actual `DashboardComponent` seemed daunting because it injects the `Router`.",
"translation": "测试实际的`DashbaordComponent`似乎令人生畏,因为它注入了`Router`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It also injects the `HeroService`, but faking that is a [familiar story](guide/testing#component-with-async-service).\nThe `Router` has a complicated API and is entwined with other services and application preconditions.",
"translation": "它同时还注入了`HeroService`,但是我们已经知道如何[伪造](guide/testing#component-with-async-service)它。\n`Router`的API非常复杂并且它缠绕了其它服务和许多应用的先决条件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Fortunately, the `DashboardComponent` isn't doing much with the `Router`",
"translation": "幸运的是,`DashbaordComponent`没有使用`Router`做很多事情。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This is often the case.\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.\nStubbing the router with a test implementation is an easy option. This should do the trick:",
"translation": "通常都是这样的。原则上,你测试的是组件,不是路由器,应该只关心在指定的条件下,组件是否导航到正确的地址。\n用模拟类来替换路由器是一种简单的方案。下面的代码应该可以",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Now set up the testing module with the test stubs for the `Router` and `HeroService`, and\ncreate a test instance of the `DashboardComponent` for subsequent testing.",
"translation": "现在我们来利用`Router`和`HeroService`的测试stub类来配置测试模块并为接下来的测试创建`DashboardComponent`的测试实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The following test clicks the displayed hero and confirms (with the help of a spy) that `Router.navigateByUrl` is called with the expected url.",
"translation": "下面的测试程序点击显示的英雄并利用spy来确认`Router.navigateByUrl`被调用了而且传进的url是所期待的值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### The _inject_ function",
"translation": "### _inject_函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Notice the `inject` function in the second `it` argument.",
"translation": "注意第二个`it`参数里面的`inject`函数。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `inject` function is one of the Angular testing utilities.\nIt injects services into the test function where you can alter, spy on, and manipulate them.",
"translation": "`inject`函数是Angular测试工具之一。\n它注入服务到测试函数以供修改、监视和操纵。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `inject` function has two parameters:",
"translation": "`inject`函数有两个参数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. An array of Angular dependency injection tokens.",
"translation": "一列数组包含了Angular依赖注入令牌",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. A test function whose parameters correspond exactly to each item in the injection token array.",
"translation": "一个测试函数,它的参数与注入令牌数组里的每个项目严格的一一对应。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "inject uses the TestBed Injector",
"translation": "使用TestBed注入器来注入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `inject` function uses the current `TestBed` injector and can only return services provided at that level.\nIt does not return services from component providers.",
"translation": "`inject`函数使用当前`TestBed`注入器,并且只返回这个级别提供的服务。\n它不会返回组件提供商提供的服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This example injects the `Router` from the current `TestBed` injector.\nThat's fine for this test because the `Router` is, and must be, provided by the application root injector.",
"translation": "这个例子通过当前的`TestBed`注入器来注入`Router`。\n对这个测试程序来说这是没问题的因为`Router`是(也必须是)由应用的根注入器来提供。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "If you need a service provided by the component's _own_ injector, call `fixture.debugElement.injector.get` instead:",
"translation": "如果你需要组件自己的注入器提供的服务,调用`fixture.debugElement.injector.get`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Use the component's own injector to get the service actually injected into the component.",
"translation": "使用组件自己的注入器来获取实际注入到组件的服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `inject` function 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": "`inject`函数关闭当前`TestBed`实例,使它无法再被配置。\n你不能再调用任何`TestBed`配置方法、`configureTestModule`或者任何`override...`方法,否则`TestBed`将抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Do not configure the `TestBed` after calling `inject`.",
"translation": "不要在调用`inject`以后再试图配置`TestBed`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Back to top",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "{@a routed-component-w-param}",
"translation": "### Test a routed component with parameters\n### 测试带有路由和路由参数的组件\nClicking a _Dashboard_ hero triggers navigation to `heroes/:id`, where `:id`\nis a route parameter whose value is the `id` of the hero to edit. \nThat URL matches a route to the `HeroDetailComponent`.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The router pushes the `:id` token value into the `ActivatedRoute.params` _Observable_ property,\nAngular injects the `ActivatedRoute` into the `HeroDetailComponent`,\nand the component extracts the `id` so it can fetch the corresponding hero via the `HeroDetailService`.\nHere's the `HeroDetailComponent` constructor:",
"translation": "路由器将`:id`令牌的值推送到`ActivatedRoute.params`**可观察**属性里,\nAngular注入`ActivatedRoute`到`HeroDetailComponent`中,\n然后组件提取`id`,这样它就可以通过`HeroDetailService`获取相应的英雄。\n下面是`HeroDetailComponent`的构造函数:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "`HeroDetailComponent` subscribes to `ActivatedRoute.params` changes in its `ngOnInit` method.",
"translation": "`HeroDetailComponent`在它的`ngOnInit`方法中监听`ActivatedRoute.params`的变化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The expression after `route.params` chains an _Observable_ operator that _plucks_ the `id` from the `params`\nand then chains a `forEach` operator to subscribe to `id`-changing events.\nThe `id` changes every time the user navigates to a different hero.",
"translation": "`route.params`之后的表达式链接了**可观察**操作符,它从`params`中提取`id`,然后链接`forEach`操作符来订阅`id`变化事件。\n每次`id`变化时,用户被导航到不同的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `forEach` passes the new `id` value to the component's `getHero` method (not shown)\nwhich fetches a hero and sets the component's `hero` property.\nIf the`id` parameter is missing, the `pluck` operator fails and the `catch` treats failure as a request to edit a new hero.",
"translation": "`forEach`将新的`id`值传递到组件的`getHero`方法(这里没有列出来),它获取英雄并将它赋值到组件的`hero`属性。\n如果`id`参数无效,`pluck`操作符就会失败,`catch`将失败当作创建新英雄来处理。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [Router](guide/router#route-parameters) guide covers `ActivatedRoute.params` in more detail.",
"translation": "[路由器](guide/router#route-parameters)章更详尽的讲述了`ActivatedRoute.params`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "A test 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/content-1/guide/testing.md"
},
{
"original": "By now you know how to stub the `Router` and a data service.\nStubbing the `ActivatedRoute` follows the same pattern except for a complication:\nthe `ActivatedRoute.params` is an _Observable_.",
"translation": "现在,你已经知道如何模拟`Router`和数据服务。\n模拟`ActivatedRoute`遵循类似的模式,但是有个额外枝节:`ActivatedRoute.params`是**可观察对象**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Create an _Observable_ test double",
"translation": "### **可观察对象**的测试替身",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `hero-detail.component.spec.ts` relies on an `ActivatedRouteStub` to set `ActivatedRoute.params` values for each test.\nThis is a cross-application, re-usable _test helper class_.\nConsider placing such helpers in a `testing` folder sibling to the `app` folder.\nThis sample keeps `ActivatedRouteStub` in `testing/router-stubs.ts`:",
"translation": "`hero-detail.component.spec.ts`依赖`ActivatedRouteStub`来为每个测试程序设置`ActivatedRoute.params`值。\n它是跨应用、可复用的**测试辅助类**。\n我们建议将这样的辅助类放到`app`目录下的名为`testing`的目录。\n本例把`ActivatedRouteStub`放到`testing/router-stubs.ts`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Notable features of this stub are:",
"translation": "这个stub类有下列值得注意的特征",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* The stub implements only two of the `ActivatedRoute` capabilities: `params` and `snapshot.params`.",
"translation": "这个stub类只实现`ActivatedRoute`的两个功能:`params`和`snapshot.params`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* <a href=\"https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md\">_BehaviorSubject_</a>\ndrives the stub's `params` _Observable_ and returns the same value to every `params` subscriber until it's given a new value.",
"translation": "<a href=\"https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md\" target=\"_blank\">_BehaviorSubject_</a>驱使这个stub类的`params`可观察对象,并为每个`params`的订阅者返回同样的值,直到它接受到新值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* The `HeroDetailComponent` chains its expressions to this stub `params` _Observable_ which is now under the tester's control.",
"translation": "`HeroDetailComponent`链接它的表达式到这个stub类的`params`可观察对象,该对象现在被测试者的控制之下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Setting the `testParams` property causes the `subject` to push the assigned value into `params`.\n That triggers the `HeroDetailComponent` _params_ subscription, described above, in the same way that navigation does.",
"translation": "设置`testParams`属性导致`subject`将指定的值推送进`params`。它触发上面描述过的`HeroDetailComponent`的`params`订阅,和导航的方式一样。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Setting the `testParams` property also updates the stub's internal value for the `snapshot` property to return.",
"translation": "设置`testParams`属性同时更新这个stub类内部值用于`snapshot`属性的返回。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [_snapshot_](guide/router#snapshot \"Router guide: snapshot\") is another popular way for components to consume route parameters.",
"translation": "[_snapshot_](guide/router#snapshot \"Router Chapter: snapshot\")是组件使用路由参数的另一种流行的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The router stubs in this guide are meant to inspire you. Create your own stubs to fit your testing needs.",
"translation": "本章的路由器stub类是为了给你灵感。创建你自己的stub类以适合你的测试需求。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Testing with the _Observable_ test double",
"translation": "### 测试**可观察对象**的替身",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The `createComponent` method and `page` object are discussed [in the next section](guide/testing#page-object).\nRely on your intuition for now.",
"translation": "[下一节](guide/testing#page-object)将解释`createComponent`方法和`page`对象,现在暂时跟着自己的直觉走。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "When the `id` cannot be found, the component should re-route to the `HeroListComponent`.\nThe test suite setup provided the same `RouterStub` [described above](guide/testing#routed-component) which spies on the router without actually navigating.\nThis test supplies a \"bad\" id and expects the component to try to navigate.",
"translation": "当无法找到`id`时,组件应该重新导航到`HeroListComponent`。\n该测试套件配置与[上面描述](guide/testing#routed-component)的`RouterStub`一样,它在不实际导航的情况下刺探路由器。\n该测试程序提供了“坏”的id期望组件尝试导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Inspect and download _all_ of the guide's application test code with this <live-example plnkr=\"app-specs\" embedded-style>live example</live-example>.",
"translation": "到<live-example plnkr=\"app-specs\">在线例子</live-example>查看和下载**所有**本章应用程序测试代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Use a _page_ object to simplify setup",
"translation": "## 使用**page**对象来简化配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `HeroDetailComponent` is a simple view with a title, two hero fields, and two buttons.",
"translation": "`HeroDetailComponent`是带有标题、两个英雄字段和两个按钮的简单视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "But there's already plenty of template complexity.",
"translation": "但是它已经有很多模板复杂性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "To fully exercise the component, the test needs a lot of setup:",
"translation": "要彻底测试该组件,测试程序需要一系列设置:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* It must wait until a hero arrives before `*ngIf` allows any element in DOM.",
"translation": "它必须在`*ngIf`允许元素进入DOM之前等待`hero`的到来",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* It needs references to the title `<span>` and the name `<input>` so it can inspect their values.",
"translation": "它需要标题名字span和名字输入框元素的引用用来检查它们的值",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* It needs references to the two buttons so it can click them.",
"translation": "它需要两个按钮的引用,以便点击它们",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* It needs spies for some of the component and router methods.",
"translation": "刺探spy组件和路由器的方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Tame the madness with a `Page` class that simplifies access to component properties and encapsulates the logic that sets them.\nHere's the `Page` class for the `hero-detail.component.spec.ts`",
"translation": "通过简化组件属性的访问和封装设置属性的逻辑,`Page`类可以轻松解决这个令人抓狂的难题。\n下面是为`hero-detail.component.spec.ts`准备的`page`类:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "A `createComponent` method creates a `page` objectand fills in the blanks once the `hero` arrives.",
"translation": "`createComponent`方法创建`page`,在`hero`到来时,自动填补空白。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [observable tests](guide/testing#tests-w-observable-double) in the previous 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": "上一节的[可观察对象测试](guide/testing#tests-w-observable-double)展示了`createComponent`和`page`如何让测试程序简短和即时。\n没有任何干扰无需等待承诺的解析也没有搜索DOM元素值进行比较。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here are a few more `HeroDetailComponent` tests to drive the point home.",
"translation": "这里是一些更多的`HeroDetailComponent`测试程序,进一步的展示了这一点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "</code-example>",
"translation": "回到顶部",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Setup with module imports",
"translation": "## 模块导入imports的配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Earlier component tests configured the testing module with a few `declarations` like this:",
"translation": "此前的组件测试程序使用了一些`declarations`来配置模块,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "* `NgModel` and friends in the `FormsModule` to enable two-way data binding.",
"translation": "`FormsModule`里的`NgModel`和其它,来进行双向数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* The `TitleCasePipe` from the `shared` folder.",
"translation": "`shared`目录里的`TitleCasePipe`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Router services (which these tests are stubbing).",
"translation": "一些路由器服务测试程序将stub伪造它们",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Hero data access services (also stubbed).",
"translation": "英雄数据访问服务同样被stub伪造了",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "One approach is to configure the testing module from the individual pieces as in this example:",
"translation": "一种方法是在测试模块中一一配置,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Because many app components need the `FormsModule` and the `TitleCasePipe`, the developer created\na `SharedModule` to combine these and other frequently requested parts.\nThe test configuration can use the `SharedModule` too as seen in this alternative setup:",
"translation": "因为许多应用组件需要`FormsModule`和`TitleCasePipe`,所以开发者创建了`SharedModule`来合并它们和一些频繁需要的部件。\n测试配置也可以使用`SharedModule`,请看下面另一种配置:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It's a bit tighter and smaller, with fewer import statements (not shown).",
"translation": "它的导入声明少一些(未显示),稍微干净一些,小一些。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Import the feature module",
"translation": "### 导入特性模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `HeroDetailComponent` is part of the `HeroModule` [Feature Module](guide/ngmodule#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/ngmodule#feature-modules)的一部分,它组合了更多互相依赖的部件,包括`SharedModule`。\n试试下面这个导入`HeroModule`的测试配置:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "In fact, if you try to declare it, Angular throws an error because\n`HeroDetailComponent` is declared in both the `HeroModule` and the `DynamicTestModule` (the testing module).",
"translation": "事实上如果里试图声明它Angular会抛出错误因为`HeroDetailComponent`已经在`HeroModule`和测试模块的`DynamicTestModule`中声明。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Importing the component's feature module is often the easiest way to configure the tests,\nespecially when the feature module is small and mostly self-contained, as feature modules should be.",
"translation": "导入组件的特性模块通常是最简单的配置测试的方法,\n尤其是当特性模块很小而且几乎自包含时...特性模块应该是自包含的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Override a component's providers",
"translation": "## 重载组件的提供商",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `HeroDetailComponent` provides its own `HeroDetailService`.",
"translation": "`HeroDetailComponent`提供自己的`HeroDetailService`服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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.\nA test cannot get to child injector services from the fixture injector.\nAnd `TestBed.configureTestingModule` can't configure them either.",
"translation": "Angular创建组件时该组件有自己的注入器它是fixture注入器的子级。\nAngular使用这个子级注入器来注册组件的提供商也就是`HeroDetailService`)。\n测试程序无法从fixture的注入器获取这个子级注入器。\n而且`TestBed.configureTestingModule`也无法配置它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Angular has been creating new instances of the real `HeroDetailService` all along!",
"translation": "Angular始终都在创建真实`HeroDetailService`的实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Fortunately, the `HeroDetailService` delegates responsibility for remote data access to an injected `HeroService`.",
"translation": "幸运的是,`HeroDetailService`将远程数据访问的责任交给了注入进来的`HeroService`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [previous test configuration](guide/testing#feature-module-import) replaces the real `HeroService` with a `FakeHeroService`\nthat intercepts server requests and fakes their responses.",
"translation": "[之前的测试配置](guide/testing#feature-module-import)将真实的`HeroService`替换为`FakeHeroService`,拦截了服务起请求,伪造了它们的响应。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Notice that `TestBed.configureTestingModule` no longer provides a (fake) `HeroService` because it's [not needed](guide/testing#spy-stub).",
"translation": "注意,`TestBed.configureTestingModule`不再提供(伪造)`HeroService`,因为已经[没有必要了](guide/testing#spy-stub)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### The _overrideComponent_ method",
"translation": "### **overrideComponent**方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Focus on the `overrideComponent` method.",
"translation": "注意这个`overrideComponent`方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It takes two arguments: the component type to override (`HeroDetailComponent`) and an override metadata object.\nThe [overide metadata object](guide/testing#metadata-override-object) is a generic defined as follows:",
"translation": "它接受两个参数:要重载的组件类型(`HeroDetailComponent`)和用于重载的元数据对象。\n[重载元数据对象](guide/testing#metadata-override-object)是泛型类,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### Provide a _spy stub_ (_HeroDetailServiceSpy_)",
"translation": "### 提供一个*刺探桩Spy stub*`HeroDetailServiceSpy`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### The override tests",
"translation": "### 重载的测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### More overrides",
"translation": "### 更多重载",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Explore the options and combinations on your own.",
"translation": "自己探索这些选项和组合。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Test a _RouterOutlet_ component",
"translation": "## 测试带有_RouterOutlet_的组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `AppComponent` displays routed components in a `<router-outlet>`.\nIt also displays a navigation bar with anchors and their `RouterLink` directives.",
"translation": "`AppComponent`在`<router-outlet>`中显示导航组件。\n 它还显示了导航条,包含了链接和它们的`RouterLink`指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The component class does nothing.",
"translation": "组件的类没有做任何事。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Unit tests can confirm that the anchors are wired properly without engaging the router.\nSee why this is worth doing [below](guide/testing#why-stubbed-routerlink-tests).",
"translation": "在不涉及路由的情况下,单元测试可以确认链接的设置是否正确。\n参见[下面的内容](guide/testing#why-stubbed-routerlink-tests),了解为什么值得这么做。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Stubbing unneeded components",
"translation": "### stub伪造不需要的组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The test setup should look familiar.",
"translation": "该测试配置应该看起来很眼熟:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `AppComponent` is the declared test subject.",
"translation": "`AppComponent`是被声明的测试对象。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The setup extends the default testing module with one real component (`BannerComponent`) and several stubs.",
"translation": "使用一个真实的组件(`BannerComponent`和几个stub该配置扩展了默认测试模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* `BannerComponent` is simple and harmless to use as is.",
"translation": "原样使用`BannerComponent`非常简单而且无害。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* The real `WelcomeComponent` has an injected service. `WelcomeStubComponent` is a placeholder with no service to worry about.",
"translation": "真实的`WelcomeComponent`有被注入的服务。`WelcomeStubComponent`是无服务的替代品。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* The real `RouterOutlet` is complex and errors easily.\nThe `RouterOutletStubComponent` (in `testing/router-stubs.ts`) is safely inert.",
"translation": "真实的`RouterOutlet`很复杂而且容易出错。\n`testing/router-stubs.ts`里的`RouterOutletStubComponent`是安全的替代品。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The component stubs are essential. \nWithout them, the Angular compiler doesn't recognize the `<app-welcome>` and `<router-outlet>` tags \nand throws an error.",
"translation": "组件stub替代品很关键。\n没有它们Angular编译器无法识别`<app-welcome`和`<router-outlet>`标签,抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Stubbing the _RouterLink_",
"translation": "### Stub伪造_RouterLink_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `RouterLinkStubDirective` contributes substantively to the test:",
"translation": "`RouterLinkStubDirective`为测试作出了重要的贡献:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `host` metadata property wires the click event of the host element (the `<a>`) to the directive's `onClick` method.\nThe URL bound to the `[routerLink]` attribute flows to the directive's `linkParams` property.\nClicking the anchor should trigger the `onClick` method which sets the telltale `navigatedTo` property.\nTests can inspect that property to confirm the expected _click-to-navigation_ behavior.",
"translation": "`host`元数据属性将宿主元素(`<a>`)的click事件与指令的`onClick`方法关联起来。\n绑定到`[routerLink]`的URL属性被传递到指令的`linkParams`属性。\n点击这个链接应该能触发`onClick`方法,从而设置`navigatedTo`属性。\n测试程序可以查看这个属性来确认期望的**点击导航**行为。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _By.directive_ and injected directives",
"translation": "### _By.directive_和注入的指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "A little more setup triggers the initial data binding and gets references to the navigation links:",
"translation": "再一步配置触发了数据绑定的初始化,获取导航链接的引用:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Two points of special interest:",
"translation": "特别值得注意的两点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. You can locate elements _by directive_, using `By.directive`, not just by css selectors.",
"translation": "你还可以按指令定位元素,使用`By.directive`而不仅仅是通过CSS选择器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "1. You can use the component's dependency injector to get an attached directive because\nAngular always adds attached directives to the component's injector.",
"translation": "你可以使用组件的依赖注入器来获取附加的指令因为Angular总是将附加组件添加到组件的注入器中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here are some tests that leverage this setup:",
"translation": "下面是一些使用这个配置的测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The \"click\" test _in this example_ is worthless.\nIt works hard to appear useful when in fact it\ntests the `RouterLinkStubDirective` rather than the _component_.\nThis is a common failing of directive stubs.",
"translation": "本例中的“click”测试程序其实毫无价值。\n它显得很有用但是事实上它测试的是`RouterLinkStubDirective`,而非测试组件。\n这是指令stub的通病。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### What good are these tests?",
"translation": "### 这些测试有什么好处?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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": "stub伪造的`RouterLink`测试可以确认带有链接和outlet的组件的设置的正确性确认组件有应该有的链接确认它们都指向了正确的方向。\n这些测试程序不关心用户点击链接时应用是否会成功的导航到目标组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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": "对于这样局限的测试目标stub伪造RouterLink和RouterOutlet是最佳选择。\n依靠真正的路由器会让它们很脆弱。\n它们可能因为与组件无关的原因而失败。\n例如一个导航守卫可能防止没有授权的用户访问`HeroListComponent`。\n这并不是`AppComponent`的过错,并且无论该组件怎么改变都无法修复这个失败的测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "A future guide update will explain how to write such tests with the `RouterTestingModule`.",
"translation": "未来本章的更新将介绍如何使用`RouterTestingModule`来编写这样的测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## \"Shallow component tests\" with *NO\\_ERRORS\\_SCHEMA*",
"translation": "## 使用*NO\\_ERRORS\\_SCHEMA*来“浅化”组件测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The [previous setup](guide/testing#stub-component) declared the `BannerComponent` and stubbed two other components\nfor _no reason other than to avoid a compiler error_.",
"translation": "[以前的配置](guide/testing#stub-component)声明了`BannerComponent`并stub伪造了两个其它组件**仅仅是为了避免编译错误,不是为别的原因**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Without them, the Angular compiler doesn't recognize the `<app-banner>`, `<app-welcome>` and `<router-outlet>` tags \nin the [_app.component.html_](guide/testing#app-component-html) template and throws an error.",
"translation": "没有它们Angular编译器无法识别[_app.component.html_](guide/testing#app-component-html)模板里的`<app-banner>`、`<app-welcome>`和`<router-outlet>`标签,并抛出错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Add `NO_ERRORS_SCHEMA` to the testing module's `schemas` metadata\nto tell the compiler to ignore unrecognized elements and attributes.\nYou no longer have to declare irrelevant components and directives.",
"translation": "添加`NO_ERRORS_SCHEMA`到测试模块的`schemas`元数据中,告诉编译器忽略不认识的元素和属性。\n这样你不再需要声明无关组件和指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "These tests are ***shallow*** because they only \"go deep\" into the components you want to test.\nHere is a setup, with `import` statements, that demonstrates the improved simplicity of _shallow_ tests, relative to the stubbing setup.",
"translation": "这些测试程序比较**浅**,因为它们只“深入”到你要测试的组件。\n这里是一套配置拥有`import`语句体现了相比使用stub伪造的配置来说**浅**测试程序的简单性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The _only_ declarations are the _component-under-test_ (`AppComponent`) and the `RouterLinkStubDirective`\nthat contributes actively to the tests.\nThe [tests in this example](guide/testing#app-component-tests) are unchanged.",
"translation": "这里**唯一**声明的是**被测试的组件**(`AppComponent`)和测试需要的`RouterLinkStubDirective`。\n没有改变任何[原测试程序](guide/testing#app-component-tests)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "_Shallow component tests_ with `NO_ERRORS_SCHEMA` greatly simplify unit testing of complex templates.\nHowever, the compiler no longer alerts you to mistakes\nsuch as misspelled or misused components and directives.",
"translation": "使用`NO_ERRORS_SCHEMA`的**浅组件测试程序**很大程度上简化了拥有复杂模板组件的单元测试。\n但是编译器将不再提醒你一些错误比如模板中拼写错误或者误用的组件和指令。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Test an attribute directive",
"translation": "## 测试属性指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "It's used throughout the application, perhaps most simply in the `AboutComponent`:",
"translation": "它的使用贯穿整个应用,也许最简单的使用在`AboutComponent`里:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Testing the specific use of the `HighlightDirective` within the `AboutComponent` requires only the\ntechniques explored above (in particular the [\"Shallow test\"](guide/testing#shallow-component-test) approach).",
"translation": "使用`AboutComponent`来测试这个`HightlightDirective`的使用,只需要上面解释过的知识就够了,(尤其是[\"浅测试程序\"](guide/testing#shallow-component-test)方法)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "[Isolated unit tests](guide/testing#isolated-unit-tests) might be helpful, \nbut attribute directives like this one tend to manipulate the DOM. \nIsolated unit tests don't touch the DOMand, therefore ,\ndo not inspire confidence in the directive's efficacy.",
"translation": "[孤立单元测试](guide/testing#isolated-unit-tests)可能有用。\n但是像这样的属性指令一般都操纵DOM。孤立单元测试不能控制DOM所以不推荐用它测试指令的功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Here are some tests of this component:",
"translation": "下面是一些该组件的测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "A few techniques are noteworthy:",
"translation": "一些技巧值得注意:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "* `DebugElement.properties` affords access to the artificial custom property that is set by the directive.",
"translation": "`DebugElement.properties`让我们可以访问由指令设置的自定义属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Isolated Unit Tests",
"translation": "## 孤立的单元测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Testing applications with the help of the Angular testing utilities is the main focus of this guide.",
"translation": "使用Angular测试工具测试应用程序是本章的重点。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "However, it's often more productive to explore the inner logic of application classes\nwith _isolated_ unit tests that don't depend upon Angular.\nSuch tests are often smaller and easier to read, write, and maintain.",
"translation": "但是,使用**孤立**单元测试来探索应用类的内在逻辑往往更加有效率它不依赖Angular。\n 这种测试程序通常比较小、更易阅读、编写和维护。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "They don't carry extra baggage:",
"translation": "它们不用背负额外的包袱:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Import from the Angular test libraries.",
"translation": "从Angular测试库导入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Configure a module.",
"translation": "配置模块",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Prepare dependency injection `providers`.",
"translation": "准备依赖注入`providers`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Call `inject` or `async` or `fakeAsync`.",
"translation": "调用`inject`,或者`async`,或者`fakeAsync`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "They follow patterns familiar to test developers everywhere:",
"translation": "它们会遵循测试时众所周知的模式:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Exhibit standard, Angular-agnostic testing techniques.",
"translation": "使用标准的、与Angular无关的测试技巧",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Create instances directly with `new`.",
"translation": "直接使用`new`创建实例",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Substitute test doubles (stubs, spys, and mocks) for the real dependencies.",
"translation": "用测试替身stubspy和mock替代真正的依赖",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Write both kinds of tests",
"translation": "同时采用这两种测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Good developers write both kinds of tests for the same application part, often in the same spec file.\nWrite simple _isolated_ unit tests to validate the part in isolation.\nWrite _Angular_ tests to validate the part as it interacts with Angular,\nupdates the DOM, and collaborates with the rest of the application.",
"translation": "优秀的开发者同时编写这两种测试程序来测试相同的应用部件往往在同一个spec文件。\n编写简单的**孤立**单元测试程序来验证孤立的部分。\n编写**Angular**测试程序来验证与Angular互动、更新DOM、以及与应用其它部分互动的部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Services",
"translation": "### 服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Services are good candidates for isolated unit testing.\nHere are some synchronous and asynchronous unit tests of the `FancyService`\nwritten without assistance from Angular testing utilities.",
"translation": "服务是应用孤立测试的好例子。\n下面是未使用Angular测试工具的一些`FancyService`的同步和异步单元测试:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "A rough line count suggests that these isolated unit tests are about 25% smaller than equivalent Angular tests.\nThat's telling but not decisive.\nThe benefit comes from reduced setup and code complexity.",
"translation": "粗略行数表明这些孤立单元测试比同等的Angular测试小25%。\n这表明了它的好处但是不是最关键的。\n主要的好处来自于缩减的配置和代码的复杂性。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Compare these equivalent tests of `FancyService.getTimeoutValue`.",
"translation": "比较下面两个同等的`FancyService.getTimeoutValue`测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "They have about the same line-count, but the Angular-dependent version\nhas more moving parts including a couple of utility functions (`async` and `inject`).\nBoth approaches work and it's not much of an issue if you're using the\nAngular testing utilities nearby for other reasons.\nOn the other hand, why burden simple service tests with added complexity?",
"translation": "它们有类似的行数。\n但是依赖Angular的版本有更多活动的部分包括一些工具函数`async`和`inject`)。\n两种方法都可行而且如果你为了某些原因使用Angular测试工具也并没有什么问题。\n反过来为什么要为简单的服务测试程序添加复杂度呢",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Pick the approach that suits you.",
"translation": "选择你喜欢的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Services with dependencies",
"translation": "### 带依赖的服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Services often depend on other services that Angular injects into the constructor.\nYou can test these services _without_ the `TestBed`.\nIn many cases, it's easier to create and _inject_ dependencies by hand.",
"translation": "服务通常依赖其它服务Angular通过构造函数注入它们。\n你可以**不使用**TestBed测试这些服务。\n在许多情况下创建和手动**注入**依赖来的更加容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `DependentService` is a simple example:",
"translation": "`DependentService`是一个简单的例子:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It delegates its only method, `getValue`, to the injected `FancyService`.",
"translation": "它将唯一的方法,`getValue`,委托给了注入的`FancyService`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here are several ways to test it.",
"translation": "这里是几种测试它的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The first test creates a `FancyService` with `new` and passes it to the `DependentService` constructor.",
"translation": "第一个测试程序使用`new`创建`FancyService`实例,并将它传递给`DependentService`构造函数。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "However, it's rarely that simple. The injected service can be difficult to create or control.\nYou can mock the dependency, use a dummy value, or stub the pertinent service method\nwith a substitute method that 's easy to control.",
"translation": "很少有这么简单的,注入的服务有可能很难创建和控制。\n你可以mock依赖或者使用假值或者用易于控制的替代品stub伪造相关服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "These _isolated_ unit testing techniques are great for exploring the inner logic of a service or its\nsimple integration with a component class.\nUse the Angular testing utilities when writing tests that validate how a service interacts with components\n_within the Angular runtime environment_.",
"translation": "这些**孤立**单元测试技巧是一个很好的方法,用来探索服务的内在逻辑,以及它与组件类简单的集成。\n当在**运行时间环境下**使用Angular测试工具来验证一个服务是如何与组件互动的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Pipes",
"translation": "### 管道\nPipes are easy to test without the Angular testing utilities.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### Write Angular tests too",
"translation": "### 同时也编写Angular测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Consider adding component tests such as this one:",
"translation": "考虑像这样添加组件测试程序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Components",
"translation": "### 组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Component tests typically examine how a component class interacts with its own template or with collaborating components.\nThe Angular testing utilities are specifically designed to facilitate such tests.",
"translation": "组件测试通常检查该组件类是如何与自己的模板或者其它合作组件交互的。\nAngular测试工具是专门为这种测试设计的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Consider this `ButtonComp` component.",
"translation": "考虑这个`ButtonComp`组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The following Angular test demonstrates that clicking a button in the template leads\nto an update of the on-screen message.",
"translation": "下面的Angular测试演示点击模板里的按钮后引起了屏幕上的消息的更新。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The assertions verify that the data values flow from one HTML control (the `<button>`) to the component and\nfrom the component back to a _different_ HTML control (the `<span>`).\nA passing test means the component and its template are wired correctly.",
"translation": "该判断验证了数据绑定从一个HTML控件(`<button>`)流动到组件,以及从组件回到**不同**的HTML控件(`<span>`)。\n通过的测试程序说明组件和它的模块是否设置正确。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Isolated unit tests can more rapidly probe a component at its API boundary,\nexploring many more conditions with less effort.",
"translation": "孤立单元测试可以更快的在API边界探测组件更轻松的探索更多条件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here are a set of unit tests that verify the component's outputs in the face of a variety of\ncomponent inputs.",
"translation": "下面是一套单元测试程序,用来验证面对多种输入时组件的输出。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Isolated component tests offer a lot of test coverage with less code and almost no setup.\nThis is even more of an advantage with complex components, which\nmay require meticulous preparation with the Angular testing utilities.",
"translation": "孤立组件单元测试使用更少的代码以及几乎不存在的配置,提供了很多测试覆盖率。\n在测试复杂的组件时这个优势显得更加明显因为可能需要使用Angular测试工具进行精心准备。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "On the other hand, isolated unit tests can't confirm that the `ButtonComp` is\nproperly bound to its template or even data bound at all.\nUse Angular tests for that.",
"translation": "但是,孤立测试无法确认`ButtonComp`是否与其模板正确的绑定,或者是否有数据绑定。\n使用Angular测试来应对它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## Angular testing utility APIs",
"translation": "## Angular测试工具API",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This section takes inventory of the most useful Angular testing features and summarizes what they do.",
"translation": "本节将最有用的Angular测试功能提取出来并总结了它们的作用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The Angular testing utilities include the `TestBed`, the `ComponentFixture`, and a handful of functions that control the test environment.\nThe [_TestBed_](guide/testing#testbed-api-summary) and [_ComponentFixture_](guide/testing#component-fixture-api-summary) classes are covered separately.",
"translation": "Angular测试工具包括`TestBed`、`ComponentFixture`和一些其他函数,用来控制测试环境。\n[_TestBed_](guide/testing#testbed-api-summary)和[_ComponentFixture_](guide/testing#component-fixture-api-summary)在这里分别解释了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here's a summary of the stand-alone functions, in order of likely utility:",
"translation": "下面是一些独立函数的总结,以使用频率排序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Function",
"translation": "函数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Runs the body of a test (`it`) or setup (`beforeEach`) function within a special _async test zone_.\n See [discussion above](guide/testing#async).",
"translation": "在特殊的**async测试区域**运行测试程序(`it`)或者设置(`beforeEach`)的主体。\n 参见[上面的讨论](guide/testing#async).\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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](guide/testing#fake-async).",
"translation": "在特殊的**fakeAsync测试区域**运行测试程序(`it`)的主体,造就控制流更加线性的代码风格。\n 参见[上面的讨论](guide/testing#fake-async).\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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](guide/testing#tick).",
"translation": "接受一个可选参数,往前推移虚拟时间提供数字的毫秒数,清除在这段时间内的异步行为。\n 参见[上面的讨论](guide/testing#tick)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Injects one or more services from the current `TestBed` injector into a test function.\n See [above](guide/testing#inject).",
"translation": "从当前`TestBed`注入器注入一个或多个服务到测试函数。参见[上面](guide/testing#inject)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "A provider token for a service that turns on [automatic change detection](guide/testing#automatic-change-detection).",
"translation": "一个提供商令牌,用来设置**auto-changeDetect**的值,它默认值为`false`。\n 参见[自动变更检测](guide/testing#automatic-change-detection)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### _TestBed_ class summary",
"translation": "### _TestBed_ 类总结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The module definition passed to `configureTestingModule` \nis a subset of the `@NgModule` metadata properties.",
"translation": "传递给`configureTestingModule`的模块定义是`@NgModule`元数据属性的子集。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Call `TestBed` methods _within_ a `beforeEach()` to ensure a fresh start before each individual test.",
"translation": "在`BeforeEach()`内调用`TestBed`方法,这样确保在运行每个单独测试时,都有崭新的开始。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here are the most important static methods, in order of likely utility.",
"translation": "这里列出了最重要的静态方法,以使用频率排序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Methods",
"translation": "方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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](guide/testing#compile-components).",
"translation": "在你完成配置以后异步编译测试模块。\n 如果**任何**测试组件有`templateUrl`或`styleUrls`,那么你**必须**调用这个方法。因为获取组件模块和样式文件必须是异步的。\n 参见[上面的描述](guide/testing#compile-components)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec.",
"translation": "调用完`compileComponents`之后,`TestBed`的配置就会在当前测试期间被冻结。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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`的配置就会在当前测试期间被冻结。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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`方法可以深入到当前测试模块深处,修改其中一个内部模块。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Replace metadata for the given component class, which could be nested deeply\n within an inner module.",
"translation": "替换指定组件类的元数据,该组件类可能嵌套在一个很深的内部模块中。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Replace metadata for the given directive class, which could be nested deeply\n within an inner module.",
"translation": "替换指定指令类的元数据,该指令可能嵌套在一个很深的内部模块中。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Replace metadata for the given pipe class, which could be nested deeply\n within an inner module.",
"translation": "替换指定管道类的元数据,该管道可能嵌套在一个很深的内部模块中。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Retrieve a service from the current `TestBed` injector.",
"translation": "从当前`TestBed`注入器获取一个服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `inject` function is often adequate for this purpose.\n But `inject` throws an error if it can't provide the service.\n What if the service is optional?",
"translation": "`inject`函数通常很适合这个任务。\n 但是如果`inject`不能提供服务,它会抛出错误。\n 如果服务是可选的呢?",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "After calling `get`, the `TestBed` configuration is frozen for the duration of the current spec.",
"translation": "一旦调用,`TestBed`的配置就会在当前测试期间被冻结。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Initialize the testing environment for the entire test run.",
"translation": "为整套测试的运行初始化测试环境。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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>`的形式提供非浏览器平台的替代品。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Reset the initial test environment, including the default testing module.",
"translation": "重设初始测试环境,包括默认测试模块在内。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### The _ComponentFixture_",
"translation": "### _ComponentFixture_对象",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### _ComponentFixture_ properties",
"translation": "### _ComponentFixture_的属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here are the most important properties for testers, in order of likely utility.",
"translation": "下面是对测试最重要的属性,以使用频率排序:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Properties",
"translation": "属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The instance of the component class created by `TestBed.createComponent`.",
"translation": "被`TestBed.createComponent`创建的组件类实例。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `DebugElement` associated with the root element of the component.",
"translation": "与组件根元素关联的`DebugElement`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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](guide/testing#debug-element-details).",
"translation": "`debugElement`在测试和调试期间提供对组件及其DOM元素的访问。\n 它是测试者至关重要的属性。它最有用的成员在[下面](guide/testing#debug-element-details)有所介绍。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The native DOM element at the root of the component.",
"translation": "组件的原生根DOM元素。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `ChangeDetectorRef` for the component.",
"translation": "组件的`ChangeDetectorRef`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "### _ComponentFixture_ methods",
"translation": "### _ComponentFixture_的方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Here are the most useful methods for testers.",
"translation": "下面是对测试最有用的方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Methods",
"translation": "方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Trigger a change detection cycle for the component.",
"translation": "为组件触发一轮变化检查。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Runs `checkNoChanges`afterwards to confirm that there are no circular updates unless\n called as `detectChanges(false)`;",
"translation": "之后,运行`checkNoChanges`,来确认没有循环更新,除非它被这样调用:`detectChanges(false)`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Set this to `true` when you want the fixture to detect changes automatically.",
"translation": "设置fixture是否应该自动试图检测变化。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Do a change detection run to make sure there are no pending changes.\n Throws an exceptions if there are.",
"translation": "运行一次变更检测来确认没有待处理的变化。如果有未处理的变化,它将抛出一个错误。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Returns a promise that resolves when the fixture is stable.",
"translation": "返回一个承诺在fixture稳定时解析。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "To resume testing after completion of asynchronous activity or\n asynchronous change detection, hook that promise.\n See [above](guide/testing#when-stable).",
"translation": "钩住这个承诺,以在异步行为或者异步变更检测之后继续测试。参见[上面](guide/testing#when-stable)。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Trigger component destruction.",
"translation": "触发组件的销毁。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### _DebugElement_",
"translation": "### _DebugElement_ 方法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The `DebugElement` provides crucial insights into the component's DOM representation.",
"translation": "`DebugElement`提供了对组件的DOM的访问。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "Here are the most useful `DebugElement` members for testers, in approximate order of utility:",
"translation": "下面是`DebugElement`最有用的成员,以使用频率排序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Member",
"translation": "成员",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The corresponding DOM element in the browser (null for WebWorkers).",
"translation": "与浏览器中DOM元素对应WebWorkers时值为null。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Calling `query(predicate: Predicate<DebugElement>)` returns the first `DebugElement`\n that matches the [predicate](guide/testing#query-predicate) at any depth in the subtree.",
"translation": "调用`query(predicate: Predicate<DebugElement>)`返回子树所有层中第一个匹配[predicate](guide/testing#query-predicate)的`DebugElement`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Calling `queryAll(predicate: Predicate<DebugElement>)` returns all `DebugElements`\n that matches the [predicate](guide/testing#query-predicate) at any depth in subtree.",
"translation": "调用`query(predicate: Predicate<DebugElement>)`返回子树所有层中所有匹配[predicate](guide/testing#query-predicate)`DebugElement`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The host dependency injector.\n For example, the root element's component instance injector.",
"translation": "宿主依赖注入器。\n 比如,根元素的组件实例注入器。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The element's own component instance, if it has one.",
"translation": "元素自己的组件实例(如果有)。 \n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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`。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The `DebugElement` parent. Null if this is the root element.",
"translation": "`DebugElement`的父级。如果`DebugElement`是根元素,`parent`为null。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The element tag name, if it is an element.",
"translation": "元素的标签名字,如果它是一个元素的话。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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](guide/testing#trigger-event-handler).",
"translation": "如果在元素的`listeners`列表中有一个对应的`listener`,则以事件名字触发。\n 第二个参数是**事件对象**,一般为事件处理器。\n 参见[上面](guide/testing#trigger-event-handler)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The callbacks attached to the component's `@Output` properties and/or the element's event properties.",
"translation": "元素的`@Output`属性以及/或者元素的事件属性所附带的回调函数。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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`元数据中列出来的令牌。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Where to find this element in the source component template.",
"translation": "source是在源组件模板中查询这个元素的处所。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "The Angular `By` class has three static methods for common predicates:",
"translation": "Angular的`By`类为常用条件方法提供了三个静态方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* `By.all` - return all elements.",
"translation": "`By.all` - 返回所有元素",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* `By.css(selector)` - return elements with matching CSS selectors.",
"translation": "`By.css(selector)` - 返回符合CSS选择器的元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "## Test environment setup files",
"translation": "## 测试环境的设置文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Unit testing requires some configuration and bootstrapping that is captured in _setup files_.\nThe setup files for this guide are provided for you when you follow the [Setup](guide/setup) instructions.\nThe CLI delivers similar files with the same purpose.",
"translation": "单元测试需要一些配置和启动代码,它们被收集到了这些*设置文件*中。\n当你遵循[环境设置](guide/setup)中的步骤操作时,就会得到这些设置文件。\nCLI工具也会生成类似的文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Here's a brief description of this guide's setup files:",
"translation": "下面是对本章中这些设置文件的简短说明:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The deep details of these files and how to reconfigure them for your needs\nis a topic beyond the scope of this guide .",
"translation": "本章不会深入讲解这些文件的详情以及如何根据需要重新配置它们,那超出了本章的范围。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "File",
"translation": "文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "Description",
"translation": "描述",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The karma configuration file that specifies which plug-ins to use,\n which application and test files to load, which browser(s) to use,\n and how to report test results.",
"translation": "这个karma配置文件指定了要使用那些插件、要加载那些应用文件和测试文件、要使用哪些浏览器以及如何报告测试结果。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "It loads three other setup files:",
"translation": "它加载了下列设置文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "This shim prepares karma specifically for the Angular test environment\n and launches karma itself.\n It loads the `systemjs.config.js` file as part of that process.",
"translation": "这个垫片shim文件为karma准备Angular特有的测试环境并启动karma自身。\n 这期间,它还加载`systemjs.config.js`文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "[SystemJS](https://github.com/systemjs/systemjs/blob/master/README.md)\n loads the application and test files.\n This script tells SystemJS where to find those files and how to load them.\n It's the same version of `systemjs.config.js` you installed during [setup](guide/testing#setup).",
"translation": "[SystemJS](https://github.com/systemjs/systemjs/blob/master/README.md)加载应用文件和测试文件。\n 这个脚本告诉SystemJS到哪里去找那些文件以及如何加载它们。\n 它和你在[环境设置](guide/testing#setup)期间安装的那个`systemjs.config.js`是同一个版本。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "An optional file that supplements the SystemJS configuration in `systemjs.config.js` with\n configuration for the specific needs of the application itself.",
"translation": "一个可选的文件,它会为`systemjs.config.js`中提供SystemJS的配置加上应用自身需要的特殊配置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "A stock `systemjs.config.js` can't anticipate those needs.\n You fill the gaps here.",
"translation": "常规的`systemjs.config.js`文件无法满足那些需求,我们需要自己填充它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The sample version for this guide adds the **model barrel**\n to the SystemJs `packages` configuration.",
"translation": "本章的例子中把**模型桶barrel*添加到了SystemJS的`packages`配置中。\n </td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### npm packages",
"translation": "### npm包",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "The sample tests are written to run in Jasmine and karma.\nThe two \"fast path\" setups added the appropriate Jasmine and karma npm packages to the\n`devDependencies` section of the `package.json`.\nThey're installed when you run `npm install`.",
"translation": "这些范例测试是为在Jasmine和karma而写的。\n那两条“捷径”设置会把适当的Jasmine和Karma包添加到`package.json`的`devDependencies`区。\n当我们运行`npm install`时,它们就会被安装上。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "## FAQ: Frequently Asked Questions",
"translation": "## 常见问题\n</div>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### Why put specs next to the things they test?",
"translation": "### 为何将测试的spec配置文件放置到被测试文件的傍边",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "* Such tests are easy to find.",
"translation": "这样的测试程序很容易被找到",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* You see at a glance if a part of your application lacks tests.",
"translation": "你可以一眼看出应用程序的那些部分缺乏测试程序。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* Nearby tests can reveal how a part works in context.",
"translation": "临近的测试程序可以展示代码是如何在上下文中工作的",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* When you move the source (inevitable), you remember to move the test.",
"translation": "当你移动代码(无可避免)时,你记得一起移动测试程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "* When you rename the source file (inevitable), you remember to rename the test file.",
"translation": "当你重命名源代码文件(无可避免),你记得重命名测试程序文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"original": "### When would I put specs in a test folder?",
"translation": "### 什么时候我应该把测试spec文件放到测试目录中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "It's often better to create an appropriate folder for them in the `tests` directory.",
"translation": "通常,在`test`目录中为它们创建一个合适的目录比较好。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/testing.md"
},
{
"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/content-1/guide/testing.md"
},
{
"original": "# TypeScript Configuration",
"translation": "# TypeScript 配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "* [tsconfig.json](guide/typescript-configuration#tsconfig) &mdash; TypeScript compiler configuration.",
"translation": "[tsconfig.json](guide/typescript-configuration#tsconfig) - TypeScript编译器配置。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "* [typings](guide/typescript-configuration#typings) &mdash; TypesScript declaration files.",
"translation": "[typings](guide/typescript-configuration#typings) - TypesScript类型声明文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "## *tsconfig.json*",
"translation": "## *tsconfig.json* 文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "The [Setup](guide/setup) guide uses the following `tsconfig.json`:",
"translation": "我们在[搭建本地开发环境](guide/setup)中创建过如下的`tsconfig.json`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "This file contains options and flags that are essential for Angular applications.",
"translation": "该文件中的选项和标志是写Angular应用程序的基础。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "### *noImplicitAny* and *suppressImplicitAnyIndexErrors*",
"translation": "### *noImplicitAny*与*suppressImplicitAnyIndexErrors*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "The documentation setup sets the `noImplicitAny` flag to `true`.",
"translation": "本文档在环境搭建时将`noImplicitAny`标志设置为`true`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "When 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`并且TypeScript编译器无法推断出类型时它仍然会生成JavaScript文件。\n但是它也会**报告一个错误**。\n很多饱经沧桑的程序员更喜欢这种严格的设置因为类型检查能在编译期间捕获更多意外错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "The documentation setup sets this flag to `true` as well.",
"translation": "本文档在环境搭建时将`noImplicitAny`标志设置为`true`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "## TypeScript Typings",
"translation": "## TypeScript类型定义(typings)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "Use [TypeScript type definition files](https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html)&mdash;`d.ts files`&mdash;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/content-1/guide/typescript-configuration.md"
},
{
"original": "TypeScript-aware editors leverage these same definition files to display type information about library features.",
"translation": "TypeScript敏感的编辑器借助这些定义文件来显示这些库中各个特性的类型定义。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "**You need do nothing to get *typings* files for library packages that include `d.ts` files. Angular packages include them already.**",
"translation": "**我们不需要为那些包含了`d.ts`文件的库获取*类型定义*文件 —— Angular的所有包都是如此。**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "### lib.d.ts",
"translation": "### lib.d.ts 文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "Thanks to that, you have all the `es6` typings even when targeting `es5`.",
"translation": "得益于这项设置,即使编译目标设置为`es5`,我们也能获得所有的`es6`类型信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "### Installable typings files",
"translation": "### 安装类型定义文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "Many libraries&mdash;jQuery, Jasmine, and Lodash among them&mdash;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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "QuickStart identifies two *typings*, or `d.ts`, files:",
"translation": "我们在“快速上手”中指定过两个*类型定义*文件(`d.ts`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework.",
"translation": "[jasmine](http://jasmine.github.io/)是Jasmine测试框架的类型定义",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"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/content-1/guide/typescript-configuration.md"
},
{
"original": "QuickStart doesn't require these typings but many of the samples do.",
"translation": "“快速上手”本身不需要这些类型定义,但是文档中的很多例子都需要。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/typescript-configuration.md"
},
{
"original": "# Upgrading from AngularJS",
"translation": "# 从 AngularJS 升级",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "## Preparation",
"translation": "## 准备工作",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Follow the AngularJS Style Guide",
"translation": "### 遵循AngularJS风格指南",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "There are a few rules in particular that will make it much easier to do *an incremental upgrade* using the Angular `upgrade/static` module:",
"translation": "有一些特别的规则可以让使用Angular的`upgrade/static`模块进行*增量升级*变得更简单:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Using a Module Loader",
"translation": "### 使用模块加载器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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&lt;script&gt; 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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Migrating to TypeScript",
"translation": "### 迁移到TypeScript",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "#### Using Component Directives",
"translation": "#### 使用组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "To be Angular compatible, an AngularJS component directive should configure\nthese attributes:",
"translation": "要与Angular兼容AngularJS的组件型指令应该配置下列属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* `restrict: 'E'`. Components are usually used as elements.",
"translation": "`restrict: 'E'`。组件通常会以元素的方式使用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "* `controller` and `controllerAs`. Components have their own controllers.",
"translation": "`controller`和`controllerAs`。组件要有自己的控制器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* `template` or `templateUrl`. Components have their own templates.",
"translation": "`template`或`templateUrl`。组件要有自己的模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Component directives may also use the following attributes:",
"translation": "组件型指令还可能使用下列属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* `transclude: true/{}`, if the component needs to transclude content from elsewhere.",
"translation": "`transclude: true`:如果组件需要从其它地方透传内容,就设置它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* `require`, if the component needs to communicate with some parent component's\n controller.",
"translation": "`require`:如果组件需要和父组件的控制器通讯,就设置它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Component directives **should not** use the following attributes:",
"translation": "组件型指令**不能**使用下列属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* `compile`. This will not be supported in Angular.",
"translation": "`compile`。Angular不再支持它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "* It requires less boilerplate code.",
"translation": "它需要更少的样板代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* It enforces the use of component best practices like `controllerAs`.",
"translation": "它强制你遵循组件的最佳实践,比如`controllerAs`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* It has good default values for directive attributes like `scope` and `restrict`.",
"translation": "指令中像`scope`和`restrict`这样的属性应该有良好的默认值。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "The component directive example from above looks like this when expressed\nusing the component API:",
"translation": "如果使用这个组件API进行快捷定义那么上面看到的组件型指令就变成了这样",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "## Upgrading with ngUpgrade",
"translation": "## 使用升级适配器进行升级",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### How ngUpgrade Works",
"translation": "### 升级模块工作原理",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "#### Dependency Injection",
"translation": "#### 依赖注入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Dependency injection tokens are always strings",
"translation": "依赖注入的令牌(Token)永远是字符串(译注:指服务名称)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "#### Components and the DOM",
"translation": "#### 组件与DOM",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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 thatcomponent . Consider a situation\nwhere you use an Angular component from AngularJS like this:",
"translation": "当我们使用一个属于另一个框架的组件时,就会发生一个跨框架边界的切换。不过,这种切换只发生在该组件元素的*子节点*上。\n考虑一个场景我们从AngularJS中使用一个Angular组件就像这样",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "#### Change Detection",
"translation": "#### 变更检测",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Using UpgradeModule with Angular _NgModules_",
"translation": "### 通过Angular的*NgModule*来使用UpgradeModule",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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的模块进行引导时就得把Anuglar 2的模块传给`UpgradeModule`。我们来看看怎么做。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Read more about [NgModules](guide/ngmodule).",
"translation": "要了解Angular模块的更多信息请参阅[Angular模块](guide/ngmodule)页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "### Bootstrapping hybrid applications",
"translation": "### 引导混合式应用程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Say you have an `ng-app` driven bootstrap such as this one:",
"translation": "比如我们现在有这样一个通过 `ng-app` 进行引导的应用:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Next, create an `app.module.ts` file and add the following `NgModule` class:",
"translation": "接下来,创建一个`app.module.ts`文件,并添加下列`NgModule`类:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Now you can bootstrap `AppModule` using the `platformBrowserDynamic.bootstrapModule` method.",
"translation": "现在,我们就可以使用 `platformBrowserDynamic.bootstrapModule` 方法来启动 `AppModule` 了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Using Angular Components from AngularJS Code",
"translation": "### 在AngularJS的代码中使用Angular的组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Say you have a simple Angular component that shows information about a hero:",
"translation": "假设我们有一个简单的用来显示英雄信息的Angular组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "All Angular components, directives and pipes must be declared in an NgModule.",
"translation": "所有Angular组件、指令和管道都必须声明在NgModule中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Use kebab-case for downgraded component attributes",
"translation": "在降级过的组件属性中使用中线命名法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "But when using them from AngularJS templates, you must use kebab-case:",
"translation": "但是从AngularJS的模板中使用它们时我们得使用中线命名法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Using AngularJS Component Directives from Angular Code",
"translation": "### 从Angular代码中使用AngularJS组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "A simple example of an upgradable component is one that just has a template\nand a controller:",
"translation": "可升级组件的简单例子是只有一个模板和一个控制器的指令:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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 it's 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/content-1/guide/upgrade.md"
},
{
"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\nit's children.",
"translation": "升级后的组件是Angular的**指令**,而不是**组件**因为Angular不知道AngularJS将在它下面创建元素。\nAngular所知道的是升级后的组件只是一个指令一个标签Angular不需要关心组件本身及其子元素。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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,\n provide the inputs and outputs using **Angular template syntax**,\nobserving the following rules:",
"translation": "升级后的组件也可能有输入属性和输出属性它们是在原AngularJS组件型指令的scope/controller绑定中定义的。\n当我们从Angular模板中使用该组件时我们要使用**Angular模板语法**来提供这些输入属性和输出属性,但要遵循下列规则:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Binding definition",
"translation": "绑定定义",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Template syntax",
"translation": "模板语法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Attribute binding",
"translation": "属性(Attribute)绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Expression binding",
"translation": "表达式绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "One-way binding",
"translation": "单向绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Two-way binding",
"translation": "双向绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "For example, imagine a hero detail AngularJS component directive\nwith one input and one output:",
"translation": "举个例子假设我们在AngularJS中有一个表示“英雄详情”的组件型指令它带有一个输入属性和一个输出属性",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Projecting AngularJS Content into Angular Components",
"translation": "### 把AngularJS的内容投影到Angular组件中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "</div>",
"translation": "### Transcluding Angular Content into AngularJS Component Directives\n### 把Angular的内容透传进AngularJS的组件型指令",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "<code-example path=\"upgrade-module/src/app/a-to-ajs-transclusion/container.component.ts\" title=\"container.component.ts\">\n</code-example>",
"translation": "### Making AngularJS Dependencies Injectable to Angular\n### 让AngularJS中的依赖可被注入到Angular",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "You can then inject it in Angular using it's class as a type annotation:",
"translation": "然后我们可以一个字符串型令牌把它注入到Angular中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Making Angular Dependencies Injectable to AngularJS",
"translation": "### 让Angular的依赖能被注入到AngularJS中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "For example, you might have an Angular service called `Heroes`:",
"translation": "例如我们可能有一个Angular的`Heroes`服务:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "After this, the service is injectable anywhere in AngularJS code:",
"translation": "此后该服务就能被注入到AngularJS代码中的任何地方了",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "## Using Ahead-of-time compilation with hybrid apps",
"translation": "## 在混合式应用中使用AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "## PhoneCat Upgrade Tutorial",
"translation": "## PhoneCat升级教程",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "In terms of project structure, this is where the work begins:",
"translation": "在项目结构方面,我们工作的起点是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Switching to TypeScript",
"translation": "### 切换到TypeScript",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Begin by installing TypeScript to the project.",
"translation": "让我们先把TypeScript包安装到项目中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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": "我们还应该配置TypeScript编译器以便它能理解我们的项目结构。我们要往项目目录下添加一个`tsconfig.json`文件,\n就像在[搭建本地开发环境](guide/setup)中做过的那样。它将告诉TypeScript编译器该如何编译我们的源文件。\n`tsconfig.json`文件会告诉 TypeScript 编译器如何把 TypeScript 文件转成 ES5 代码,并打包进 CommonJS 模块中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Now launch the TypeScript compiler from the command line in watch mode:",
"translation": "现在,从命令行中用监视模式启动 TypeScript 编译器:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Keep this process running in the background, watching and recompiling as you make changes.",
"translation": "让这个进程一直在后台运行,监听任何变化并自动重新编译。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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的类型定义。\n当我们正确调用AngularJS的API时TypeScript会帮我们检查它 —— 比如往Angular模块中注册组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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": "我们用typings工具安装的这个[AngularJS.x类型定义文件](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/angularjs)\n并不是由Angular开发组维护的但它也已经足够全面了。借助这些类型定义的帮助它可以为AngularJS.x程序加上全面的类型注解。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Here's what the new class for the phone list component controller looks like:",
"translation": "新的“电话列表(phone list)”组件控制器类是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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": "该项目还包含一些动画,在此指南的当前版本我们先不升级它,等到后面的发行版再改。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "* Add Angular and the other new dependencies to `package.json`",
"translation": "把Angular和其它新依赖添加到`package.json`中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* The SystemJS configuration file `systemjs.config.js` to the project root directory.",
"translation": "把SystemJS的配置文件`systemjs.config.js`添加到项目的根目录。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Once these are done, run:",
"translation": "这些完成之后,就运行:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Creating the _AppModule_",
"translation": "### 创建*AppModule*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Now create a new `app.module.ts` with the minimum `NgModule` class:",
"translation": "然后创建一个新的`app.module.ts`文件,其中是一个最小化的`NgModule`类:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "### Bootstrapping a hybrid PhoneCat",
"translation": "### 引导PhoneCat的混合式应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "First, remove the `ng-app` attribute from `index.html`.\nThen import `UpgradeModule` in the `AppModule`, and override it's `ngDoBootstrap` method:",
"translation": "首先,从`index.html`中移除`ng-app`。然后在`AppModule`中导入`UpgradeModule`,并改写它的`ngDoBootstrap`方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "#### Why declare _angular_ as _angular.IAngularStatic_?",
"translation": "#### 为何要声明*angular*为*angular.IAngularStatic*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### Upgrading the Phone service",
"translation": "### 升级`Phone`服务",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "* For loading the list of all phones into the phone list component.",
"translation": "把所有电话的列表加载到电话列表组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* For loading the details of a single phone into the phone detail component.",
"translation": "把一台电话的详情加载到电话详情组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Here's the full, final code for the service:",
"translation": "最终,该类的全部代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Now that you are loading `phone.service.ts` through an import that is resolved\nby SystemJS, you should **remove the &lt;script&gt; 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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "You could use the `toPromise` method of `Observable` to turn those\nObservables into Promises in the service. In many cases that\nreduce the number of changes to the component controllers.",
"translation": "我们也能使用`Observable`的`toPromise`方法来在服务中把这些可观察对象转变成承诺,以进一步减小组件控制器中需要修改的代码量。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "### Upgrading Components",
"translation": "### 升级组件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "#### No Angular _filter_ or _orderBy_ filters",
"translation": "#### Angular中没有`filter`或`orderBy`过滤器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Remove the &lt;script&gt; tag for the phone list component from `index.html`.",
"translation": "从`index.html`中移除电话列表组件的&lt;script&gt;标签。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Now set the remaining `phone-detail.component.ts` as follows:",
"translation": "现在,剩下的`phone-detail.component.ts`文件变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Convert the phone detail component template into Angular syntax as follows:",
"translation": "我们现在也要把该组件的模板转变成Angular的语法。\n这里是它完整的新模板",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "There are several notable changes here:",
"translation": "这里有几个值得注意的改动:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* You've removed the `$ctrl.` prefix from all expressions.",
"translation": "我们从所有表达式中移除了`$ctrl.`前缀。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-src` with property\n bindings for the standard `src` property.",
"translation": "正如我们在电话列表中做过的那样,我们把`ng-src`替换成了标准的`src`属性绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-repeat`s with `*ngFor`s.",
"translation": "我们把`ng-repeat`替换成了`*ngFor`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "* You've replaced `ng-click` with an event binding for the standard `click`.",
"translation": "我们把`ng-click`替换成了一个到标准`click`事件的绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Add `PhoneDetailComponent` component to the `NgModule` _declarations_ and _entryComponents_:",
"translation": "把`PhoneDetailComponent`组件添加到`NgModule`的_declarations_和_entryComponents_中",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "You should now also remove the phone detail component &lt;script&gt; tag from `index.html`.",
"translation": "我们现在应该从`index.html`中移除电话详情组件的&lt;script>。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "#### Add the _CheckmarkPipe_",
"translation": "#### 添加*CheckmarkPipe*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "The AngularJS directive had a `checkmark` _filter_.\nTurn that into an Angular **pipe**.",
"translation": "AngularJS指令中有一个`checkmark`*过滤器*我们把它转换成Angular的**管道**。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Now import and declare the newly created pipe and\nremove the filter &lt;script&gt; tag from `index.html`:",
"translation": "当我们做这个修改时,也要同时从`core`模块文件中移除对该过滤器的注册。该模块的内容变成了:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "### AOT compile the hybrid app",
"translation": "### 对混合式应用做AOT编译",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "And that's all you need to use AOT while upgrading your app!",
"translation": "这就是想要在升级应用期间AOT编译所需的一切",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "### Adding The Angular Router And Bootstrap",
"translation": "### 添加Angular路由器和引导程序",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "#### Add the Angular router",
"translation": "#### 添加Angular路由器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Angular has an [all-new router](guide/router).",
"translation": "Angular有一个[全新的路由器](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "<code-example path=\"upgrade-phonecat-3-final/index.html\" region=\"appcomponent\" title=\"index.html (body)\" linenums=\"false\">\n</code-example>",
"translation": "#### Create the _Routing Module_\n#### 创建*路由模块*\nA router needs configuration whether it's the AngularJS or Angular or any other router.",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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 it's view into the host web page.",
"translation": "现在,修改`AppModule`,让它导入这个`AppRoutingModule`,并同时声明根组件`AppComponent`。\n这会告诉Angular它应该使用根组件`AppComponent`引导应用,并把它的视图插入到宿主页面中。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "#### Generate links for each phone",
"translation": "#### 为每个电话生成链接",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "See the [Routing](guide/router) page for details.",
"translation": "要了解详情,请查看[路由与导航](guide/router)页。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "#### Use route parameters",
"translation": "#### 使用路由参数",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "You are now running a pure Angular application!",
"translation": "我们现在运行的就是纯正的Angular应用了",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "### Say Goodbye to AngularJS",
"translation": "### 再见AngularJS",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "The application is still bootstrapped as a hybrid app.\nThere's no need for that anymore.",
"translation": "应用仍然以混合式应用的方式启动,然而这再也没有必要了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Switch the bootstrap method of the application from the `UpgradeModule` to the Angular way.",
"translation": "把应用的引导(`bootstrap`)方法从`UpgradeAdapter`的改为Angular的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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 it's mapping in `systemjs.config.js` can also go.",
"translation": "还需要反安装AngularJS的外部类型定义文件。我们现在只需要Jasmine的那些。\n`systemjs.config.js`中的`@angular/upgrade`包及其映射也可以移除了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "## Appendix: Upgrading PhoneCat Tests",
"translation": "## 附录升级PhoneCat的测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "### E2E Tests",
"translation": "### E2E测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Update the `protractor-conf.js` to sync with hybrid apps:",
"translation": "再对`protractor-conf.js`做下列修改,与混合应用同步:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "When you start to upgrade components and their templates to Angular, you'll make more changes \n because 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/content-1/guide/upgrade.md"
},
{
"original": "Previous code",
"translation": "老代码",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "New code",
"translation": "新代码",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "Notes",
"translation": "说明",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "The repeater matcher relies on AngularJS `ng-repeat`",
"translation": "repeater匹配器依赖于AngularJS中的`ng-repeat`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "The repeater matcher relies on AngularJS `ng-repeat`",
"translation": "repeater匹配器依赖于AngularJS中的`ng-repeat`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "The model matcher relies on AngularJS `ng-model`",
"translation": "model匹配器依赖于AngularJS中的`ng-model`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "The model matcher relies on AngularJS `ng-model`",
"translation": "model匹配器依赖于AngularJS中的`ng-model`\n </td>\n </tr>\n <tr>\n <td>",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "The binding matcher relies on AngularJS data binding",
"translation": "binding匹配器依赖于AngularJS的数据绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "Replace the `ng12Hybrid` previously added with the following in `protractor-conf.js`:",
"translation": "替换之前在`protractor-conf.js`中加入 `ng12Hybrid`,象这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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": "同样我们的测试代码中有两个Protractor API调用内部使用了`$location`。该服务没有了,\n我们就得把这些调用用一个WebDriver的通用URL API代替。第一个API是“重定向(redirect)”规约:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "And the second is the phone links spec:",
"translation": "然后是“电话链接(phone links)”规约:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"original": "### Unit Tests",
"translation": "### 单元测试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "For instance, in the phone detail component spec , you can use ES2015\nfeatures like arrow functions and block-scoped variablesand benefit from the type\ndefinitions of the AngularJS services you're consuming:",
"translation": "比如在这个电话详情组件的规约中我们不仅用到了ES2015中的箭头函数和块作用域变量这些特性还为所用的一些\nAngularJS服务提供了类型定义。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"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/content-1/guide/upgrade.md"
},
{
"original": "# User Input",
"translation": "# 用户输入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "Run the <live-example></live-example>.",
"translation": "运行<live-example></live-example",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "The following example shows an event binding that implements a click handler:",
"translation": "下例展示了一个事件绑定,它实现了一个点击事件处理器:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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 reponds\nto the click event by calling the component's `onClickMe` method.",
"translation": "等号左边的`(click)`表示把按钮的点击事件作为**绑定目标**。\n等号右边引号中的文本是**模板语句**,通过调用组件的`onClickMe`方法来响应这个点击事件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "When the user clicks the button, Angular calls the `onClickMe` method from `ClickMeComponent`.",
"translation": "当用户点击按钮时Angular 调用`ClickMeComponent`的`onClickMe`方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "### Type the _$event_",
"translation": "### *$event*的类型",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "The following example rewrites the method with types:",
"translation": "下面的例子,使用了带类型方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "### Passing _$event_ is a dubious practice",
"translation": "### 传入 *$event* 是靠不住的做法",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "The next section shows how to use template reference variables to address this problem.",
"translation": "下面将介绍如何用模板引用变量来解决这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "## Get user input from a template reference variable",
"translation": "## 从一个模板引用变量中获得用户输入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "The following example uses a template reference variable\nto implement a keystroke loopback in a simple template.",
"translation": "下面的例子使用了局部模板变量,在一个超简单的模板中实现按键反馈功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "Type something in the input box, and watch the display update with each keystroke.",
"translation": "在输入框中输入,就会看到每次按键时,显示也随之更新了。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "**This won't work at all unless you bind to an event**.",
"translation": "**除非你绑定一个事件,否则这将完全无法工作。**",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "Angular updates the bindings (and therefore the screen)\nonly if the app does something in response to asynchronous events, such as keystrokes.",
"translation": "只有在应用做了些异步事件如击键Angular 才更新绑定(并最终影响到屏幕)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "This 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": "本例代码将`keyup`事件绑定到了数字0这是可能是最短的模板语句。\n虽然这个语句不做什么但它满足 Angular 的要求,所以 Angular 将更新屏幕。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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`变量及其结构了。\n{@a key-event}",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "## Key event filtering (with `key.enter`)",
"translation": "## 按键事件过滤(通过`key.enter`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "Here's how it works.",
"translation": "下面展示了它是如何工作的。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "## On blur",
"translation": "## 失去焦点事件 (blur)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "To fix this issue, listen to both the _Enter_ key and the _blur_ event.",
"translation": "下面通过同时监听输入框的回车键和失去焦点事件来修正这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "</code-example>",
"translation": "## Put it all together\n## 把它们放在一起",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "Below is the \"Little Tour of Heroes\" component.",
"translation": "下面就是“简版英雄指南”组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "</code-example>",
"translation": "### Observations\n### 小结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "* **Use template variables to refer to elements** &mdash;\nThe `newHero` template variable refers to the `<input>` element.\nYou can reference `newHero` from any sibling or child of the `<input>` element.",
"translation": "**使用模板变量来引用元素** &mdash; `newHero`模板变量引用了`<input>`元素。\n你可以在`<input>`的任何兄弟或子级元素中引用`newHero`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "* **Pass values, not elements** &mdash;\nInstead of passing the `newHero` into the component's `addHero` method,\nget the input box value and pass *that* to `addHero`.",
"translation": "**传递数值,而非元素** &mdash;\n获取输入框的值并将*它*传递给组件的`addHero`,而不要传递`newHero`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "* **Keep template statements simple** &mdash;\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": "**保持模板语句简单** &mdash;\n`(blur)`事件被绑定到两个 JavaScript 语句。\n第一句调用`addHero`。第二句`newHero.value=''`在添加新英雄到列表中后清除输入框。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "## Source code",
"translation": "## 源代码",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "Following is all the code discussed in this page.",
"translation": "下面是本章讨论过的所有源码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"original": "You have mastered the basic primitives for responding to user input and gestures.",
"translation": "你已经掌握了响应用户输入和操作的基础技术。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/user-input.md"
},
{
"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/content-1/guide/user-input.md"
},
{
"original": "# Visual Studio 2015 QuickStart",
"translation": "# Visual Studio 2015 快速上手",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "Some developers prefer Visual Studio as their Integrated Development Environment (IDE).",
"translation": "有些开发者喜欢用Visual Studio。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "## ASP.NET 4.x Project",
"translation": "## ASP.NET 4.x 项目",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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 template for Visual Studio 2015</a>。 \n 注意,最终代码与本文不对应,请适当调节。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Node.js",
"translation": "前提条件: Node.js",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Visual Studio 2015 Update 3",
"translation": "前提条件: Visual Studio 2015 Update 3",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Configure External Web tools",
"translation": "前提条件: 配置External Web tools",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "* Open the **Options** dialog with `Tools` | `Options`.",
"translation": "到`Tools` | `Options`打开**Options**对话框",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "Click OK to close the dialog.",
"translation": "* 点击OK关闭对话框。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "Restart Visual Studio for this change to take effect.",
"translation": "* 重启Visual Studio以让设置变化生效。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "Prerequisite: Install TypeScript 2.2 for Visual Studio 2015",
"translation": "前提条件: 安装TypeScript 2.2 for Visual Studio 2015",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "While Visual Studio Update 3 ships with TypeScript support out of the box, it currently doesnt 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/content-1/guide/visual-studio-2015.md"
},
{
"original": "To install TypeScript 2.2:",
"translation": "要安装TypeScript 2.2",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "At this point, Visual Studio is ready. Its a good idea to close Visual Studio and \nrestart it to make sure everything is clean.",
"translation": "至此Visual Studio准备好了。重新启动Visual Stuido这样我们可以有一个崭新的开始。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "Step 1: Download the QuickStart files",
"translation": "第一步: 现在“快速上手”文件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "Step 2: Create the Visual Studio ASP.NET project",
"translation": "第二步创建Visual Studio ASP.net项目",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "Create the ASP.NET 4.x project in the usual way as follows:",
"translation": "按照下列步骤创建ASP.NET 4.x项目",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "* In Visual Studio, select `File` | `New` | `Project` from the menu.",
"translation": "在Visual Studio中选择`File` | `New` | `Project`菜单。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "Step 3: Copy the QuickStart files into the ASP.NET project folder",
"translation": "第三步: 把“快速上手”的文件复制到ASP.NET项目所在的目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "* src/app folder (answer *No* if asked to search for TypeScript Typings)",
"translation": "src/app目录如果询问是否要搜索TypeScript类型回答*No*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "Step 4: Restore the required packages",
"translation": "第四步: 恢复需要的包",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "Restore the packages required for an Angular application as follows:",
"translation": "按下面的步骤恢复Angular应用程序需要的包",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "* Ignore the warnings.",
"translation": "忽略所有警告。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "* Click the `Refresh` icon in Solution Explorer.",
"translation": "在Solution Explorer里点击`Refresh`图标。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "Step 5: Build and run the app",
"translation": "第五步:构建和运行应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "### To run in VS with F5",
"translation": "### 按 F5 以在 VS 中运行",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "### For apps that use routing",
"translation": "### 为了使用路由的应用",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "#### Configure IIS rewrite rules",
"translation": "#### 配置 IIS 重写规则",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"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/content-1/guide/visual-studio-2015.md"
},
{
"original": "It's faster to run without the debugger by pressing `Ctrl-F5`.",
"translation": "按`Ctrl-F5`不带调试器的运行应用,速度会更快。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "The default browser opens and displays the QuickStart sample application.",
"translation": "默认浏览器打开并显示《快速上手》例子应用。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "Try editing any of the project files. Save and refresh the browser to\nsee the changes.",
"translation": "尝试编辑任何项目文件,*保存*并刷新浏览器来查看效果。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/visual-studio-2015.md"
},
{
"original": "# Webpack: An Introduction",
"translation": "# Webpack简介",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "# Contents",
"translation": "# 目录",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [What is Webpack?](guide/webpack#what-is-webpack)",
"translation": "[什么是Webpack](guide/webpack#what-is-webpack)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Entries and outputs](guide/webpack#entries-outputs)",
"translation": "[入口与输出](guide/webpack#entries-outputs)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Multiple bundles](guide/webpack#multiple-bundles)",
"translation": "[多重包](guide/webpack#multiple-bundles)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Loaders](guide/webpack#loaders)",
"translation": "[加载器](guide/webpack#loaders)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Plugins](guide/webpack#plugins)",
"translation": "[插件](guide/webpack#plugins)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Configuring Webpack](guide/webpack#configure-webpack)",
"translation": "[配置Webpack](guide/webpack#configure-webpack)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Common configuration](guide/webpack#common-configuration)",
"translation": "[公共配置](guide/webpack#common-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Inside `webpack.common.js`](guide/webpack#inside-webpack-commonjs)",
"translation": "[深入`webpack.common.js`](guide/webpack#inside-webpack-commonjs)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [entry](guide/webpack#common-entries)",
"translation": "[入口](guide/webpack#common-entries)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [resolve extension-less imports](guide/webpack#common-resolves)",
"translation": "[解析无扩展名的导入](guide/webpack#common-resolves)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Plugins](guide/webpack#plugins)",
"translation": "[插件](guide/webpack#plugins)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Environment specific configuration](guide/webpack#environment-configuration)",
"translation": "[针对特定环境进行配置](guide/webpack#environment-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Development configuration](guide/webpack#development-configuration)",
"translation": "[开发环境配置](guide/webpack#development-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Production configuration](guide/webpack#production-configuration)",
"translation": "[生产环境配置](guide/webpack#production-configuration)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Trying it out](guide/webpack#try)",
"translation": "[试一下](guide/webpack#try)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Highlights](guide/webpack#highlights)",
"translation": "[重点](guide/webpack#highlights)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [Conclusion](guide/webpack#conclusion)",
"translation": "[总结](guide/webpack#conclusion)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "## What is Webpack?",
"translation": "## 什么是Webpack",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "### Entries and outputs",
"translation": "### 入口与输出",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Webpack inspects that file and traverses its `import` dependencies recursively.",
"translation": "Webpack探查那个文件并且递归遍历它的`import`依赖。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:",
"translation": "然后它把这些文件**输出**到当前配置所指定的_包文件_`app.js`中:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "#### Multiple bundles",
"translation": "#### 多重包",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "### Loaders",
"translation": "### 加载器(Loader)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "When Webpack encounters `import` statements like the following,\nit applies the `test` RegEx patterns.",
"translation": "当Webpack遇到如下所示的`import`语句时,它就会调用正则表达式的`test`方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "When a pattern matches the filename, Webpack processes the file with the associated loader.",
"translation": "如果一个模式匹配上文件名Webpack就用它所关联的加载器处理这个文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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.\n Then 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追加到页面上的*&lt;style&gt;*元素中)。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "### Plugins",
"translation": "### 插件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "## Configuring Webpack",
"translation": "## 配置Webpack",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Begin by setting up the development environment.",
"translation": "从设置开发环境开始。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "Create a new project folder.",
"translation": "创建一个新的项目文件夹。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "Add these files :",
"translation": "把下列文件添加到根目录下:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Open a terminal window and install the npm packages.",
"translation": "打开命令行窗口并安装这些*npm*包",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "### Polyfills",
"translation": "### Polyfills 填充库",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "You'll need polyfills to run an Angular application in most browsers as explained\nin the [Browser Support](guide/browser-support) guide.",
"translation": "我们在[_浏览器支持_](guide/browser-support)章节里解释过Angular应用要能在大多数的浏览器里运行它还需要一些polyfills。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "### Common configuration",
"translation": "### 通用配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Gather the common configuration in a file called `webpack.common.js`.",
"translation": "我们可以把这些通用的配置收归到一个文件,命名为`webpack.common.js`。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "### Inside _webpack.common.js_",
"translation": "### webpack.common.js解读",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "* [`entry`](guide/webpack#common-entries)&mdash;the entry-point files that define the bundles.",
"translation": "[`entries`](guide/webpack#common-entries) - 包体的入口文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [`resolve`](guide/webpack#common-resolves)&mdash;how to resolve file names when they lack extensions.",
"translation": "[`resolve`](guide/webpack#common-resolves) - 省略扩展名时如何解释文件名。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* [`module.rules`](guide/webpack#common-rules)&mdash; `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/content-1/guide/webpack.md"
},
{
"original": "* [`plugins`](guide/webpack#common-plugins)&mdash;creates instances of the plugins.",
"translation": "[`plugins`](guide/webpack#common-plugins) - 创建插件的实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "#### _entry_",
"translation": "#### _entry_ 入口",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "The first export is the `entry` object:",
"translation": "如上所述,第一个导出的对象是*entries*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "This `entry` object defines the three bundles:",
"translation": "`entry`对象定义了三个包:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* `polyfills`&mdash;the polyfills needed to run Angular applications in most modern browsers.",
"translation": "`polyfills` - 使得Angular应用能够运行在大多数的现代浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* `vendor`&mdash;the third-party dependencies such as Angular, lodash, and bootstrap.css.",
"translation": "`vendor` - 第三方依赖如Angular、lodash和bootstrap.css。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* `app`&mdash;the application code.",
"translation": "`app` - 应用代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "#### _resolve_ extension-less imports",
"translation": "#### _resolve_ 无扩展名的文件导入",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "#### _module.rules_",
"translation": "#### _module.rules_ 规则",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "Rules tell Webpack which loaders to use for each file, or module:",
"translation": "Rules用来告诉Webpack加载不同文件或模块时该用哪个加载器。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* `awesome-typescript-loader`&mdash;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/content-1/guide/webpack.md"
},
{
"original": "* `angular2-template-loader`&mdash;loads angular components' template and styles.",
"translation": "`angular2-template-loader` - 用于加载Angular组件的模板和样式",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* `html-loader`&mdash;for component templates.",
"translation": "`html-loader` - 为组件模板准备的加载器",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* images/fonts&mdash;Images and fonts are bundled as well.",
"translation": "`images/fonts` - 图片和字体文件也能被打包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* CSS&mdash;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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Multiple loaders can be chained using the array notation.",
"translation": "多重加载器也能使用数组形式串联起来。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "#### _plugins_",
"translation": "#### _插件_",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "Finally, create instances of three plugins:",
"translation": "最后,创建三个插件实例:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "#### *CommonsChunkPlugin*",
"translation": "#### *CommonsChunkPlugin* 插件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "#### _HtmlWebpackPlugin_",
"translation": "#### _HtmlWebpackPlugin_ 插件",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "### Environment-specific configuration",
"translation": "### 环境相关的配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "These files tend to be short and simple.",
"translation": "这些文件越小越简单越好。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "### Development configuration",
"translation": "### 开发环境配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "Here is the `webpack.dev.js` development configuration file.",
"translation": "下面是开发环境的而配置文件`webpack.dev.js`",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "The development build relies on the Webpack development server, configured near the bottom of the file.",
"translation": "开发环境下的构建依赖于Webpack的开发服务器我们在靠近文件底部的地方配置了它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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`中插入适当的&lt;script&gt;和&lt;link&gt;标签。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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`插件就会转而把一个&lt;link&gt;标签写进`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/content-1/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "### Production configuration",
"translation": "### 产品环境配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "Configuration of a *production* build resembles *development* configuration with a few key changes.",
"translation": "*产品环境*下的配置和*开发环境*下的配置很相似……除了一些关键的改动。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Put the production output bundle files in the `dist` folder.",
"translation": "把产品环境的输出包放在`dist`目录下。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "There are additional plugins:",
"translation": "还有一些别的插件:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* *`NoEmitOnErrorsPlugin`&mdash; stops the build if there is an error.",
"translation": "*`NoEmitOnErrorsPlugin`* - 如果出错就停止构建。*",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "*`UglifyJsPlugin`&mdash; minifies the bundles.",
"translation": "`UglifyJsPlugin` - 最小化(minify)生成的包。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* *`ExtractTextPlugin`&mdash; extracts embedded css as external files, adding cache-busting hash to the filename.",
"translation": "*`ExtractTextPlugin`* - 把内嵌的css抽取成外部文件并为其文件名添加“缓存无效哈希”。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* *`DefinePlugin`&mdash; use to define environment variables that you can reference within the application.",
"translation": "*`DefinePlugin`* - 用来定义环境变量,以便我们在自己的程序中引用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* *`LoaderOptionsPlugins`&mdash; to override options of certain loaders.",
"translation": "*`LoaderOptionsPlugins`* - 为特定的加载器提供选项。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "### Test configuration",
"translation": "### 测试环境配置",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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": "我们不用预编译TypeScriptWebpack随时在内存中转译我们的TypeScript文件并且把产出的JS直接反馈给Karma。\n硬盘上没有任何临时文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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&mdash;and only&mdash;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/content-1/guide/webpack.md"
},
{
"original": "Grab the app code at the end of this guide and try:",
"translation": "抓取本指南底部的应用代码,并试一试:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "## Trying it out",
"translation": "## 试一试",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "Highlights",
"translation": "### 重点:",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "* There are no `<script>` or `<link>` tags in the `index.html`. \nThe `HtmlWebpackPlugin` inserts them dynamically at runtime.",
"translation": "在`index.html`中没有&lt;script&gt;或&lt;link&gt;标签。\n `HtmlWebpackPlugin`会在运行时动态插入它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"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/content-1/guide/webpack.md"
},
{
"original": "* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.\n The application imports these modules too; they'd be duplicated in the `app.js` bundle\n if 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`包中。\n{@a conclusion}",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "## Conclusion",
"translation": "## 总结",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "You've learned just enough Webpack to configurate development, test and production builds \nfor a small Angular application.",
"translation": "我们学到了刚好够用来在开发、测试、产品环境下构建一个小型Angular应用的Webpack配置知识。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "_You could always do more_. Search the web for expert advice and expand your Webpack knowledge.",
"translation": "_但我们还能做得更多_。搜索互联网来获得专家的建议并扩展你对Webpack的认识。",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"original": "[Back to top](guide/webpack#top)",
"translation": "[回到顶部](guide/webpack#top)",
"sourceFile": "/Users/twer/private/GDE/content-1/guide/webpack.md"
},
{
"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/content-1/marketing/docs.md"
},
{
"original": "## Assumptions",
"translation": "## 基本假设",
"sourceFile": "/Users/twer/private/GDE/content-1/marketing/docs.md"
},
{
"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 \"学习 JavaScript\")和来自[最新标准](https://babeljs.io/learn-es2015/ \"Latest JavaScript standards\")的一些知识,比如 [类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes \"ES2015 类\") 和 [模块](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import \"ES2015 模块\")。\n下列代码范例都是用最新版本的JavaScript写的利用[类型](https://www.typescriptlang.org/docs/handbook/classes.html \"TypeScript 类型\")实现依赖注入,并使用[装饰器](https://www.typescriptlang.org/docs/handbook/decorators.html \"装饰器\")来提供元数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/marketing/docs.md"
},
{
"original": "## Feedback",
"translation": "## 反馈",
"sourceFile": "/Users/twer/private/GDE/content-1/marketing/docs.md"
},
{
"original": "You can sit with us!",
"translation": "你也可以和我们一起做贡献!",
"sourceFile": "/Users/twer/private/GDE/content-1/marketing/docs.md"
},
{
"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/content-1/marketing/docs.md"
},
{
"original": "The grand plan for this tutorial is to build an app that helps a staffing agency manage its stable of heroes.",
"translation": "本教程的终极计划是构建一个程序,来帮助招聘公司管理一群英雄。\n 即使英雄们也需要找工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "The Tour of Heroes app covers the core fundamentals of Angular. You'll build a basic app that\nhas many of the features you'd expect to find in a full-blown, data-driven app: acquiring and displaying\na list of heroes, editing a selected hero's detail, and navigating among different\nviews of heroic data.",
"translation": "这篇《英雄指南》涵盖`了 Angular 的核心原理。这次构建的应用会涉及很多特性:获得并显示英雄列表,编辑所选英雄的详情,并在英雄数据的多个视图之间建立导航。这些特性,在成熟的、数据驱动的应用中经常见到。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "You'll use built-in directives to show and hide elements and display lists of hero data.\nYou'll create components to display hero details and show an array of heroes.\nYou'll use one-way data binding for read-only data. You'll add editable fields to update a model\nwith two-way data binding. You'll bind component methods to user events, like keystrokes and clicks.\nYou'll enable users to select a hero from a master list and edit that hero in the details view. You'll\nformat data with pipes. You'll create a shared service to assemble the heroes.\nAnd you'll use routing to navigate among different views and their components.\n<!-- CF: Should this be a bullet list? --",
"translation": "我们将使用内置指令来显示 / 隐藏元素,并且显示英雄数据的列表。\n 我们将创建组件来显示英雄的详情和英雄列表。\n 我们将对只读数据使用单向数据绑定。我们将添加一些可编辑字段,并通过双向数据绑定更新模型。\n 我们将把组件上的方法绑定到用户事件上,比如按键和点击。\n 我们将让用户能从主列表视图中选择一个英雄,然后在详情视图中编辑它。\n 我们将通过管道对数据进行格式化。\n 我们将创建一个共享服务来管理我们的英雄们。\n 我们将使用路由在不同的视图及其组件之间进行导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "You'll learn enough core Angular to get started and gain confidence that\nAngular can do whatever you need it to do.\nYou'll cover a lot of ground at an introductory level, and you'll find many links\nto pages with greater depth.",
"translation": "完成本教程后,我们将学习足够的 Angular 核心技术,并确信 Angular 确实能做到我们需要它做的。\n 我们将涵盖大量入门级知识,同时我们也会看到大量链接,指向更深入的章节。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "When you're done with this tutorial, the 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/content-1/tutorial/index.md"
},
{
"original": "## What you'll build",
"translation": "## 我们要构建出什么",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"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/content-1/tutorial/index.md"
},
{
"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/content-1/tutorial/index.md"
},
{
"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/content-1/tutorial/index.md"
},
{
"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/content-1/tutorial/index.md"
},
{
"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/content-1/tutorial/index.md"
},
{
"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/content-1/tutorial/index.md"
},
{
"original": "The following diagram captures all of the navigation options.",
"translation": "下面这张图汇总了我们所有可能的导航路径。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "Here's the app in action:",
"translation": "下图演示了我们应用中的所有操作。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "## Next step",
"translation": "## 接下来",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "You'll build the Tour of Heroes app, step by step.\nEach step is motivated with a requirement that you've likely\nmet in many applications. Everything has a reason.",
"translation": "让我们一起一步步构建出《英雄指南》。\n 正如我们在无数应用遇到那样,每一步都由一个需求驱动。毕竟做任何事都要有个理由。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "Along the way, you'll become familiar with many of the core fundamentals of Angular.",
"translation": "这一路上,我们将遇到很多 Angular 核心原理。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "Start now by building a simple [hero editor](tutorial/toh-pt1 \"The Hero Editor\").",
"translation": "现在就开始构建一个简单的[英雄编辑器](tutorial/toh-pt1 \"英雄编辑器\")吧!",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/index.md"
},
{
"original": "## Setup to develop locally",
"translation": "## 为本地开发搭建环境",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Follow the [setup](guide/setup) instructions for creating a new project\nnamed <code>angular-tour-of-heroes</code>.",
"translation": "根据[开发环境](guide/setup)中的说明创建一个名为<ngio-ex path=\"angular-tour-of-heroes\"></ngio-ex>的新项目",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "The file structure should look like this:",
"translation": "该项目的文件结构应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"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/content-1/tutorial/toh-pt1.md"
},
{
"original": "## Keep the app transpiling and running",
"translation": "## 保持应用不断转译和运行",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Enter the following command in the terminal window:",
"translation": "在命令行窗口中输入以下命令:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "This command runs the TypeScript compiler in \"watch mode\", recompiling automatically when the code changes.\nThe command simultaneously launches the app in a browser and refreshes the browser when the code changes.",
"translation": "这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。\n同时该命令还会在浏览器中启动该应用并且当代码变化时刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.",
"translation": "在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "## Show the hero",
"translation": "## 显示此英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Add two properties to the `AppComponent`: a `title` property for the app name and a `hero` property\nfor a hero named \"Windstorm.\"",
"translation": "往`AppComponent`中添加两个属性:`title`属性用来表示应用的名字,而`hero`属性用来表示名叫“Windstorm”的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Now update the template in the `@Component` decorator with data bindings to these new properties.",
"translation": "下面,更新`@Component`装饰器中指定的模板,为这些新属性建立数据绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "The browser refreshes and displays the title and hero name.",
"translation": "保存后,浏览器应自动刷新,显示标题和英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "The double curly braces are Angular's *interpolation binding* syntax.\nThese interpolation bindings present the component's `title` and `hero` property values,\nas strings, inside the HTML header tags.",
"translation": "这里的双大括号是Angular中的*插值表达式绑定*语法。它们表示组件的`title`和`hero`属性的值会作为字符串插入到HTML标签中间。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Read more about interpolation in the [Displaying Data](guide/displaying-data) page.",
"translation": "要了解插值表达式的更多知识,见[显示数据](guide/displaying-data)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "### Hero object",
"translation": "### Hero 对象",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "The hero needs more properties.\nConvert the `hero` from a literal string to a class.",
"translation": "显然,英雄还需要更多属性。\n让我们把`hero`从一个字符串字面量换成一个类。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Create a `Hero` class with `id` and `name` properties.\nAdd these properties near the top of the `app.component.ts` file, just below the import statement.",
"translation": "创建一个`Hero`类,它具有`id`和`name`属性。\n现在把下列代码放在`app.component.ts`的顶部,仅次于 import 语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "In the `AppComponent` class, refactor the component's `hero` property to be of type `Hero`,\nthen initialize it with an `id` of `1` and the name `Windstorm`.",
"translation": "现在,有了一个`Hero`类,我们把组件`hero`属性的类型换成`Hero`。\n然后以`1`为 id、以 “Windstorm” 为名字,初始化它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Because you changed the hero from a string to an object,\nupdate the binding in the template to refer to the hero's `name` property.",
"translation": "我们把`hero`从一个字符串换成了对象,所以也得更新模板中的绑定表达式,来引用`hero`的`name`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "The browser refreshes and continues to display the hero's name.",
"translation": "浏览器自动刷新,并继续显示这位英雄的名字。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "### Adding HTML with multi-line template strings",
"translation": "### 使用多行模板字符串添加更多 HTML",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "To show all of the hero's properties,\nadd a `<div>` for the hero's `id` property and another `<div>` for the hero's `name`.\nTo keep the template readable, place each `<div>` on its own line.",
"translation": "要显示英雄的所有属性,还要为英雄的`id`属性添加一个`<div>`,为英雄的`name`属性添加另一个`<div>`。\n为了保持模板的可读性把每个`<div>`单独放一行。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "The backticks around the component template let you put the `<h1>`, `<h2>`, and `<div>` elements on their own lines,\nthanks to the <i>template literals</i> feature in ES2015 and TypeScript. For more information, see\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals\" target=\"_blank\" title=\"template literal\">Template literals</a>.",
"translation": "反引号包裹的组件模板能让你把`<h1>`、`<h2>`和`<div>`元素各自放在一行上。\n感谢ES2015和TypeScript的*模板字面量*特性。要了解更多,请参见<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals\" target=\"_blank\" title=\"template literal\">模板字面量Template literals</a> 页。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "## Edit the hero name",
"translation": "## 编辑英雄名字",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Users should be able to edit the hero name in an `<input>` textbox.\nThe textbox should both _display_ the hero's `name` property\nand _update_ that property as the user types.",
"translation": "用户应该能在一个`<input>`输入框中编辑英雄的名字。\n当用户输入时这个输入框应该能同时*显示*和*修改*英雄的`name`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "You need a two-way binding between the `<input>` form element and the `hero.name` property.",
"translation": "也就是说,我们要在表单元素`<input>`和组件的`hero.name`属性之间建立双向绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "### Two-way binding",
"translation": "### 双向绑定",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Refactor the hero name in the template so it looks like this:",
"translation": "把模板中的英雄名字重构成这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "`[(ngModel)]` is the Angular syntax to bind the `hero.name` property\nto the textbox.\nData flows _in both directions:_ from the property to the textbox,\nand from the textbox back to the property.",
"translation": "`[(ngModel)]`是一个Angular语法用与把`hero.name`绑定到输入框中。\n它的数据流是*双向的*:从属性到输入框,并且从输入框回到属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Unfortunately, immediately after this change, the application breaks.\nIf you looked in the browser console, you'd see Angular complaining that\n\"`ngModel` ... isn't a known property of `input`.\"",
"translation": "不幸的是,做了这项改动之后,我们的程序崩溃了。\n打开浏览器的控制台我们会看到Angular抱怨说“`ngModel` ... isn't a known property of `input`.”(`ngModel`不是`input`元素的已知属性)",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Although `NgModel` is a valid Angular directive, it isn't available by default.\nIt belongs to the optional `FormsModule`.\nYou must opt-in to using that module.",
"translation": "虽然`NgModel`是一个有效的Angular指令但它默认情况下却是不可用的。\n它属于一个可选模块`FormsModule`。\n我们必须选择使用那个模块。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "### Import the _FormsModule_",
"translation": "### 导入 _FormsModule_",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Open the `app.module.ts` file and import the `FormsModule` symbol from the `@angular/forms` library.\nThen add the `FormsModule` to the `@NgModule` metadata's `imports` array, which contains the list\nof external modules that the app uses.",
"translation": "打开`app.module.ts`文件,并且从`@angular/forms`库中导入符号`FormsModule`。\n然后把`FormsModule`添加到`@NgModule`元数据的`imports`数组中,它是当前应用正在使用的外部模块列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "The updated `AppModule` looks like this:",
"translation": "修改后的`AppModule`是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Read more about `FormsModule` and `ngModel` in the\n[Two-way data binding with ngModel](guide/forms#ngModel) section of the\n[Forms](guide/forms) guide and the\n[Two-way binding with NgModel](guide/template-syntax#ngModel) section of the\n[Template Syntax](guide/template-syntax) guide.",
"translation": "要学习关于`FormsModule`和`ngModel`的更多知识,参见[表单](guide/forms#ngModel)和\n[模板语法](guide/template-syntax#ngModel)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "When the browser refreshes, the app should work again.\nYou 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/content-1/tutorial/toh-pt1.md"
},
{
"original": "## Summary",
"translation": "## 我们已经走过的路",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Take stock of what you've built.",
"translation": "我们来盘点一下已经构建完成的部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "* The Tour of Heroes app uses the double curly braces of interpolation (a type of one-way data binding)\nto display the app title and properties of a `Hero` object.",
"translation": "我们的《英雄指南》使用双大括号插值表达式(单向数据绑定的一种形式)来显示应用的标题和`Hero`对象的属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "* You wrote a multi-line template using ES2015's template literals to make the template readable.",
"translation": "我们使用 ES2015 的模板字符串写了一个多行模板,使我们的模板更具可读性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "* You added a two-way data binding to the `<input>` element\nusing the built-in `ngModel` directive. This binding both displays the hero's name and allows users to change it.",
"translation": "为了同时显示和修改英雄的名字,我们还使用了内置的`ngModel`指令,往`<input>`元素上添加了双向数据绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "* The `ngModel` directive propagates changes to every other binding of the `hero.name`.",
"translation": "`ngModel`指令将这些修改传播到每一个对`hero.name`的其它绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Your app should look like this <live-example></live-example>.",
"translation": "运行这部分的<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "Here's the complete `app.component.ts` as it stands now:",
"translation": "完整的`app.component.ts`是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "## Next step",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"original": "In the [next tutorial page](tutorial/toh-pt2 \"Master/Detail\"), you'll build on the Tour of Heroes app to display a list of heroes.\nYou'll also allow the user to select heroes and display their details.\nYou'll learn more about how to retrieve lists and bind them to the template.",
"translation": "在[教程的下一章](tutorial/toh-pt2),我们将在这个《英雄指南》中显示一个英雄列表。\n我们将允许允许用户选择英雄并显示他们的详情。\n我们还将学会如何获取列表以及将它们绑定到模板中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt1.md"
},
{
"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/content-1/tutorial/toh-pt2.md"
},
{
"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/content-1/tutorial/toh-pt2.md"
},
{
"original": "## Where you left off",
"translation": "## 延续上一步教程",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Before you continue with this page of the Tour of Heroes,\nverify that you have the following structure after [The Hero Editor](tutorial/toh-pt1) page.\nIf your structure doesn't match, go back to that page to figure out what you missed.",
"translation": "在继续《英雄指南》的第二部分之前,先来检查一下,完成[第一部分](tutorial/toh-pt1)之后,你是否已经有了如下目录结构。如果没有,你得先回到第一部分,看看错过了哪里。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "## Keep the app transpiling and running",
"translation": "## 让应用代码保持转译和运行",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Enter the following command in the terminal window:",
"translation": "在控制台中敲下列命令:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "This command runs the TypeScript compiler in \"watch mode\", recompiling automatically when the code changes.\nThe command simultaneously launches the app in a browser and refreshes the browser when the code changes.",
"translation": "这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。\n 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.",
"translation": "在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "## Displaying heroes",
"translation": "## 显示我们的英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "To display a list of heroes, you'll add heroes to the view's template.",
"translation": "要显示英雄列表,我们就要先往视图模板中添加一些英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### Create heroes",
"translation": "### 创建英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Create an array of ten heroes.",
"translation": "我们先创建一个由十位英雄组成的数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The `HEROES` array is of type `Hero`, the class defined in the previous page.\nEventually this app will fetch the list of heroes from a web service, but for now\nyou can display mock heroes.",
"translation": "`HEROES`是一个由`Hero`类的实例构成的数组,我们在第一部分定义过它。\n我们当然希望从一个 Web 服务中获取这个英雄列表,但别急,我们得把步子迈得小一点,先用一组模拟出来的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### Expose heroes",
"translation": "### 暴露英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Create a public property in `AppComponent` that exposes the heroes for binding.",
"translation": "我们在`AppComponent`上创建一个公共属性,用来暴露这些英雄,以供绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The `heroes` type isn't defined because TypeScript infers it from the `HEROES` array.",
"translation": "我们并不需要明确定义`heroes`属性的数据类型TypeScript 能从`HEROES`数组中推断出来。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The hero data is separated from the class implementation\nbecause ultimately the hero names will come from a data service.",
"translation": "英雄的数据从实现类中分离了出来,因为最终,英雄的名字会来自一个数据服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### Display hero names in a template",
"translation": "### 在模板中显示英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "To display the hero names in an unordered list,\ninsert the following chunk of HTML below the title and above the hero details.",
"translation": "我们还要在模板中创建一个无序列表来显示这些英雄的名字。\n那就在标题和英雄详情之间插入下面这段 HTML 代码。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Now you can fill the template with hero names.",
"translation": "现在,我们有了一个模板。接下来,就用英雄们的数据来填充它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### List heroes with ngFor",
"translation": "### 通过 ngFor 来显示英雄列表",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The goal is to bind the array of heroes in the component to the template, iterate over them,\nand display them individually.",
"translation": "我们想要把组件中的`heroes`数组绑定到模板中,迭代并逐个显示它们。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Modify the `<li>` tag by adding the built-in directive `*ngFor`.",
"translation": "首先,修改`<li>`标签,往上添加内置指令`*ngFor`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The (`*`) prefix to `ngFor` is a critical part of this syntax.\nIt indicates that the `<li>` element and its children\nconstitute a master template.",
"translation": "`ngFor`的`*`前缀表示`<li>`及其子元素组成了一个主控模板。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The `ngFor` directive iterates over the component's `heroes` array\nand renders an instance of this template for each hero in that array.",
"translation": "`ngFor`指令在`AppComponent.heroes`属性返回的`heroes`数组上迭代,并输出此模板的实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The `let hero` part of the expression identifies `hero` as the template input variable,\nwhich holds the current hero item for each iteration.\nYou can reference this variable within the template to access the current hero's properties.",
"translation": "引号中赋值给`ngFor`的那段文本表示“*从`heroes`数组中取出每个英雄,存入一个局部的`hero`变量,并让它在相应的模板实例中可用*”。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Read more about `ngFor` and template input variables in the\n[Showing an array property with *ngFor](guide/displaying-data#ngFor) section of the\n[Displaying Data](guide/displaying-data) page and the\n[ngFor](guide/template-syntax#ngFor) section of the\n[Template Syntax](guide/template-syntax) page.",
"translation": "要学习更多关于`ngFor`和模板输入变量的知识,参见[显示数据](guide/displaying-data)一章的[用*ngFor显示数组属性](guide/displaying-data#ngFor)和\n[模板语法](guide/template-syntax)章的[ngFor](guide/template-syntax#ngFor)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Within the `<li>` tags, add content\nthat uses the `hero` template variable to display the hero's properties.",
"translation": "接着,我们在`<li>`标签中插入一些内容,以便使用模板变量`hero`来显示英雄的属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "When the browser refreshes, a list of heroes appears.",
"translation": "当浏览器刷新时,我们就看到了英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### Style the heroes",
"translation": "### 给我们的英雄们“美容”",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Users should get a visual cue of which hero they are hovering over and which hero is selected.",
"translation": "当用户的鼠标划过英雄或选中一个英雄时,我们得让他/她看起来醒目一点。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "To add styles to your component, set the `styles` property on the `@Component` decorator\nto the following CSS classes:",
"translation": "要想给我们的组件添加一些样式,请把`@Component`装饰器的`styles`属性设置为下列 CSS 类:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Remember to use the backtick notation for multi-line strings.",
"translation": "注意,我们又使用了反引号语法来书写多行字符串。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Adding these styles makes the file much longer. In a later page you'll move the styles to a separate file.",
"translation": "添加这些样式会让此文件变得更长。在后面的章节中,我们将会把这些样式移到单独的文件中去。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "When you assign styles to a component, they are scoped to that specific component.\nThese styles apply only to the `AppComponent` and don't affect the outer HTML.",
"translation": "当我们为一个组件指定样式时,它们的作用域将仅限于该组件。\n 上面的例子中,这些样式只会作用于`AppComponent`组件,而不会“泄露”到外部 HTML 中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The template for displaying heroes should look like this:",
"translation": "用于显示英雄们的模板应该是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "## Selecting a hero",
"translation": "## 选择英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The app now displays a list of heroes as well as a single hero in the details view. But\nthe list and the details view are not connected.\nWhen users select a hero from the list, the selected hero should appear in the details view.\nThis UI pattern is known as \"master/detail.\"\nIn this case, the _master_ is the heroes list and the _detail_ is the selected hero.",
"translation": "我们的应用已经有了英雄列表和单个英雄的详情视图。\n 但列表和单独的英雄之间还没有任何关联。\n 我们希望用户在列表中选中一个英雄,然后让这个被选中的英雄出现在详情视图中。\n 这种 UI 布局模式,通常被称为“主从结构”。\n 在这个例子中,主视图是英雄列表,从视图则是被选中的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Next you'll connect the master to the detail through a `selectedHero` component property,\nwhich is bound to a click event.",
"translation": "接下来,我们要通过组件中的一个`selectedHero`属性来连接主从视图,它被绑定到了点击事件上。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### Handle click events",
"translation": "### 处理点击事件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Add a click event binding to the `<li>` like this:",
"translation": "我们再往`<li>`元素上插入一句点击事件的绑定代码:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The parentheses identify the `<li>` element's `click` event as the target.\nThe `onSelect(hero)` expression calls the `AppComponent` method, `onSelect()`,\npassing the template input variable `hero`, as an argument.\nThat's the same `hero` variable you defined previously in the `ngFor` directive.",
"translation": "圆括号标识`<li>`元素上的`click`事件是绑定的目标。\n 等号右边的`onSelect(hero)`表达式调用`AppComponent`的`onSelect()`方法,并把模板输入变量`hero`作为参数传进去。\n 它是我们前面在`ngFor`指令中定义的那个`hero`变量。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Learn more about event binding at the\n[User Input](guide/user-input) page and the\n[Event binding](guide/template-syntax#event-binding) section of the\n[Template Syntax](guide/template-syntax) page.",
"translation": "关于事件绑定的更多内容,参见:\n [用户输入](guide/user-input)页 和\n [模板语法](guide/template-syntax)页的[事件绑定](guide/template-syntax#event-binding)节。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### Add a click handler to expose the selected hero",
"translation": "### 添加点击处理器以暴露选中的英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "You no longer need the `hero` property because you're no longer displaying a single hero; you're displaying a list of heroes.\nBut the user will be able to select one of the heroes by clicking on it.\nSo replace the `hero` property with this simple `selectedHero` property:",
"translation": "我们不再需要`AppComponent`的`hero`属性,因为不需要再显示单个的英雄,我们只需要显示英雄列表。但是用户可以点选一个英雄。\n所以我们要把`hero`属性**替换**成`selectedHero`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The hero names should all be unselected before the user picks a hero, so\nyou won't initialize the `selectedHero` as you did with `hero`.",
"translation": "在用户选取一个英雄之前,所有的英雄名字都应该是未选中的。所以我们不希望像`hero`一样初始化`selectedHero`变量。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Add an `onSelect()` method that sets the `selectedHero` property to the `hero` that the user clicks.",
"translation": "现在,**添加一个`onSelect`方法**,用于将用户点击的英雄赋给`selectedHero`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The template still refers to the old `hero` property.\nBind to the new `selectedHero` property instead as follows:",
"translation": "我们将把所选英雄的详细信息显示在模板中。目前,它仍然引用之前的`hero`属性。\n我们这就修改模板让它绑定到新的`selectedHero`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### Hide the empty detail with ngIf",
"translation": "### 使用 ngIf 隐藏空的详情",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "When the app loads, `selectedHero` is undefined.\nThe selected hero is initialized when the user clicks a hero's name.\nAngular can't display properties of the undefined `selectedHero` and throws the following error,\nvisible in the browser's console:",
"translation": "当应用加载时,我们会看到一个英雄列表,但还没有任何英雄被选中。\n`selectedHero`属性是`undefined`。\n因此我们会看到浏览器控制台中出现下列错误",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Although `selectedHero.name` is displayed in the template,\nyou must keep the hero detail out of the DOM until there is a selected hero.",
"translation": "虽然我们要在模板中显示的是`selectedHero.name`但在选中了一个英雄之前我们必须让这些英雄详情留在DOM之外。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Wrap the HTML hero detail content of the template with a `<div>`.\nThen add the `ngIf` built-in directive and set it to the `selectedHero` property of the component.",
"translation": "我们可以把模板中的英雄详情内容区放在一个`<div>`中。\n 然后,添加一个`ngIf`内置指令,把`ngIf`的值设置为组件的`selectedHero`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Don't forget the asterisk (`*`) in front of `ngIf`.",
"translation": "别忘了`ngIf`前的星号 (`*`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The app no longer fails and the list of names displays again in the browser.",
"translation": "应用不再出错,而名字列表也再次显示在浏览器中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "When there is no selected hero, the `ngIf` directive removes the hero detail HTML from the DOM.\nThere are no hero detail elements or bindings to worry about.",
"translation": "当没有选中英雄时,`ngIf`指令会从 DOM 中移除表示英雄详情的这段 HTML 。\n 没有了表示英雄详情的元素,也就不用担心绑定问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "When the user picks a hero, `selectedHero` becomes defined and\n`ngIf` puts the hero detail content into the DOM and evaluates the nested bindings.",
"translation": "当用户选取了一个英雄,`selectedHero`变成了“已定义的”值,于是`ngIf`把英雄详情加回 DOM 中,并计算它所嵌套的各种绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Read more about `ngIf` and `ngFor` in the\n[Structural Directives](guide/structural-directives) page and the\n[Built-in directives](guide/template-syntax#directives) section of the\n[Template Syntax](guide/template-syntax) page.",
"translation": "要了解更多`ngIf``ngFor`和其它结构型指令的信息,参见\n[结构型指令](guide/structural-directives)和\n[模板语法](guide/template-syntax)章的[内置指令](guide/template-syntax#directives)部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "### Style the selected hero",
"translation": "### 给所选英雄添加样式",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "While the selected hero details appear below the list, it's difficult to identify the selected hero within the list itself.",
"translation": "我们在下面的详情区看到了选中的英雄,但是我们还是没法在上面的列表区快速定位这位英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "In the `styles` metadata that you added above, there is a custom CSS class named `selected`.\nTo make the selected hero more visible, you'll apply this `selected` class to the `<li>` when the user clicks on a hero name.\nFor example, when the user clicks \"Magneta\", it should render with a distinctive but subtle background color\nlike this:",
"translation": "在我们前面添加的`styles`元数据中,有一个名叫`selected`的自定义CSS类。\n要想让选中的英雄更加醒目当用户点击一个英雄名字时我们要为`<li>`添加`selected`类。\n例如当用户点击“Magneta”时它应该使用不一样的醒目的背景色。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "In the template, add the following `[class.selected]` binding to the `<li>`:",
"translation": "在这个模板中,往`<li>`上添加一个`[class.selected]`绑定:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "When the expression (`hero === selectedHero`) is `true`, Angular adds the `selected` CSS class.\nWhen the expression is `false`, Angular removes the `selected` class.",
"translation": "当表达式(`hero === selectedHero`)为`true`时Angular会添加一个CSS类`selected`。为`false`时则会移除`selected`类。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Read more about the `[class]` binding in the [Template Syntax](guide/template-syntax#ngClass \"Template syntax: NgClass\") guide.",
"translation": "关于`[class]`绑定的更多信息,参见[模板语法](guide/template-syntax#ngClass \"Template syntax: NgClass\")。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "After clicking \"Magneta\", the list should look like this:",
"translation": "浏览器重新加载了我们的应用。\n我们选中英雄 Magneta通过背景色的变化它被清晰的标记出来。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Here's the complete `app.component.ts` as of now:",
"translation": "完整的`app.component.ts`文件如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "## Summary",
"translation": "## 已走的路",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "Here's what you achieved in this page:",
"translation": "在本章中,我们完成了以下内容:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "* The Tour of Heroes app displays a list of selectable heroes.",
"translation": "我们的《英雄指南》现在显示一个可选英雄的列表",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "* You added the ability to select a hero and show the hero's details.",
"translation": "我们可以选择英雄,并显示这个英雄的详情",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "* You learned how to use the built-in directives `ngIf` and `ngFor` in a component's template.",
"translation": "我们学会了如何在组件模板中使用内置的`ngIf`和`ngFor`指令",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "## Next step",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "You've expanded the Tour of Heroes app, but it's far from complete.\nAn app shouldn't be one monolithic component.\nIn the [next page](tutorial/toh-pt3 \"Multiple Components\"), you'll split the app into subcomponents and make them work together.",
"translation": "我们的《英雄指南》长大了,但还远远不够完善。\n我们显然不能把整个应用都放进一个组件中。\n我们将在[下一章](tutorial/toh-pt3)把它拆分成一系列子组件,然后教它们协同工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt2.md"
},
{
"original": "The `AppComponent` is doing _everything_ at the moment.\nIn the beginning, it showed details of a single hero.\nThen it became a master/detail form with both a list of heroes and the hero detail.\nSoon there will be new requirements and capabilities.\nYou can't keep piling features on top of features in one component; that's not maintainable.",
"translation": "此刻,`AppComponent`负责*所有事*。\n起初它只显示单个英雄的详情。然后它变成了主从结构同时显示英雄列表和一个英雄详情。\n现在我们很快又会有新需求了。\n我们不能把这些需求全都放在一个组件中否则将不可维护。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "You'll need to break it up into sub-components, each focused on a specific task or workflow.\nEventually, the `AppComponent` could become a simple shell that hosts those sub-components.",
"translation": "我们要把它拆分成一些子组件,每个子组件只聚焦在一个特定的任务或工作流上。\n最后`AppComponent`将会变成一个简单的壳,用来作为那些子组件的宿主。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "In this page, you'll take the first step in that direction by carving out the hero details into a separate, reusable component.\nWhen you're done, the app should look like this <live-example></live-example>.",
"translation": "本章中,我们要做的第一步就是把英雄详情拆分到一个独立的、可复用的组件中。\n做完这些应用是这样的<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "## Where you left off",
"translation": "## 延续上一步教程",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Before getting started on this page, verify that you have the following structure from earlier in the Tour of Heroes.\nIf not, go back to the previous pages.",
"translation": "在继续《英雄指南》之前,先检查一下,是否已经有了如下目录结构。如果没有,回上一章,看看错过了哪里。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Keep the app transpiling and running while you build the Tour of Heroes\nby entering the `npm start` command in a terminal window\n[as you did before](tutorial/toh-pt1#keep-transpiling \"Keep the app running\").",
"translation": "[像以前一样](tutorial/toh-pt1#keep-transpiling \"Keep the app running\"),在终端窗口中输入`npm start`命令,以便在构建《英雄指南》时保持持续转译和运行。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "## Make a hero detail component",
"translation": "## 制作英雄详情组件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Add a file named `hero-detail.component.ts` to the `app/` folder.\nThis file will hold the new `HeroDetailComponent`.",
"translation": "往`app/`文件夹下添加一个名叫`hero-detail.component.ts`的文件。这个文件中会存放这个新的`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "The file and component names follow the standard described in the Angular\n[style guide](guide/styleguide#naming).",
"translation": "文件名和组件名遵循[风格指南](guide/styleguide#naming)中的标准方式。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "* The component _class_ name should be written in _upper camel case_ and end in the word \"Component\".\nThe hero detail component class is `HeroDetailComponent`.",
"translation": "组件的类名应该是*大驼峰形式*,并且以`Component`结尾。\n 因此英雄详情组件的类名是`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "* The component _file_ name should be spelled in [_lower dash case_](guide/glossary#dash-case),\neach word separated by dashes, and end in `.component.ts`.\nThe `HeroDetailComponent` class goes in the `hero-detail.component.ts` file.",
"translation": "组件的文件名应该是[小写中线形式](guide/glossary#dash-case),每个单词之间用中线分隔,并且以`.component.ts`结尾。\n 因此`HeroDetailComponent`类应该放在`hero-detail.component.ts`文件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Start writing the `HeroDetailComponent` as follows:",
"translation": "`HeroDetailComponent`的代码如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "To define a component, you always import the `Component` symbol.",
"translation": "要定义一个组件,我们总是要先导入符号`Component`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "The `@Component` decorator provides the Angular metadata for the component.\nThe CSS selector name, `hero-detail`, will match the element tag\nthat identifies this component within a parent component's template.\n[Near the end of this tutorial page](tutorial/toh-pt3#add-hero-detail \"Add the HeroDetailComponent to the AppComponent\"),\nyou'll add a `<hero-detail>` element to the `AppComponent` template.",
"translation": "`@Component`装饰器为组件提供了Angular元数据。\nCSS选择器的名字`hero-detail`会匹配元素的标签名,用于在父组件的模板中标记出当前组件的位置。\n[本章的最后](tutorial/toh-pt3#add-hero-detail \"Add the HeroDetailComponent to the AppComponent\"),我们会把`<hero-detail>`添加到`AppComponent`的模板中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Always `export` the component class because you'll always `import` it elsewhere.",
"translation": "总是`export`这个组件类,因为你必然会在别处`import`它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "### Hero detail template",
"translation": "### 英雄详情的模板",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "To move the hero detail view to the `HeroDetailComponent`,\ncut the hero detail _content_ from the bottom of the `AppComponent` template\nand paste it into a new `template` property in the `@Component` metadata.",
"translation": "要把英雄详情的视图移入`HeroDetailComponent`,只要把英雄详情的 *内容* 从`AppComponent`模板的底部剪切出来,\n粘贴到`@Component`元数据的`template`属性中就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "The `HeroDetailComponent` has a _hero_, not a _selected hero_.\nReplace the word, \"selectedHero\", with the word, \"hero\", everywhere in the template.\nWhen you're done, the new template should look like this:",
"translation": "`HeroDetailComponent`有一个 `hero`属性,而不再是`selectedHero`。\n所以我们也要在模板中把所有的`selectedHero`替换为`hero`。\n这些完成之后新的模板是这样的",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "### Add the *hero* property",
"translation": "### 添加`hero`属性",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "The `HeroDetailComponent` template binds to the component's `hero` property.\nAdd that property to the `HeroDetailComponent` class like this:",
"translation": "`HeroDetailComponent`模板绑定到了该组件的`hero`属性上。\n把这个属性添加到`HeroDetailComponent`类上,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "The `hero` property is typed as an instance of `Hero`.\nThe `Hero` class is still in the `app.component.ts` file.\nNow there are two components that need to reference the `Hero` class.\nThe Angular [style guide](guide/styleguide#rule-of-one \"Style guide: rule of one\") recommends one class per file anyway.",
"translation": "`hero`属性的类型是`Hero`。\n`Hero`类仍然在`app.component.ts`文件中。\n现在有两个组件需要`Hero`类的引用。\n而Angular[风格指南](guide/styleguide#rule-of-one \"Style guide: rule of one\")建议每个文件中只有一个类。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Move the `Hero` class from `app.component.ts` to its own `hero.ts` file.",
"translation": "因此我们要把`Hero`类从`app.component.ts`移到它自己的`hero.ts`文件中:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Now that the `Hero` class is in its own file, the `AppComponent` and the `HeroDetailComponent` have to import it.\nAdd the following `import` statement near the top of _both_ the `app.component.ts` and the `hero-detail.component.ts` files.",
"translation": "现在,`Hero`类有了自己的文件,`AppComponent` 和 `HeroDetailComponent` 就要`import`它了。\n把下列`import`语句添加到`app.component.ts`和`hero-detail.component.ts`文件的顶部。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "### The *hero* property is an *input* property",
"translation": "### *hero*属性是一个***输入***属性",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "[Later in this page](tutorial/toh-pt3#add-hero-detail \"Add the HeroDetailComponent to the AppComponent\"),\nthe parent `AppComponent` will tell the child `HeroDetailComponent` which hero to display\nby binding its `selectedHero` to the `hero` property of the `HeroDetailComponent`.\nThe binding will look like this:",
"translation": "[在本章稍后的部分](tutorial/toh-pt3#add-hero-detail \"Add the HeroDetailComponent to the AppComponent\")\n父组件`AppComponent`会告诉子组件`HeroDetailComponent`要显示哪个英雄,\n告诉的方法是把它的`selectedHero`属性绑定到`HeroDetailComponent`的`hero`属性上。\n这种绑定是这样的",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Putting square brackets around the `hero` property, to the left of the equal sign (=),\nmakes it the *target* of a property binding expression.\nYou must declare a *target* binding property to be an *input* property.\nOtherwise, Angular rejects the binding and throws an error.",
"translation": "在等号的左边,是方括号围绕的`hero`属性,这表示它是属性绑定表达式的*目标*。\n我们要绑定到的*目标*属性必须是一个*输入*属性否则Angular会拒绝绑定并抛出一个错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "First, amend the `@angular/core` import statement to include the `Input` symbol.",
"translation": "首先,修改`@angular/core`导入语句,使其包含符号`Input`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Then declare that `hero` is an *input* property by\npreceding it with the `@Input` decorator that you imported earlier.",
"translation": "然后,通过在`hero`属性前面加上`@Input`装饰器,来表明它是一个输入属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Read more about _input_ properties in the\n[Attribute Directives](guide/attribute-directives#why-input) page.",
"translation": "要了解*输入属性*的更多知识,参见[属性型指令](guide/attribute-directives#why-input)页。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "That's it. The `hero` property is the only thing in the `HeroDetailComponent` class.",
"translation": "现在,`hero`属性是`HeroDetailComponent`类中唯一的东西。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "All it does is receive a hero object through its `hero` input property and then bind to that property with its template.",
"translation": "它所做的一切就是通过它的输入属性`hero`接收一个英雄对象,然后把这个属性绑定到自己的模板中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Here's the complete `HeroDetailComponent`.",
"translation": "下面是完整的`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "## Declare _HeroDetailComponent_ in the _AppModule_",
"translation": "## 在`AppModule`中声明`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Every component must be declared in one&mdash;and only one&mdash;NgModule.",
"translation": "每个组件都必须在一个且只有一个Angular模块中声明。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Open `app.module.ts` in your editor and import the `HeroDetailComponent` so you can refer to it.",
"translation": "打开`app.module.ts`并且导入`HeroDetailComponent`,以便我们可以引用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Add `HeroDetailComponent` to the module's `declarations` array.",
"translation": "把`HeroDetailComponent`添加到该模块的`declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "In general, the `declarations` array contains a list of application components, pipes, and directives that belong to the module.\nA component must be declared in a module before other components can reference it.\nThis module declares only the two application components, `AppComponent` and `HeroDetailComponent`.",
"translation": "通常,`declarations`数组包含应用中属于该模块的组件、管道和指令的列表。\n组件在被其它组件引用之前必须先在一个模块中声明过。\n这个模块只声明了两个组件`AppComponent` 和 `HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Read more about NgModules in the [NgModules](guide/ngmodule \"NgModules\") guide.",
"translation": "要了解关于Angular模块的更多知识参见[Angular模块](guide/ngmodule \"Angular Modules (NgModule)\")页。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "## Add the _HeroDetailComponent_ to the _AppComponent_",
"translation": "## 把`HeroDetailComponent`添加到`AppComponent`中",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "The `AppComponent` is still a master/detail view.\nIt used to display the hero details on its own, before you cut out that portion of the template.\nNow it will delegate to the `HeroDetailComponent`.",
"translation": "`AppComponent`仍然是主从视图。\n在我们剪切模板之前它自己显示英雄的详情。\n现在它委托给了`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Recall that `hero-detail` is the CSS [`selector`](tutorial/toh-pt3#selector \"HeroDetailComponent selector\")\nin the `HeroDetailComponent` metadata.\nThat's the tag name of the element that represents the `HeroDetailComponent`.",
"translation": "回想一下,`hero-detail`正是`HeroDetailComponent`元数据中使用的 CSS [`selector`](tutorial/toh-pt3#selector \"HeroDetailComponent selector\")\n它是一个HTML元素的标签名用于表示`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Add a `<hero-detail>` element near the bottom of the `AppComponent` template,\nwhere the hero detail view used to be.",
"translation": "把`<hero-detail>`元素添加到`AppComponent`模板的底部,那里就是英雄详情视图所在的位置。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Coordinate the master `AppComponent` with the `HeroDetailComponent`\nby binding the `selectedHero` property of the `AppComponent`\nto the `hero` property of the `HeroDetailComponent`.",
"translation": "协调主视图`AppComponent`与`HeroDetailComponent`的方式是把`AppComponent`的`selectedHero`属性绑定到`HeroDetailComponent`的`hero`属性上。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Now every time the `selectedHero` changes, the `HeroDetailComponent` gets a new hero to display.",
"translation": "每当`selectedHero`变化时,`HeroDetailComponent`就会显示一个新的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "The revised `AppComponent` template should look like this:",
"translation": "修改后的`AppComponent`模板是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "## What changed?",
"translation": "## 有哪些变化?",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "As [before](tutorial/toh-pt2), whenever a user clicks on a hero name,\nthe hero detail appears below the hero list.\nBut now the `HeroDetailView` is presenting those details.",
"translation": "仍然像[以前](tutorial/toh-pt2)一样,一旦用户点击了英雄的名字,英雄详情就会显示在英雄列表的下方。\n不过现在改用`HeroDetailView`来表示英雄详情了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Refactoring the original `AppComponent` into two components yields benefits, both now and in the future:",
"translation": "我们把原来的`AppComponent`重构成了两个组件具有一些显著优点,无论是现在还是未来:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "1. You simplified the `AppComponent` by reducing its responsibilities.",
"translation": "通过缩减`AppComponent`的职责,我们简化了它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "1. You can evolve the `HeroDetailComponent` into a rich hero editor\nwithout touching the parent `AppComponent`.",
"translation": "我们将来可以把`HeroDetailComponent`改进为功能更丰富的英雄编辑器,而不用动`AppComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "1. You can evolve the `AppComponent` without touching the hero detail view.",
"translation": "同样,我们也可以改进`AppComponent`而不用动英雄详情视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "1. You can re-use the `HeroDetailComponent` in the template of some future parent component.",
"translation": "我们可以在未来的其它父组件的模板中复用`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "### Review the app structure",
"translation": "### 审视本应用的代码结构",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Verify that you have the following structure:",
"translation": "验证它是否已经有了如下结构:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Here are the code files discussed in this page.",
"translation": "下面是我们在本章讨论的代码文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "## Summary",
"translation": "## 走过的路",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Here's what you achieved in this page:",
"translation": "来盘点一下我们已经构建了什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "* You created a reusable component.",
"translation": "我们创建了一个可复用组件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "* You learned how to make a component accept input.",
"translation": "我们学会了如何让一个组件接收输入",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "* You learned to declare the required application directives in an NgModule. You\nlisted the directives in the `@NgModule` decorator's `declarations` array.",
"translation": "我们学会了在 Angular 模块中声明该应用所需的指令。\n只要把这些指令列在`NgModule`装饰器的`declarations`数组中就可以了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "* You learned to bind a parent component to a child component.",
"translation": "我们学会了把父组件绑定到子组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Your app should look like this <live-example></live-example>.",
"translation": "现在,应用应该变成了这样:<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "## Next step",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "The Tour of Heroes app is more reusable with shared components,\nbut its (mock) data is still hard coded within the `AppComponent`.\nThat's not sustainable.\nData access should be refactored to a separate service\nand shared among the components that need data.",
"translation": "通过抽取共享组件,我们的《英雄指南》变得更有复用性了,但在`AppComponent`中,我们仍然使用着硬编码的模拟数据。显然,这种方式不能“可持续发展”。\n 我们要把数据访问逻辑重构到一个独立的服务中,并在需要数据的组件之间共享。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "Youll learn to create services in the [next tutorial](tutorial/toh-pt4 \"Services\") page.",
"translation": "在[下一步](tutorial/toh-pt4),我们将学习如何创建服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt3.md"
},
{
"original": "As the Tour of Heroes app evolves, you'll add more components that need access to hero data.",
"translation": "随着《英雄指南》的成长,我们要添加更多需要访问英雄数据的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Instead of copying and pasting the same code over and over,\nyou'll create a single reusable data service and\ninject it into the components that need it.\nUsing a separate service keeps components lean and focused on supporting the view,\nand makes it easy to unit-test components with a mock service.",
"translation": "为了不再把相同的代码复制一遍又一遍,我们要创建一个单一的可复用的数据服务,并且把它注入到需要它的那些组件中。\n使用单独的服务可以保持组件精简使其集中精力为视图提供支持并且借助模拟Mock服务可以更容易的对组件进行单元测试。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Because data services are invariably asynchronous,\nyou'll finish the page with a *Promise*-based version of the data service.",
"translation": "由于数据服务总是异步的因此我们最终会提供一个基于承诺Promise的数据服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"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/content-1/tutorial/toh-pt4.md"
},
{
"original": "## Where you left off",
"translation": "## 延续上一步教程",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Before continuing with the Tour of Heroes, verify that you have the following structure.\nIf not, go back to the previous pages.",
"translation": "在继续《英雄指南》之前,先检查一下,是否已经有如下目录结构。如果没有,回上一章,看看错过了哪里。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "## Keep the app transpiling and running",
"translation": "## 让应用代码保持转译和运行",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Enter the following command in the terminal window:",
"translation": "在终端窗口中输入如下命令:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "This command runs the TypeScript compiler in \"watch mode\", recompiling automatically when the code changes.\nThe command simultaneously launches the app in a browser and refreshes the browser when the code changes.",
"translation": "这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。\n 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.",
"translation": "在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "## Creating a hero service",
"translation": "## 创建英雄服务",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The stakeholders want to show the heroes in various ways on different pages.\nUsers can already select a hero from a list.\nSoon you'll add a dashboard with the top performing heroes and create a separate view for editing hero details.\nAll three views need hero data.",
"translation": "客户向我们描绘了本应用更大的目标:想要在不同的页面中用多种方式显示英雄。\n 现在我们已经能从列表中选择一个英雄了,但这还不够。\n 很快,我们将添加一个仪表盘来显示表现最好的英雄,并创建一个独立视图来编辑英雄的详情。\n 所有这些视图都需要英雄数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "At the moment, the `AppComponent` defines mock heroes for display.\nHowever, defining heroes is not the component's job,\nand you can't easily share the list of heroes with other components and views.\nIn this page, you'll move the hero data acquisition business to a single service that provides the data and\nshare that service with all components that need the data.",
"translation": "目前,`AppComponent`显示的是模拟数据。\n不过定义这些英雄并非组件的任务否则我们没法与其它组件和视图共享这些英雄列表数据。\n在这一章我们将把获取英雄数据的任务重构为一个单独的服务它将提供英雄数据并把服务在所有需要英雄数据的组件间共享。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Create the HeroService",
"translation": "### 创建 HeroService",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Create a file in the `app` folder called `hero.service.ts`.",
"translation": "在`app`目录下创建一个名叫`hero.service.ts`的文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The naming convention for service files is the service name in lowercase followed by `.service`.\nFor a multi-word service name, use lower [dash-case](guide/glossary#dash-case).\nFor example, the filename for `SpecialSuperHeroService` is `special-super-hero.service.ts`.",
"translation": "我们遵循的文件命名约定是:服务名称的小写形式(基本名),加上`.service`后缀。\n如果服务名称包含多个单词我们就把基本名部分写成中线形式 ([dash-case](guide/glossary#dash-case))。\n例如`SpecialSuperHeroService`服务应该被定义在`special-super-hero.service.ts`文件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Name the class `HeroService` and export it for others to import.",
"translation": "我们把这个类命名为`HeroService`,并导出它,以供别人使用。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Injectable services",
"translation": "### 可注入的服务",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Notice that you imported the Angular `Injectable` function and applied that function as an `@Injectable()` decorator.",
"translation": "注意,我们导入了 Angular 的`Injectable`函数,并作为`@Injectable()`装饰器使用这个函数。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Don't forget the parentheses. Omitting them leads to an error that's difficult to diagnose.",
"translation": "**不要忘了写圆括号!**如果忘了写,就会导致一个很难诊断的错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The `@Injectable()` decorator tells TypeScript to emit metadata about the service.\nThe metadata specifies that Angular may need to inject other dependencies into this service.",
"translation": "当 TypeScript 看到`@Injectable()`装饰器时,就会记下本服务的元数据。\n 如果 Angular 需要往这个服务中注入其它依赖,就会使用这些元数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Although the `HeroService` doesn't have any dependencies at the moment,\napplying the `@Injectable()` decorator from the start ensures\nconsistency and future-proofing.",
"translation": "虽然*此时*`HeroService`还没有任何依赖,但我们还是得加上这个装饰器。\n作为一项最佳实践无论是出于提高统一性还是减少变更的目的\n都应该从一开始就加上`@Injectable()`装饰器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Getting hero data",
"translation": "### 获取英雄数据",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Add a `getHeroes()` method stub.",
"translation": "添加一个名叫`getHeros`的桩方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The `HeroService` could get `Hero` data from anywhere&mdash;a\nweb service, local storage, or a mock data source.\nRemoving data access from the component means\nyou can change your mind about the implementation anytime,\nwithout touching the components that need hero data.",
"translation": "`HeroService`可以从任何地方获取`Hero`数据 —— Web服务、本地存储或模拟数据源。\n从组件中移除数据访问逻辑意味着你可以随时更改这些实现方式而不影响需要这些英雄数据的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Move the mock hero data",
"translation": "### 移动模拟的英雄数据",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Cut the `HEROES` array from `app.component.ts` and paste it to a new file in the `app` folder named `mock-heroes.ts`.\nAdditionally, copy the `import {Hero} ...` statement because the heroes array uses the `Hero` class.",
"translation": "从`app.component.ts`文件中剪切`HEROS`数组,把它粘贴到`app`目录下一个名叫`mock-heroes.ts`的文件中。\n还要复制`import {Hero}...`语句,因为我们的英雄数组用到了`Hero`类。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The `HEROES` constant is exported so it can be imported elsewhere, such as the `HeroService`.",
"translation": "我们导出了`HEROES`常量,以便可以在其它地方导入它 &mdash; 例如`HeroService`服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "In `app.component.ts`, where you cut the `HEROES` array,\nadd an uninitialized `heroes` property:",
"translation": "在刚刚剪切出`HEROES`数组的`app.component.ts`文件中,添加一个尚未初始化的`heroes`属性:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Return mocked hero data",
"translation": "### 返回模拟的英雄数据",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Back in the `HeroService`, import the mock `HEROES` and return it from the `getHeroes()` method.\nThe `HeroService` looks like this:",
"translation": "回到`HeroService`,我们导入`HEROES`常量,并在`getHeroes`方法中返回它。\n我们的`HeroService`服务现在是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Import the hero service",
"translation": "### 导入HeroService",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "You're ready to use the `HeroService` in other components, starting with `AppComponent`.",
"translation": "我们可以在多个组件中使用 HeroService 服务了,先从 AppComponent 开始。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Import the `HeroService` so that you can reference it in the code.",
"translation": "先导入`HeroService`,以便我们可以在代码中引用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Don't use *new* with the *HeroService*",
"translation": "### 不要`new`出`HeroService`",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "How should the `AppComponent` acquire a runtime concrete `HeroService` instance?",
"translation": "该如何在运行中获得一个具体的`HeroService`实例呢?",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "You could create a new instance of the `HeroService` with `new` like this:",
"translation": "你可能想用`new`来创建`HeroService`的实例,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "However, this option isn't ideal for the following reasons:",
"translation": "但这不是个好主意,有很多理由,例如:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* The component has to know how to create a `HeroService`.\nIf you change the `HeroService` constructor,\nyou must find and update every place you created the service.\nPatching code in multiple places is error prone and adds to the test burden.",
"translation": "我们的组件得弄清楚该如何创建`HeroService`。\n 如果有一天我们修改了`HeroService`的构造函数,我们不得不找出创建过此服务的每一处代码,并修改它。\n 围着补丁代码转圈很容易导致错误,还会增加测试负担。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* You create a service each time you use `new`.\nWhat if the service caches heroes and shares that cache with others?\nYou couldn't do that.",
"translation": "我们每次使用`new`都会创建一个新的服务实例。\n 如果这个服务需要缓存英雄列表,并把这个缓存共享给别人呢?怎么办?\n 没办法,做不到。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* With the `AppComponent` locked into a specific implementation of the `HeroService`,\nswitching implementations for different scenarios, such as operating offline or using\ndifferent mocked versions for testing, would be difficult.",
"translation": "我们把`AppComponent`锁定到`HeroService`的一个特定实现。\n 我们很难在不同的场景中切换实现。\n 例如,能离线操作吗?能在测试时使用不同的模拟版本吗?这可不容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Inject the *HeroService*",
"translation": "### 注入 *HeroService*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Instead of using the *new* line, you'll add two lines.",
"translation": "你可以用两行代码代替用`new`时的一行:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* Add a constructor that also defines a private property.",
"translation": "添加一个构造函数,并定义一个私有属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* Add to the component's `providers` metadata.",
"translation": "添加组件的`providers`元数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Add the constructor:",
"translation": "添加构造函数:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The constructor itself does nothing. The parameter simultaneously\ndefines a private `heroService` property and identifies it as a `HeroService` injection site.",
"translation": "构造函数自己什么也不用做,它在参数中定义了一个私有的`heroService`属性,并把它标记为注入`HeroService`的靶点。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Now Angular knows to supply an instance of the `HeroService` when it creates an `AppComponent`.",
"translation": "现在,当创建`AppComponent`实例时Angular 知道需要先提供一个`HeroService`的实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Read more about dependency injection in the [Dependency Injection](guide/dependency-injection) page.",
"translation": "更多依赖注入的信息,见[依赖注入](guide/dependency-injection)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The *injector* doesn't know yet how to create a `HeroService`.\nIf you ran the code now, Angular would fail with this error:",
"translation": "*注入器*还不知道该如何创建`HeroService`。\n如果现在运行我们的代码Angular 就会失败,并报错:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "To teach the injector how to make a `HeroService`,\nadd the following `providers` array property to the bottom of the component metadata\nin the `@Component` call.",
"translation": "我们还得注册一个`HeroService`**提供商**,来告诉*注入器*如何创建`HeroService`。\n要做到这一点我们在`@Component`组件的元数据底部添加`providers`数组属性如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The `providers` array tells Angular to create a fresh instance of the `HeroService` when it creates an `AppComponent`.\nThe `AppComponent`, as well as its child components, can use that service to get hero data.",
"translation": "`providers`数组告诉 Angular当它创建新的`AppComponent`组件时,也要创建一个`HeroService`的新实例。\n`AppComponent`会使用那个服务来获取英雄列表,在它组件树中的每一个子组件也同样如此。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### *getHeroes()* in the *AppComponent*",
"translation": "### *AppComponent* 中的 *getHeroes()*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The service is in a `heroService` private variable.",
"translation": "该服务被存入了一个私有变量`heroService`中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "You could call the service and get the data in one line.",
"translation": "我们可以在同一行内调用此服务,并获得数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "You don't really need a dedicated method to wrap one line. Write it anyway:",
"translation": "在真实的世界中,我们并不需要把一行代码包装成一个专门的方法,但无论如何,我们在演示代码中先这么写:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### The *ngOnInit* lifecycle hook",
"translation": "### *ngOnInit* 生命周期钩子",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "`AppComponent` should fetch and display hero data with no issues.",
"translation": "毫无疑问,`AppComponent`应该获取英雄数据并显示它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "You might be tempted to call the `getHeroes()` method in a constructor, but\na constructor should not contain complex logic,\nespecially a constructor that calls a server, such as a data access method.\nThe constructor is for simple initializations, like wiring constructor parameters to properties.",
"translation": "你可能想在构造函数中调用`getHeroes()`方法,但构造函数不应该包含复杂的逻辑,特别是那些需要从服务器获取数据的逻辑更是如此。构造函数是为了简单的初始化工作而设计的,例如把构造函数的参数赋值给属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "To have Angular call `getHeroes()`, you can implement the Angular *ngOnInit lifecycle hook*.\nAngular offers interfaces for tapping into critical moments in the component lifecycle:\nat creation, after each change, and at its eventual destruction.",
"translation": "只要我们实现了 Angular 的 **ngOnInit** *生命周期钩子*Angular 就会主动调用这个钩子。\nAngular提供了一些接口用来介入组件生命周期的几个关键时间点刚创建时、每次变化时以及最终被销毁时。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Each interface has a single method. When the component implements that method, Angular calls it at the appropriate time.",
"translation": "每个接口都有唯一的一个方法。只要组件实现了这个方法Angular 就会在合适的时机调用它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Read more about lifecycle hooks in the [Lifecycle Hooks](guide/lifecycle-hooks) page.",
"translation": "更多生命周期钩子信息,见[生命周期钩子](guide/lifecycle-hooks)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Here's the essential outline for the `OnInit` interface (don't copy this into your code):",
"translation": "这是`OnInit`接口的基本轮廓(但不要拷贝到你自己的代码中):",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Add the implementation for the `OnInit` interface to your export statement:",
"translation": "往export语句中添加`OnInit`接口的实现:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Write an `ngOnInit` method with the initialization logic inside. Angular will call it\nat the right time. In this case, initialize by calling `getHeroes()`.",
"translation": "我们写了一个带有初始化逻辑的`ngOnInit`方法Angular会在适当的时候调用它。\n 在这个例子中,我们通过调用`getHeroes()`来完成初始化。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The app should run as expected, showing a list of heroes and a hero detail view\nwhen you click on a hero name.",
"translation": "我们的应用将会像期望的那样运行,显示英雄列表,并且在我们点击英雄的名字时,显示英雄的详情。\n{@a async}",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "## Async services and Promises",
"translation": "## 异步服务与承诺",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The `HeroService` returns a list of mock heroes immediately;\nits `getHeroes()` signature is synchronous.",
"translation": "我们的`HeroService`立即返回一个模拟的英雄列表,它的`getHeroes()`函数签名是同步的。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Eventually, the hero data will come from a remote server.\nWhen using a remote server, users don't have to wait for the server to respond;\nadditionally, you aren't able to block the UI during the wait.",
"translation": "但最终,英雄的数据会从远端服务器获取。当使用远端服务器时,用户不会等待服务器的响应。换句话说,你没法在等待期间阻塞浏览器界面。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "To coordinate the view with the response, \nyou can use *Promises*, which is an asynchronous \ntechnique that changes the signature of the `getHeroes()` method.",
"translation": "为了协调视图与响应,我们可以使用*承诺Promise*,它是一种异步技术,它会改变`getHeroes()`方法的签名。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### The hero service makes a Promise",
"translation": "### `HeroService`会生成一个承诺",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "A *Promise* essentially promises to call back when the results are ready.\nYou ask an asynchronous service to do some work and give it a callback function.\nThe service does that work and eventually calls the function with the results or an error.",
"translation": "**承诺** 就是 …… 好吧,它就是一个承诺,在有了结果时,它承诺会回调我们。\n我们请求一个异步服务去做点什么并且给它一个回调函数。\n它会去做在某个地方一旦完成它就会调用我们的回调函数并通过参数把工作结果或者错误信息传给我们。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "This is a simplified explanation. Read more about ES2015 Promises in the\n[Promises for asynchronous programming](http://exploringjs.com/es6/ch_promises.html) page of\n[Exploring ES6](http://exploringjs.com/es6.html).",
"translation": "这里只是粗略说说,要了解更多 ES2015 Promise 的信息,见[ES6概览](http://http://exploringjs.com/es6.html)中的[承诺与异步编程](http://exploringjs.com/es6/ch_promises.html)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Update the `HeroService` with this Promise-returning `getHeroes()` method:",
"translation": "把`HeroService`的`getHeroes`方法改写为返回承诺的形式:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "You're still mocking the data. You're simulating the behavior of an ultra-fast, zero-latency server,\nby returning an *immediately resolved Promise* with the mock heroes as the result.",
"translation": "我们继续使用模拟数据。我们通过返回一个 *立即解决的承诺* 的方式,模拟了一个超快、零延迟的超级服务器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "### Act on the Promise",
"translation": "### 基于承诺的行动",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "As a result of the change to `HeroService`, `this.heroes` is now set to a `Promise` rather than an array of heroes.",
"translation": "修改`HeroService`之后,`this.heroes`会被赋值为一个`Promise`而不再是英雄数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "You have to change the implementation to *act on the `Promise` when it resolves*.\nWhen the `Promise` resolves successfully, you'll have heroes to display.",
"translation": "我们得修改这个实现,把它变成*基于承诺*的,并在承诺的事情被解决时再行动。\n 一旦承诺的事情被成功解决Resolve我们就会显示英雄数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Pass the callback function as an argument to the Promise's `then()` method:",
"translation": "我们把回调函数作为参数传给承诺对象的**then**方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "As described in [Arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions),\nthe ES2015 arrow function\nin the callback is more succinct than the equivalent function expression and gracefully handles `this`.",
"translation": "回调中所用的 [ES2015 箭头函数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n比等价的函数表达式更加简洁能优雅的处理 *this* 指针。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The callback sets the component's `heroes` property to the array of heroes returned by the service.",
"translation": "在回调函数中,我们把服务返回的英雄数组赋值给组件的`heroes`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The app is still running, showing a list of heroes, and\nresponding to a name selection with a detail view.",
"translation": "程序仍在运行,显示英雄列表,在选择英雄姓名时,会在详情视图中显示英雄的信息。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "At the end of this page, [Appendix: take it slow](tutorial/toh-pt4#slow) describes what the app might be like with a poor connection.",
"translation": "查看附录中的“[慢!](tutorial/toh-pt4#slow)”,来了解在较差的网络连接中这个应用会是什么样的。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "## Review the app structure",
"translation": "## 回顾本应用的结构",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Verify that you have the following structure after all of your refactoring:",
"translation": "再检查下,经历了本章的所有重构之后,应该有了下列文件结构:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Here are the code files discussed in this page.",
"translation": "下面是本章讨论过的代码文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Here's what you achieved in this page:",
"translation": "来盘点一下我们完成了什么。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* You created a service class that can be shared by many components.",
"translation": "我们创建了一个能被多个组件共享的服务类。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* You used the `ngOnInit` lifecycle hook to get the hero data when the `AppComponent` activates.",
"translation": "我们使用了`ngOnInit`生命周期钩子,以便在`AppComponent`激活时获取英雄数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* You defined the `HeroService` as a provider for the `AppComponent`.",
"translation": "我们把`HeroService`定义为`AppComponent`的一个提供商。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* You created mock hero data and imported them into the service.",
"translation": "我们创建了模拟的英雄数据,并把它导入我们的服务中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "* You designed the service to return a Promise and the component to get the data from the Promise.",
"translation": "我们把服务设计为返回承诺,组件从承诺中获取数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Your app should look like this <live-example></live-example>.",
"translation": "现在应用变成了这样:<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "## Next step",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "The Tour of Heroes has become more reusable using shared components and services.\nThe next goal is to create a dashboard, add menu links that route between the views, and format data in a template.\nAs the app evolves, you'll discover how to design it to make it easier to grow and maintain.",
"translation": "通过使用共享组件和服务,我们的《英雄指南》更有复用性了。\n 我们还要创建一个仪表盘,要添加在视图间路由的菜单链接,还要在模板中格式化数据。\n 随着我们应用的进化,我们还会学到如何进行设计,让它更易于扩展和维护。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Read about the Angular component router and navigation among the views in the [next tutorial](tutorial/toh-pt5 \"Routing and Navigation\") page.",
"translation": "我们将在[下一章](tutorial/toh-pt5)学习 Angular 组件路由,以及在视图间导航的知识。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "## Appendix: Take it slow",
"translation": "## 附件:慢一点……",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "To simulate a slow connection,\nimport the `Hero` symbol and add the following `getHeroesSlowly()` method to the `HeroService`.",
"translation": "我们可以模拟慢速连接。导入`Hero`类,并且在`HeroService`中添加如下的`getHeroesSlowly()`方法:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Like `getHeroes()`, it also returns a `Promise`.\nBut this Promise waits two seconds before resolving the Promise with mock heroes.",
"translation": "像`getHeroes()`一样,它也返回一个承诺。\n但是这个承诺会在提供模拟数据之前等待两秒钟。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "Back in the `AppComponent`, replace `getHeroes()` with `getHeroesSlowly()`\nand see how the app behaves.",
"translation": "回到`AppComponent`,用`heroService.getHeroesSlowly()`替换`heroService.getHeroes()`,并观察应用的行为。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt4.md"
},
{
"original": "There are new requirements for the Tour of Heroes app:",
"translation": "我们收到了《英雄指南》的一些新需求:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Add a *Dashboard* view.",
"translation": "添加一个*仪表盘*视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Add the ability to navigate between the *Heroes* and *Dashboard* views.",
"translation": "在*英雄列表*和*仪表盘*视图之间导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"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/content-1/tutorial/toh-pt5.md"
},
{
"original": "* When users click a *deep link* in an email, open the detail view for a particular hero.",
"translation": "在邮件中点击一个*深链接*,会直接打开一个特定英雄的详情视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "When youre done, users will be able to navigate the app like this:",
"translation": "完成时,用户就能像这样在应用中导航:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "To satisfy these requirements, you'll add Angulars router to the app.",
"translation": "我们将把 Angular *路由器*加入应用中,以满足这些需求。\n(译注:硬件领域中的路由器是用来帮你找到另一台网络设备的,而这里的路由器用于帮你找到一个组件)",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "For more information about the router, read the [Routing and Navigation](guide/router) page.",
"translation": "更多信息,见[路由和导航](guide/router)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"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/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Where you left off",
"translation": "## 延续上一步教程",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Before continuing with the Tour of Heroes, verify that you have the following structure.",
"translation": "在继续《英雄指南》之前,我们先验证一下目录结构:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Keep the app transpiling and running",
"translation": "## 让应用代码保持转译和运行",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Enter the following command in the terminal window:",
"translation": "打开终端/控制台窗口,运行如下命令:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "This command runs the TypeScript compiler in \"watch mode\", recompiling automatically when the code changes.\nThe command simultaneously launches the app in a browser and refreshes the browser when the code changes.",
"translation": "这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。\n 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.",
"translation": "在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Action plan",
"translation": "## 行动计划",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Here's the plan:",
"translation": "下面是我们的计划:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Turn `AppComponent` into an application shell that only handles navigation.",
"translation": "把`AppComponent`变成应用程序的“壳”,它只处理导航",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`.",
"translation": "把现在由`AppComponent`关注的*英雄们*移到一个独立的`HeroesComponent`中",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Add routing.",
"translation": "添加路由",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Create a new `DashboardComponent`.",
"translation": "创建一个新的`DashboardComponent`组件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Tie the *Dashboard* into the navigation structure.",
"translation": "把*仪表盘*加入导航结构中",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "*Routing* is another name for *navigation*. The router is the mechanism for navigating from view to view.",
"translation": "*路由*是导航的另一个名字。*路由器*就是从一个视图导航到另一个视图的机制。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Splitting the *AppComponent*",
"translation": "## 拆分 *AppComponent*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The current app loads `AppComponent` and immediately displays the list of heroes.",
"translation": "现在的应用会加载`AppComponent`组件,并且立刻显示出英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The revised app should present a shell with a choice of views (*Dashboard* and *Heroes*)\nand then default to one of them.",
"translation": "我们修改后的应用将提供一个壳,它会选择*仪表盘*和*英雄列表*视图之一,然后默认显示它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The `AppComponent` should only handle navigation, so you'll\nmove the display of *Heroes* out of `AppComponent` and into its own `HeroesComponent`.",
"translation": "`AppComponent`组件应该只处理导航。\n我们来把*英雄列表*的显示职责,从`AppComponent`移到`HeroesComponent`组件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### *HeroesComponent*",
"translation": "### *HeroesComponent* 组件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "`AppComponent` is already dedicated to *Heroes*.\nInstead of moving the code out of `AppComponent`, rename it to `HeroesComponent`\nand create a separate `AppComponent` shell.",
"translation": "`AppComponent`的职责已经被移交给`HeroesComponent`了。\n 与其把`AppComponent`中所有的东西都搬过去,不如索性把它改名为`HeroesComponent`,然后单独创建一个新的`AppComponent`壳。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Do the following:",
"translation": "步骤如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Rename the <code>app.component.ts</code> file to <code>heroes.component.ts</code>.",
"translation": "把<code>app.component.ts</code>文件改名为<code>heroes.component.ts</code>。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Rename the `AppComponent` class as `HeroesComponent` (rename locally, _only_ in this file).",
"translation": "把`AppComponent`类改名为`HeroesComponent`(注意,*只*在这一个文件中改名)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Rename the selector `my-app` as `my-heroes`.",
"translation": "把`my-app`选择器改名为`my-heroes`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Create *AppComponent*",
"translation": "### 创建 *AppComponent*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The new `AppComponent` is the application shell.\nIt will have some navigation links at the top and a display area below.",
"translation": "新的`AppComponent`将成为应用的“壳”。\n 它将在顶部放一些导航链接,并且把我们要导航到的页面放在下面的显示区中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Perform these steps:",
"translation": "执行下列步骤:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* add the supporting `import` statements.",
"translation": "添加支持性的`import`语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Create the file <code>src/app/app.component.ts</code>.",
"translation": "创建一个名叫<span ngio-ex>src/app/app.component.ts</span>的新文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Define an exported `AppComponent` class.",
"translation": "定义一个导出的 `AppComponent`类。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Add an `@Component` decorator above the class with a `my-app` selector.",
"translation": "在类的上方添加`@Component`元数据装饰器,装饰器带有`my-app`选择器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Move the following from `HeroesComponent` to `AppComponent`:",
"translation": "将下面的项目从`HeroesComponent`移到`AppComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* `title` class property.",
"translation": "`title`类属性",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* `@Component` template `<h1>` element, which contains a binding to `title`.",
"translation": "`@Component`模板中的`<h1>`标签,它包含了对`title`属性的绑定。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Add a `<my-heroes>` element to the app template just below the heading so you still see the heroes.",
"translation": "在模板的标题下面添加`<my-heroes>`标签,以便我们仍能看到英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Add `HeroesComponent` to the `declarations` array of `AppModule` so Angular recognizes the `<my-heroes>` tags.",
"translation": "添加`HeroesComponent`组件到根模块的`declarations`数组中,以便 Angular 能认识`<my-heroes>`标签。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Add `HeroService` to the `providers` array of `AppModule` because you'll need it in every other view.",
"translation": "添加`HeroService`到`AppModule`的`providers`数组中,因为我们的每一个视图都需要它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Remove `HeroService` from the `HeroesComponent` `providers` array since it was promoted.",
"translation": "从`HerosComponent`的`providers`数组中移除`HeroService`,因为它被提到模块了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Add the supporting `import` statements for `AppComponent`.",
"translation": "为`AppComponent`添加一些`import`语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The first draft looks like this:",
"translation": "我们的第一个草稿版就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Remove <i>HeroService</i> from the <i>HeroesComponent</i> providers",
"translation": "从<i>HeroesComponent</i>的<code>providers</code>中移除<i>HeroService</i>",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Go back to the `HeroesComponent` and **remove the `HeroService`** from its `providers` array.\nWe are *promoting* this service from the `HeroesComponent` to the root `NgModule`.\nWe ***do not want two copies*** of this service at two different levels of our app.",
"translation": "回到`HeroesComponent`,并从`providers`数组中**移除`HeroService`**。\n把它从`HeroesComponent`*提升*到根`NgModule`中。\n我们不希望在应用的两个不同层次上存在它的***两个副本***。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The app still runs and displays heroes.",
"translation": "应用仍然在运行,并显示着英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Add routing",
"translation": "## 添加路由",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Instead of displaying automatically, heroes should display after users click a button.\nIn other words, users should be able to navigate to the list of heroes.",
"translation": "我们希望在用户点击按钮之后才显示英雄列表,而不是自动显示。\n 换句话说,我们希望用户能“导航”到英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Use the Angular router to enable navigation.",
"translation": "我们要使用 Angular *路由器*进行导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The Angular router is an external, optional Angular NgModule called `RouterModule`.\nThe router is a combination of multiple provided services (`RouterModule`),\nmultiple directives (`RouterOutlet, RouterLink, RouterLinkActive`),\nand a configuration (`Routes`). You'll configure the routes first.",
"translation": "Angular 路由器是一个可选的外部 Angular NgModule名叫`RouterModule`。\n路由器包含了多种服务(`RouterModule`)、多种指令(`RouterOutlet、RouterLink、RouterLinkActive`)、\n和一套配置(`Routes`)。我们将先配置路由。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### *&lt;base href>*",
"translation": "### *&lt;base href>* 组件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Open `index.html` and ensure there is a `<base href=\"...\">` element\n(or a script that dynamically sets this element)\nat the top of the `<head>` section.",
"translation": "打开`index.html`,确保它的`<head>`区顶部有一个`<base href=\"...\">`元素(或动态生成该元素的脚本)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "base href is essential",
"translation": "基地址base href是必须的",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "For more information, see the [Set the base href](guide/router)\nsection of the [Routing and Navigation](guide/router) page.",
"translation": "要了解更多信息,请参见[路由与导航](guide/router)章的[设置基地址base href](guide/router)部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Configure routes",
"translation": "### 配置路由",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Create a configuration file for the app routes.",
"translation": "本应用还没有路由。我们来为应用的路由新建一个配置。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "*Routes* tell the router which views to display when a user clicks a link or\npastes a URL into the browser address bar.",
"translation": "*路由*告诉路由器,当用户点击链接或者把 URL 粘贴到浏览器地址栏时,应该显示哪个视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Define the first route as a route to the heroes component.",
"translation": "我们的第一个路由是指向英雄列表组件的。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The `Routes` are an array of *route definitions*.",
"translation": "这个`Routes`是一个*路由定义*的数组。\n此时我们只有一个路由定义但别急后面还会添加更多。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "This route definition has the following parts:",
"translation": "*路由定义*包括以下部分:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* *Path*: The router matches this route's path to the URL in the browser address bar (`heroes`).",
"translation": "**Path**: 路由器会用它来匹配浏览器地址栏中的地址,如`heroes`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* *Component*: The component that the router should create when navigating to this route (`HeroesComponent`).",
"translation": "*Component*: 导航到此路由时,路由器需要创建的组件(`HeroesComponent`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Read more about defining routes with `Routes` in the [Routing & Navigation](guide/router) page.",
"translation": "关于`Routes`定义的更多信息,见[路由与导航](guide/router)一章。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Make the router available",
"translation": "### 让路由器可用",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Import the `RouterModule` and add it to the `AppModule` imports array.",
"translation": "导入`RouterModule`并添加到`AppModule`的`imports`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The `forRoot()` method is called because a configured router is provided at the app's root.\nThe `forRoot()` method supplies the Router service providers and directives needed for routing, and\nperforms the initial navigation based on the current browser URL.",
"translation": "这里使用了`forRoot()`方法,因为我们是在应用*根部*提供配置好的路由器。\n`forRoot()`方法提供了路由需要的路由服务提供商和指令,并基于当前浏览器 URL 初始化导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Router outlet",
"translation": "### 路由出口(Outlet)",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "If you paste the path, `/heroes`, into the browser address bar at the end of the URL,\nthe router should match it to the `heroes` route and display the `HeroesComponent`.\nHowever, you have to tell the router where to display the component.\nTo do this, you can add a `<router-outlet>` element at the end of the template.\n`RouterOutlet` is one of the directives provided by the `RouterModule`.\nThe router displays each component immediately below the `<router-outlet>` as users navigate through the app.",
"translation": "如果我们把路径`/heroes`粘贴到浏览器的地址栏,路由器会匹配到`'Heroes'`路由,并显示`HeroesComponent`组件。\n我们必须***告诉路由器它位置***,所以我们把`<router-outlet>`标签添加到模板的底部。\n `RouterOutlet`是由`RouterModule`提供的指令之一。\n 当我们在应用中导航时,路由器就把激活的组件显示在`<router-outlet>`里面。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Router links",
"translation": "### 路由器链接",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Users shouldn't have to paste a route URL into the address bar.\nInstead, add an anchor tag to the template that, when clicked, triggers navigation to the `HeroesComponent`.",
"translation": "我们当然不会真让用户往地址栏中粘贴路由的 URL\n而应该在模板中的什么地方添加一个锚标签。点击时就会导航到`HeroesComponent`组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The revised template looks like this:",
"translation": "修改过的模板是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Note the `routerLink` binding in the anchor tag.\nThe `RouterLink` directive (another of the `RouterModule` directives) is bound to a string\nthat tells the router where to navigate when the user clicks the link.",
"translation": "注意,锚标签中的`[routerLink]`绑定。\n我们把`RouterLink`指令(`ROUTER_DIRECTIVES`中的另一个指令)绑定到一个字符串。\n它将告诉路由器当用户点击这个链接时应该导航到哪里。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Since the link is not dynamic, a routing instructionis defined with a one-time binding to the route path.\nLooking back at the route configuration, you can confirm that `'/heroes'` is the path of the route to the `HeroesComponent`.",
"translation": "由于这个链接不是动态的,我们只要用**一次性绑定**的方式绑定到路由的**路径 (path) **就行了。\n回来看路由配置表我们清楚的看到这个路径 —— `'/heroes'`就是指向`HeroesComponent`的那个路由的路径。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Read more about dynamic router links and the link parameters array\nin the [Appendix: Link Parameters Array](guide/router#link-parameters-array) section of the\n[Routing & Navigation](guide/router) page.",
"translation": "关于动态路由器链接和*链接参数数组更多信息,见[路由与导航](guide/router)中的[附录:链接参数数组](guide/router#link-parameters-array)部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Refresh the browser. The browser displays the app title and heroes link, but not the heroes list.",
"translation": "刷新浏览器。我们只看到了应用标题和英雄链接。英雄列表到哪里去了?",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The browser's address bar shows `/`.\nThe route path to `HeroesComponent` is `/heroes`, not `/`.\nSoon you'll add a route that matches the path `/`.",
"translation": "浏览器的地址栏显示的是`/`。而到`HeroesComponent`的路由中的路径是`/heroes`,不是`/`。\n我们没有任何路由能匹配当前的路径`/`,所以,自然没啥可显示的。\n接下来我们就修复这个问题。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Click the *Heroes* navigation link. The address bar updates to `/heroes`\nand the list of heroes displays.",
"translation": "我们点击“Heroes英雄列表”导航链接浏览器地址栏更新为`/heroes`,并且看到了英雄列表。我们终于导航过去了!",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "`AppComponent` now looks like this:",
"translation": "现在,`AppComponent`是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The *AppComponent* is now attached to a router and displays routed views.\nFor this reason, and to distinguish it from other kinds of components,\nthis component type is called a *router component*.",
"translation": "*AppComponent*现在加上了路由器,并能显示路由到的视图了。\n因此为了把它从其它种类的组件中区分出来我们称这类组件为*路由器组件*。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Add a dashboard",
"translation": "## 添加一个*仪表盘*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Routing only makes sense when multiple views exist.\nTo add another view, create a placeholder `DashboardComponent`, which users can navigate to and from.",
"translation": "当我们有多个视图的时候,路由才有意义。所以我们需要另一个视图。先创建一个`DashboardComponent`的占位符,让用户可以导航到它或从它导航出来。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You'll make this component more useful later.",
"translation": "我们先不实现它,稍后,我们再回来,给这个组件一些实际用途。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Configure the dashboard route",
"translation": "### 配置仪表盘路由",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "To teach `app.module.ts` to navigate to the dashboard,\nimport the dashboard component and\nadd the following route definition to the `Routes` array of definitions.",
"translation": "要让`app.module.ts`能导航到仪表盘,就要先导入仪表盘组件,然后把下列路由定义添加到`Routes`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Also import and add `DashboardComponent` to the `AppModule`'s `declarations`.",
"translation": "然后还得把`DashboardComponent`添加到`AppModule`的`declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Add a redirect route",
"translation": "### 添加重定向路由",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Currently, the browser launches with `/` in the address bar.\nWhen the app starts, it should show the dashboard and\ndisplay a `/dashboard` URL in the browser address bar.",
"translation": "浏览器启动时地址栏中的地址是`/`。\n当应用启动时它应该显示仪表盘并且在浏览器的地址栏显示URL`/dashboard`",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "To make this happen, use a redirect route. Add the following\nto the array of route definitions:",
"translation": "我们可以使用重定向路由来实现它。把下面的内容添加到路由定义数组中:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Read more about *redirects* in the [Redirecting routes](guide/router) section\nof the [Routing & Navigation](guide/router) page.",
"translation": "关于*重定向*的更多信息,见[路由](guide/router#redirect)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Add navigation to the template",
"translation": "### 添加导航到模版中",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Add a dashboard navigation link to the template, just above the *Heroes* link.",
"translation": "在模板上添加一个到仪表盘的导航链接,就放在*Heroes英雄列表*链接的上方。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The `<nav>` tags don't do anything yet, but they'll be useful later when you style the links.",
"translation": "我们在`<nav>`标签中放了两个链接。\n它们现在还没有作用但稍后当我们对这些链接添加样式时会显得比较方便。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "In your browser, go to the application root (`/`) and reload.\nThe app displays the dashboard and you can navigate between the dashboard and the heroes.",
"translation": "刷新浏览器。应用显示出了仪表盘,并可以在仪表盘和英雄列表之间导航了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Add heroes to the dashboard",
"translation": "## 把英雄添加到仪表盘",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "To make the dashboard more interesting, you'll display the top four heroes at a glance.",
"translation": "我们想让仪表盘更有趣,比如:让用户一眼就能看到四个顶级英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Replace the `template` metadata with a `templateUrl` property that points to a new\ntemplate file.",
"translation": "把元数据中的`template`属性替换为`templateUrl`属性,它将指向一个新的模板文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Create that file with this content:",
"translation": "使用下列内容创建文件:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "`*ngFor` is used again to iterate over a list of heroes and display their names.\nThe extra `<div>` elements will help with styling later.",
"translation": "我们再次使用`*ngFor`来在英雄列表上迭代,并显示他们的名字。\n还添加了一个额外的`<div>`元素,来帮助稍后的美化工作。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Sharing the *HeroService*",
"translation": "### 共享 *HeroService*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "To populate the component's `heroes` array, you can re-use the `HeroService`.",
"translation": "要想管理该组件的`heroes`数组,我们可以复用`HeroService`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Earlier, you removed the `HeroService` from the `providers` array of `HeroesComponent`\nand added it to the `providers` array of `AppModule`.\nThat move created a singleton `HeroService` instance, available to all components of the app.\nAngular injects `HeroService` and you can use it in the `DashboardComponent`.",
"translation": "在前面的章节中,我们从`HeroesComponent`的`providers`数组中移除了`HeroService`服务,\n 并把它添加到`AppModule`的`providers`数组中。\n这个改动创建了一个`HeroService`的单例对象,应用中的*所有*组件都可以使用它。\nAngular 会把`HeroService`注入到`DashboardComponent`,我们就能在`DashboardComponent`中使用它了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Get heroes",
"translation": "### 获取英雄数据",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "In <code>dashboard.component.ts</code>, add the following `import` statements.",
"translation": "打开<code>dashboard.component.ts</code>文件,并添加下列`import`语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "We need `OnInit` interface because we'll initialize the heroes in the `ngOnInit` method as we've done before.\nWe need the `Hero` and `HeroService` symbols in order to reference those types.",
"translation": "我们需要实现`OnInit`接口,因为我们将在`ngOnInit`方法中初始化英雄数组 —— 就像上次一样。\n我们需要导入`Hero`类和`HeroService`类来引用它们的数据类型。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Now create the `DashboardComponent` class like this:",
"translation": "我们现在就实现`DashboardComponent`类,像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "This kind of logic is also used in the `HeroesComponent`:",
"translation": "我们在之前的`HeroesComponent`中也看到过类似的逻辑:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Define a `heroes` array property.",
"translation": "创建一个`heroes`数组属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Inject the `HeroService` in the constructor and hold it in a private `heroService` field.",
"translation": "在构造函数中注入`HeroService`,并且把它保存在一个私有的`heroService`字段中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* Call the service to get heroes inside the Angular `ngOnInit()` lifecycle hook.",
"translation": "在 Angular 的`ngOnInit`生命周期钩子里面调用服务来获得英雄数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "In this dashboard you specify four heroes (2nd, 3rd, 4th, and 5th) with the `Array.slice` method.",
"translation": "在仪表盘中我们用`Array.slice`方法提取了四个英雄第2、3、4、5个。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Refresh the browser to see four hero names in the new dashboard.",
"translation": "刷新浏览器,在这个新的仪表盘中就看到了四个英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Navigating to hero details",
"translation": "## 导航到英雄详情",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "While the details of a selected hero displays at the bottom of the `HeroesComponent`,\nusers should be able to navigate to the `HeroDetailComponent` in the following additional ways:",
"translation": "虽然我们在`HeroesComponent`组件的底部显示了所选英雄的详情,\n 但用户还没法*导航*到`HeroDetailComponent`组件。我们可以用下列方式导航到`HeroDetailComponent`",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* From the dashboard to a selected hero.",
"translation": "从*Dashboard仪表盘*导航到一个选定的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* From the heroes list to a selected hero.",
"translation": "从*Heroes英雄列表*导航到一个选定的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* From a \"deep link\" URL pasted into the browser address bar.",
"translation": "把一个指向该英雄的“深链接” URL 粘贴到浏览器的地址栏。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Routing to a hero detail",
"translation": "### 路由到一个英雄详情",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You can add a route to the `HeroDetailComponent` in `app.module.ts`, where the other routes are configured.",
"translation": "我们将在`app.module.ts`中添加一个到`HeroDetailComponent`的路由,也就是配置其它路由的地方。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The new route is unusual in that you must tell the `HeroDetailComponent` which hero to show.\nYou didn't have to tell the `HeroesComponent` or the `DashboardComponent` anything.",
"translation": "这个新路由的不寻常之处在于,我们必须告诉`HeroDetailComponent`*该显示哪个英雄*。\n 之前,我们不需要告诉`HeroesComponent`组件和`DashboardComponent`组件任何东西。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Currently, the parent `HeroesComponent` sets the component's `hero` property to a\nhero object with a binding like this:",
"translation": "现在,父组件`HeroesComponent`通过数据绑定来把一个英雄对象设置为组件的`hero`属性。就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "But this binding won't work in any of the routing scenarios.",
"translation": "显然,在我们的任何一个路由场景中它都无法工作。\n最后一种场景肯定不行我们无法将一个完整的 hero 对象嵌入到 URL 中!不过我们本来也不想这样。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Parameterized route",
"translation": "### 参数化路由",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You can add the hero's `id` to the URL. When routing to the hero whose `id` is 11,\nyou could expect to see a URL such as this:",
"translation": "我们*可以*把英雄的`id`添加到 URL 中。当导航到一个`id`为 11 的英雄时,我们期望的 URL 是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The `/detail/` part of the URL is constant. The trailing numeric `id` changes from hero to hero.\nYou need to represent the variable part of the route with a *parameter* (or *token*) that stands for the hero's `id`.",
"translation": "URL中的`/detail/`部分是固定不变的,但结尾的数字`id`部分会随着英雄的不同而变化。\n我们要把路由中可变的那部分表示成一个*参数 (parameter) *或*令牌 (token) *,代表英雄的`id`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Configure a route with a parameter",
"translation": "### 配置带参数的路由",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Use the following *route definition*.",
"translation": "我们将使用下列*路由定义*。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The colon (:) in the path indicates that `:id` is a placeholder for a specific hero `id`\nwhen navigating to the `HeroDetailComponent`.",
"translation": "路径中的冒号 (:) 表示`:id`是一个占位符,当导航到这个`HeroDetailComponent`组件时,它将被填入一个特定英雄的`id`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Be sure to import the hero detail component before creating this route.",
"translation": "别忘了在创建这个路由前导入英雄详情组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You're finished with the app routes.",
"translation": "我们已经完成了本应用的路由的配置。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You didn't add a `'Hero Detail'` link to the template because users\ndon't click a navigation *link* to view a particular hero;\nthey click a *hero name*, whether the name displays on the dashboard or in the heroes list.",
"translation": "我们没有往模板中添加一个`'英雄详情'`,这是因为用户不会直接点击导航栏中的链接去查看一个特定的英雄。\n 它们只会通过在英雄列表或者仪表盘中点击来显示一个英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You don't need to add the hero clicks until the `HeroDetailComponent`\nis revised and ready to be navigated to.",
"translation": "要想支持“点击英雄”,就得先对`HeroDetailComponent`进行修改,好让我们能导航到它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Revise the *HeroDetailComponent*",
"translation": "## 修改*HeroDetailComponent*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Here's what the `HeroDetailComponent` looks like now:",
"translation": "在重写`HeroDetailComponent`之前,我们先看看它现在的样子:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The template won't change. Hero names will display the same way.\nThe major changes are driven by how you get hero names.",
"translation": "模板不用修改,我们会用原来的方式显示英雄。导致这次大修的原因是如何获得这个英雄的数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You'll no longer receive the hero in a parent component property binding.\nThe new `HeroDetailComponent` should take the `id` parameter from the `paramMap` Observable\nin the `ActivatedRoute` service and use the `HeroService` to fetch the hero with that `id`.",
"translation": "我们不会再从父组件的属性绑定中接收英雄数据。\n新的`HeroDetailComponent`应该从`ActivatedRoute`服务的可观察对象`params`中取得`id`参数,\n并通过`HeroService`服务获取具有这个指定`id`的英雄数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Add the following imports:",
"translation": "先添加下列导入语句:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Inject the `ActivatedRoute`, `HeroService`, and `Location` services\ninto the constructor, saving their values in private fields:",
"translation": "然后注入`ActivatedRoute`和`HeroService`服务到构造函数中,将它们的值保存到私有变量中:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Tell the class to implement the `OnInit` interface.",
"translation": "我们告诉这个类,我们要实现`OnInit`接口。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Inside the `ngOnInit()` lifecycle hook, use the `paramMap` Observable to\nextract the `id` parameter value from the `ActivatedRoute` service\nand use the `HeroService` to fetch the hero with that `id`.",
"translation": "在`ngOnInit()`生命周期钩子中,我们从`ActivatedRoute`服务的可观察对象`params`中提取`id`参数,\n并且使用`HeroService`来获取具有这个`id`的英雄数据。。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The `switchMap` operator maps the `id` in the Observable route parameters\nto a new `Observable`, the result of the `HeroService.getHero()` method.",
"translation": "注意`switchMap`运算符如何将可观察的路由参数中的 `id` 映射到一个新的`Observable`\n即`HeroService.getHero()`方法的结果。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "If a user re-navigates to this component while a `getHero` request is still processing,\n `switchMap` cancels the old request and then calls `HeroService.getHero()` again.",
"translation": "如果用户在 `getHero` 请求执行的过程中再次导航这个组件,`switchMap` 再次调用`HeroService.getHero()`之前,\n 会取消之前的请求。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The hero `id` is a number. Route parameters are always strings.\nSo the route parameter value is converted to a number with the JavaScript (+) operator.",
"translation": "英雄的`id`是数字,而路由参数的值*总是字符串*。\n 所以我们需要通过 JavaScript 的 (+) 操作符把路由参数的值转成数字。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Do you need to unsubscribe?",
"translation": "### 我需要取消订阅吗?",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "As described in the [ActivatedRoute: the one-stop-shop for route information](guide/router#activated-route)\nsection of the [Routing & Navigation](guide/router) page,\nthe `Router` manages the observables it provides and localizes\nthe subscriptions. The subscriptions are cleaned up when the component is destroyed, protecting against\nmemory leaks, so you don't need to unsubscribe from the route `paramMap` `Observable`.",
"translation": "正如以前在[路由与导航](guide/router)章的[ActivatedRoute一站式获取路由信息](guide/router#activated-route)部分讲过的,`Router`管理它提供的[可观察对象](guide/router#activated-route),并使订阅局部化。当组件被销毁时,会清除\n订阅防止内存泄漏所以我们不需要从路由参数`Observable`_取消订阅_。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Add *HeroService.getHero()*",
"translation": "### 添加 *HeroService.getHero()*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "In the previous code snippet, `HeroService` doesn't have a `getHero()` method. To fix this issue,\nopen `HeroService` and add a `getHero()` method that filters the heroes list from `getHeroes()` by `id`.",
"translation": "在前面的代码片段中`HeroService`没有`getHero()`方法。要解决这个问题,请打开`HeroService`并添加一个`getHero()`方法,它会根据`id`从`getHeroes()`中过滤英雄列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Find the way back",
"translation": "### 回到原路",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Users have several ways to navigate *to* the `HeroDetailComponent`.",
"translation": "用户有多种方式导航到`HeroDetailComponent`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "To navigate somewhere else, users can click one of the two links in the `AppComponent` or click the browser's back button.\nNow add a third option, a `goBack()` method that navigates backward one step in the browser's history stack\nusing the `Location` service you injected previously.",
"translation": "要导航到别处,用户可以点击`AppComponent`中的两个链接之一,也可以点击浏览器的后退按钮。\n我们来添加第三个选项一个`goBack()`方法,它使用之前注入的`Location`服务,\n 利用浏览器的历史堆栈,导航到上一步。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Going back too far could take users out of the app.\nIn a real app, you can prevent this issue with the <em>CanDeactivate</em> guard.\nRead more on the [CanDeactivate](api/router/CanDeactivate) page.",
"translation": "回退太多步会跑出我们的应用。\n在真实的应用中我们需要使用<em>CanDeactivate</em>守卫对此进行防范。\n要了解更多参见[CanDeactivate](api/router/CanDeactivate)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You'll wire this method with an event binding to a *Back* button that you'll add to the component template.",
"translation": "然后,我们通过一个事件绑定把此方法绑定到模板底部的 *Back后退*按钮上。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Migrate the template to its own file\ncalled <code>hero-detail.component.html</code>:",
"translation": "修改模板,添加这个按钮以提醒我们还要做更多的改进,\n并把模板移到独立的<span ngio-ex>hero-detail.component.html</span>文件中去。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Update the component metadata with a `templateUrl` pointing to the template file that you just created.",
"translation": "然后修改组件元数据的`templateUrl`属性,让它指向我们刚刚创建的模板文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Refresh the browser and see the results.",
"translation": "刷新浏览器,查看结果。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Select a dashboard hero",
"translation": "## 选择一个*仪表盘*中的英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "When a user selects a hero in the dashboard, the app should navigate to the `HeroDetailComponent` to view and edit the selected hero.",
"translation": "当用户从仪表盘中选择了一位英雄时,本应用要导航到`HeroDetailComponent`以查看和编辑所选的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Although the dashboard heroes are presented as button-like blocks, they should behave like anchor tags.\nWhen hovering over a hero block, the target URL should display in the browser status bar\nand the user should be able to copy the link or open the hero detail view in a new tab.",
"translation": "虽然仪表盘英雄被显示为像按钮一样的方块,但是它们的行为应该像锚标签一样。\n当鼠标移动到一个英雄方块上时目标 URL 应该显示在浏览器的状态条上,用户应该能拷贝链接或者在新的浏览器标签页中打开英雄详情视图。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "To achieve this effect, reopen `dashboard.component.html` and replace the repeated `<div *ngFor...>` tags\nwith `<a>` tags. Change the opening `<a>` tag to the following:",
"translation": "要达到这个效果,再次打开`dashboard.component.html`,将用来迭代的`<div *ngFor...>`替换为`<a>`,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Notice the `[routerLink]` binding.\nAs described in the [Router links](tutorial/toh-pt5#router-links) section of this page,\ntop-level navigation in the `AppComponent` template has router links set to fixed paths of the\ndestination routes, \"/dashboard\" and \"/heroes\".",
"translation": "注意`[routerLink]`绑定。正如本章的[Router links](tutorial/toh-pt5#router-links)部分所说,\n[`AppComponent`模板](tutorial/toh-pt5#router-links)中的顶级导航有一些路由器链接被设置固定的路径,例如“/dashboard”和“/heroes”。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "This time, you're binding to an expression containing a *link parameters array*.\nThe array has two elements: the *path* of\nthe destination route and a *route parameter* set to the value of the current hero's `id`.",
"translation": "这次,我们绑定了一个包含**链接参数数组**的表达式。\n该数组有两个元素目标路由和一个用来设置当前英雄的 id 值的**路由参数**。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The two array items align with the *path* and *:id*\ntoken in the parameterized hero detail route definition that you added to\n`app.module.ts` earlier:",
"translation": "这两个数组项与之前在`app.module.ts`添加的参数化的英雄详情路由定义中的 ***path*** 和 ***:id*** 对应。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Refresh the browser and select a hero from the dashboard; the app navigates to that heros details.",
"translation": "刷新浏览器,并从仪表盘中选择一位英雄,应用就会直接导航到英雄的详情。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Refactor routes to a _Routing Module_",
"translation": "## 重构路由为一个**路由模块**",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Almost 20 lines of `AppModule` are devoted to configuring four routes. \nMost applications have many more routes and they add guard services \nto protect against unwanted or unauthorized navigations. (Read more about guard services in the [Route Guards](guide/router#guards)\nsection of the [Routing & Navigation](guide/router) page.)\nRouting considerations could quickly dominate this module and obscure its primary purpose, which is to \nestablish key facts about the entire app for the Angular compiler.",
"translation": "`AppModule`中有将近 20 行代码是用来配置四个路由的。\n绝大多数应用有更多路由并且它们还有守卫服务来保护不希望或未授权的导航。\n要了解守卫服务的更多知识参见[路由与导航](guide/router)页的[路由守卫](guide/router#guards)\n路由的配置可能迅速占领这个模块并掩盖其主要目的即为 Angular 编译器设置整个应用的关键配置。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "It's a good idea to refactor the routing configuration into its own class.\nThe current `RouterModule.forRoot()` produces an Angular `ModuleWithProviders`,\na class dedicated to routing should be a *routing module*.\nFor more information, see the [Milestone #2: The Routing Module](guide/router#routing-module)\nsection of the [Routing & Navigation](guide/router) page.",
"translation": "我们应该重构路由配置到它自己的类。\n什么样的类呢\n当前的`RouterModule.forRoot()`产生一个Angular `ModuleWithProviders`,所以这个路由类应该是一种模块类。\n它应该是一个[**路由模块**](guide/router#routing-module)。要想了解更多,请参阅[路由与导航](guide/router)一章的[里程碑2路由模块](guide/router#routing-module)部分。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "By convention , a routing module name contains the word \"Routing\" and \naligns with the name of the module that declares the components navigated to.",
"translation": "按约定,**路由模块**的名字应该包含 “Routing”并与导航到的组件所在的模块的名称看齐。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Create an `app-routing.module.ts` file as a sibling to `app.module.ts`. Give it the following contents, extracted from the `AppModule` class:",
"translation": "在`app.module.ts`所在目录创建`app-routing.module.ts`文件。将下面从`AppModule`类提取出来的代码拷贝进去:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The following points are typical of routing modules:",
"translation": "典型**路由模块**需要注意的有:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* The Routing Module pulls the routes into a variable. The variable clarifies the\n routing module pattern in case you export the module in the future.",
"translation": "将路由抽出到一个变量中。如果你将来要导出这个模块,这种 \"路由模块\" 的模式也会更加明确。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* The Routing Module adds `RouterModule.forRoot(routes)` to `imports`.",
"translation": "添加`RouterModule.forRoot(routes)`到`imports`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* The Routing Module adds `RouterModule` to `exports` so that the components in the companion module have access to Router declarables ,\n such as `RouterLink` and `RouterOutlet`.",
"translation": "把`RouterModule`添加到路由模块的`exports`中,以便关联模块(比如`AppModule`)中的组件可以访问路由模块中的声明,比如`RouterLink` 和 `RouterOutlet`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* There are no `declarations`. Declarations are the responsibility of the companion module.",
"translation": "无`declarations`!声明是关联模块的任务。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* If you have guard services, the Routing Module adds module `providers`. (There are none in this example.)",
"translation": "如果有守卫服务,把它们添加到本模块的`providers`中(本例子中没有守卫服务)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Update *AppModule*",
"translation": "### 修改 *AppModule*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Delete the routing configuration from `AppModule` and import the `AppRoutingModule`.\nUse an ES2015 `import` statement *and* add it to the `NgModule.imports` list.",
"translation": "删除`AppModule`中的路由配置,并导入`AppRoutingModule`\n使用 ES `import`语句导入,**并**将它添加到`NgModule.imports`列表)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Here is the revised `AppModule`, compared to its pre-refactor state:",
"translation": "下面是修改后的`AppModule`,与重构前的对比:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The revised and simplified `AppModule` is focused on identifying the key pieces of the app.",
"translation": "修改并简化后的`AppModule`更专注于应用中的关键片段。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Select a hero in the *HeroesComponent*",
"translation": "## 在 *HeroesComponent* 中选择一位英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "In the `HeroesComponent`,\nthe current template exhibits a \"master/detail\" style with the list of heroes\nat the top and details of the selected hero below.",
"translation": "在`HeroesComponent`中,当前模板展示了一个主从风格的界面:上方是英雄列表,底下是所选英雄的详情。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Delete the `<h1>` at the top.",
"translation": "删除顶部的`<h1>`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Delete the last line of the template with the `<hero-detail>` tags.",
"translation": "删除模板最后带有`<hero-detail>`标签的那一行。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You'll no longer show the full `HeroDetailComponent` here.\nInstead, you'll display the hero detail on its own page and route to it as you did in the dashboard.",
"translation": "我们不在这里展示完整的`HeroDetailComponent`了。\n 而是在独立的路由和页面中显示英雄详情,就像我们在仪表盘中所做的那样。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "However, when users select a hero from the list, they won't go to the detail page.\nInstead, they'll see a mini detail on *this* page and have to click a button to navigate to the *full detail* page.",
"translation": "但是,当用户从列表中选择一个英雄时,他们不会在导航到详情页,\n而是在*当前页*显示一个Mini版详情视图当用户点击一个按钮时才导航到*完整的详情*页面。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Add the *mini detail*",
"translation": "### 添加 *mini 版英雄详情*",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Add the following HTML fragment at the bottom of the template where the `<hero-detail>` used to be:",
"translation": "在模板底部原来放`<hero-detail>`的地方添加下列 HTML 片段:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "After clicking a hero, users should see something like this below the hero list:",
"translation": "点击一个英雄,用户将会在英雄列表的下方看到这些:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Format with the uppercase pipe",
"translation": "### 使用*uppercase*管道格式化",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The hero's name is displayed in capital letters because of the `uppercase` pipe\nthat's included in the interpolation binding, right after the pipe operator ( | ).",
"translation": "注意,英雄的名字全被显示成大写字母。那是`uppercase`管道的效果,借助它,我们能干预插值表达式绑定的过程。可以管道操作符 ( | ) 后面看到它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Pipes are a good way to format strings, currency amounts, dates and other display data.\nAngular ships with several pipes and you can write your own.",
"translation": "管道擅长做下列工作:格式化字符串、金额、日期和其它显示数据。\nAngular 自带了一些管道,我们也可以写自己的管道。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Read more about pipes on the [Pipes](guide/pipes) page.",
"translation": "关于管道的更多信息,参见[管道](guide/pipes)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Move content out of the component file",
"translation": "### 把内容移出组件文件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You still have to update the component class to support navigation to the\n`HeroDetailComponent` when users click the *View Details* button.",
"translation": "当用户点击*查看详情*按钮时,要让它能导航到`HeroDetailComponent`,我们还需要修改它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The component file is big.\nIt's difficult to find the component logic amidst the noise of HTML and CSS.",
"translation": "这个组件文件太大了。要想在 HTML 和 CSS 的噪音中看清组件的工作逻辑太难了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Before making any more changes, migrate the template and styles to their own files.",
"translation": "在做更多修改之前,我们先把模板和样式移到它们自己的文件中去:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "First, move the template contents from `heroes.component.ts`\ninto a new <code>heroes.component.html</code> file.\nDon't copy the backticks. As for `heroes.component.ts`, you'll\ncome back to it in a minute. Next, move the\nstyles contents into a new <code>heroes.component.css</code> file.",
"translation": "首先,从`heroes.component.ts`中把模板内容移到新的<code>heroes.component.html</code>文件中,但不要把反引号也拷贝过去。就像`heroes.component.ts`一样,我们很快就能做完。接着,把样式的内容移到新的<code>heroes.component.css</code>文件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The two new files should look like this:",
"translation": "这两个新文件是这样的:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Now, back in the component metadata for `heroes.component.ts`,\ndelete `template` and `styles`, replacing them with\n`templateUrl` and `styleUrls` respectively.\nSet their properties to refer to the new files.",
"translation": "现在,回来编辑`heroes.component.ts`中的组件元数据,删除`template` 和 `styles`属性,代之以相应的`templateUrl` 和 `styleUrls`属性。让它们指向这些新文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The `styleUrls` property is an array of style file names (with paths).\nYou could list multiple style files from different locations if you needed them.",
"translation": "`styleUrls`属性是一个由样式文件的文件名(包括路径)组成的数组。我们还可以列出来自多个不同位置的样式文件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Update the _HeroesComponent_ class",
"translation": "### 更新 _HeroesComponent_ 类",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The `HeroesComponent` navigates to the `HeroesDetailComponent` in response to a button click.\nThe button's click event is bound to a `gotoDetail()` method that navigates _imperatively_\nby telling the router where to go.",
"translation": "点击按钮时,`HeroesComponent`导航到`HeroDetailComponent`。\n该按钮的点击事件绑定到了`gotoDetail()`方法,它使用命令式的导航,告诉路由器去哪儿。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "This approach requires the following changes to the component class:",
"translation": "该方法需要对组件类做一些修改:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "1. Import the `Router` from the Angular router library.",
"translation": "从 Angular 路由器库导入`Router`",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "1. Inject the `Router` in the constructor, along with the `HeroService`.",
"translation": "在构造函数中注入`Router`(与`HeroService`一起)",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "1. Implement `gotoDetail()` by calling the router `navigate()` method.",
"translation": "实现`gotoDetail()`,调用路由器的`navigate()`方法",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Note that you're passing a two-element *link parameters array*&mdash;a\npath and the route parameter&mdash;to\nthe router `navigate()` method, just as you did in the `[routerLink]` binding\nback in the `DashboardComponent`.\nHere's the revised `HeroesComponent` class:",
"translation": "注意,我们将一个包含两个元素的**链接参数数组** &mdash; \n路径和路由参数 &mdash; 传递到路由的`navigate`\n与之前在`DashboardComponent`中使用`[routerLink]`绑定一样。\n修改完成的`HeroesComponent`类如下所示:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"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 版英雄详情到英雄详情,再回到英雄列表。\n 我们可以在仪表盘和英雄列表之间跳来跳去。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You've met all of the navigational requirements that propelled this page.",
"translation": "我们已经满足了在本章开头设定的所有导航需求。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Style the app",
"translation": "## 美化本应用",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The app is functional but it needs styling.\nThe dashboard heroes should display in a row of rectangles.\nYou've received around 60 lines of CSS for this purpose, including some simple media queries for responsive design.",
"translation": "应用在功能上已经正常了,但还需要美化。\n仪表盘上的英雄应该显示在一行上的几个方块中。\n我们拿到了大约60行CSS来完成这件事包括一些简单的媒体查询代码以实现响应式设计。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "As you now know, adding the CSS to the component `styles` metadata\nwould obscure the component logic.\nInstead, edit the CSS in a separate `*.css` file.",
"translation": "我们不能把这 60 来行 CSS 粘贴到组件元数据的`styles`中,否则它会淹没组件的工作逻辑。反之,我们应该在独立的`*.css`文件中编辑这些CSS。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Add a <code>dashboard.component.css</code> file to the `app` folder and reference\nthat file in the component metadata's `styleUrls` array property like this:",
"translation": "把<code>dashboard.component.css</code>文件添加到`app`目录下,并在组件元数据的`styleUrls`数组属性中引用它。就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Add stylish hero details",
"translation": "### 美化英雄详情",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You've also been provided with CSS styles specifically for the `HeroDetailComponent`.",
"translation": "我们还拿到了一些`HeroDetailComponent`特有的 CSS 风格。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Add a <code>hero-detail.component.css</code> to the `app`\nfolder and refer to that file inside\nthe `styleUrls` array as you did for `DashboardComponent`.\nAlso, in `hero-detail.component.ts`, remove the `hero` property `@Input` decorator\nand its import.",
"translation": "在`app`目录下添加<span ngio-ex>hero-detail.component.css</span>文件,\n并且在`styleUrls`数组中引用它 —— 就像之前在`DashboardComponent`中做过的那样。\n同时删除`hero``@Input`装饰器属性和它的导入语句。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Here's the content for the component CSS files.",
"translation": "上述组件的 CSS 文件内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Style the navigation links",
"translation": "### 美化导航链接",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The provided CSS makes the navigation links in the `AppComponent` look more like selectable buttons.\nYou'll surround those links in `<nav>` tags.",
"translation": "设计师还给了我们一些 CSS用于让`AppComponent`中的导航链接看起来更像可被选择的按钮。\n要让它们协同工作我们得把那些链接包含在`<nav>`标签中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Add an <code>app.component.css</code> file to the `app` folder with the following content.",
"translation": "在`app`目录下添加一个<span ngio-ex>app.component.css</span>文件,内容如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "**The *routerLinkActive* directive**",
"translation": "***routerLinkActive*指令**",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The Angular router provides a `routerLinkActive` directive you can use to\n add a class to the HTML navigation element whose route matches the active route.\n All you have to do is define the style for it.",
"translation": "Angular路由器提供了`routerLinkActive`指令,我们可以用它来为匹配了活动路由的 HTML 导航元素自动添加一个 CSS 类。\n 我们唯一要做的就是为它定义样式。真好!",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Add a `styleUrls` property that refers to this CSS file as follows:",
"translation": "首先把`moduleId: module.id`添加到`AppComponent`组件的`@Component`元数据中以启用*相对于模块的*文件URL。\n然后添加`styleUrls`属性使其指向这个CSS文件代码如下",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Global application styles",
"translation": "### 应用的全局样式",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "When you add styles to a component, you keep everything a component needs&mdash;HTML,\nthe CSS, the code&mdash;together in one convenient place.\nIt's easy to package it all up and re-use the component somewhere else.",
"translation": "当我们把样式添加到组件中时,我们假定组件所需的一切 &mdash; HTML、CSS、程序代码 &mdash; 都在紧邻的地方。\n 这样,无论是把它们打包在一起还是在别的组件中复用它都会很容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You can also create styles at the *application level* outside of any component.",
"translation": "我们也可以在所有组件之外创建*应用级*样式。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "The designers provided some basic styles to apply to elements across the entire app.\nThese correspond to the full set of master styles that you installed earlier during [setup](guide/setup).\nHere's an excerpt:",
"translation": "我们的设计师提供了一组基础样式,这些样式应用到的元素横跨整个应用。\n它们与我们之前在[开发环境](guide/setup)时安装的整套样式对应。\n下面是摘录",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Create the file <code>styles.css</code>.\nEnsure that the file contains the [master styles provided here](https://raw.githubusercontent.com/angular/angular/master/aio/tools/examples/shared/boilerplate/src/styles.css).",
"translation": "创建文件<code>styles.css</code>。确保该文件的内容包含[如下的主样式](https://raw.githubusercontent.com/angular/angular/master/aio/tools/examples/shared/boilerplate/src/styles.css)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Look at the app now. The dashboard, heroes, and navigation links are styled.",
"translation": "看看现在的应用!我们的仪表盘、英雄列表和导航链接都漂亮多了!",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Application structure and code",
"translation": "## 应用结构和代码",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Review the sample source code in the <live-example></live-example> for this page.\nVerify that you have the following structure:",
"translation": "回顾一下本章<live-example></live-example>中范例代码。\n 验证我们是否已经得到了如下结构:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "## Summary",
"translation": "## 小结",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Here's what you achieved in this page:",
"translation": "本章中我们完成了这些:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* You added the Angular router to navigate among different components.",
"translation": "添加了 Angular *路由器*在各个不同组件之间导航。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* You learned how to create router links to represent navigation menu items.",
"translation": "学会了如何创建路由链接来表示导航栏的菜单项。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* You used router link parameters to navigate to the details of the user-selected hero.",
"translation": "使用路由链接参数来导航到用户所选的英雄详情。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* You shared the `HeroService` among multiple components.",
"translation": "在多个组件之间共享了`HeroService`服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* You moved HTML and CSS out of the component file and into their own files.",
"translation": "把 HTML 和 CSS 从组件中移出来,放到了它们自己的文件中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "* You added the `uppercase` pipe to format data.",
"translation": "添加了`uppercase`管道,来格式化数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "Your app should look like this <live-example></live-example>.",
"translation": "我们的应用现在变成了这样:<live-example></live-example>。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "### Next step",
"translation": "### 前方的路",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "You have much of the foundation you need to build an app.\nYou're still missing a key piece: remote data access.",
"translation": "我们有了很多用于构建应用的基石。\n 但我们仍然缺少很关键的一块:远程数据存取。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "In the [next tutorial page](tutorial/toh-pt6 \"Http\")\nyoull replace the mock data with data retrieved from a server using http.",
"translation": "在下一章,我们将从硬编码模拟数据改为使用 http 服务从服务器获取数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt5.md"
},
{
"original": "# HTTP",
"translation": "# HTTP 服务",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "In this page, you'll make the following improvements.",
"translation": "在这一章中,我们将进行如下增强:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* Get the hero data from a server.",
"translation": "从服务器获取英雄数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* Let users add, edit, and delete hero names.",
"translation": "让用户添加、编辑和删除英雄名。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* Save the changes to the server.",
"translation": "把这些更改保存到服务器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "You'll teach the app to make corresponding HTTP calls to a remote server's web API.",
"translation": "我们要让应用能够对远端服务器提供的Web API发起相应的HTTP调用。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"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/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Where you left off",
"translation": "## 延续上一步教程",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "In the [previous page](tutorial/toh-pt5), you learned to navigate between the dashboard and the fixed heroes list,\nediting a selected hero along the way.\nThat's the starting point for this page.",
"translation": "在[前一章](tutorial/toh-pt5)中,我们学会了在仪表盘和固定的英雄列表之间导航,并编辑选定的英雄。这也就是本章的起点。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Keep the app transpiling and running",
"translation": "## 保持应用的转译与运行",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Enter the following command in the terminal window:",
"translation": "在终端窗口输入如下命令:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "This command runs the TypeScript compiler in \"watch mode\", recompiling automatically when the code changes.\nThe command simultaneously launches the app in a browser and refreshes the browser when the code changes.",
"translation": "这个命令会在“监听”模式下运行TypeScript编译器当代码变化时它会自动重新编译。\n 同时,该命令还会在浏览器中启动该应用,并且当代码变化时刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.",
"translation": "在后续构建《英雄指南》过程中,应用能持续运行,而不用中断服务来编译或刷新浏览器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Providing HTTP Services",
"translation": "## 提供 HTTP 服务",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The `HttpModule` is not a core NgModule.\n`HttpModule` is Angular's optional approach to web access. It exists as a separate add-on module called `@angular/http`\nand is shipped in a separate script file as part of the Angular npm package.",
"translation": "`HttpModule`***并不是*** Angular 的核心模块。\n 它是 Angular 用来进行 Web 访问的一种可选方式,并位于一个名叫 `@angular/http` 的独立附属模块中,并作为 Angular 的 npm 包之一而发布出来。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "You're ready to import from `@angular/http` because `systemjs.config` configured *SystemJS* to load that library when you need it.",
"translation": "`systemjs.config`中已经配置好了 *SystemJS*,并在必要时加载它,因此我们已经准备好从`@angular/http`中导入它了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Register for HTTP services",
"translation": "## 注册 *HTTP* 服务",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The app will depend on the Angular `http` service, which itself depends on other supporting services.\nThe `HttpModule` from the `@angular/http` library holds providers for a complete set of HTTP services.",
"translation": "我们的应用将会依赖于 Angular 的`http`服务,它本身又依赖于其它支持类服务。\n 来自`@angular/http`库中的`HttpModule`保存着这些 HTTP 相关服务提供商的全集。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "To allow access to these services from anywhere in the app,\nadd `HttpModule` to the `imports` list of the `AppModule`.",
"translation": "我们要能从本应用的任何地方访问这些服务,就要把`HttpModule`添加到`AppModule`的`imports`列表中。\n这里同时也是我们引导应用及其根组件`AppComponent`的地方。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Notice that you also supply `HttpModule` as part of the *imports* array in root NgModule `AppModule`.",
"translation": "注意,现在`HttpModule`已经是根模块`AppModule`的`imports`数组的一部分了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Simulate the web API",
"translation": "## 模拟web API",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "We recommend registering app-wide services in the root\n`AppModule` *providers*.",
"translation": "我们建议在根模块`AppModule`的`providers`数组中注册全应用级的服务。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Until you have a web server that can handle requests for hero data,\nthe HTTP client will fetch and save data from\na mock service, the *in-memory web API*.",
"translation": "在拥有一个能处理Web请求的服务器之前我们可以先用HTTP客户端通过一个模拟Mock服务内存Web API来获取和保存数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Update <code>src/app/app.module.ts</code> with this version, which uses the mock service:",
"translation": "修改<code>src/app/app.module.ts</code>,让它使用这个模拟服务:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Rather than require a real API server, this example simulates communication with the remote server by adding the\n<a href=\"https://github.com/angular/in-memory-web-api\" title=\"In-memory Web API\">InMemoryWebApiModule</a>\nto the module `imports`, effectively replacing the `Http` client's XHR backend service with an in-memory alternative.",
"translation": "导入`InMemoryWebApiModule`并将其加入到模块的`imports`数组。\n `InMemoryWebApiModule`将`Http`客户端默认的后端服务 &mdash;\n 这是一个辅助服务,负责与远程服务器对话 &mdash;\n 替换成了*内存 Web API*服务:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The `forRoot()` configuration method takes an `InMemoryDataService` class\nthat primes the in-memory database.\nAdd the file `in-memory-data.service.ts` in `app` with the following content:",
"translation": "`forRoot()`配置方法需要`InMemoryDataService`类实例,用来向内存数据库填充数据:\n往`app`目录下新增一个文件`in-memory-data.service.ts`,填写下列内容:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "This file replaces `mock-heroes.ts`, which is now safe to delete.\nAdded hero \"Zero\" to confirm that the data service can handle a hero with `id==0`.",
"translation": "这个文件已经替换了`mock-heroes.ts`,可以删除`mock-heroes.ts`了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The in-memory web API is only useful in the early stages of development and for demonstrations such as this Tour of Heroes.\n Don't worry about the details of this backend substitution; you can\n skip it when you have a real web API server.",
"translation": "内存Web API只在开发的早期阶段或写《英雄指南》这样的演示程序时才有用。有了它你将来替换后端实现时就不用关心这些细节问题了。如果你已经有了一个真实的Web API服务器尽管跳过它吧。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Heroes and HTTP",
"translation": "## 英雄与 HTTP",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "In the current `HeroService` implementation, a Promise resolved with mock heroes is returned.",
"translation": "在目前的`HeroService`的实现中返回的是一个能解析resolve成模拟英雄列表的承诺Promise。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "This was implemented in anticipation of ultimately\nfetching heroes with an HTTP client, which must be an asynchronous operation.",
"translation": "我们返回一个承诺 (Promise),它用模拟版的英雄列表进行解析。\n 它当时可能看起来显得有点过于复杂,不过我们预料到总有这么一天会通过 HTTP 客户端来获取英雄数据,\n 而且我们知道,那一定是一个异步操作。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Now convert `getHeroes()` to use HTTP.",
"translation": "现在,我们把`getHeroes()`换成使用 HTTP。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Update the import statements as follows:",
"translation": "更新后的导入声明如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Refresh the browser. The hero data should successfully load from the\nmock server.",
"translation": "刷新浏览器后,英雄数据就会从模拟服务器被成功读取。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### HTTP Promise",
"translation": "### Http 承诺Promise",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The Angular `http.get` returns an RxJS `Observable`.\n*Observables* are a powerful way to manage asynchronous data flows.\nYou'll read about [Observables](tutorial/toh-pt6#observables) later in this page.",
"translation": "Angular 的`http.get`返回一个 RxJS 的`Observable`对象。\n*Observable可观察对象*是一个管理异步数据流的强力方式。\n后面我们还会进一步学习[可观察对象](tutorial/toh-pt6#observables)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "For now, you've converted the `Observable` to a `Promise` using the `toPromise` operator.",
"translation": "*现在*,我们先利用`toPromise`操作符把`Observable`直接转换成`Promise`对象,回到已经熟悉的地盘。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The Angular `Observable` doesn't have a `toPromise` operator out of the box.",
"translation": "不幸的是Angular 的`Observable`并没有一个`toPromise`操作符... 没有打包在一起发布。Angular的`Observable`只是一个骨架实现。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "There are many operators like `toPromise` that extend `Observable` with useful capabilities.\nTo use those capabilities, you have to add the operators themselves.\nThat's as easy as importing them from the RxJS library like this:",
"translation": "有很多像`toPromise`这样的操作符,用于扩展`Observable`,为其添加有用的能力。\n 如果我们希望得到那些能力,就得自己添加那些操作符。\n 那很容易,只要从 RxJS 库中导入它们就可以了,就像这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "You'll add more operators, and learn why you must do so, [later in this tutorial](tutorial/toh-pt6#rxjs-imports).",
"translation": "我们还要添加更多的操作符,并且必须这么做,要了解其中的原因,参见[本章稍后的部分](tutorial/toh-pt6#rxjs-imports)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Extracting the data in the *then* callback",
"translation": "### 在 *then* 回调中提取出数据",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "In the *Promise*'s `then()` callback , you call the `json` method of the HTTP `Response` to extract the\ndata within the response.",
"translation": "在 *promise* 的`then()`回调中,我们调用 HTTP 的`Reponse`对象的`json`方法,以提取出其中的数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The response JSON has a single `data` property, which\nholds the array of heroes that the caller wants.\nSo you grab that array and return it as the resolved Promise value.",
"translation": "这个由`json`方法返回的对象只有一个`data`属性。\n这个`data`属性保存了*英雄*数组,这个数组才是调用者真正想要的。\n所以我们取得这个数组并且把它作为承诺的值进行解析。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Note the shape of the data that the server returns.\n This particular in-memory web API example returns an object with a `data` property.\n Your API might return something else. Adjust the code to match your web API.",
"translation": "仔细看看这个由服务器返回的数据的形态。\n这个*内存 Web API* 的范例中所做的是返回一个带有`data`属性的对象。\n你的 API 也可以返回其它东西。请调整这些代码以匹配*你的 Web API*。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The caller is unaware that you fetched the heroes from the (mock) server.\nIt receives a Promise of *heroes* just as it did before.",
"translation": "调用者并不知道这些实现机制,它仍然像以前那样接收一个包含*英雄数据*的承诺。\n它也不知道我们已经改成了从服务器获取英雄数据。\n它也不必了解把 HTTP 响应转换成英雄数据时所作的这些复杂变换。\n看到美妙之处了吧这正是将数据访问委托组一个服务的目的。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Error Handling",
"translation": "### 错误处理",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "At the end of `getHeroes()`, you `catch` server failures and pass them to an error handler.",
"translation": "在`getHeroes()`的最后,我们`catch`了服务器的失败信息,并把它们传给了错误处理器:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "This is a critical step.\nYou must anticipate HTTP failures, as they happen frequently for reasons beyond your control.",
"translation": "这是一个关键的步骤!\n我们必须预料到 HTTP 请求会失败,因为有太多我们无法控制的原因可能导致它们频繁出现各种错误。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "This demo service logs the error to the console; in real life,\nyou would handle the error in code. For a demo, this works.",
"translation": "在这个范例服务中,我们把错误记录到控制台中;在真实世界中,我们应该用代码对错误进行处理。但对于演示来说,这就够了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The code also includes an error to\nthe caller in a rejected promise, so that the caller can display a proper error message to the user.",
"translation": "我们还要通过一个被拒绝 (rejected) 的承诺来把该错误用一个用户友好的格式返回给调用者,\n以便调用者能把一个合适的错误信息显示给用户。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Get hero by id",
"translation": "### 通过id获取英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "When the `HeroDetailComponent` asks the `HeroService` to fetch a hero,\nthe `HeroService` currently fetches all heroes and\nfilters for the one with the matching `id`.\nThat's fine for a simulation, but it's wasteful to ask a real server for all heroes when you only want one.\nMost web APIs support a _get-by-id_ request in the form `api/hero/:id` (such as `api/hero/11`).",
"translation": "当`HeroDetailComponent`向`HeroService`请求获取一个英雄时,`HeroService`会获取所有英雄,并从中过滤出与`id`匹配的那一个。\n这对于例子来说倒是无可厚非\n 不过在真实服务中,这种为了获取一个英雄而请求全部英雄的做法就有点浪费了,\n 许多Web API支持*get-by-id*请求,形如:`api/hero/:id`(如:`api/hero/11`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Update the `HeroService.getHero()` method to make a _get-by-id_ request:",
"translation": "修改 `HeroService.getHero()` 方法来发起一个 *get-by-id* 请求:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "This request is almost the same as `getHeroes()`.\nThe hero id in the URL identifies which hero the server should update.",
"translation": "此方法基本上与`getHeroes`方法一致通过在URL中添加英雄的id来告诉服务器应该获取_那个_英雄\n 匹配`api/hero/:id`模式。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Also, the `data` in the response is a single hero object rather than an array.",
"translation": "我们还要把响应中返回的`data`改为一个英雄对象,而不再是对象数组。组。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Unchanged _getHeroes_ API",
"translation": "### `getHeroes` API 没变",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Although you made significant internal changes to `getHeroes()` and `getHero()`,\nthe public signatures didn't change.\nYou still return a Promise from both methods.\nYou won't have to update any of the components that call them.",
"translation": "尽管我们在`getHeroes()`和`getHero()`方法的*内部*做了重大修改,\n 但是他们的公共签名却没有变。这两个方法仍然返回的是一个Promise对象\n 所以并不需要修改任何调用他们的组件。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Now it's time to add the ability to create and delete heroes.",
"translation": "现在,我们该支持创建和删除英雄了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Updating hero details",
"translation": "## 更新英雄详情",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Try editing a hero's name in the hero detail view.\nAs you type, the hero name is updated in the view heading.\nBut if you click the Back button, the changes are lost.",
"translation": "我们已经可以在英雄详情中编辑英雄的名字了。来试试吧。在输入的时候,页头上的英雄名字也会随之更新。\n不过当我们点了`Back后退`按钮时,这些修改就丢失了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Updates weren't lost before. What changed?\nWhen the app used a list of mock heroes, updates were applied directly to the\nhero objects within the single, app-wide, shared list. Now that you're fetching data\nfrom a server, if you want changes to persist, you must write them back to\nthe server.",
"translation": "以前是不会丢失更新的,怎么回事?\n当该应用使用模拟出来的英雄列表时修改的是一份全局共享的英雄列表而现在改成了从服务器获取数据。\n如果我们希望这些更改被持久化我们就得把它们写回服务器。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Add the ability to save hero details",
"translation": "### 保存英雄详情",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"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/content-1/tutorial/toh-pt6.md"
},
{
"original": "Add the following `save()` method, which persists hero name changes using the hero service\n`update()` method and then navigates back to the previous view.",
"translation": "`save()`方法使用 hero 服务的`update()`方法来持久化对英雄名字的修改,然后导航回前一个视图:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Add a hero service _update()_ method",
"translation": "### hero 服务的`update`方法",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The overall structure of the `update()` method is similar to that of\n`getHeroes()`, but it uses an HTTP `put()` to persist server-side changes.",
"translation": "`update()`方法的大致结构与`getHeroes()`类似,不过我们使用 HTTP 的 `put()` 方法来把修改持久化到服务端:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "To identify which hero the server should update, the hero `id` is encoded in\nthe URL. The `put()` body is the JSON string encoding of the hero, obtained by\ncalling `JSON.stringify`. The body content type\n(`application/json`) is identified in the request header.",
"translation": "我们通过一个编码在 URL 中的英雄 `id` 来告诉服务器应该更新哪个英雄。`put` 的 body 是该英雄的 JSON 字符串,它是通过调用`JSON.stringify`得到的。\n并且在请求头中标记出的 body 的内容类型(`application/json`)。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Refresh the browser, change a hero name, save your change,\nand click the browser Back button. Changes should now persist.",
"translation": "刷新浏览器试一下,对英雄名字的修改确实已经被持久化了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Add the ability to add heroes",
"translation": "## 添加英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "To add a hero, the app needs the hero's name. You can use an `input`\nelement paired with an add button.",
"translation": "要添加一个新的英雄,我们得先知道英雄的名字。我们使用一个 `input` 元素和一个添加按钮来实现。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Insert the following into the heroes component HTML, just after\nthe heading:",
"translation": "把下列代码插入 heroes 组件的 HTML 中,放在标题的下面:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"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/content-1/tutorial/toh-pt6.md"
},
{
"original": "When the given name is non-blank, the handler delegates creation of the\nnamed hero to the hero service, and then adds the new hero to the array.",
"translation": "当指定的名字不为空的时候,点击处理器就会委托 hero 服务来创建一个具有此名字的英雄,\n 并把这个新的英雄添加到我们的数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Implement the `create()` method in the `HeroService` class.",
"translation": "然后,我们在`HeroService`类中实现这个`create()`方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Refresh the browser and create some heroes.",
"translation": "刷新浏览器,并创建一些新的英雄!",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Add the ability to delete a hero",
"translation": "## 删除英雄",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Each hero in the heroes view should have a delete button.",
"translation": "在英雄列表视图中的每个英雄都应该有一个删除按钮。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Add the following button element to the heroes component HTML, after the hero\nname in the repeated `<li>` element.",
"translation": "把这个按钮元素添加到英雄列表组件的 HTML 中,把它放在`<li>`标签中的英雄名的后面:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The `<li>` element should now look like this:",
"translation": "`<li>`元素应该变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "In addition to calling the component's `delete()` method, the delete button's\nclick handler code stops the propagation of the click event&mdash;you\ndon't want the `<li>` click handler to be triggered because doing so would\nselect the hero that the user will delete.",
"translation": "除了调用组件的`delete()`方法之外,这个删除按钮的点击处理器还应该阻止点击事件向上冒泡 &mdash;\n我们并不希望触发`<li>`的事件处理器,否则它会选中我们要删除的这位英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The logic of the `delete()` handler is a bit trickier:",
"translation": "`delete()`处理器的逻辑略复杂:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Of course you delegate hero deletion to the hero service, but the component\nis still responsible for updating the display: it removes the deleted hero\nfrom the array and resets the selected hero, if necessary.",
"translation": "当然,我们仍然把删除英雄的操作委托给了 hero 服务,\n不过该组件仍然负责更新显示它从数组中移除了被删除的英雄如果删除的是正选中的英雄还会清空选择。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "To place the delete button at the far right of the hero entry,\nadd this CSS:",
"translation": "我们希望删除按钮被放在英雄条目的最右边。\n于是 CSS 变成了这样:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Hero service _delete()_ method",
"translation": "### hero 服务的`delete()`方法",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Add the hero service's `delete()` method, which uses the `delete()` HTTP method to remove the hero from the server:",
"translation": "hero 服务的`delete()`方法使用 HTTP 的 `delete()` 方法来从服务器上移除该英雄:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Refresh the browser and try the new delete functionality.",
"translation": "刷新浏览器,并试一下这个新的删除功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Observables",
"translation": "## 可观察对象 (Observable)",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Each `Http` service method returns an `Observable` of HTTP `Response` objects.",
"translation": "`Http`服务中的每个方法都返回一个 HTTP `Response`对象的`Observable`实例。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The `HeroService` converts that `Observable` into a `Promise` and returns the promise to the caller.\nThis section shows you how, when, and why to return the `Observable` directly.",
"translation": "我们的`HeroService`中把那个`Observable`对象转换成了`Promise`(承诺),并把这个承诺返回给了调用者。\n 这一节,我们将学会直接返回`Observable`,并且讨论何时以及为何那样做会更好。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Background",
"translation": "### 背景",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "An *Observable* is a stream of events that you can process with array-like operators.",
"translation": "一个*可观察对象*是一个事件流,我们可以用数组型操作符来处理它。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Angular core has basic support for observables. \nDevelopers augment that support with operators and extensions from the\n<a href=\"http://reactivex.io/rxjs\" target=\"_blank\" title=\"RxJS\">RxJS library</a>.\nYou'll see how shortly.",
"translation": "Angular 内核中提供了对可观察对象的基本支持。而我们这些开发人员可以自己从 <a href=\"http://reactivex.io/rxjs\" target=\"_blank\" title=\"RxJS\">RxJS</a> 库中引入操作符和扩展。\n 我们会简短的讲解下如何做。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Recall that the `HeroService` chained the `toPromise` operator to the `Observable` result of `http.get()`.\nThat operator converted the `Observable` into a `Promise` and you passed that promise back to the caller.",
"translation": "快速回忆一下`HeroService`,它在`http.get()`返回的`Observable`后面串联了一个`toPromise`操作符。\n该操作符把`Observable`转换成了`Promise`,并且我们把那个承诺返回给了调用者。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Converting to a Promise is often a good choice. You typically ask `http.get()` to fetch a single chunk of data.\nWhen you receive the data, you're done.\nThe calling component can easily consume a single result in the form of a Promise.",
"translation": "转换成承诺通常是更好地选择,我们通常会要求`http.get()`获取单块数据。只要接收到数据,就算完成。\n使用承诺这种形式的结果是让调用方更容易写并且承诺已经在 JavaScript 程序员中被广泛接受了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "But requests aren't always done only once.\nYou may start one request,\ncancel it, and make a different request before the server has responded to the first request.",
"translation": "但是请求并非总是“一次性”的。我们可以开始一个请求,\n 并且取消它,在服务器对第一个请求作出回应之前,再开始另一个不同的请求 。\n 像这样一个_请求-取消-新请求_的序列用*承诺*是很难实现的,但接下来我们会看到,它对于*可观察对象*却很简单。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "A *request-cancel-new-request* sequence is difficult to implement with `Promise`s, but\neasy with `Observable`s.",
"translation": "*请求-取消-新请求*的序列对于`Promise`来说是很难实现的,但是对`Observable`来说则很容易。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Add the ability to search by name",
"translation": "### 支持按名搜索",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "You're going to add a *hero search* feature to the Tour of Heroes.\nAs the user types a name into a search box, you'll make repeated HTTP requests for heroes filtered by that name.",
"translation": "我们要为《英雄指南》添加一个*英雄搜索*特性。\n 当用户在搜索框中输入一个名字时,我们将不断发起 HTTP 请求,以获得按名字过滤的英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Start by creating `HeroSearchService` that sends search queries to the server's web API.",
"translation": "我们先创建`HeroSearchService`服务,它会把搜索请求发送到我们服务器上的 Web API。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The `http.get()` call in `HeroSearchService` is similar to the one\nin the `HeroService`, although the URL now has a query string.",
"translation": "`HeroSearchService`中的`http.get()`调用和`HeroService`中的很相似,只是这次带了查询字符串。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "More importantly, you no longer call `toPromise()`.\n Instead you return the *Observable* from the the `http.get()`, \n after chaining it to another RxJS operator, <code>map()</code>, \n to extract heroes from the response data.",
"translation": "更重要的是:我们不再调用`toPromise`方法,而是从`http.get`\n 方法中返回一个*Observable*对象之后调用RxJS的<code>map</code>操作符\n 来从返回数据中提取英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "RxJS operator chaining makes response processing easy and readable.\n See the [discussion below about operators](tutorial/toh-pt6#rxjs-imports).",
"translation": "链式RxJS操作可以让我们简单、易读的处理响应数据。详见[下面关于操作符的讨论](tutorial/toh-pt6#rxjs-imports)",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### HeroSearchComponent",
"translation": "### HeroSearchComponent 组件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Let's create a new `HeroSearchComponent` that calls this new `HeroSearchService`.",
"translation": "我们再创建一个新的`HeroSearchComponent`来调用这个新的`HeroSearchService`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The component template is simple&mdash;just a text box and a list of matching search results.",
"translation": "组件模板很简单,就是一个输入框和一个显示匹配的搜索结果的列表。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Also, add styles for the new component.",
"translation": "我们还要往这个新组件中添加样式。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"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/content-1/tutorial/toh-pt6.md"
},
{
"original": "As expected, the `*ngFor` repeats hero objects from the component's `heroes` property.",
"translation": "不出所料,`*ngFor`从该组件的`heroes`属性重复获取 *hero* 对象。这也没啥特别的。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "But as you'll soon see, the `heroes` property is now an *Observable* of hero arrays, rather than just a hero array.\nThe `*ngFor` can't do anything with an `Observable` until you route it through the `async` pipe (`AsyncPipe`).\nThe `async` pipe subscribes to the `Observable` and produces the array of heroes to `*ngFor`.",
"translation": "但是,接下来我们看到`heroes`属性现在是英雄列表的`Observable`对象,而不再只是英雄数组。\n `*ngFor`不能用可观察对象做任何事,除非我们在它后面跟一个`async` pipe (`AsyncPipe`)。\n 这个`async`管道会订阅到这个可观察对象,并且为`*ngFor`生成一个英雄数组。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Create the `HeroSearchComponent` class and metadata.",
"translation": "该创建`HeroSearchComponent`类及其元数据了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "#### Search terms",
"translation": "#### 搜索词",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Focus on the `searchTerms`:",
"translation": "仔细看下这个`searchTerms`",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "A `Subject` is a producer of an _observable_ event stream;\n`searchTerms` produces an `Observable` of strings, the filter criteria for the name search.",
"translation": "`Subject`主题是一个_可观察的_事件流中的生产者。\n `searchTerms`生成一个产生字符串的`Observable`用作按名称搜索时的过滤条件。Each call to `search()` puts a new string into this subject's _observable_ stream by calling `next()`.",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "#### Initialize the *heroes* property (*ngOnInit*)",
"translation": "#### 初始化 *heroes* 属性(*ngOnInit*)",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "A `Subject` is also an `Observable`.\nYou can turn the stream\nof search terms into a stream of `Hero` arrays and assign the result to the `heroes` property.",
"translation": "`Subject`也是一个`Observable`对象。\n我们要把搜索词的流转换成`Hero`数组的流,并把结果赋值给`heroes`属性。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Passing every user keystroke directly to the `HeroSearchService` would create an excessive amount of HTTP requests,\ntaxing server resources and burning through the cellular network data plan.",
"translation": "如果我们直接把每一次用户按键都直接传给`HeroSearchService`,就会发起一场 HTTP 请求风暴。\n 这可不好玩。我们不希望占用服务器资源,也不想耗光蜂窝移动网络的流量。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Instead, you can chain `Observable` operators that reduce the request flow to the string `Observable`.\nYou'll make fewer calls to the `HeroSearchService` and still get timely results. Here's how:",
"translation": "不过,我们可以在字符串的`Observable`后面串联一些`Observable`操作符,来归并这些请求。\n 我们将对`HeroSearchService`发起更少的调用,并且仍然获得足够及时的响应。做法如下:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"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/content-1/tutorial/toh-pt6.md"
},
{
"original": "* `distinctUntilChanged` ensures that a request is sent only if the filter text changed.",
"translation": "`distinctUntilChanged`确保只在过滤条件变化时才发送请求,\n 这样就不会重复请求同一个搜索词了。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"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/content-1/tutorial/toh-pt6.md"
},
{
"original": "With the [switchMap operator](http://www.learnrxjs.io/operators/transformation/switchmap.html)\n (formerly known as `flatMapLatest`),\n every qualifying key event can trigger an `http()` 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(正式名称是`flatMapLatest`)\n每次符合条件的按键事件都会触发一次对`http()`方法的调用。即使在发送每个请求前都有 300 毫秒的延迟,\n我们仍然可能同时拥有多个在途的 HTTP 请求,并且它们返回的顺序未必就是发送时的顺序。`switchMap()` preserves the original request order while returning\n only the observable from the most recent `http` method call.\nResults from prior calls are canceled and discarded.",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* `catch` intercepts a failed observable.\nThe simple example prints the error to the console; a real life app would do better.\nThen to clear the search result, you return an observable containing an empty array .",
"translation": "`catch`拦截失败的可观察对象。这个简单的例子中只是把错误信息打印到控制台(但实际的应用需要做更多事),然后返回一个包含空数组的可观察对象,以清空搜索结果。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Import RxJS operators",
"translation": "### 导入 RxJS 操作符",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Most RxJS operators are not included in Angular's base `Observable` implementation.\nThe base implementation includes only what Angular itself requires.",
"translation": "大部分RxJS操作符都不包括在Angular的`Observable`基本实现中基本实现只包括Angular本身所需的功能。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "When you need more RxJS features, extend `Observable` by *importing* the libraries in which they are defined.\nHere are all the RxJS imports that _this_ component needs:",
"translation": "如果想要更多的RxJS功能我们必须*导入*其所定义的库来扩展`Observable`对象,\n 以下是*这个*模块所需导入的所有RxJS操作符",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "The `import 'rxjs/add/...'` syntax may be unfamiliar.\nIt's missing the usual list of symbols between the braces: `{...}`.",
"translation": "你可能并不熟悉这种`import 'rxjs/add/...'`语法,它缺少了花括号中的导入列表:`{...}`。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "You don't need the operator symbols themselves.\nIn each case, the mere act of importing the library\nloads and executes the library's script file which, in turn, adds the operator to the `Observable` class.",
"translation": "这是因为我们并不需要操作符本身,这种情况下,我们所做的其实是导入这个库,加载并运行其中的脚本,\n它会把操作符添加到`Observable`类中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "### Add the search component to the dashboard",
"translation": "### 为仪表盘添加搜索组件",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Add the hero search HTML element to the bottom of the `DashboardComponent` template.",
"translation": "将表示“英雄搜索”组件的 HTML 元素添加到`DashboardComponent`模版的最后面。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Finally, import `HeroSearchComponent` from\n<code>hero-search.component.ts</code>\nand add it to the `declarations` array.",
"translation": "最后,从<span ngio-ex>hero-search.component.ts</span>中导入`HeroSearchComponent`并将其添加到`declarations`数组中。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"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": "再次运行该应用,跳转到*仪表盘*,并在英雄下方的搜索框里输入一些文本。\n运行效果如下",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## App structure and code",
"translation": "## 应用的结构与代码",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Review the sample source code in the <live-example></live-example> for this page.\nVerify that you have the following structure:",
"translation": "回顾一下本章<live-example></live-example>中的范例代码。\n 验证我们是否得到了如下结构:",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Summary",
"translation": "## 最后冲刺",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "You're at the end of your journey, and you've accomplished a lot.",
"translation": "旅程即将结束,不过我们已经收获颇丰。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* You added the necessary dependencies to use HTTP in the app.",
"translation": "我们添加了在应用程序中使用 HTTP 的必备依赖。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* You refactored `HeroService` to load heroes from a web API.",
"translation": "我们重构了`HeroService`,以通过 web API 来加载英雄数据。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* You extended `HeroService` to support `post()`, `put()`, and `delete()` methods.",
"translation": "我们扩展了`HeroService`来支持 `post()`、`put()` 和 `delete()` 方法。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* You updated the components to allow adding, editing, and deleting of heroes.",
"translation": "我们更新了组件,以允许用户添加、编辑和删除英雄。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* You configured an in-memory web API.",
"translation": "我们配置了一个内存 Web API。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "* You learned how to use Observables.",
"translation": "我们学会了如何使用“可观察对象”。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "Here are the files you added or changed in this page.",
"translation": "下面是我们**添加或修改**之后的文件汇总。",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "## Next step",
"translation": "## 下一步",
"sourceFile": "/Users/twer/private/GDE/content-1/tutorial/toh-pt6.md"
},
{
"original": "That 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/content-1/tutorial/toh-pt6.md"
}
]