不再使用li进行切换,而是全面转换到li内嵌p元素
This commit is contained in:
parent
e11efe4aef
commit
7711fa6557
|
@ -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).
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)`
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -73,12 +73,14 @@ code-example(format='')
|
|||
[Title](../api/platform/browser/Title-class.html)服务是一个简单的类,提供了一个API,用来获取和设置当前HTML文档的标题。
|
||||
|
||||
* `getTitle() : string` — Gets the title of the current HTML document.
|
||||
|
||||
* `getTitle(): string` —— 获取当前HTML文档的标题。
|
||||
|
||||
`getTitle(): string` —— 获取当前HTML文档的标题。
|
||||
|
||||
|
||||
* `setTitle( newTitle : string )` — 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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" )
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
* 用测试复制品(stub,spy和mock)替代真正的依赖
|
||||
用测试复制品(stub,spy和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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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路由器
|
||||
|
|
|
@ -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 <script> or <link> tags in the `index.html`.
|
||||
The `HtmlWebpackPlugin` inserts them dynamically at runtime.
|
||||
|
||||
* 在`index.html`中没有<script>或<link>标签。
|
||||
在`index.html`中没有<script>或<link>标签。
|
||||
`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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue