不再使用li进行切换,而是全面转换到li内嵌p元素

This commit is contained in:
Zhicheng Wang 2017-02-26 21:44:00 +08:00
parent e11efe4aef
commit 7711fa6557
26 changed files with 669 additions and 469 deletions

View File

@ -25,23 +25,23 @@ a(id="top")
* [Template basics](#template-basics) - binding and local variables.
* [模板基础](#template-basics) - 绑定变量与局部变量。
[模板基础](#template-basics) - 绑定变量与局部变量。
* [Template directives](#template-directives) - built-in directives `ngIf` and `ngClass`.
* [模板指令](#template-directives) - 内置指令`ngIf`和`ngClass`。
[模板指令](#template-directives) - 内置指令`ngIf`和`ngClass`。
* [Filters/pipes](#filters-pipes) - built-in *filters*, known as *pipes* in Angular.
* [过滤器/管道](#filters-pipes) - 内置*过滤器(filter)*在Angular中叫*管道(pipe)*。
[过滤器/管道](#filters-pipes) - 内置*过滤器(filter)*在Angular中叫*管道(pipe)*。
* [Modules/controllers/components](#controllers-components) - *modules* in Angular are slightly different from *modules* in AngularJS, and *controllers* are *components* in Angular.
* [模块/控制器/组件](#controllers-components) - Angular 中的*模块*和AngularJS 中的略有不同;而*控制器*在Angular 中叫组件。
[模块/控制器/组件](#controllers-components) - Angular 中的*模块*和AngularJS 中的略有不同;而*控制器*在Angular 中叫组件。
* [Style sheets](#style-sheets) - more options for CSS than in AngularJS.
* [样式表](#style-sheets) - Angular 相对AngularJS 在 CSS 方面有了更多选项。
[样式表](#style-sheets) - Angular 相对AngularJS 在 CSS 方面有了更多选项。
.l-main-section
:marked
@ -1023,11 +1023,11 @@ table(width="100%")
Angular的模块用`NgModule`装饰器进行定义,有如下用途:
- `imports`: specifies the list of other modules that this module depends upon
- `imports`: 指定当前模块依赖的其它模块列表
`imports`: 指定当前模块依赖的其它模块列表
- `declaration`: keeps track of your components, pipes, and directives.
- `declaration`: 用于记录组件、管道和指令。
`declaration`: 用于记录组件、管道和指令。
For more information on modules, see [Angular Modules](../guide/ngmodule.html).

View File

@ -11,26 +11,46 @@ a#toc
## Table of Contents
## 目录
* [Overview](#overview)
* [概览](#overview)
[概览](#overview)
* [_Ahead-of-Time_ vs _Just-in-Time_](#aot-jit)
* [_预编译_ vs _即时编译_](#aot-jit)
[_预编译_ vs _即时编译_](#aot-jit)
* [Compile with AOT](#compile)
* [用AOT进行编译](#compile)
[用AOT进行编译](#compile)
* [Bootstrap](#bootstrap)
* [引导](#bootstrap)
[引导](#bootstrap)
* [Tree Shaking](#tree-shaking)
* [摇树优化Tree Shaking](#tree-shaking)
[摇树优化Tree Shaking](#tree-shaking)
* [Load the bundle](#load)
* [加载捆文件](#load)
[加载捆文件](#load)
* [Serve the app](#serve)
* [启动应用服务器](#serve)
[启动应用服务器](#serve)
* [Workflow and convenience script](#workflow)
* [工作流与辅助脚本](#workflow)
[工作流与辅助脚本](#workflow)
* [Source Code](#source-code)
* [源码](#source-code)
[源码](#source-code)
* [Tour of Heroes](#toh)
* [英雄指南](#toh)
[英雄指南](#toh)
a#overview
.l-main-section
:marked

View File

@ -26,11 +26,11 @@ include ../_util-fns
1. We have to remember the full path back to the application root.
1. 我们不得不记住到应用程序根目录的完整路径。
我们不得不记住到应用程序根目录的完整路径。
1. We have to update the URL when we move the component around in the application files structure.
1. 当我们在应用的文件结构中移动这个组件时将不得不更新这个URL
当我们在应用的文件结构中移动这个组件时将不得不更新这个URL
It would be much easier to write and maintain our application components if we could specify template and style locations
*relative* to their component class file.

View File

@ -46,23 +46,23 @@ include ../_util-fns
* [The *provide* Object literal](#provide)
* [*provide*对象](#provide)
[*provide*对象](#provide)
* [useValue - the *value provider*](#usevalue)
* [useValue - *值提供商*](#usevalue)
[useValue - *值提供商*](#usevalue)
* [useClass - the *class provider*](#useclass)
* [useClass - *类提供商*](#useclass)
[useClass - *类提供商*](#useclass)
* [useExisting - the *alias provider*](#useexisting)
* [useExisting - *别名提供商*](#useexisting)
[useExisting - *别名提供商*](#useexisting)
* [useFactory - the *factory provider*](#usefactory)
* [useFactory - *工厂提供商*](#usefactory)
[useFactory - *工厂提供商*](#usefactory)
[Define providers with object literals](#object-literals)
@ -74,11 +74,11 @@ include ../_util-fns
* [class-interface](#class-interface)
* [类-接口](#class-interface)
[类-接口](#class-interface)
* [OpaqueToken](#opaque-token)
* [Opaque令牌](#opaque-token)
[Opaque令牌](#opaque-token)
[Inject into a derived class](#di-inheritance)
@ -90,23 +90,23 @@ include ../_util-fns
* [Find parent with a known component type](#known-parent)
* [通过已知组件类型查找父组件](#known-parent)
[通过已知组件类型查找父组件](#known-parent)
* [Cannot find a parent by its base class](#base-parent)
* [无法通过自己的基类查找父组件](#base-parent)
[无法通过自己的基类查找父组件](#base-parent)
* [Find a parent by its class-interface](#class-interface-parent)
* [通过类-接口查找父组件](#class-interface-parent)
[通过类-接口查找父组件](#class-interface-parent)
* [Find a parent in a tree of parents (*@SkipSelf*)](#parent-tree)
* [在父组件树里查找一个父组件(*@SkipSelf*)](#parent-tree)
[在父组件树里查找一个父组件(*@SkipSelf*)](#parent-tree)
* [A *provideParent* helper function](#provideparent)
* [*provideParent*助手函数](#provideparent)
[*provideParent*助手函数](#provideparent)
[Break circularities with a forward class reference (*forwardRef*)](#forwardref)
@ -1343,11 +1343,11 @@ a(id="parent-tree")
1. It tell the injector to start its search for a `Parent` dependency in a component *above* itself,
which *is* what parent means.
1. 它告诉注入器从一个在自己*上一级*的组件开始搜索一个`Parent`依赖。
它告诉注入器从一个在自己*上一级*的组件开始搜索一个`Parent`依赖。
2. Angular throws a cyclic dependency error if we omit the `@SkipSelf` decorator.
2. 如果没写`@SkipSelf`装饰器的话Angular就会抛出一个循环依赖错误。
如果没写`@SkipSelf`装饰器的话Angular就会抛出一个循环依赖错误。
`Cannot instantiate cyclic dependency! (BethComponent -> Parent -> BethComponent)`

View File

@ -96,34 +96,34 @@ a#template1
- The `<input>` element carries the HTML validation attributes: `required`, `minlength`, and `maxlength`.
- `<input>`元素具有HTML验证属性`required`、`minlength`、和 `maxlength`。
`<input>`元素具有HTML验证属性`required`、`minlength`、和 `maxlength`。
- We set the `name` attribute of the input box to `"name"` so Angular can track this input element and associate it
with an Angular form control called `name` in its internal control model.
- 我们设置输入框的`name`属性为`"name"`这样Angular可以跟踪这个输入元素并将其内部控制器模型的一个名为`name`的Angular表单控制关联起来。
我们设置输入框的`name`属性为`"name"`这样Angular可以跟踪这个输入元素并将其内部控制器模型的一个名为`name`的Angular表单控制关联起来。
- We use the `[(ngModel)]` directive to two-way data bind the input box to the `hero.name` property.
- 我们使用`[(ngModel)]`指令,将输入框双向数据绑定到`hero.name`属性。
我们使用`[(ngModel)]`指令,将输入框双向数据绑定到`hero.name`属性。
- We set a template variable (`#name`) to the value `"ngModel"` (always `ngModel`).
This gives us a reference to the Angular `NgModel` directive
associated with this control that we can use _in the template_
to check for control states such as `valid` and `dirty`.
- 我们将模板变量(`#name`)赋值为`"ngModel"` (总是 `ngModel`)。
我们将模板变量(`#name`)赋值为`"ngModel"` (总是 `ngModel`)。
它为我们提供了与这个控制器关联的Angular `NgModel`指令的引用,我们在模板中使用它,以检查控制器状态,比如`valid`和`dirty`。
- The `*ngIf` on `<div>` element reveals a set of nested message `divs` but only if there are "name" errors and
the control is either `dirty` or `touched`.
- `<div>`元素的`*ngIf`揭露了一套嵌套消息`divs`但是只在有“name”错误和控制器为`dirty`或者`touched`。
`<div>`元素的`*ngIf`揭露了一套嵌套消息`divs`但是只在有“name”错误和控制器为`dirty`或者`touched`。
- Each nested `<div>` can present a custom message for one of the possible validation errors.
We've prepared messages for `required`, `minlength`, and `maxlength`.
- 每个嵌套的`<div>`为其中一个可能出现的验证错误显示一条自定义消息。我们已经为`required`、`minlength`、和 `maxlength`准备了消息。
每个嵌套的`<div>`为其中一个可能出现的验证错误显示一条自定义消息。我们已经为`required`、`minlength`、和 `maxlength`准备了消息。
The full template repeats this kind of layout for each data entry control on the form.
@ -183,17 +183,17 @@ a#template2
* It takes a lot of HTML to represent all possible error conditions.
This gets out of hand when there are many controls and many validation rules.
* 它使用了很多HTML来表现所有可能出现的错误情况。
它使用了很多HTML来表现所有可能出现的错误情况。
如果有太多控制器和太多验证规则,我们就失去了控制。
* We're not fond of so much JavaScript logic in HTML.
* 我们不喜欢在HTML里面插入这么多JavaScript。
我们不喜欢在HTML里面插入这么多JavaScript。
* The messages are static strings, hard-coded into the template.
We often require dynamic messages that we should shape in code.
* 这些消息是静态的字符串,被硬编码到模板中。我们通常要求在代码中可以塑造的动态消息。
这些消息是静态的字符串,被硬编码到模板中。我们通常要求在代码中可以塑造的动态消息。
We can move the logic and the messages into the component with a few changes to
the template and component.
@ -217,23 +217,23 @@ a#template2
- The hard-code error message `<div>` are gone.
- 硬编码的错误消息`<div>`消失了。
硬编码的错误消息`<div>`消失了。
- There's a new attribute, `forbiddenName`, that is actually a custom validation directive.
It invalidates the control if the user enters "bob" anywhere in the name ([try it](#live-example)).
We discuss [custom validation directives](#custom-validation) later in this cookbook.
- 添加了一个新属性`forbiddenName`,它实际上是一个自定义验证指令。
添加了一个新属性`forbiddenName`,它实际上是一个自定义验证指令。
如果用户名字中的任何地方输入“bob”该指令变将控制器标记为无效[试试](#live-example))。
我们在本烹饪书后面介绍了[自定义验证指令](#custom-validation)。
- The `#name` template variable is gone because we no longer refer to the Angular control for this element.
- 模板变量`#name`消失了因为我们不再需要为这个元素引用Angular控制器。
模板变量`#name`消失了因为我们不再需要为这个元素引用Angular控制器。
- Binding to the new `formErrors.name` property is sufficent to display all name validation error messages.
- Binding to the new `formErrors.name` property is sufficent to display all name validation error messages.
- 绑定到新的`formErrors.name`属性,就可以处理所有名字验证错误信息了。
绑定到新的`formErrors.name`属性,就可以处理所有名字验证错误信息了。
#### Component class
@ -272,22 +272,22 @@ a#template2
- Angular `@ViewChild` queries for a template variable when you pass it
the name of that variable as a string (`'heroForm'` in this case).
- Angular的`@ViewChild`使用传入的模板变量的字符串名字(这里是`'heroForm'`),来查询对应的模板变量。
Angular的`@ViewChild`使用传入的模板变量的字符串名字(这里是`'heroForm'`),来查询对应的模板变量。
- The `heroForm` object changes several times during the life of the component, most notably when we add a new hero.
We'll have to re-inspect it periodically.
- `heroForm`对象在组件的生命周期内变化了好几次,最值得注意的是当我们添加一个新英雄时的变化。我们必须定期重新检测它。
`heroForm`对象在组件的生命周期内变化了好几次,最值得注意的是当我们添加一个新英雄时的变化。我们必须定期重新检测它。
- Angular calls the `ngAfterViewChecked` [lifecycle hook method](../guide/lifecycle-hooks.html#afterview)
when anything changes in the view.
That's the right time to see if there's a new `heroForm` object.
- 当视图有任何变化时Angular调用`ngAfterViewChecked`[生命周期钩子方法](../guide/lifecycle-hooks.html#afterview)。这是查看是否有新`heroForm`对象的最佳时机。
当视图有任何变化时Angular调用`ngAfterViewChecked`[生命周期钩子方法](../guide/lifecycle-hooks.html#afterview)。这是查看是否有新`heroForm`对象的最佳时机。
- When there _is_ a new `heroForm` model, we subscribe to its `valueChanged` _Observable_ property.
- 当出现新`heroForm`模型时,我们订阅它的`valueChanged`**可观察**属性。
当出现新`heroForm`模型时,我们订阅它的`valueChanged`**可观察**属性。
The `onValueChanged` handler looks for validation errors after every user keystroke.
@ -318,19 +318,19 @@ a#template2
- clears the prior error message if any
- 如果有之前的错误信息,清楚它们
如果有之前的错误信息,清楚它们
- acquires the field's corresponding Angular form control
- 获取控件对应的Angular表单控制器
获取控件对应的Angular表单控制器
- if such a control exists _and_ its been changed ("dirty") _and_ its invalid ...
- 如果这样的控制器存在并且它被更新“dirty”**以及**它无效...
如果这样的控制器存在并且它被更新“dirty”**以及**它无效...
- the handler composes a consolidated error message for all of the control's errors.
- 处理器便为所有控制器的错误合成一条错误消息。
处理器便为所有控制器的错误合成一条错误消息。
We'll need some error messages of course, a set for each validated property, one message per validation rule:
@ -442,15 +442,15 @@ a#reactive
* add, change, and remove validation functions on the fly
* 随时添加、修改和删除验证函数
随时添加、修改和删除验证函数
* manipulate the control model dynamically from within the component
* 在组件内动态操纵控制器模型
在组件内动态操纵控制器模型
* [test](#testing) validation and control logic with isolated unit tests.
* 使用孤立单元测试来[测试](#testing)验证和控制器逻辑
使用孤立单元测试来[测试](#testing)验证和控制器逻辑
The third cookbook sample re-writes the hero form in _reactive forms_ style.
@ -507,12 +507,12 @@ a#reactive
- the validation attributes are gone (except `required`) because we'll be validating in code.
- 验证属性没有了(除了`required`),因为我们将在代码中验证。
验证属性没有了(除了`required`),因为我们将在代码中验证。
- `required` remains, not for validation purposes (we'll cover that in the code),
but rather for css styling and accessibility.
- 保留了`required`不是为了验证目的我们将在代码中再行解释而是为了CSS样式和可访问性。
保留了`required`不是为了验证目的我们将在代码中再行解释而是为了CSS样式和可访问性。
.l-sub-section
:marked
@ -530,13 +530,13 @@ a#reactive
- the `formControlName` replaces the `name` attribute; it serves the same
purpose of correlating the input box with the Angular form control.
- `formControlName`替换了`name`属性它起到了关联输入框和Angular表单控制器的同样作用。
`formControlName`替换了`name`属性它起到了关联输入框和Angular表单控制器的同样作用。
- the two-way `[(ngModel)]` binding is gone.
The reactive approach does not use data binding to move data into and out of the form controls.
We do that in code.
- 双向`[(ngModel)]`绑定消失了。
双向`[(ngModel)]`绑定消失了。
响应式表单方法不使用数据绑定从表单控制器移入和移出数据。我们在代码中做这些。
.l-sub-section
@ -571,12 +571,12 @@ a#reactive
:marked
- we inject the `FormBuilder` in a constructor.
- 我们注入`FormBuilder`到构造函数中。
我们注入`FormBuilder`到构造函数中。
- we call a `buildForm` method in the `ngOnInit` [lifecycle hook method](../guide/lifecycle-hooks.html#hooks-overview)
because that's when we'll have the hero data. We'll call it again in the `addHero` method.
- 我们在`ngOnInit`[生命周期钩子方法](../guide/lifecycle-hooks.html#hooks-overview)中调用`buildForm`方法,
我们在`ngOnInit`[生命周期钩子方法](../guide/lifecycle-hooks.html#hooks-overview)中调用`buildForm`方法,
因为这正是我们拥有英雄数据的时刻。我们将在`addHero`方法中再次调用它。
.l-sub-section
@ -590,7 +590,7 @@ a#reactive
to the form's `valueChanged` event and calls it immediately
to set error messages for the new control model.
- `buildForm`方法使用`FormBuilder``fb`)来声明表单控制器模型。
`buildForm`方法使用`FormBuilder``fb`)来声明表单控制器模型。
然后它将相同的`onValueChanged`(有一行代码不一样)处理器附加到表单的`valueChanged`事件,
并立刻为新的控制器模型设置错误消息。
@ -646,11 +646,11 @@ a#reactive
1. when the user submits the form
1. 当用户提交标单时
当用户提交标单时
1. when the user chooses to add a new hero
1. 当用户选择添加新英雄
当用户选择添加新英雄
The `onSubmit` method simply replaces the `hero` object with the combined values of the form:

View File

@ -92,22 +92,22 @@ a#angular-i18n
1. Mark static text messages in your component templates for translation.
1. 在组件模板中标记需要翻译的静态文本信息。
在组件模板中标记需要翻译的静态文本信息。
1. An angular _i18n_ tool extracts the marked messages into an industry standard translation source file.
1. Angular的_i18n_工具将标记的信息提取到一个行业标准的翻译源文件。
Angular的_i18n_工具将标记的信息提取到一个行业标准的翻译源文件。
1. A translator edits that file, translating the extracted text messages into the target language,
and returns the file to you.
1. 翻译人员编辑该文件,翻译提取出来的文本信息到目标语言,并将该文件还给你。
翻译人员编辑该文件,翻译提取出来的文本信息到目标语言,并将该文件还给你。
1. The Angular compiler imports the completed translation files,
replaces the original messages with translated text, and generates a new version of the application
in the target language.
1. Angular编译器导入完成翻译的文件使用翻译的文本替换原始信息并生成新的目标语言版本的应用程序。
Angular编译器导入完成翻译的文件使用翻译的文本替换原始信息并生成新的目标语言版本的应用程序。
You need to build and deploy a separate version of the application for each supported language.
@ -556,16 +556,16 @@ a#merge
* the translation file
* 翻译文件
翻译文件
* the translation file format
* 翻译文件的格式
翻译文件的格式
* the <a href="https://en.wikipedia.org/wiki/XLIFF" target="_blank">_Locale ID_</a>
(`es` or `en-US` for instance)
* 目标<a href="https://en.wikipedia.org/wiki/XLIFF" target="_blank">_语言环境ID_</a>
目标<a href="https://en.wikipedia.org/wiki/XLIFF" target="_blank">_语言环境ID_</a>
(例如`es`或`en-US`)
_How_ you provide this information depends upon whether you compile with
@ -575,11 +575,11 @@ a#merge
* With [JIT](#jit), you provide the information at bootstrap time.
* 使用[JiT](#jit)时,在引导时提供
使用[JiT](#jit)时,在引导时提供
* With [AOT](#aot), you pass the information as `ngc` options.
* 使用[AoT](#aot)时,在`ngc`命令的选项里提供
使用[AoT](#aot)时,在`ngc`命令的选项里提供
a#jit
.l-main-section
@ -663,7 +663,7 @@ a#text-plugin
* `LOCALE_ID` is the locale of the target language.
* `LOCALE_ID`是目标语言的语言环境。
`LOCALE_ID`是目标语言的语言环境。
The `getTranslationProviders` function in the following `src/app/i18n-providers.ts`
creates those providers based on the user's _locale_

View File

@ -27,92 +27,151 @@ block includes
声明(declarations)
* [What classes should I add to _declarations_?](#q-what-to-declare)
* [我应该把哪些类加到_declarations_中](#q-what-to-declare)
[我应该把哪些类加到_declarations_中](#q-what-to-declare)
* [What is a _declarable_?](#q-declarable)
* [什么是*可声明的*](#q-declarable)
[什么是*可声明的*](#q-declarable)
* [What classes should I *not* add to _declarations_?](#q-what-not-to-declare)
* [我*不应该*把哪些类加到_declarations_中](#q-what-not-to-declare)
[我*不应该*把哪些类加到_declarations_中](#q-what-not-to-declare)
* [Why list the same component in multiple _NgModule_ properties?](#q-why-multiple-mentions)
* [为什么要把同一个组件列在*NgModule*的不同属性中?](#q-why-multiple-mentions)
[为什么要把同一个组件列在*NgModule*的不同属性中?](#q-why-multiple-mentions)
* [What does "_Can't bind to 'x' since it isn't a known property of 'y'_" mean?](#q-why-cant-bind-to)
* ["_Can't bind to 'x' since it isn't a known property of 'y'_"是什么意思?](#q-why-cant-bind-to)
["_Can't bind to 'x' since it isn't a known property of 'y'_"是什么意思?](#q-why-cant-bind-to)
Imports
导入(imports)
* [What should I import?](#q-what-to-import)
* [我应该导入什么?](#q-what-to-import)
[我应该导入什么?](#q-what-to-import)
* [Should I import _BrowserModule_ or _CommonModule_?](#q-browser-vs-common-module)
* [我应该导入_BrowserModule_还是_CommonModule_](#q-browser-vs-common-module)
[我应该导入_BrowserModule_还是_CommonModule_](#q-browser-vs-common-module)
* [What if I import the same module twice?](#q-reimport)
* [如果我两次导入了同一个模块会怎么样?](#q-reimport)
[如果我两次导入了同一个模块会怎么样?](#q-reimport)
Exports
导出(exports)
* [What should I export?](#q-what-to-export)
* [我应该导出什么?](#q-what-to-export)
[我应该导出什么?](#q-what-to-export)
* [What should I *not* export?](#q-what-not-to-export)
* [我*不*应该导出什么?](#q-what-not-to-export)
[我*不*应该导出什么?](#q-what-not-to-export)
* [Can I re-export imported classes and modules?](#q-re-export)
* [我能再次导出(re-export)所导入的类和模块吗?](#q-re-export)
[我能再次导出(re-export)所导入的类和模块吗?](#q-re-export)
* [What is the _forRoot_ method?](#q-for-root)
* [_forRoot_方法是什么](#q-for-root)
[_forRoot_方法是什么](#q-for-root)
Service Providers
服务提供商(providers)
* [Why is a service provided in a feature module visible everywhere?](#q-module-provider-visibility)
* [为什么特性模块中提供的服务是到处可见的?](#q-module-provider-visibility)
[为什么特性模块中提供的服务是到处可见的?](#q-module-provider-visibility)
* [Why is a service provided in a _lazy loaded_ module visible only to that module?](#q-lazy-loaded-module-provider-visibility)
* [为什么*惰性加载*模块中的服务提供商只对那个模块本身可见?](#q-lazy-loaded-module-provider-visibility)
[为什么*惰性加载*模块中的服务提供商只对那个模块本身可见?](#q-lazy-loaded-module-provider-visibility)
* [What if two modules provide the _same_ service?](#q-module-provider-duplicates)
* [如果两个模块提供了*同一个*服务会怎样?](#q-module-provider-duplicates)
[如果两个模块提供了*同一个*服务会怎样?](#q-module-provider-duplicates)
* [How do I restrict service scope to a module?](#q-component-scoped-providers)
* [如何把服务的范围限制在某个模块中?](#q-component-scoped-providers)
[如何把服务的范围限制在某个模块中?](#q-component-scoped-providers)
* [Should I add app-wide providers to the root _AppModule_ or the root _AppComponent_?](#q-root-component-or-module)
* [我应该把全应用级的提供商添加到根模块*AppModule*还是根组件*AppComponent*](#q-root-component-or-module)
[我应该把全应用级的提供商添加到根模块*AppModule*还是根组件*AppComponent*](#q-root-component-or-module)
* [Should I add other providers to a module or a component?](#q-component-or-module)
* [我应该把其它提供商添加到模块中还是组件中?](#q-component-or-module)
[我应该把其它提供商添加到模块中还是组件中?](#q-component-or-module)
* [Why is it bad if _SharedModule_ provides a service to a lazy loaded module?](#q-why-bad)
* [为什么让*SharedModule*为惰性加载模块提供服务是个馊主意?](#q-why-bad)
[为什么让*SharedModule*为惰性加载模块提供服务是个馊主意?](#q-why-bad)
* [Why does lazy loading create a child injector?](#q-why-child-injector)
* [为什么惰性加载模块要创建一个子注入器?](#q-why-child-injector)
[为什么惰性加载模块要创建一个子注入器?](#q-why-child-injector)
* [How can I tell if a module or service was previously loaded?](#q-is-it-loaded)
* [我要怎样才能知道一个模块或服务已经被加载过?](#q-is-it-loaded)
[我要怎样才能知道一个模块或服务已经被加载过?](#q-is-it-loaded)
Entry Components
入口组件
* [What is an _entry component_?](#q-entry-component-defined)
* [什么是*入口组件*](#q-entry-component-defined)
[什么是*入口组件*](#q-entry-component-defined)
* [What is the difference between a _bootstrap_ component and an _entry component_?](#q-bootstrap_vs_entry_component)
* [*引导*组件和*入口*组件有什么不同?](#q-bootstrap_vs_entry_component)
[*引导*组件和*入口*组件有什么不同?](#q-bootstrap_vs_entry_component)
* [When do I add components to _entryComponents_?](#q-when-entry-components)
* [什么情况下我应该把组件添加到*entryComponent*中?](#q-when-entry-components)
[什么情况下我应该把组件添加到*entryComponent*中?](#q-when-entry-components)
* [Why does Angular need _entryComponents_?](#q-why-entry-components)
* [为什么Angular需要_entryComponents_](#q-why-entry-components)
[为什么Angular需要_entryComponents_](#q-why-entry-components)
General
一般问题
* [What kinds of modules should I have and how should I use them?](#q-module-recommendations)
* [我需要哪些类型的模块?我应该如何使用它们?](#q-module-recommendations)
[我需要哪些类型的模块?我应该如何使用它们?](#q-module-recommendations)
* [What's the difference between Angular and JavaScript Modules?](#q-ng-vs-js-modules)
* [Angular模块和JavaScript模块有什么不同](#q-ng-vs-js-modules)
[Angular模块和JavaScript模块有什么不同](#q-ng-vs-js-modules)
* [What is a "template reference"?](#q-template-reference)
* [什么是“模板引用”?](#q-template-reference)
[什么是“模板引用”?](#q-template-reference)
* [How does Angular find components, directives, and pipes in a template?](#q-template-reference)
* [Angular如何是在模板中查找组件、指令和管道的](#q-template-reference)
[Angular如何是在模板中查找组件、指令和管道的](#q-template-reference)
* [What is the Angular Compiler?](#q-angular-compiler)
* [什么是Angular编译器Compiler](#q-angular-compiler)
[什么是Angular编译器Compiler](#q-angular-compiler)
* [Can you summarize the _NgModule_ API?](#q-ngmodule-api)
* [你能总结一下_NgModule_ API吗](#q-ngmodule-api)
[你能总结一下_NgModule_ API吗](#q-ngmodule-api)
.l-hr
@ -167,26 +226,26 @@ a#q-what-not-to-declare
* a class that is already declared in another module, whether an app module, @angular module, or 3rd party module
* 已经被其它模块声明过的类,无论是在应用模块、@angular模块还是第三方模块中。
已经被其它模块声明过的类,无论是在应用模块、@angular模块还是第三方模块中。
* an array of directives imported from another module.
For example, do not declare FORMS_DIRECTIVES from `@angular/forms`.
* 一组从其它模块中导入的指令。
一组从其它模块中导入的指令。
例如,不要声明来自`@angular/forms`的FORMS_DIRECTIVES。
* module classes
* 模块类
模块类
* service classes
* 服务类
服务类
* non-Angular classes and objects such as
strings, numbers, functions, entity models, configurations, business logic, and helper classes.
* 非Angular的类和对象比如字符串、数字、函数、实体模型、配置、业务逻辑和辅助类。
非Angular的类和对象比如字符串、数字、函数、实体模型、配置、业务逻辑和辅助类。
.l-hr
@ -209,13 +268,21 @@ a#q-why-multiple-mentions
这*看起来*是多余的,不过这些函数具有不同的功能,我们无法从它出现在一个列表中推断出它也应该在另一个列表中。
* `AppComponent` could be declared in this module but not bootstrapped.
* `AppComponent`可能被声明在此模块中,但可能不是引导组件。
`AppComponent`可能被声明在此模块中,但可能不是引导组件。
* `AppComponent` could be bootstrapped in this module but declared in a different feature module.
* `AppComponent`可能在此模块中引导,但可能是由另一个特性模块声明的。
`AppComponent`可能在此模块中引导,但可能是由另一个特性模块声明的。
* `HeroComponent` could be imported from another app module (so we can't declare it) and re-exported by this module.
* `HeroComponent`可能是从另一个应用模块中导入的(所以我们没法声明它)并且被当前模块重新导出。
`HeroComponent`可能是从另一个应用模块中导入的(所以我们没法声明它)并且被当前模块重新导出。
* `HeroComponent` could be exported for inclusion in an external component's template and also dynamically loaded in a pop-up dialog.
* `HeroComponent`可能被导入,以便用在外部组件的模板中,但也可能同时被一个弹出式对话框加载。
`HeroComponent`可能被导入,以便用在外部组件的模板中,但也可能同时被一个弹出式对话框加载。
.l-hr
@ -388,27 +455,27 @@ a#q-what-not-to-export
* Private components, directives, and pipes that you need only within components declared in this module.
If you don't want another module to see it, don't export it.
* 那些你只想在当前模块中声明的那些组件中使用的私有组件、指令和管道。如果你不希望任何模块看到它,就不要导出。
那些你只想在当前模块中声明的那些组件中使用的私有组件、指令和管道。如果你不希望任何模块看到它,就不要导出。
* Non-declarable objects such as services, functions, configurations, entity models, etc.
* 不可声明的对象,比如服务、函数、配置、实体模型等。
不可声明的对象,比如服务、函数、配置、实体模型等。
* Components that are only loaded dynamically by the router or by bootstrapping.
Such [entry components](#q-entry-component-defined) can never be selected in another component's template.
There's no harm in exporting them but no benefit either.
* 那些只被路由器或引导函数动态加载的组件。
比如[入口组件](#q-entry-component-defined)可能从来不会在其它组件的模板中出现。
导出它们没有坏处,但也没有好处。
那些只被路由器或引导函数动态加载的组件。
比如[入口组件](#q-entry-component-defined)可能从来不会在其它组件的模板中出现。
导出它们没有坏处,但也没有好处。
* Pure service modules that don't have public (exported) declarations.
For example, there is no point in re-exporting `HttpModule` because it doesn't export anything.
It's only purpose is to add http service providers to the application as a whole.
* 纯服务模块没有公开(导出)的声明。
例如,没必要重新导出`HttpModule`,因为它不导出任何东西。
它唯一的用途是一起把http的那些服务提供商添加到应用中。
纯服务模块没有公开(导出)的声明。
例如,没必要重新导出`HttpModule`,因为它不导出任何东西。
它唯一的用途是一起把http的那些服务提供商添加到应用中。
.l-hr
@ -1029,9 +1096,12 @@ a#q-entry-component-defined
Angular会自动把两种组件添加到模块的`entryComponents`中:
1. the component in the `@NgModule.bootstrap` list
1. 那些出现在`@NgModule.bootstrap`列表中的组件
那些出现在`@NgModule.bootstrap`列表中的组件
1. components referenced in router configuration
1. 那些被路由定义引用的组件
那些被路由定义引用的组件
We don't have to mention these components explicitly although it does not harm to do so.
@ -1244,13 +1314,21 @@ a#q-module-recommendations
特性模块一般可分成下面这四种:
* [Domain Feature Modules](#domain-feature-module)
* [领域特性模块](#domain-feature-module)
[领域特性模块](#domain-feature-module)
* [Routing Modules](#routing-module)
* [路由模块](#routing-module)
[路由模块](#routing-module)
* [Service Feature Modules](#service-feature-module)
* [服务特性模块](#service-feature-module)
[服务特性模块](#service-feature-module)
* [Widget Feature Modules](#widget-feature-module)
* [窗口部件特性模块](#widget-feature-module)
[窗口部件特性模块](#widget-feature-module)
.l-sub-section
:marked
@ -1387,19 +1465,20 @@ table
* defines routes
* 定义路由
定义路由
* adds router configuration to the module's `imports`
* 添加路由配置到模块的`imports`中
添加路由配置到模块的`imports`中
* re-exports `RouterModule`
* 重新导出`RouterModule`
重新导出`RouterModule`
* adds guard and resolver service providers to the module's `providers`.
* 添加守卫和解析器服务提供商到模块的`providers`。
添加守卫和解析器服务提供商到模块的`providers`。
The name of the Routing Module should parallel the name of its companion module, using the suffix "Routing".
For example, `FooModule` in `foo.module.ts` has a routing module named `FooRoutingModule`
@ -1678,18 +1757,18 @@ code-example(format='.').
1. An Angular module bounds [_declarable classes_](#q-declarables) only.
Declarables are the only classes that matter to the [Angular compiler](#q-angular-compiler).
1. Angular模块只绑定了[_可声明的类_](#q-declarables),这些可声明的类只是供[Angular编译器](#q-angular-compiler)用的。
Angular模块只绑定了[_可声明的类_](#q-declarables),这些可声明的类只是供[Angular编译器](#q-angular-compiler)用的。
1. Instead of defining all member classes in one giant file (as in a JavaScript module),
we list the module's classes in the `@NgModule.declarations` list.
1. JavaScript模块把所有成员类都定义在一个巨型文件Angular模块则把自己的类都列在`@NgModule.declarations`数组中。
JavaScript模块把所有成员类都定义在一个巨型文件Angular模块则把自己的类都列在`@NgModule.declarations`数组中。
1. An Angular module can only export the [_declarable classes_](#q-declarables)
it owns or imports from other modules.
It doesn't declare or export any other kind of class.
1. Angular模块只能导出[_可声明的类_](#q-declarables)。这可能是它自己拥有的也可能是从其它模块中导入的。它不会声明或导出任何其它类型的类。
Angular模块只能导出[_可声明的类_](#q-declarables)。这可能是它自己拥有的也可能是从其它模块中导入的。它不会声明或导出任何其它类型的类。
The Angular Module is also special in another way.
Unlike JavaScript modules, an Angular module can extend the _entire_ application with services
@ -2026,9 +2105,13 @@ table
这样,那些无法自动发现的组件就只剩下两个来源了:
1. Components bootstrapped using one of the imperative techniques.
1. 使用某种命令式技巧引导的组件。
使用某种命令式技巧引导的组件。
1. Components dynamically loaded into the DOM by some means other than the router.
1. 使用路由器之外的手段动态加载到DOM中的组件。
使用路由器之外的手段动态加载到DOM中的组件。
Both are advanced techniques that few developers will ever employ.
If you are one of those few, you'll have to add these components to the

View File

@ -73,12 +73,14 @@ code-example(format='')
[Title](../api/platform/browser/Title-class.html)服务是一个简单的类提供了一个API用来获取和设置当前HTML文档的标题。
* `getTitle() : string` &mdash; Gets the title of the current HTML document.
* `getTitle(): string` —— 获取当前HTML文档的标题。
`getTitle(): string` —— 获取当前HTML文档的标题。
* `setTitle( newTitle : string )` &mdash; Sets the title of the current HTML document.
* `setTitle( newTitle: string)` —— 设置当前HTML文档的标题。
`setTitle( newTitle: string)` —— 设置当前HTML文档的标题。
Let's inject the `Title` service into the root `AppComponent` and expose a bindable `setTitle` method that calls it:

View File

@ -46,39 +46,40 @@ include ../_util-fns
- [Prerequisite](#prereq1): Install Node.js
- [前提条件](#prereq1): 安装Node.js
[前提条件](#prereq1): 安装Node.js
- [Prerequisite](#prereq2): Install Visual Studio 2015 Update 3
- [前提条件](#prereq2): 安装Visual Studio 2015 Update 3
[前提条件](#prereq2): 安装Visual Studio 2015 Update 3
- [Prerequisite](#prereq3): Configure External Web tools
- [前提条件](#prereq3): 配置External Web tools
[前提条件](#prereq3): 配置External Web tools
- [Prerequisite](#prereq4): Install TypeScript 2 for Visual Studio 2015
- [前提条件](#prereq4): 安装TypeScript 2 for Visual Studio 2015
[前提条件](#prereq4): 安装TypeScript 2 for Visual Studio 2015
- [Step 1](#download): Download the QuickStart files
- [第一步](#download): 下载“快速起步”的文件
[第一步](#download): 下载“快速起步”的文件
- [Step 2](#create-project): Create the Visual Studio ASP.NET project
- [第二步](#create-project): 创建Visual Studio ASP.NET项目
[第二步](#create-project): 创建Visual Studio ASP.NET项目
- [Step 3](#copy): Copy the QuickStart files into the ASP.NET project folder
- [第三步](#copy): 把“快速起步”中的文件拷贝到ASP.NET的项目目录中
[第三步](#copy): 把“快速起步”中的文件拷贝到ASP.NET的项目目录中
- [Step 4](#restore): Restore required packages
- [第四步](#restore): 恢复需要的包
[第四步](#restore): 恢复需要的包
- [Step 5](#build-and-run): Build and run the app
- [第五步](#build-and-run): 构建和运行应用程序
[第五步](#build-and-run): 构建和运行应用程序
.l-main-section
h2#prereq1 Prerequisite: Node.js
@ -127,22 +128,26 @@ h2#prereq3 前提条件: 配置External Web tools
* Open the **Options** dialog with `Tools` | `Options`
* 到`Tools` | `Options`打开**Options**对话框
到`Tools` | `Options`打开**Options**对话框
* In the tree on the left, select `Projects and Solutions` | `External Web Tools`.
* 在左边树型项目中,选择`Projects and Solutions` | `External Web Tools`。
在左边树型项目中,选择`Projects and Solutions` | `External Web Tools`。
* On the right, move the `$(PATH)` entry above the `$(DevEnvDir`) entries. This tells Visual Studio to
use the external tools (such as npm) found in the global path before using its own version of the external tools.
* 在右侧,将`$(PATH)`移动到 `$(DevEnvDir`)上面。这样Visual Stuio就会在使用自带的外部工具时优先使用全局路径中的外部工具比如npm
* Click OK to close the dialog.
Click OK to close the dialog.
* 点击OK关闭对话框。
* Restart Visual Studio for this change to take effect.
Restart Visual Studio for this change to take effect.
* 重启Visual Studio以让设置变化生效。
@ -168,11 +173,11 @@ h2#prereq4 前提条件: 安装TypeScript 2 for Visual Studio 2015
* Download and install **[TypeScript 2.0 for Visual Studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe)**
* 下载并安装**[TypeScript 2.0 for Visual Studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe)**
下载并安装**[TypeScript 2.0 for Visual Studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe)**
* OR install it with npm: `npm install -g typescript@2.0`.
* 或者通过NPM来安装`npm install -g typescript@2.0`。
或者通过NPM来安装`npm install -g typescript@2.0`。
You can find out more about TypeScript 2 support in Visual studio **[here](https://blogs.msdn.microsoft.com/typescript/2016/09/22/announcing-typescript-2-0/)**
@ -205,20 +210,24 @@ h2#create-project 第二步创建Visual Studio ASP.net项目
按照下列步骤创建ASP.NET 4.x项目
* In Visual Studio, select `File` | `New` | `Project` from the menu.
* 在Visual Studio中选择`File` | `New` | `Project`菜单。
在Visual Studio中选择`File` | `New` | `Project`菜单。
* In the template tree, select `Templates` | `Visual C#` (or `Visual Basic`) | `Web`.
* 在模板树中,选择`Templates` | `Visual C#`(或`Visual Basic`) | `Web`菜单。
在模板树中,选择`Templates` | `Visual C#`(或`Visual Basic`) | `Web`菜单。
* Select the `ASP.NET Web Application` template, give the project a name, and click OK.
* 选择`ASP.NET Web Application`模板输入项目名点击“OK”按钮。
选择`ASP.NET Web Application`模板输入项目名点击“OK”按钮。
* Select the desired ASP.NET 4.5.2 template and click OK.
* 选择自己喜欢的ASP.NET 4.5.2模板点击OK。
选择自己喜欢的ASP.NET 4.5.2模板点击OK。
.l-sub-section
:marked
@ -240,37 +249,33 @@ h2#copy 第三步: 拷贝“快速起步”的文件到ASP.NET项目所在的目
* Click the `Show All Files` button in Solution Explorer to reveal all of the hidden files in the project.
* 在Solution Explorer中点击`Show All Files`按钮,显示项目中所有隐藏文件。
在Solution Explorer中点击`Show All Files`按钮,显示项目中所有隐藏文件。
* Right-click on each folder/file to be included in the project and select `Include in Project`.
Minimally, include the following folder/files:
* 右键点击每个目录和文件,选择`Include in Project`。
右键点击每个目录和文件,选择`Include in Project`。
最少要添加下列文件:
* app folder (answer *No* if asked to search for TypeScript Typings)
* app目录如果询问是否要搜索TypeScript类型回答*No*
app目录如果询问是否要搜索TypeScript类型回答*No*
* styles.css
* styles.css
* index.html
* index.html
* package.json
* package.json
* tsconfig.json
* tsconfig.json
* typings.json
* typings.json
.l-main-section
h2#restore Step 4: Restore the required packages
@ -286,29 +291,30 @@ h2#restore 第四步: 恢复需要的包
<br>This uses `npm` to install all of the packages defined in the `package.json` file.
It may take some time.
* 在Solution Explorer中右键点击`package.json`,选择`Restore Packages`。
在Solution Explorer中右键点击`package.json`,选择`Restore Packages`。
<br>这样Visual Studio会使用`npm`来安装在`package.json`中定义的所有包.
这可能需要花一点时间。
* If desired, open the Output window (`View` | `Output`) to watch the npm commands execute.
* 如果愿意打开Output窗口(`View` | `Output`)来监控npm命令的执行情况。
如果愿意打开Output窗口(`View` | `Output`)来监控npm命令的执行情况。
* Ignore the warnings.
* 忽略所有警告。
忽略所有警告。
* When the restore is finished, a message should say: `npm command completed with exit code 0`.
* 当恢复完成后,将会出现一条消息:`npm command completed with exit code 0`.
当恢复完成后,将会出现一条消息:`npm command completed with exit code 0`.
* Click the `Refresh` icon in Solution Explorer.
* 在Solution Explorer里点击`Refresh`图标。
在Solution Explorer里点击`Refresh`图标。
* **Do not** include the `node_modules` folder in the project. Let it be a hidden project folder.
* **不要**将`node_modules`目录添加到项目中,让它隐藏。
**不要**将`node_modules`目录添加到项目中,让它隐藏。
.l-main-section
h2#build-and-run Step 5: Build and run the app

View File

@ -36,43 +36,43 @@ include ../_util-fns
* [Example: Transitioning between two states](#example-transitioning-between-states)
* [范例:在两个状态之间进行转场(Transition)](#example-transitioning-between-states)
[范例:在两个状态之间进行转场(Transition)](#example-transitioning-between-states)
* [States and transitions](#states-and-transitions)
* [状态与转场](#states-and-transitions)
[状态与转场](#states-and-transitions)
* [Example: Entering and leaving](#example-entering-and-leaving).
* [范例:进场与离场](#example-entering-and-leaving)
[范例:进场与离场](#example-entering-and-leaving)
* [Example: Entering and leaving from different states](#example-entering-and-leaving-from-different-states).
* [范例:从其它状态进场与离场](#example-entering-and-leaving-from-different-states)
[范例:从其它状态进场与离场](#example-entering-and-leaving-from-different-states)
* [Animatable properties and units](#animatable-properties-and-units).
* [可动的(Animatable)属性与单位](#animatable-properties-and-units)
[可动的(Animatable)属性与单位](#animatable-properties-and-units)
* [Automatic property calculation](#automatic-property-calculation).
* [自动属性值计算](#automatic-property-calculation)
[自动属性值计算](#automatic-property-calculation)
* [Animation timing](#animation-timing).
* [动画时间线(Timing)](#animation-timing)
[动画时间线(Timing)](#animation-timing)
* [Multi-step animations with keyframes](#multi-step-animations-with-keyframes).
* [基于关键帧(Keyframes)的多阶段动画](#multi-step-animations-with-keyframes)
[基于关键帧(Keyframes)的多阶段动画](#multi-step-animations-with-keyframes)
* [Parallel animation groups](#parallel-animation-groups).
* [并行动画组(Group)](#parallel-animation-groups)
[并行动画组(Group)](#parallel-animation-groups)
* [Animation callbacks](#animation-callbacks).
* [动画回调](#animation-callbacks)
[动画回调](#animation-callbacks)
.l-sub-section
:marked
@ -226,11 +226,11 @@ figure.image-display
* The `active => *` transition applies when the element's state changes from `active` to anything else.
* 当该元素的状态从`active`变成任何其它状态时,`active => *`转场都会生效。
当该元素的状态从`active`变成任何其它状态时,`active => *`转场都会生效。
* The `* => *` transition applies when *any* change between two states takes place.
* 当在*任意*两个状态之间切换时,`* => *`转场都会生效。
当在*任意*两个状态之间切换时,`* => *`转场都会生效。
figure.image-display
img(src="/resources/images/devguide/animations/ng_animate_transitions_inactive_active_wildcards.png" alt="The wildcard state can be used to match many different transitions at once" width="400")
@ -276,11 +276,11 @@ figure
* Enter: `void => *`
* 进场:`void => *`
进场:`void => *`
* Leave: `* => void`
* 离场:`* => void`
离场:`* => void`
+makeExample('animations/ts/src/app/hero-list-enter-leave.component.ts', 'animationdef')(format=".")
@ -320,19 +320,19 @@ figure
* Inactive hero enter: `void => inactive`
* 非激活英雄进场:`void => inactive`
非激活英雄进场:`void => inactive`
* Active hero enter: `void => active`
* 激活英雄进场:`void => active`
激活英雄进场:`void => active`
* Inactive hero leave: `inactive => void`
* 非激活英雄离场:`inactive => void`
非激活英雄离场:`inactive => void`
* Active hero leave: `active => void`
* 激活英雄离场:`active => void`
激活英雄离场:`active => void`
This gives you fine-grained control over each transition:
@ -373,7 +373,7 @@ figure.image-display
* `50` is the same as saying `'50px'`
* `50`相当于`'50px'`
`50`相当于`'50px'`
## Automatic property calculation
@ -423,15 +423,15 @@ figure
* As a plain number, in milliseconds: `100`
* 作为一个普通数字,以毫秒为单位,如:`100`
作为一个普通数字,以毫秒为单位,如:`100`
* In a string, as milliseconds: `'100ms'`
* 作为一个字符串,以毫秒为单位,如:`'100ms'`
作为一个字符串,以毫秒为单位,如:`'100ms'`
* In a string, as seconds: `'0.1s'`
* 作为一个字符串,以秒为单位,如:`'0.1s'`
作为一个字符串,以秒为单位,如:`'0.1s'`
### Delay
@ -445,7 +445,7 @@ figure
* Wait for 100ms and then run for 200ms: `'0.2s 100ms'`
* 等待100毫秒然后运行200毫秒`'0.2s 100ms'`。
等待100毫秒然后运行200毫秒`'0.2s 100ms'`。
### Easing
@ -461,11 +461,11 @@ figure
* Wait for 100ms and then run for 200ms, with easing: `'0.2s 100ms ease-out'`
* 等待100毫秒然后运行200毫秒并且带缓动`'0.2s 100ms ease-out'`
等待100毫秒然后运行200毫秒并且带缓动`'0.2s 100ms ease-out'`
* Run for 200ms, with easing: `'0.2s ease-in-out'`
* 运行200毫秒并且带缓动`'0.2s ease-in-out'`
运行200毫秒并且带缓动`'0.2s ease-in-out'`
figure
img(src="/resources/images/devguide/animations/animation_timings.gif" alt="Animations with specific timings" align="right" style="width:220px;margin-left:20px" )

View File

@ -13,16 +13,27 @@ block includes
# 目录
* [Directives overview](#directive-overview)
[指令概览](#directive-overview)
* [Build a simple attribute directive](#write-directive)
[创建简单的属性型指令](#write-directive)
* [Apply the attribute directive to an element in a template](#apply-directive)
[应用属性型指令到模板中的元素](#apply-directive)
* [Respond to user-initiated events](#respond-to-user)
[响应用户引发的事件](#respond-to-user)
* [Pass values into the directive with an _@Input_ data binding](#bindings)
[使用数据绑定把值传到指令中](#bindings)
* [Bind to a second property](#second-property)
[绑定第二个属性](#second-property)
@ -570,13 +581,21 @@ figure.image-display
本章介绍了如何:
- [Build an **attribute directive**](#write-directive) that modifies the behavior of an element.
[构建一个**属性型指令**](#write-directive),它用于修改一个元素的行为。
[构建一个**属性型指令**](#write-directive),它用于修改一个元素的行为。
- [Apply the directive](#apply-directive) to an element in a template.
[把一个指令应用到](#apply-directive)模板中的某个元素上。
[把一个指令应用到](#apply-directive)模板中的某个元素上。
- [Respond to **events**](#respond-to-user) that change the directive's behavior.
[响应**事件**](#respond-to-user)以改变指令的行为。
[响应**事件**](#respond-to-user)以改变指令的行为。
- [**Bind** values to the directive](#bindings).
[把值**绑定**到指令中](#bindings)。
[把值**绑定**到指令中](#bindings)。
The final source code follows:

View File

@ -378,7 +378,7 @@ figure.image-display
This will display the hero form when the application component is loaded.
We've also dropped the `name` field from the class body.
1. `template`中只有新元素标签,即组件的`selector`属性。当应用组件被加载时,将显示这个英雄表单。
`template`中只有新元素标签,即组件的`selector`属性。当应用组件被加载时,将显示这个英雄表单。
.l-main-section
:marked

View File

@ -42,6 +42,7 @@ figure
* [Interfaces are optional (technically)](#interface-optional)
[接口是可选的(从技术上说)](#interface-optional)
* [Other Angular lifecycle hooks](#other-lifecycle-hooks)
[其他Angular生命周期钩子](#other-lifecycle-hooks)
@ -484,14 +485,14 @@ a#spy
1. Angular calls hook methods for *directives* as well as components.<br><br>
1. 就像对组件一样Angular也会对*指令*调用这些钩子方法。
就像对组件一样Angular也会对*指令*调用这些钩子方法。
2. A spy directive can provide insight into a DOM object that you cannot change directly.
Obviously you can't touch the implementation of a native `div`.
You can't modify a third party component either.
But you can watch both with a directive.
2. 一个侦探(spy)指令可以让我们在无法直接修改DOM对象实现代码的情况下透视其内部细节。
一个侦探(spy)指令可以让我们在无法直接修改DOM对象实现代码的情况下透视其内部细节。
显然,你不能修改一个原生`div`元素的实现代码。
你同样不能修改第三方组件。
但我们用一个指令就能监视它们了。
@ -547,9 +548,12 @@ figure.image-display
使用`ngOnInit`有两个原因:
1. to perform complex initializations shortly after construction
1. 在构造函数之后马上执行复杂的初始化逻辑
在构造函数之后马上执行复杂的初始化逻辑
1. to set up the component after Angular sets the input properties
1. 在Angular设置完输入属性之后对该组件进行准备。
在Angular设置完输入属性之后对该组件进行准备。
Experienced developers agree that components should be cheap and safe to construct.
@ -874,12 +878,12 @@ figure.image-display
* The *AfterView* hooks concern `ViewChildren`, the child components whose element tags
appear *within* the component's template.
* *AfterView*钩子所关心的是`ViewChildren`,这些子组件的元素标签会出现在该组件的模板*里面*。
*AfterView*钩子所关心的是`ViewChildren`,这些子组件的元素标签会出现在该组件的模板*里面*。
* The *AfterContent* hooks concern `ContentChildren`, the child components that Angular
projected into the component.
* *AfterContent*钩子所关心的是`ContentChildren`这些子组件被Angular投影进该组件中。
*AfterContent*钩子所关心的是`ContentChildren`这些子组件被Angular投影进该组件中。
The following *AfterContent* hooks take action based on changing values in a *content child*
which can only be reached by querying for it via the property decorated with

View File

@ -922,7 +922,7 @@ a#feature-modules
* The app lacks clear boundaries between contact functionality and other application features.
That lack of clarity makes it harder to assign development responsibilities to different teams.
* 该应用在联系人和其它特性区之间缺乏清晰的边界。
该应用在联系人和其它特性区之间缺乏清晰的边界。
这种缺失,导致难以在不同的开发组之间分配职责。
We mitigate these problems with _feature modules_.

View File

@ -87,13 +87,16 @@ a(id="dependencies")
应用程序的`package.json`文件中,`dependencies`区下有三类包:
* ***Features*** - Feature packages give the application framework and utility capabilities.
* ***特性*** - 特性包为应用程序提供了框架和工具方面的能力。
***特性*** - 特性包为应用程序提供了框架和工具方面的能力。
* ***Polyfills*** - Polyfills plug gaps in the browser's JavaScript implementation.
* ***填充(Polyfills)*** - 填充包弥合了不同浏览器上的JavaScript实现方面的差异。
***填充(Polyfills)*** - 填充包弥合了不同浏览器上的JavaScript实现方面的差异。
* ***Other*** - Other libraries that support the application such as `bootstrap` for HTML widgets and styling.
* ***其它*** - 其它库对本应用提供支持,比如`bootstrap`包提供了HTML中的小部件和样式。
***其它*** - 其它库对本应用提供支持,比如`bootstrap`包提供了HTML中的小部件和样式。
.l-main-section
:marked

View File

@ -199,28 +199,28 @@ figure.image-display
* A pipe is a class decorated with pipe metadata.
* 管道是一个带有“管道元数据(pipe metadata)”装饰器的类。
管道是一个带有“管道元数据(pipe metadata)”装饰器的类。
* The pipe class implements the `PipeTransform` interface's `transform` method that
accepts an input value followed by optional parameters and returns the transformed value.
* 这个管道类实现了`PipeTransform`接口的`transform`方法,该方法接受一个输入值和一些可选参数,并返回转换后的值。
这个管道类实现了`PipeTransform`接口的`transform`方法,该方法接受一个输入值和一些可选参数,并返回转换后的值。
* There will be one additional argument to the `transform` method for each parameter passed to the pipe.
Our pipe has one such parameter: the `exponent`.
* 当每个输入值被传给`transform`方法时,还会带上另一个参数,比如我们这个管道中的`exponent`(放大指数)。
当每个输入值被传给`transform`方法时,还会带上另一个参数,比如我们这个管道中的`exponent`(放大指数)。
* We tell Angular that this is a pipe by applying the
`@Pipe` #{_decorator} which we import from the core Angular library.
* 我们通过`@Pipe`#{_decoratorCn}告诉Angular这是一个管道。该#{_decoratorCn}是从Angular的`core`库中引入的。
我们通过`@Pipe`#{_decoratorCn}告诉Angular这是一个管道。该#{_decoratorCn}是从Angular的`core`库中引入的。
* The `@Pipe` #{_decorator} allows us to define the
pipe name that we'll use within template expressions. It must be a valid JavaScript identifier.
Our pipe's name is `exponentialStrength`.
* 这个`@Pipe`#{_decoratorCn}允许我们定义管道的名字这个名字会被用在模板表达式中。它必须是一个有效的JavaScript标识符。
这个`@Pipe`#{_decoratorCn}允许我们定义管道的名字这个名字会被用在模板表达式中。它必须是一个有效的JavaScript标识符。
比如,我们这个管道的名字是`exponentialStrength`。
.l-sub-section

View File

@ -58,125 +58,129 @@ include ../../../_includes/_see-addr-bar
* Setting the [base href](#base-href)
* 设置[页面的基地址base href](#base-href)
设置[页面的基地址base href](#base-href)
* Importing from the [router library](#import)
* 从[路由库](#import)中导入
从[路由库](#import)中导入
* [Configuring the router](#route-config)
* [配置路由器](#route-config)
[配置路由器](#route-config)
* Handling unmatched URLs with a [wildcard route](#wildcard-route)
* 使用[通配符路由](#wildcard-route)处理那些没有匹配上的URL
使用[通配符路由](#wildcard-route)处理那些没有匹配上的URL
* The [link parameters array](#link-parameters-array) that propels router navigation
* 推动路由器导航的[链接参数数组](#link-parameters-array)
推动路由器导航的[链接参数数组](#link-parameters-array)
* Setting the [default route](#default-route) where the application navigates at launch
* [Redirecting](#redirect) from one route to another
* Navigating when the user clicks a data-bound [RouterLink](#router-link)
* 在用户点击绑定到数据的[RouterLink](#router-link)时进行导航
在用户点击绑定到数据的[RouterLink](#router-link)时进行导航
* Navigating under [program control](#navigate)
* 在[程序的控制下](#navigate)进行导航
在[程序的控制下](#navigate)进行导航
* Retrieving information from the [route](#activated-route)
* 从[当前路由获取信息](#activated-route)
从[当前路由获取信息](#activated-route)
* [Animating](#route-animation) transitions for route components
* 为路由组件添加转场[动画](#route-animation)
为路由组件添加转场[动画](#route-animation)
* Navigating [relative](#relative-navigation) to the current URL
* [相对当前URL进行导航](#relative-navigation)
[相对当前URL进行导航](#relative-navigation)
* Toggling css classes for the [active router link](#router-link-active)
* 利用[`router-link-active`指令]切换CSS类(#router-link-active)
利用[`router-link-active`指令]切换CSS类(#router-link-active)
* Embedding critical information in the URL with [route parameters](#route-parameters)
* 用[路由参数](#route-parameters)把重要信息嵌入URL
用[路由参数](#route-parameters)把重要信息嵌入URL
* Providing non-critical information in [optional route parameters](#optional-route-parameters)
* 在[可选路由参数](#optional-route-parameters)中提供非关键信息
在[可选路由参数](#optional-route-parameters)中提供非关键信息
* Refactoring routing into a [routing module](#routing-module)
* 重构路由到[路由模块](#routing-module)
重构路由到[路由模块](#routing-module)
* [Importing routing modules in the proper order](#routing-module-order)
* Add [child routes](#child-routing-component) under a feature section
* 在“特性分区”下添加[子路由](#child-routing-component)
在“特性分区”下添加[子路由](#child-routing-component)
* [Grouping child routes](#component-less-route) without a component
* 不借助组件[对子路由进行分组](#component-less-route)
不借助组件[对子路由进行分组](#component-less-route)
* Displaying [multiple routes](#named-outlets) in separate outlets
* 从一个路由[重定向](#redirect)到另一个路由
从一个路由[重定向](#redirect)到另一个路由
* Confirming or canceling navigation with [guards](#guards)
* 借助[守卫函数](#guards)确认或取消导航
借助[守卫函数](#guards)确认或取消导航
* [CanActivate](#can-activate-guard) to prevent navigation to a route
* 用[CanActivate](#can-activate-guard)阻止导航进某路由
用[CanActivate](#can-activate-guard)阻止导航进某路由
* [CanActivateChild](#can-activate-child-guard) to prevent navigation to a child route
* 用[CanActivateChild](#can-activate-child-guard)阻止导航进某子路由
用[CanActivateChild](#can-activate-child-guard)阻止导航进某子路由
* [CanDeactivate](#can-deactivate-guard) to prevent navigation away from the current route
* 用[CanDeactivate](#can-deactivate-guard)阻止离开当前路由的导航
用[CanDeactivate](#can-deactivate-guard)阻止离开当前路由的导航
* [Resolve](#resolve-guard) to pre-fetch data before activating a route
* 用[Resolve](#resolve-guard)在路由激活之前预先获取数据
用[Resolve](#resolve-guard)在路由激活之前预先获取数据
* [CanLoad](#can-load-guard) to prevent asynchronous routing
* 用[CanLoad](#can-load-guard)阻止异步路由
用[CanLoad](#can-load-guard)阻止异步路由
* Providing optional information across routes with [query parameters](#query-parameters)
* 用[查询参数](#query-parameters)提供跨路由的可选信息
用[查询参数](#query-parameters)提供跨路由的可选信息
* Jumping to anchor elements using a [fragment](#fragment)
* 使用[fragment](#fragment)跳转到其它元素
使用[fragment](#fragment)跳转到其它元素
* Loading feature areas [asynchronously](#asynchronous-routing)
* [异步](#asynchronous-routing)加载特性分区
[异步](#asynchronous-routing)加载特性分区
* Preloading feature areas [during navigation](#preloading)
* [在导航时](#preloading)预加载特性分区
[在导航时](#preloading)预加载特性分区
* Using a [custom strategy](#custom-preloading) to only preload certain features
* 使用[自定义策略](#custom-preloading)来只预加载指定分区
使用[自定义策略](#custom-preloading)来只预加载指定分区
* [Inspect the router's configuration](#inspect-config).
* [审查路由器的配置](#inspect-config)。
[审查路由器的配置](#inspect-config)。
* Choosing the "HTML5" or "hash" [URL style](#browser-url-styles)
* 选择"HTML5"或"hash"[URL风格](#browser-url-styles)
选择"HTML5"或"hash"[URL风格](#browser-url-styles)
.l-main-section
@ -973,31 +977,31 @@ a#redirect
* load the router library
* 加载路由库
加载路由库
* add a nav bar to the shell template with anchor tags, `routerLink` and `routerLinkActive` directives
* 往壳组件的模板中添加一个导航条导航条中有一些A标签、`routerLink`指令和`routerLinkActive`指令
往壳组件的模板中添加一个导航条导航条中有一些A标签、`routerLink`指令和`routerLinkActive`指令
* add a `router-outlet` to the shell template where views will be displayed
* 往壳组件的模板中添加一个`router-outlet`指令,视图将会被显示在那里
往壳组件的模板中添加一个`router-outlet`指令,视图将会被显示在那里
* configure the router module with `RouterModule.forRoot`
* 用`RouterModule.forRoot`配置路由器模块
用`RouterModule.forRoot`配置路由器模块
* set the router to compose "HTML 5" browser URLs
* 设置路由器使其合成“HTML 5”模式的浏览器URL。
设置路由器使其合成“HTML 5”模式的浏览器URL。
* handle invalid routes with a `wildcard` route
* 使用通配符路由来处理无效路由
使用通配符路由来处理无效路由
* navigate to the default route when the app launches with an empty path
* 当应用在空路径下启动时,导航到默认路由
当应用在空路径下启动时,导航到默认路由
The rest of the starter app is mundane, with little interest from a router perspective.
@ -1072,19 +1076,19 @@ a#redirect
* separates routing concerns from other application concerns
* 把路由这个关注点从其它应用类关注点中分离出去
把路由这个关注点从其它应用类关注点中分离出去
* provides a module to replace or remove when testing the application
* 测试特征模块时,可以替换或移除路由模块
测试特征模块时,可以替换或移除路由模块
* provides a well-known location for routing service providers including guards and resolvers
* 为路由服务提供商(包括守卫和解析器等)提供一个共同的地方
为路由服务提供商(包括守卫和解析器等)提供一个共同的地方
* does **not** [declare components](../cookbook/ngmodule-faq.html#routing-module)
* **不要**[声明组件](../cookbook/ngmodule-faq.html#routing-module)
**不要**[声明组件](../cookbook/ngmodule-faq.html#routing-module)
:marked
### Refactor routing configuration into a _routing module_
@ -2316,8 +2320,6 @@ figure.image-display
要导航到`CrisisDetailComponent`以展示`id=2`的危机完整的URL是`/crisis-center/2` (`/crisis-center` + `''` + `'/2'`)。
* 要导航到`CrisisDetailComponent`以展示`id=2`的危机完整的URL是`/crisis-center/2` (`/crisis-center` + `''` + `'/2'`)。
The absolute URL for the latter example, including the `localhost` origin, is
本例子中包含站点部分的绝对URL就是
@ -2613,23 +2615,23 @@ a#clear-secondary-routes
* Perhaps the user is not authorized to navigate to the target component.
* 该用户可能无权导航到目标组件。
该用户可能无权导航到目标组件。
* Maybe the user must login (*authenticate*) first.
* 可能用户得先登录(认证)。
可能用户得先登录(认证)。
* Maybe you should fetch some data before you display the target component.
* 在显示目标组件前,我们可能得先获取某些数据。
在显示目标组件前,我们可能得先获取某些数据。
* You might want to save pending changes before leaving a component.
* 在离开组件前,我们可能要先保存修改。
在离开组件前,我们可能要先保存修改。
* You might ask the user if it's OK to discard pending changes rather than save them.
* 我们可能要询问用户:你是否要放弃本次更改,而不用保存它们?
我们可能要询问用户:你是否要放弃本次更改,而不用保存它们?
You can add _guards_ to the route configuration to handle these scenarios.
@ -2641,11 +2643,11 @@ a#clear-secondary-routes
* if it returns `true`, the navigation process continues
* 如果它返回`true`,导航过程会继续
如果它返回`true`,导航过程会继续
* if it returns `false`, the navigation process stops and the user stays put
* 如果它返回`false`,导航过程会终止,且用户会留在原地。
如果它返回`false`,导航过程会终止,且用户会留在原地。
.l-sub-section
@ -2674,23 +2676,23 @@ a#clear-secondary-routes
1. [CanActivate](../api/router/index/CanActivate-interface.html) to mediate navigation *to* a route.
1. 用[CanActivate](../api/router/index/CanActivate-interface.html)来处理导航*到*某路由的情况。
用[CanActivate](../api/router/index/CanActivate-interface.html)来处理导航*到*某路由的情况。
2. [CanActivateChild](../api/router/index/CanActivateChild-interface.html) to mediate navigation *to* a child route.
2. 用[CanActivateChild](../api/router/index/CanActivateChild-interface.html)处理导航*到*子路由的情况。
用[CanActivateChild](../api/router/index/CanActivateChild-interface.html)处理导航*到*子路由的情况。
3. [CanDeactivate](../api/router/index/CanDeactivate-interface.html) to mediate navigation *away* from the current route.
3. 用[CanDeactivate](../api/router/index/CanDeactivate-interface.html)来处理从当前路由*离开*的情况。
用[CanDeactivate](../api/router/index/CanDeactivate-interface.html)来处理从当前路由*离开*的情况。
4. [Resolve](../api/router/index/Resolve-interface.html) to perform route data retrieval *before* route activation.
4. 用[Resolve](../api/router/index/Resolve-interface.html)在路由激活*之前*获取路由数据。
用[Resolve](../api/router/index/Resolve-interface.html)在路由激活*之前*获取路由数据。
5. [CanLoad](../api/router/index/CanLoad-interface.html) to mediate navigation *to* a feature module loaded _asynchronously_.
5. 用[CanLoad](../api/router/index/CanLoad-interface.html)来处理*异步*导航到某特性模块的情况。
用[CanLoad](../api/router/index/CanLoad-interface.html)来处理*异步*导航到某特性模块的情况。
:marked
You can have multiple guards at every level of a routing hierarchy.
@ -3687,11 +3689,11 @@ a#final-app
* the *path* of the route to the destination component
* 指向目标组件的那个路由的*路径path*
指向目标组件的那个路由的*路径path*
* required and optional route parameters that go into the route URL
* 必备路由参数和可选路由参数它们将进入该路由的URL
必备路由参数和可选路由参数它们将进入该路由的URL
You can bind the `RouterLink` directive to such an array like this:

View File

@ -75,7 +75,7 @@ h2#best-practices 最佳实践
previous versions. Check the Angular [change
log](https://github.com/angular/angular/blob/master/CHANGELOG.md) for security-related updates.
* **及时把Angular包更新到最新版本。**
**及时把Angular包更新到最新版本。**
我们会频繁的更新Angular库这些更新可能会修复之前版本中发现的安全漏洞。查看Angular的[更新记录](https://github.com/angular/angular/blob/master/CHANGELOG.md),了解与安全有关的更新。
* **Don't modify your copy of Angular.**
@ -83,12 +83,12 @@ h2#best-practices 最佳实践
important security fixes and enhancements. Instead, share your Angular improvements with the
community and make a pull request.
* **不要修改你的Angular副本。**
**不要修改你的Angular副本。**
私有的、定制版的Angular往往跟不上最新版本这可能导致你忽略重要的安全修复与增强。反之应该在社区共享你对Angular所做的改进并创建Pull Request。
* **Avoid Angular APIs marked in the documentation as “[_Security Risk_](#bypass-security-apis).”**
* **避免使用本文档中带“[_安全风险_](#bypass-security-apis)”标记的Angular API。**
**避免使用本文档中带“[_安全风险_](#bypass-security-apis)”标记的Angular API。**
.l-main-section
h2#xss Preventing cross-site scripting (XSS)
@ -152,19 +152,19 @@ h2#xss 防范跨站脚本(XSS)攻击
* **HTML** is used when interpreting a value as HTML, for example, when binding to `innerHtml`
* **HTML**值需要被解释为HTML时使用比如当绑定到`innerHTML`时。
**HTML**值需要被解释为HTML时使用比如当绑定到`innerHTML`时。
* **Style** is used when binding CSS into the `style` property
* **样式**值需要作为CSS绑定到`style`属性时使用。
**样式**值需要作为CSS绑定到`style`属性时使用。
* **URL** is used for URL properties such as `<a href>`
* **URL**值需要被用作URL属性时使用比如`<a href>`。
**URL**值需要被用作URL属性时使用比如`<a href>`。
* **Resource URL** is a URL that will be loaded and executed as code, for example, in `<script src>`
* **资源URL**:值需要被当做代码而加载并执行时使用,比如`<script src>`中的URL。
**资源URL**:值需要被当做代码而加载并执行时使用,比如`<script src>`中的URL。
Angular sanitizes untrusted values for the first three items; sanitizing resource URLs is not
possible because they contain arbitrary code. In development mode, Angular prints a console warning

View File

@ -50,15 +50,15 @@ block includes
- [Process the response object](#extract-data).
- [处理响应对象](#extract-data)。
[处理响应对象](#extract-data)。
- [Always handle errors](#error-handling).
- [总是处理错误](#error-handling)。
[总是处理错误](#error-handling)。
- [Send data to the server](#update).
- [把数据发送到服务器](#update)。
[把数据发送到服务器](#update)。
- [Fall back to promises](#promises).
@ -66,17 +66,15 @@ block includes
- [Cross-Origin Requests: Wikipedia example](#cors).
- [跨域请求Wikipedia 示例](#cors)。
[跨域请求Wikipedia 示例](#cors)。
<ul>
<li> [Search parameters](#search-parameters).</li>
- [Search parameters](#search-parameters).
<li> [设置查询参数](#search-parameters)。</li>
[设置查询参数](#search-parameters)。
<li> [More fun with observables](#more-observables).</li>
- [More fun with observables](#more-observables).
<li> [限制搜索词输入频率](#more-observables)。</li>
</ul>
[限制搜索词输入频率](#more-observables)。
- [Guarding against Cross-Site Request Forgery](#xsrf).

View File

@ -16,15 +16,25 @@ block includes
在本章中,我们将:
- [learn what structural directives are](#definition)
- [学习什么是结构型(structural)指令](#definition)
[学习什么是结构型(structural)指令](#definition)
- [study *ngIf*](#ngIf)
- [研究*ngIf*](#ngIf)
[研究*ngIf*](#ngIf)
- [discover the `<template>` element](#template)
- [`<template>`元素揭秘](#template)
[`<template>`元素揭秘](#template)
- [understand the asterisk (\*) in **ngFor*](#asterisk)
- [理解**ngFor*中的星号(\*)](#asterisk)
[理解**ngFor*中的星号(\*)](#asterisk)
- [write our own structural directive](#unless)
- [写我们自己的结构型指令](#unless)
[写我们自己的结构型指令](#unless)
Try the <live-example></live-example>.
@ -40,11 +50,16 @@ block includes
Angular指令可分为三种
1. Components
1. 组件
组件
1. Attribute directives
1. 属性型指令
属性型指令
1. Structural directives
1. 结构型指令
结构型指令
The *Component* is really a directive with a template.
It's the most common of the three directives and we write lots of them as we build our application.
@ -378,20 +393,20 @@ block unless-intro
* import the `Directive` decorator.
* 导入`Directive`装饰器。
导入`Directive`装饰器。
* add a CSS **attribute selector** (in brackets) that identifies our directive.
* 添加一个CSS**属性选择器**(括号中),来标记出我们的指令。
添加一个CSS**属性选择器**(括号中),来标记出我们的指令。
* specify the name of the public `input` property for binding
(typically the name of the directive itself).
* 指定`input`属性用于绑定的公开名称(通常就是指令自己的名字)。
指定`input`属性用于绑定的公开名称(通常就是指令自己的名字)。
* apply the decorator to our implementation class.
* 把这个装饰器应用到我们的实现类上。
把这个装饰器应用到我们的实现类上。
Here is how we begin:

View File

@ -47,11 +47,11 @@ a#top
* [Test a component with a service dependency](#component-with-dependency)
- [test doubles](#service-test-doubles)
- [测试复制品](#service-test-doubles)
[测试复制品](#service-test-doubles)
- [get the injected service](#get-injected-service)
- [获取注入的服务](#get-injected-service)
[获取注入的服务](#get-injected-service)
- [_TestBed.get_](#testbed-get)
* [Test a component with an async service](#component-with-async-service)
@ -82,11 +82,11 @@ a#top
* [Test a _RouterOutlet_ component](#router-outlet-component)
- [stubbing unneeded components](#stub-component)
- [模拟不需要的组件](#stub-component)
[模拟不需要的组件](#stub-component)
- [Stubbing the _RouterLink_](#router-link-stub)
- [模拟_RouterLink_](#router-link-stub)
[模拟_RouterLink_](#router-link-stub)
- [_By.directive_ and injected directives](#by-directive)
* ["Shallow" component tests with *NO\_ERRORS\_SCHEMA*](#shallow-component-test)
@ -96,17 +96,17 @@ a#top
* [Isolated unit tests](#isolated-unit-tests "Unit testing without the Angular testing utilities")
- [Services](#isolated-service-tests)
- [服务](#isolated-service-tests)
[服务](#isolated-service-tests)
- [Pipes](#isolated-pipe-tests)
- [管道](#isolated-pipe-tests)
[管道](#isolated-pipe-tests)
- [Components](#isolated-component-tests)
* [Angular testing utility APIs](#atu-apis)
- [Stand-alone functions](#atu-apis): `async`, `fakeAsync`, etc.
- [独立函数](#atu-apis): `async`, `fakeAsync`, etc.
[独立函数](#atu-apis): `async`, `fakeAsync`, etc.
- [_TestBed_](#testbed-class-summary)
@ -154,18 +154,18 @@ a#testing-intro
1. They **guard** against changes that break existing code (“regressions”).
1. 测试**守护**由于代码变化而打破已有代码(“回归”)的情况。
测试**守护**由于代码变化而打破已有代码(“回归”)的情况。
1. They **clarify** what the code does both when used as intended and when faced with deviant conditions.
1. 不管代码被正确使用还是错误使用,测试程序起到**澄清**代码的作用。
不管代码被正确使用还是错误使用,测试程序起到**澄清**代码的作用。
1. They **reveal** mistakes in design and implementation.
Tests shine a harsh light on the code from many angles.
When a part of the application seems hard to test, the root cause is often a design flaw,
something to cure now rather than later when it becomes expensive to fix.
1. 测试程序**暴露**设计和实现可能出现的错误。测试程序从很多角度为代码亮出警报灯。当应用程序很难被测试时,
测试程序**暴露**设计和实现可能出现的错误。测试程序从很多角度为代码亮出警报灯。当应用程序很难被测试时,
其根本原因一般都是设计缺陷,这种缺陷最好立刻被修正,不要等到它变得很难被修复的时候才行动。
This chapter assumes that you know something about testing. Don't worry if you don't.
@ -438,31 +438,31 @@ a#test-debugging
- Reveal the karma browser window (hidden earlier).
- 显示`Karma`的浏览器窗口(之前被隐藏了)。
显示`Karma`的浏览器窗口(之前被隐藏了)。
- Click the "DEBUG" button; it opens a new browser tab and re-runs the tests
- 点击“DEBUG”按钮它打开一页新浏览器标签并重新开始运行测试程序
点击“DEBUG”按钮它打开一页新浏览器标签并重新开始运行测试程序
- Open the browser's “Developer Tools” (F12 or Ctrl-Shift-I).
- 打开浏览器的“Developer Tools”(F12或者Ctrl-Shift-I)。
打开浏览器的“Developer Tools”(F12或者Ctrl-Shift-I)。
- Pick the "sources" section
- 选择“sources”页
选择“sources”页
- Open the `1st.spec.ts` test file (Ctrl-P, then start typing the name of the file).
- 打开`1st.spec.ts`测试文件Ctrl-P, 然后输入文件名字)。
打开`1st.spec.ts`测试文件Ctrl-P, 然后输入文件名字)。
- Set a breakpoint in the test
- 在测试程序中设置断点。
在测试程序中设置断点。
- Refresh the browser … and it stops at the breakpoint.
- 刷新浏览器...然后它就会停在断点上。
刷新浏览器...然后它就会停在断点上。
figure.image-display
img(src='/resources/images/devguide/testing/karma-1st-spec-debug.png' style="width:700px;" alt="Karma debugging")
@ -1310,15 +1310,15 @@ a#component-with-input-output
1. Test it as used by `DashboardComponent`
1. 把它当作被`DashbaordComponent`使用的组件来测试
把它当作被`DashbaordComponent`使用的组件来测试
1. Test it as a stand-alone component
1. 把它当作独立的组件来测试
把它当作独立的组件来测试
1. Test it as used by a substitute for `DashboardComponent`
1. 把它当作被`DashbaordComponent`的替代组件使用的组件来测试
把它当作被`DashbaordComponent`的替代组件使用的组件来测试
A quick look at the `DashboardComponent` constructor discourages the first approach:
@ -1529,11 +1529,11 @@ a#component-inside-test-host
1. It _declares_ both the `DashboardHeroComponent` and the `TestHostComponent`.
1. 它同时**声明**了`DashbaordComponent`和`TestHostComponent`。
它同时**声明**了`DashbaordComponent`和`TestHostComponent`。
1. It _creates_ the `TestHostComponent` instead of the `DashboardHeroComponent`.
1. 它**创建**了`TestHostComponent`,而非`DashboardHeroComponent`。
它**创建**了`TestHostComponent`,而非`DashboardHeroComponent`。
The `fixture` returned by `createComponent` holds an instance of `TestHostComponent` instead of an instance of `DashboardHeroComponent`.
@ -1627,11 +1627,11 @@ a#inject
1. an array of Angular dependency injection tokens
1. 一列数组包含了Angular依赖注入令牌
一列数组包含了Angular依赖注入令牌
1. a test function whose parameters correspond exactly to each item in the injection token array
1. 一个测试函数,它的参数与注入令牌数组里的每个项目严格的一一对应。
一个测试函数,它的参数与注入令牌数组里的每个项目严格的一一对应。
.callout.is-important
header inject uses the TestBed Injector
@ -1760,27 +1760,26 @@ a#stub-observable
* The stub implements only two of the `ActivatedRoute` capabilities: `params` and `snapshot.params`.
* 这个stub类只实现`ActivatedRoute`的两个功能:`params`和`snapshot.params`。
这个stub类只实现`ActivatedRoute`的两个功能:`params`和`snapshot.params`。
* <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md" target="_blank">_BehaviorSubject_</a>
drives the stub's `params` _Observable_ and returns the same value to every `params` subscriber until it's given a new value.
* <a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md" target="_blank">_BehaviorSubject_</a>
驱使这个stub类的`params`可观察对象,并为每个`params`的订阅者返回同样的值,直到它接受到新值。
<a href="https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md" target="_blank">_BehaviorSubject_</a>驱使这个stub类的`params`可观察对象,并为每个`params`的订阅者返回同样的值,直到它接受到新值。
* The `HeroDetailComponent` chain its expressions to this stub `params` _Observable_ which is now under the tester's control.
* `HeroDetailComponent`链接它的表达式到这个stub类的`params`可观察对象,该对象现在被测试者的控制之下。
`HeroDetailComponent`链接它的表达式到这个stub类的`params`可观察对象,该对象现在被测试者的控制之下。
* Setting the `testParams` property causes the `subject` to push the assigned value into `params`.
That triggers the `HeroDetailComponent` _params_ subscription, described above, in the same way that navigation does.
* 设置`testParams`属性导致`subject`将指定的值推送进`params`。
它触发上面描述过的`HeroDetailComponent`的`params`订阅,和导航的方式一样。
设置`testParams`属性导致`subject`将指定的值推送进`params`。它触发上面描述过的`HeroDetailComponent`的`params`订阅,和导航的方式一样。
* Setting the `testParams` property also updates the stub's internal value for the `snapshot` property to return.
* 设置`testParams`属性同时更新这个stub类内部值用于`snapshot`属性的返回。
设置`testParams`属性同时更新这个stub类内部值用于`snapshot`属性的返回。
.l-sub-section(style="margin-left:30px")
:marked
The [_snapshot_](router.html#snapshot "Router guide: snapshot") is another popular way for components to consume route parameters.
@ -1865,19 +1864,19 @@ figure.image-display
* to wait until a `hero` arrives before `*ngIf` allows any element in DOM
* 在`*ngIf`允许元素进入DOM之前等待`hero`的到来
在`*ngIf`允许元素进入DOM之前等待`hero`的到来
* element references for the title name span and name input-box to inspect their values
* 标题名字span和名字输入框元素的引用用来检查它们的值
标题名字span和名字输入框元素的引用用来检查它们的值
* two button references to click
* 两个按钮的引用,用来点击
两个按钮的引用,用来点击
* spies on component and router methods
* 刺探spy组件和路由器的方法
刺探spy组件和路由器的方法
Even a small form such as this one can produce a mess of tortured conditional setup and CSS element selection.
@ -1946,19 +1945,19 @@ a#import-module
* `NgModel` and friends in the `FormsModule` enable two-way data binding
* `FormsModule`里的`NgModel`和其它,来进行双向数据绑定
`FormsModule`里的`NgModel`和其它,来进行双向数据绑定
* The `TitleCasePipe` from the `shared` folder
* `shared`目录里的`TitleCasePipe`
`shared`目录里的`TitleCasePipe`
* Router services (which these tests are stubbing)
* 一些路由器服务测试程序将stub伪造它们
一些路由器服务测试程序将stub伪造它们
* Hero data access services (also stubbed)
* 英雄数据访问服务同样被stub伪造了
英雄数据访问服务同样被stub伪造了
One approach is to configure the testing module from the individual pieces as in this example:
@ -2212,16 +2211,16 @@ a#stub-component
* `BannerComponent` is simple and harmless to use as is.
* 原样使用`BannerComponent`非常简单而且无害。
原样使用`BannerComponent`非常简单而且无害。
* The real `WelcomeComponent` has an injected service. `WelcomeStubComponent` is a placeholder with no service to worry about.
* 真实的`WelcomeComponent`有被注入的服务。`WelcomeStubComponent`是无服务的替代品。
真实的`WelcomeComponent`有被注入的服务。`WelcomeStubComponent`是无服务的替代品。
* The real `RouterOutlet` is complex and errors easily.
The `RouterOutletStubComponent` (in `testing/router-stubs.ts`) is safely inert.
* 真实的`RouterOutlet`很复杂而且容易出错。
真实的`RouterOutlet`很复杂而且容易出错。
`testing/router-stubs.ts`里的`RouterOutletStubComponent`是安全的替代品。
The component stubs are essential.
@ -2269,12 +2268,12 @@ a#inject-directive
1. You can locate elements _by directive_, using `By.directive`, not just by css selectors.
1. 你还可以按指令定位元素,使用`By.directive`而不仅仅是通过CSS选择器。
你还可以按指令定位元素,使用`By.directive`而不仅仅是通过CSS选择器。
1. You can use the component's dependency injector to get an attached directive because
Angular always adds attached directives to the component's injector.
1. 你可以使用组件的依赖注入器来获取附加的指令因为Angular总是将附加组件添加到组件的注入器中。
你可以使用组件的依赖注入器来获取附加的指令因为Angular总是将附加组件添加到组件的注入器中。
a#app-component-tests
:marked
@ -2462,14 +2461,13 @@ figure.image-display
* The `By.directive` predicate is a great way to get the elements that have this directive _when their element types are unknown_.
* 当**已知元素类型**时,`By.directive`是一种获取拥有这个指令的元素的好方法。
当**已知元素类型**时,`By.directive`是一种获取拥有这个指令的元素的好方法。
* The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:not" target="_blank">`:not` pseudo-class</a>
in `By.css('h2:not([highlight])')` helps find `<h2>` elements that _do not_ have the directive.
`By.css('*:not([highlight])')` finds _any_ element that does not have the directive.
* `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])')`查找**所有**不带该指令的元素。
`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])')`查找**所有**不带该指令的元素。
// Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future?
* `DebugElement.styles` affords access to element styles even in the absence of a real browser, thanks to the `DebugElement` abstraction.
@ -2480,8 +2478,7 @@ figure.image-display
The test for the default color uses the injector of the 2nd `<h2>` to get its `HighlightDirective` instance
and its `defaultColor`.
* Angular将指令添加到它的元素的注入器中。
默认颜色的测试程序使用第二个`<h2>`的注入器来获取它的`HighlightDirective`实例以及它的`defaultColor`。
Angular将指令添加到它的元素的注入器中。默认颜色的测试程序使用第二个`<h2>`的注入器来获取它的`HighlightDirective`实例以及它的`defaultColor`。
// Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future?
@ -2515,19 +2512,19 @@ a#isolated-unit-tests
* import from the Angular test libraries
* 从Angular测试库导入
从Angular测试库导入
* configure a module
* 配置模块
配置模块
* prepare dependency injection `providers`
* 准备依赖注入`providers`
准备依赖注入`providers`
* call `inject` or `async` or `fakeAsync`
* 调用`inject`,或者`async`,或者`fakeAsync`
调用`inject`,或者`async`,或者`fakeAsync`
They do
@ -2535,15 +2532,15 @@ a#isolated-unit-tests
* exhibit standard, Angular-agnostic testing techniques
* 使用标准的、与Angular无关的测试技巧
使用标准的、与Angular无关的测试技巧
* create instances directly with `new`
* 直接使用`new`创建实例
直接使用`new`创建实例
* substitute test doubles (stubs, spys, and mocks) for the real dependencies.
* 用测试复制品stubspy和mock替代真正的依赖
用测试复制品stubspy和mock替代真正的依赖
.callout.is-important
header Write both kinds of tests
@ -3474,15 +3471,15 @@ a#query-predicate
* `By.all` - return all elements
* `By.all` - 返回所有元素
`By.all` - 返回所有元素
* `By.css(selector)` - return elements with matching CSS selectors.
* `By.css(selector)` - 返回符合CSS选择器的元素。
`By.css(selector)` - 返回符合CSS选择器的元素。
* `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.
* `By.directive(directive)` - 返回Angular能匹配一个指令类实例的所有元素。
`By.directive(directive)` - 返回Angular能匹配一个指令类实例的所有元素。
+makeExample('testing/ts/src/app/hero/hero-list.component.spec.ts', 'by', 'src/app/hero/hero-list.component.spec.ts')(format=".")
@ -3682,23 +3679,23 @@ a(href="#top").to-top 返回顶部
- Such tests are easy to find
- 这样的测试程序很容易被找到
这样的测试程序很容易被找到
- You see at a glance if a part of our application lacks tests.
- 你可以一眼看出应用程序的那些部分缺乏测试程序。
你可以一眼看出应用程序的那些部分缺乏测试程序。
- Nearby tests can reveal how a part works in context.
- 临近的测试程序可以展示代码是如何在上下文中工作的
临近的测试程序可以展示代码是如何在上下文中工作的
- When you move the source (inevitable), you remember to move the test.
- 当你移动代码(无可避免)时,你记得一起移动测试程序
当你移动代码(无可避免)时,你记得一起移动测试程序
- When you rename the source file (inevitable), you remember to rename the test file.
- 当你重命名源代码文件(无可避免),你记得重命名测试程序文件。
当你重命名源代码文件(无可避免),你记得重命名测试程序文件。
.l-hr

View File

@ -18,11 +18,11 @@ include ../_util-fns
* [tsconfig.json](#tsconfig) - TypeScript compiler configuration.
* [tsconfig.json](#tsconfig) - TypeScript编译器配置。
[tsconfig.json](#tsconfig) - TypeScript编译器配置。
* [typings](#typings) - TypesScript declaration files.
* [typings](#typings) - TypesScript类型声明文件。
[typings](#typings) - TypesScript类型声明文件。
a(id="tsconfig")
.l-main-section
@ -178,13 +178,12 @@ code-example(format=".")
* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework
* [jasmine](http://jasmine.github.io/)是Jasmine测试框架的类型定义
[jasmine](http://jasmine.github.io/)是Jasmine测试框架的类型定义
* [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *nodejs* environment;
You can view an example in the [webpack](./webpack.html) page.
* [node](https://www.npmjs.com/package/@types/node)是为了在*nodejs*环境中引用对象的代码提供的类型定义。
在[webpack](./webpack.html)页面可以看到例子。
[node](https://www.npmjs.com/package/@types/node)是为了在*nodejs*环境中引用对象的代码提供的类型定义。在[webpack](./webpack.html)页面可以看到例子。
QuickStart doesn't require these typings but many of the samples do.

View File

@ -39,51 +39,97 @@ include ../_util-fns
Angular `upgrade`模块的设计目标就是让你渐进、无缝的完成升级。
1. [Preparation](#preparation)
1. [准备工作](#preparation)
[准备工作](#preparation)
1. [Follow the Angular Style Guide](#follow-the-angular-style-guide)
1. [遵循Angular风格指南](#follow-the-angular-style-guide)
[遵循Angular风格指南](#follow-the-angular-style-guide)
2. [Using a Module Loader](#using-a-module-loader)
2. [使用模块加载器](#using-a-module-loader)
[使用模块加载器](#using-a-module-loader)
3. [Migrating to TypeScript](#migrating-to-typescript)
3. [迁移到TypeScript](#migrating-to-typescript)
[迁移到TypeScript](#migrating-to-typescript)
4. [Using Component Directives](#using-component-directives)
4. [使用组件型指令](#using-component-directives)
[使用组件型指令](#using-component-directives)
2. [Upgrading with The Upgrade Module](#upgrading-with-the-upgrade-module)
2. [通过升级模块进行升级](#upgrading-with-the-upgrade-module)
[通过升级模块进行升级](#upgrading-with-the-upgrade-module)
1. [How The Upgrade Module Works](#how-the-upgrade-module-works)
1. [升级模块是如何工作的](#how-the-upgrade-module-works)
[升级模块是如何工作的](#how-the-upgrade-module-works)
2. [Bootstrapping hybrid applications](#bootstrapping-hybrid-applications)
2. [引导混合(hybrid)应用](#bootstrapping-hybrid-applications)
[引导混合(hybrid)应用](#bootstrapping-hybrid-applications)
3. [Using Angular Components from AngularJS Code](#using-angular-components-from-angularjs-code)
3. [从AngularJS的代码中使用Angular的组件](#using-angular-components-from-angularjs-code)
[从AngularJS的代码中使用Angular的组件](#using-angular-components-from-angularjs-code)
4. [Using AngularJS Component Directives from Angular Code](#using-angularjs-component-directives-from-angular-components-from-angularjs-code)
4. [从Angular的代码中使用AngularJS的组件](#using-angularjs-component-directives-from-angular-components-from-angularjs-code)
[从Angular的代码中使用AngularJS的组件](#using-angularjs-component-directives-from-angular-components-from-angularjs-code)
5. [Projecting AngularJS Content into Angular Components](#projecting-angularjs-content-into-angular-components)
5. [把AngularJS的内容投影(project)进Angular组件中](#projecting-angularjs-content-into-angular-components)
[把AngularJS的内容投影(project)进Angular组件中](#projecting-angularjs-content-into-angular-components)
6. [Transcluding Angular Content into AngularJS Component Directives](#transcluding-angular-content-into-angularjs-component-directives)
6. [把Angular的内容透传(transclude)到AngularJS的组件型指令中](#transcluding-angular-content-into-angularjs-component-directives)
[把Angular的内容透传(transclude)到AngularJS的组件型指令中](#transcluding-angular-content-into-angularjs-component-directives)
7. [Making AngularJS Dependencies Injectable to Angular](#making-angularjs-dependencies-injectable-to-angular)
7. [让AngularJS提供的依赖可以被注入到Angular](#making-angularjs-dependencies-injectable-to-angular)
[让AngularJS提供的依赖可以被注入到Angular](#making-angularjs-dependencies-injectable-to-angular)
8. [Making Angular Dependencies Injectable to AngularJS](#making-angular-dependencies-injectable-to-angularjs)
8. [让Angular提供的依赖可以被注入到AngularJS](#making-angular-dependencies-injectable-to-angularjs)
[让Angular提供的依赖可以被注入到AngularJS](#making-angular-dependencies-injectable-to-angularjs)
3. [PhoneCat Upgrade Tutorial](#phonecat-upgrade-tutorial)
3. [PhoneCat准备工作教程](#phonecat-preparation-tutorial)
[PhoneCat准备工作教程](#phonecat-preparation-tutorial)
1. [Switching to TypeScript](#switching-to-typescript)
1. [切换到TypeScript](#switching-to-typescript)
[切换到TypeScript](#switching-to-typescript)
2. [Installing Angular](#installing-angular)
2. [安装Angular](#installing-angular)
[安装Angular](#installing-angular)
3. [Bootstrapping a hybrid PhoneCat](#bootstrapping-a-hybrid-phonecat)
3. [引导AngularJS+2的混合版PhoneCat](#bootstrapping-a-hybrid-phonecat)
[引导AngularJS+2的混合版PhoneCat](#bootstrapping-a-hybrid-phonecat)
4. [Upgrading the Phone service](#upgrading-the-phone-service)
4. [升级Phone服务](#upgrading-the-phone-service)
[升级Phone服务](#upgrading-the-phone-service)
5. [Upgrading Components](#upgrading-components)
5. [升级组件](#upgrading-components)
[升级组件](#upgrading-components)
6. [Switching To The Angular Router And Bootstrap](#switching-to-the-angular-router-and-bootstrap)
6. [切换到Angular的路由器并引导](#switching-to-the-angular-router-and-bootstrap)
[切换到Angular的路由器并引导](#switching-to-the-angular-router-and-bootstrap)
7. [Saying Goodbye to AngularJS](#saying-goodbye-to-angularjs)
7. [和AngularJS说再见](#saying-goodbye-to-angularjs)
[和AngularJS说再见](#saying-goodbye-to-angularjs)
3. [Appendix: Upgrading PhoneCat Tests](#appendix-upgrading-phonecat-tests)
3. [附录升级PhoneCat测试](#appendix-upgrading-phonecat-tests)
[附录升级PhoneCat测试](#appendix-upgrading-phonecat-tests)
.l-main-section
:marked
@ -133,7 +179,7 @@ include ../_util-fns
them between languages and frameworks one at a time. In this example application,
each controller, component, service, and filter is in its own source file.
* [单一规则](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#single-responsibility)
[单一规则](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#single-responsibility)
规定每个文件应该只放一个组件。这不仅让组件更容易浏览和查找,而且还将允许我们逐个迁移它们的语言和框架。
在这个范例程序中,每个控制器、工厂和过滤器都在它自己的源文件中。
@ -142,7 +188,7 @@ include ../_util-fns
rules define similar principles on a higher level of abstraction: Different parts of the
application should reside in different directories and Angular modules.
* [按特性分目录的结构](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模块中。
[按特性分目录的结构](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模块中。
When an application is laid out feature per feature in this way, it can also be
migrated one feature at a time. For applications that don't already look like
@ -218,25 +264,25 @@ include ../_util-fns
(which are really ECMAScript 2015 imports and exports) can be used to organize
code into modules.
* 对那些使用了模块加载器的程序TypeScript的导入和导出(这实际上是ECMAScript 2015导入和导出)可以把代码组织到模块中。
对那些使用了模块加载器的程序TypeScript的导入和导出(这实际上是ECMAScript 2015导入和导出)可以把代码组织到模块中。
* Type annotations can be gradually added to existing functions and variables
to pin down their types and get benefits like build-time error checking,
great autocompletion support and inline documentation.
* 类型注解可以逐步添加到已存在的函数和变量上,以固定它们的类型,并获得其优点:比如编译期错误检查、更好的支持自动完成,以及内联式文档等。
类型注解可以逐步添加到已存在的函数和变量上,以固定它们的类型,并获得其优点:比如编译期错误检查、更好的支持自动完成,以及内联式文档等。
* JavaScript features new to ES2015, like arrow functions, `let`s and `const`s,
default function parameters, and destructuring assignments can also be gradually
added to make the code more expressive.
* 那些ES2015中新增的特性比如箭头函数、`let`、`const`、默认函数参数、解构赋值等也能逐渐添加进来,让代码更有表现力。
那些ES2015中新增的特性比如箭头函数、`let`、`const`、默认函数参数、解构赋值等也能逐渐添加进来,让代码更有表现力。
* Services and controllers can be turned into *classes*. That way they'll be a step
closer to becoming Angular service and component classes, which will make our
life easier once we do the upgrade.
* 服务和控制器可以转成*类*。这样我们就能一步步接近Angular的服务和组件类了这样等到我们开始升级时也会更简单。
服务和控制器可以转成*类*。这样我们就能一步步接近Angular的服务和组件类了这样等到我们开始升级时也会更简单。
#### Using Component Directives
### 使用组件型指令
@ -264,24 +310,25 @@ include ../_util-fns
* `restrict: 'E'`. Components are usually used as elements.
* `restrict: 'E'`。组件通常会以元素的方式使用。
`restrict: 'E'`。组件通常会以元素的方式使用。
* `scope: {}` - an isolate scope. In Angular, components are always isolated
from their surroundings, and we should do this in AngularJS too.
* `scope: {}` - 一个独立作用域。在Angular中组件永远是从它们的环境中被隔离出来的在AngularJS中我们也应该这么做。
`scope: {}` - 一个独立作用域。在Angular中组件永远是从它们的环境中被隔离出来的在AngularJS中我们也应该这么做。
* `bindToController: {}`. Component inputs and outputs should be bound
to the controller instead of using the `$scope`.
* `bindToController: {}`。组件的输入和输出应该绑定到控制器,而不是`$scope`。
`bindToController: {}`。组件的输入和输出应该绑定到控制器,而不是`$scope`。
* `controller` and `controllerAs`. Components have their own controllers.
* `controller`和`controllerAs`。组件有它们自己的控制器。
`controller`和`controllerAs`。组件有它们自己的控制器。
* `template` or `templateUrl`. Components have their own templates.
* `template`或`templateUrl`。组件有它们自己的模板。
`template`或`templateUrl`。组件有它们自己的模板。
Component directives may also use the following attributes:
@ -289,12 +336,12 @@ include ../_util-fns
* `transclude: true`, if the component needs to transclude content from elsewhere.
* `transclude: true`:如果组件需要从其它地方透传内容,就设置它。
`transclude: true`:如果组件需要从其它地方透传内容,就设置它。
* `require`, if the component needs to communicate with some parent component's
controller.
* `require`:如果组件需要和父组件的控制器通讯,就设置它。
`require`:如果组件需要和父组件的控制器通讯,就设置它。
Component directives **may not** use the following attributes:
@ -302,18 +349,18 @@ include ../_util-fns
* `compile`. This will not be supported in Angular.
* `compile`。它在Angular中将不再被支持。
`compile`。它在Angular中将不再被支持。
* `replace: true`. Angular never replaces a component element with the
component template. This attribute is also deprecated in AngularJS.
* `replace: true`。Angular永远不会用组件模板替换一个组件元素。这个特性在AngularJS中也同样不建议使用了。
`replace: true`。Angular永远不会用组件模板替换一个组件元素。这个特性在AngularJS中也同样不建议使用了。
* `priority` and `terminal`. While AngularJS components may use these,
they are not used in Angular and it is better not to write code
that relies on them.
* `priority`和`terminal`。虽然AngularJS的组件可能使用这些但它们在Angular中已经没用了并且最好不要再写依赖它们的代码。
`priority`和`terminal`。虽然AngularJS的组件可能使用这些但它们在Angular中已经没用了并且最好不要再写依赖它们的代码。
An AngularJS component directive that is fully aligned with the Angular
architecture may look something like this:
@ -332,15 +379,15 @@ include ../_util-fns
* It requires less boilerplate code.
* 它需要更少的样板代码。
它需要更少的样板代码。
* It enforces the use of component best practices like `controllerAs`.
* 它强制使用组件的最佳实践,比如`controllerAs`。
它强制使用组件的最佳实践,比如`controllerAs`。
* It has good default values for directive attributes like `scope` and `restrict`.
* 对于指令中像`scope`和`restrict`这样的属性,它有良好的默认值。
对于指令中像`scope`和`restrict`这样的属性,它有良好的默认值。
The component directive example from above looks like this when expressed
using the component API:
@ -454,7 +501,7 @@ table
*root injector* and available to all components. They will always have
*string tokens* - the same tokens that they have in AngularJS.
* 通过升级它们我们就能让那些在AngularJS中能被注入的服务在Angular的代码中可用。
通过升级它们我们就能让那些在AngularJS中能被注入的服务在Angular的代码中可用。
在框架之间共享的是服务的同一个单例对象。在Angular中这些外来服务总是被放在*根注入器*中,并可用于所有组件。
它们总是具有*字符串令牌* —— 跟它们在AngularJS中的令牌相同。
@ -464,7 +511,7 @@ table
When we register a downgrade, we explicitly specify a *string token* that we want to
use in AngularJS.
* 通过降级它们我们也能让那些在Angular中能被注入的服务在AngularJS的代码中可用。
通过降级它们我们也能让那些在Angular中能被注入的服务在AngularJS的代码中可用。
只有那些来自Angular根注入器的服务才能被降级。同样的在框架之间共享的是同一个单例对象。
当我们注册一个要降级的服务时要明确指定一个打算在AngularJS中使用的*字符串令牌*。
@ -496,12 +543,12 @@ figure.image-display
owned by AngularJS, Angular treats it as if it didn't exist,
and vice versa.
1. DOM中的每个元素都只能被两个框架之一拥有。另一个框架会忽略它。
DOM中的每个元素都只能被两个框架之一拥有。另一个框架会忽略它。
如果一个元素被AngularJS拥有Angular就会当它不存在。反之亦然。
2. The root of the application *is always an AngularJS template*.
2. 应用的根节点*总是来自AngularJS中的模板*。
应用的根节点*总是来自AngularJS中的模板*。
So a hybrid application begins life as an AngularJS application,
and it is AngularJS that processes its root template. Angular then steps
@ -525,12 +572,13 @@ figure.image-display
using an Angular component, or an Angular template using an
AngularJS component.
1. 通过使用来自另一个框架的组件AngularJS的模板中用到了Angular的组件或者Angular的模板中使用了AngularJS的组件。
通过使用来自另一个框架的组件AngularJS的模板中用到了Angular的组件或者Angular的模板中使用了AngularJS的组件。
2. By transcluding or projecting content from the other framework. The
`UpgradeModule` bridges the related concepts of AngularJS transclusion
and Angular content projection together.
2. 通过透传(transclude)或投影(project)来自另一个框架的内容。`UpgradeModule`牵线搭桥把AngularJS的透传概念和Angular的内容投影概念关联起来。
通过透传(transclude)或投影(project)来自另一个框架的内容。`UpgradeModule`牵线搭桥把AngularJS的透传概念和Angular的内容投影概念关联起来。
figure.image-display
img(src="/resources/images/devguide/upgrade/dom.png" alt="DOM element ownership in a hybrid application" width="500")
@ -590,14 +638,14 @@ code-example(language="html" escape="html").
This is true whether the event originated in AngularJS or Angular code.
The zone triggers Angular change detection after every event.
* 应用中发生的每件事都运行在Angular的zone里。
应用中发生的每件事都运行在Angular的zone里。
无论事件发生在AngularJS还是Angular的代码中都是如此。
* The `UpgradeModule` will invoke the AngularJS `$rootScope.$apply()` after
every turn of the Angular zone. This also triggers AngularJS change
detection after every event.
* `UpgradeModule`将在每一次离开Angular zone时调用AngularJS的`$rootScope.$apply()`。这样也就同样会在每个事件之后触发AngularJS的变更检测。
`UpgradeModule`将在每一次离开Angular zone时调用AngularJS的`$rootScope.$apply()`。这样也就同样会在每个事件之后触发AngularJS的变更检测。
figure.image-display
img(src="/resources/images/devguide/upgrade/change_detection.png" alt="Change detection in a hybrid application" width="600")
@ -1284,7 +1332,7 @@ figure
* Each component, service, and filter is in its own source file, as per the
[Rule of 1](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#single-responsibility).
* 每个组件、服务和过滤器都在它自己的源文件中 —— 就像[单一规则](https://github.com/johnpapa/angular-styleguide#single-responsibility)所要求的。
每个组件、服务和过滤器都在它自己的源文件中 —— 就像[单一规则](https://github.com/johnpapa/angular-styleguide#single-responsibility)所要求的。
* The `core`, `phone-detail`, and `phone-list` modules are each in their
own subdirectory. Those subdirectories contain the JavaScript code as well as
@ -1293,7 +1341,7 @@ figure
and [Modularity](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#modularity)
rules.
* `core`、`phone-detail`和`phone-list`模块都在它们自己的子目录中。那些子目录除了包含HTML模板之外还包含JavaScript代码它们共同完成一个特性。
`core`、`phone-detail`和`phone-list`模块都在它们自己的子目录中。那些子目录除了包含HTML模板之外还包含JavaScript代码它们共同完成一个特性。
这是[按特性分目录的结构](https://github.com/johnpapa/angular-styleguide#style-y152)
和[模块化](https://github.com/johnpapa/angular-styleguide#modularity)规则所要求的。
@ -1301,7 +1349,7 @@ figure
found, as described in the rules for
[Organizing Tests](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y197).
* 单元测试都和应用代码在一起,它们很容易找到。就像规则
单元测试都和应用代码在一起,它们很容易找到。就像规则
[组织测试文件](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y197)中要求的那样。
:marked
@ -1554,10 +1602,11 @@ code-example(format="").
* Add Angular and the other new dependencies to `package.json`
* 把Angular和其它新依赖添加到`package.json`中
把Angular和其它新依赖添加到`package.json`中
* The SystemJS configuration file `systemjs.config.js` to the project root directory.
* 把SystemJS的配置文件`systemjs.config.js`添加到项目的根目录。
把SystemJS的配置文件`systemjs.config.js`添加到项目的根目录。
Once these are done, run:
@ -1738,9 +1787,12 @@ code-example(format="").
并且让它能帮助控制器从服务器上加载电话信息。目前,它是用`ngResource`实现的,我们用它做两件事:
* For loading the list of all phones into the phone list component
* 把所有电话的列表加载到电话列表组件中。
把所有电话的列表加载到电话列表组件中。
* For loading the details of a single phone into the phone detail component.
* 把一台电话的详情加载到电话详情组件中。
把一台电话的详情加载到电话详情组件中。
We can replace this implementation with an Angular service class, while
keeping our controllers in AngularJS land.
@ -2014,12 +2066,12 @@ code-example(format="").
* We've removed the `$ctrl.` prefix from all expressions.
* 我们从所有表达式中移除了`$ctrl.`前缀。
我们从所有表达式中移除了`$ctrl.`前缀。
* Just like we did in the phone list, we've replaced `ng-src` with property
bindings for the standard `src` property.
* 正如我们在电话列表中做过的那样,我们把`ng-src`替换成了标准的`src`属性绑定。
正如我们在电话列表中做过的那样,我们把`ng-src`替换成了标准的`src`属性绑定。
* We're using the property binding syntax around `ng-class`. Though Angular
does have [a very similar `ngClass`](../guide/template-syntax.html#directives)
@ -2027,18 +2079,18 @@ code-example(format="").
In Angular we always specify in the template when an attribute's value is
a property expression, as opposed to a literal string.
* 我们在`ng-class`周围使用了属性绑定语法。虽然Angular中有一个
我们在`ng-class`周围使用了属性绑定语法。虽然Angular中有一个
和AngularJS中[非常相似的`ngClass`](../guide/template-syntax.html#directives)指令,
但是它的值不会神奇的作为表达式进行计算。在Angular中模板中的属性(Attribute)值总是被作为
属性(Property)表达式计算,而不是作为字符串字面量。
* We've replaced `ng-repeat`s with `*ngFor`s.
* 我们把`ng-repeat`替换成了`*ngFor`。
我们把`ng-repeat`替换成了`*ngFor`。
* We've replaced `ng-click` with an event binding for the standard `click`.
* 我们把`ng-click`替换成了一个到标准`click`事件的绑定。
我们把`ng-click`替换成了一个到标准`click`事件的绑定。
* We've wrapped the whole template in an `ngIf` that causes it only to be
rendered when there is a phone present. We need this because when the component
@ -2047,7 +2099,7 @@ code-example(format="").
when we try to refer to properties on undefined objects. We need to be explicit
about cases where this is expected.
* 我们把整个模板都包裹进了一个`ngIf`中,这导致只有当存在一个电话时它才会渲染。我们必须这么做,
我们把整个模板都包裹进了一个`ngIf`中,这导致只有当存在一个电话时它才会渲染。我们必须这么做,
是因为组件首次加载时我们还没有`phone`变量,这些表达式就会引用到一个不存在的值。
和AngularJS不同当我们尝试引用未定义对象上的属性时Angular中的表达式不会默默失败。
我们必须明确指出这种情况是我们所期望的。
@ -2113,11 +2165,11 @@ code-example(format="").
1. Switch to the Angular router.
1. 切换到Angular路由器。
切换到Angular路由器。
1. Bootstrap as a pure Angular app.
1. 作为纯Angular应用进行引导。
作为纯Angular应用进行引导。
#### Switch to the Angular router
#### 切换到Angular路由器

View File

@ -28,15 +28,15 @@ style.
* [Entries and outputs](#entries-outputs)
* [入口与输出](#entries-outputs)
[入口与输出](#entries-outputs)
* [Loaders](#loaders)
* [加载器](#loaders)
[加载器](#loaders)
* [Plugins](#plugins)
* [插件](#plugins)
[插件](#plugins)
[Configuring Webpack](#configure-webpack)
@ -44,19 +44,19 @@ style.
* [Common configuration](#common-configuration)
* [公共配置](#common-configuration)
[公共配置](#common-configuration)
* [Development configuration](#development-configuration)
* [开发环境配置](#development-configuration)
[开发环境配置](#development-configuration)
* [Production configuration](#production-configuration)
* [生产环境配置](#production-configuration)
[生产环境配置](#production-configuration)
* [Test configuration](#test-configuration)
* [测试环境配置](#test-configuration)
[测试环境配置](#test-configuration)
[Trying it out](#try)
@ -724,26 +724,26 @@ a#bundle-ts
* There are no &lt;script&gt; or &lt;link&gt; tags in the `index.html`.
The `HtmlWebpackPlugin` inserts them dynamically at runtime.
* 在`index.html`中没有&lt;script&gt;或&lt;link&gt;标签。
在`index.html`中没有&lt;script&gt;或&lt;link&gt;标签。
`HtmlWebpackPlugin`会在运行时动态插入它们。
* The `AppComponent` in `app.component.ts` imports the application-wide css with a simple `import` statement.
* `app.component.ts`中的`AppComponent`类简单的用一个`import`语句导入了应用级css。
`app.component.ts`中的`AppComponent`类简单的用一个`import`语句导入了应用级css。
* The `AppComponent` itself has its own html template and css file. WebPack loads them with calls to `require()`.
Webpack stashes those component-scoped files in the `app.js` bundle too.
You don't see those calls in the source code;
they're added behind the scenes by the `angular2-template-loader` plug-in.
* `AppComponent`组件本身有它自己的HTML模板和CSS文件。Webpack通过调用`require()`方法加载它们。Webpack还把那些组件内部的文件打包进了`app.js`中。
`AppComponent`组件本身有它自己的HTML模板和CSS文件。Webpack通过调用`require()`方法加载它们。Webpack还把那些组件内部的文件打包进了`app.js`中。
我们在自己的源码中看不到这些调用,这些工作是由幕后的`angular2-template-loader`插件完成的。
* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.
The application imports these modules too; they'd be duplicated in the `app.js` bundle
if the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `app.js`.
* `vendor.ts`由`import`提供商依赖的语句组成,它最终决定了`vender.js`的内容。
`vendor.ts`由`import`提供商依赖的语句组成,它最终决定了`vender.js`的内容。
本应用也导入这些模块,如果没有`CommonsChunkPlugin`插件检测出这种重叠,并且把它们从`app.js`中移除,它们就会同时出现在`app.js`包中。
<a id="conclusions"></a>

View File

@ -809,7 +809,7 @@ block observable-transformers
Our simple example prints the error to the console; a real life application should do better.
Then we return an observable containing an empty array to clear the search result.
* `catch`拦截失败的可观察对象。这个简单的例子中只是把错误信息打印到控制台(但实际的应用需要做更多事),然后返回一个包含空数组的可观察对象,以清空搜索结果。
`catch`拦截失败的可观察对象。这个简单的例子中只是把错误信息打印到控制台(但实际的应用需要做更多事),然后返回一个包含空数组的可观察对象,以清空搜索结果。
a#rxjs-imports
:marked

View File

@ -18,7 +18,7 @@ var sourceVisible = localStorage.getItem('source-visible') === 'true';
* @param container
*/
function processContainer(container) {
var nodes = container.querySelectorAll('p,h1,h2,h3,h4,h5,h6,header,li,a');
var nodes = container.querySelectorAll('p,h1,h2,h3,h4,h5,h6,header,a');
nodes.forEach((node)=> {
if (isTranslation(node.textContent)) {
var $translated = $(node);