fix: 修正自动翻译结果
This commit is contained in:
parent
38af562aff
commit
0e0ffa481e
|
@ -3,6 +3,7 @@
|
|||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0-rc.0.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
|
|
@ -5,13 +5,17 @@ The following changes from vanilla Phonecat are applied:
|
|||
|
||||
* The TypeScript config file shown in the guide is `tsconfig.ajs.json` instead
|
||||
of the default, because we don't want to enable `noImplicitAny` for migration.
|
||||
|
||||
* Karma config for unit tests is in karma.conf.ajs.js because the boilerplate
|
||||
Karma config is not compatible with the way AngularJS tests need to be run.
|
||||
The shell script run-unit-tests.sh can be used to run the unit tests.
|
||||
|
||||
* Instead of using Bower, AngularJS and its dependencies are fetched from a CDN
|
||||
in index.html and karma.conf.ajs.js.
|
||||
|
||||
* E2E tests have been moved to the parent directory, where `gulp run-e2e-tests` can
|
||||
discover and run them along with all the other examples.
|
||||
|
||||
* Most of the phone JSON and image data removed in the interest of keeping
|
||||
repo weight down. Keeping enough to retain testability of the app.
|
||||
|
||||
|
|
|
@ -6,12 +6,16 @@ The following changes from vanilla Phonecat are applied:
|
|||
* Karma config for unit tests is in karma.conf.ajs.js because the boilerplate
|
||||
Karma config is not compatible with the way AngularJS tests need to be run.
|
||||
The shell script run-unit-tests.sh can be used to run the unit tests.
|
||||
|
||||
* Also for the Karma shim, there is a `karma-test-shim.1.js` file which isn't
|
||||
used but is shown in the test appendix.
|
||||
|
||||
* Instead of using Bower, AngularJS and its dependencies are fetched from a CDN
|
||||
in index.html and karma.conf.ajs.js.
|
||||
|
||||
* E2E tests have been moved to the parent directory, where `run-e2e-tests` can
|
||||
discover and run them along with all the other examples.
|
||||
|
||||
* Most of the phone JSON and image data removed in the interest of keeping
|
||||
repo weight down. Keeping enough to retain testability of the app.
|
||||
|
||||
|
|
|
@ -6,8 +6,10 @@ The following changes from vanilla Phonecat are applied:
|
|||
* Karma config for unit tests is in karma.conf.ng1.js because the boilerplate
|
||||
Karma config is not compatible with the way tests in this project need to be run.
|
||||
The shell script run-unit-tests.sh can be used to run the unit tests.
|
||||
|
||||
* E2E tests have been moved to the parent directory, where `run-e2e-tests` can
|
||||
discover and run them along with all the other examples.
|
||||
|
||||
* Most of the phone JSON and image data removed in the interest of keeping
|
||||
repo weight down. Keeping enough to retain testability of the app.
|
||||
|
||||
|
|
|
@ -15,4 +15,3 @@
|
|||
</div>
|
||||
|
||||
<aio-file-not-found-search></aio-file-not-found-search>
|
||||
|
||||
|
|
|
@ -259,12 +259,10 @@ Here are two sample components and the `AdComponent` interface for reference:
|
|||
最终的广告栏是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/dynamic-component-loader/ads.gif" alt="Ads">
|
||||
|
||||
</figure>
|
||||
|
||||
See the <live-example name="dynamic-component-loader"></live-example>.
|
||||
|
||||
|
||||
参见<live-example name="cb-dynamic-component-loader"></live-example>。
|
||||
参见<live-example name="cb-dynamic-component-loader"></live-example>。
|
||||
|
|
|
@ -261,12 +261,10 @@ The final form looks like this:
|
|||
完整的表单是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/dynamic-form/dynamic-form.png" alt="Dynamic-Form">
|
||||
|
||||
</figure>
|
||||
|
||||
[Back to top](guide/dynamic-form#top)
|
||||
|
||||
|
||||
[回到顶部](guide/dynamic-form#top)
|
||||
[回到顶部](guide/dynamic-form#top)
|
||||
|
|
|
@ -32,6 +32,7 @@ The following is an example of specifying a bootstrapped component,
|
|||
`AppComponent`, in a basic `app.module.ts`:
|
||||
|
||||
```typescript
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
|
@ -45,6 +46,7 @@ The following is an example of specifying a bootstrapped component,
|
|||
providers: [],
|
||||
bootstrap: [AppComponent] // bootstrapped entry component
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
A bootstrapped component is an entry component
|
||||
|
@ -69,12 +71,14 @@ The second kind of entry component occurs in a route definition like
|
|||
this:
|
||||
|
||||
```typescript
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: CustomerListComponent
|
||||
}
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
A route definition refers to a component by its type with `component: CustomerListComponent`.
|
||||
|
|
|
@ -42,6 +42,7 @@ root project directory. Replace `CustomerDashboard` with the
|
|||
name of your module. You can omit the "Module" suffix from the name because the CLI appends it:
|
||||
|
||||
```sh
|
||||
|
||||
ng generate module CustomerDashboard
|
||||
|
||||
```
|
||||
|
@ -49,6 +50,7 @@ ng generate module CustomerDashboard
|
|||
This causes the CLI to create a folder called `customer-dashboard` with a file inside called `customer-dashboard.module.ts` with the following contents:
|
||||
|
||||
```typescript
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
|
@ -59,6 +61,7 @@ import { CommonModule } from '@angular/common';
|
|||
declarations: []
|
||||
})
|
||||
export class CustomerDashboardModule { }
|
||||
|
||||
```
|
||||
|
||||
The structure of an NgModule is the same whether it is a root module or a feature module. In the CLI generated feature module, there are two JavaScript import statements at the top of the file: the first imports `NgModule`, which, like the root module, lets you use the `@NgModule` decorator; the second imports `CommonModule`, which contributes many common directives such as `ngIf` and `ngFor`. Feature modules import `CommonModule` instead of `BrowserModule`, which is only imported once in the root module. `CommonModule` only contains information for common directives such as `ngIf` and `ngFor` which are needed in most templates, whereas `BrowserModule` configures the Angular app for the browser which needs to be done only once.
|
||||
|
@ -67,6 +70,7 @@ The `declarations` array is available for you to add declarables, which
|
|||
are components, directives, and pipes that belong exclusively to this particular module. To add a component, enter the following command at the command line where `customer-dashboard` is the directory where the CLI generated the feature module and `CustomerDashboard` is the name of the component:
|
||||
|
||||
```sh
|
||||
|
||||
ng generate component customer-dashboard/CustomerDashboard
|
||||
|
||||
```
|
||||
|
@ -112,9 +116,7 @@ Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-da
|
|||
Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
||||
|
||||
</figure>
|
||||
|
||||
<hr />
|
||||
|
|
|
@ -49,7 +49,7 @@ The following example exports `NgModel` into a variable called `name`:
|
|||
|
||||
Note the following:
|
||||
|
||||
请注意以下几点:
|
||||
要注意的有两点:
|
||||
|
||||
* The `<input>` element carries the HTML validation attributes: `required` and `minlength`. It
|
||||
also carries a custom validator directive, `forbiddenName`. For more
|
||||
|
@ -164,7 +164,7 @@ for the template.
|
|||
|
||||
这个例子添加了一些getter方法。在响应式表单中,我们通常会通过它所属的控件组(FormGroup)的`get`方法来访问表单控件,但有时候为模板定义一些getter作为简短形式。
|
||||
|
||||
If you look at the template for the name input again, it is fairly similar to the template-driven example.
|
||||
If you look at the template for the name input again, it is fairly similar to the template-driven example.
|
||||
|
||||
如果我们到模板中找到name输入框,就会发现它和模板驱动的例子很相似。
|
||||
|
||||
|
@ -331,4 +331,4 @@ set the color of each form control's border.
|
|||
**You can run the <live-example></live-example> to see the complete reactive and template-driven example code.**
|
||||
|
||||
|
||||
**你可以运行<live-example></live-example>来查看完整的响应式和模板驱动表单的代码。**
|
||||
**你可以运行<live-example></live-example>来查看完整的响应式和模板驱动表单的代码。**
|
||||
|
|
|
@ -89,9 +89,7 @@ You'll learn to build a template-driven form that looks like this:
|
|||
我们将学习构建如下的“模板驱动”表单:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/hero-form-1.png" alt="Clean Form">
|
||||
|
||||
</figure>
|
||||
|
||||
The *Hero Employment Agency* uses this form to maintain personal information about heroes.
|
||||
|
@ -109,9 +107,7 @@ If you delete the hero name, the form displays a validation error in an attentio
|
|||
如果删除了英雄的名字,表单就会用醒目的样式把验证错误显示出来。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/hero-form-2.png" alt="Invalid, Name Required">
|
||||
|
||||
</figure>
|
||||
|
||||
Note that the *Submit* button is disabled, and the "required" bar to the left of the input control changes from green to red.
|
||||
|
@ -496,9 +492,7 @@ Running the app right now would be disappointing.
|
|||
如果立即运行此应用,你将会失望。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/hero-form-3.png" alt="Early form with no binding">
|
||||
|
||||
</figure>
|
||||
|
||||
You don't see hero data because you're not binding to the `Hero` yet.
|
||||
|
@ -599,9 +593,7 @@ At some point it might look like this:
|
|||
某一瞬间,它可能是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/ng-model-in-action.png" alt="ngModel in action">
|
||||
|
||||
</figure>
|
||||
|
||||
The diagnostic is evidence that values really are flowing from the input box to the model and
|
||||
|
@ -675,9 +667,7 @@ If you run the app now and change every hero model property, the form might disp
|
|||
如果现在运行本应用,修改 Hero 模型的每个属性,表单是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/ng-model-in-action-2.png" alt="ngModel in action">
|
||||
|
||||
</figure>
|
||||
|
||||
The diagnostic near the top of the form
|
||||
|
@ -845,9 +835,7 @@ The actions and effects are as follows:
|
|||
动作和它对应的效果如下:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/control-state-transitions-anim.gif" alt="Control State Transition">
|
||||
|
||||
</figure>
|
||||
|
||||
You should see the following transitions and class names:
|
||||
|
@ -855,9 +843,7 @@ You should see the following transitions and class names:
|
|||
我们会看到下列转换及其类名:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/ng-control-class-changes.png" alt="Control state transitions">
|
||||
|
||||
</figure>
|
||||
|
||||
The `ng-valid`/`ng-invalid` pair is the most interesting, because you want to send a
|
||||
|
@ -881,9 +867,7 @@ on the left of the input box:
|
|||
可以在输入框的左侧添加带颜色的竖条,用于标记必填字段和无效输入:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/validity-required-indicator.png" alt="Invalid Form">
|
||||
|
||||
</figure>
|
||||
|
||||
You achieve this effect by adding these class definitions to a new `forms.css` file
|
||||
|
@ -919,9 +903,7 @@ When the user deletes the name, the form should look like this:
|
|||
当用户删除姓名时,应该是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/forms/name-required-error.png" alt="Name required">
|
||||
|
||||
</figure>
|
||||
|
||||
To achieve this effect, extend the `<input>` tag with the following:
|
||||
|
@ -1291,4 +1273,3 @@ Here’s the code for the final version of the application:
|
|||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
|
|
@ -37,61 +37,133 @@ of some of the things they contain:
|
|||
|
||||
<tr>
|
||||
|
||||
<td><code>BrowserModule</code></td>
|
||||
<td>
|
||||
|
||||
<td><code>@angular/platform-browser</code></td>
|
||||
<code>BrowserModule</code>
|
||||
|
||||
<td>When you want to run your app in a browser</td>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
<code>@angular/platform-browser</code>
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
When you want to run your app in a browser
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td><code>CommonModule</code></td>
|
||||
<td>
|
||||
|
||||
<td><code>@angular/common</code></td>
|
||||
<code>CommonModule</code>
|
||||
|
||||
<td>When you want to use <code>NgIf</code>, <code>NgFor</code></td>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
<code>@angular/common</code>
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
When you want to use <code>NgIf</code>, <code>NgFor</code>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td><code>FormsModule</code></td>
|
||||
<td>
|
||||
|
||||
<td><code>@angular/forms</code></td>
|
||||
<code>FormsModule</code>
|
||||
|
||||
<td>When you build template driven forms (includes <code>NgModel</code>)</td>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
<code>@angular/forms</code>
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
When you build template driven forms (includes <code>NgModel</code>)
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td><code>ReactiveFormsModule</code></td>
|
||||
<td>
|
||||
|
||||
<td><code>@angular/forms</code></td>
|
||||
<code>ReactiveFormsModule</code>
|
||||
|
||||
<td>When building reactive forms</td>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
<code>@angular/forms</code>
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
When building reactive forms
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td><code>RouterModule</code></td>
|
||||
<td>
|
||||
|
||||
<td><code>@angular/router</code></td>
|
||||
<code>RouterModule</code>
|
||||
|
||||
<td>For Routing and when you want to use <code>RouterLink</code>,<code>.forRoot()</code>, and <code>.forChild()</code></td>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
<code>@angular/router</code>
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
For Routing and when you want to use <code>RouterLink</code>,<code>.forRoot()</code>, and <code>.forChild()</code>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td><code>HttpClientModule</code></td>
|
||||
<td>
|
||||
|
||||
<td><code>@angular/common/http</code></td>
|
||||
<code>HttpClientModule</code>
|
||||
|
||||
<td>When you to talk to a server</td>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
<code>@angular/common/http</code>
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
When you to talk to a server
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
|
@ -106,6 +178,7 @@ or your feature module as appropriate, and list them in the `@NgModule`
|
|||
`app.module.ts`.
|
||||
|
||||
```typescript
|
||||
|
||||
/* import modules so that AppModule can access them */
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
@ -123,6 +196,7 @@ import { AppComponent } from './app.component';
|
|||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
```
|
||||
|
||||
The imports at the top of the array are JavaScript import statements
|
||||
|
@ -147,9 +221,7 @@ If you do import `BrowserModule` into a lazy loaded feature module,
|
|||
Angular returns an error telling you to use `CommonModule` instead.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/frequent-ngmodules/browser-module-error.gif" width=750 alt="BrowserModule error">
|
||||
|
||||
</figure>
|
||||
|
||||
<hr />
|
||||
|
|
|
@ -20,6 +20,7 @@ unexpected definitions.
|
|||
[S](guide/glossary#S) [T](guide/glossary#T) [U](guide/glossary#U) [V](guide/glossary#V) [W](guide/glossary#W) [X](guide/glossary#X) [Y](guide/glossary#Y) [Z](guide/glossary#Z)
|
||||
|
||||
{@a A}
|
||||
|
||||
{@a aot}
|
||||
|
||||
## Ahead-of-time (AOT) compilation
|
||||
|
@ -276,31 +277,31 @@ Angular 有一个非常强大的数据绑定框架,具有各种数据绑定操
|
|||
|
||||
* [Interpolation](guide/template-syntax#interpolation).
|
||||
|
||||
[插值表达式 (interpolation)](guide/template-syntax#interpolation)。
|
||||
[插值表达式 (interpolation)](guide/template-syntax#interpolation)。
|
||||
|
||||
* [Property binding](guide/template-syntax#property-binding).
|
||||
|
||||
[property 绑定 (property binding)](guide/template-syntax#property-binding)。
|
||||
[property 绑定 (property binding)](guide/template-syntax#property-binding)。
|
||||
|
||||
* [Event binding](guide/template-syntax#event-binding).
|
||||
|
||||
[事件绑定 (event binding)](guide/template-syntax#event-binding)。
|
||||
[事件绑定 (event binding)](guide/template-syntax#event-binding)。
|
||||
|
||||
* [Attribute binding](guide/template-syntax#attribute-binding).
|
||||
|
||||
[attribute 绑定 (attribute binding)](guide/template-syntax#attribute-binding)。
|
||||
[attribute 绑定 (attribute binding)](guide/template-syntax#attribute-binding)。
|
||||
|
||||
* [Class binding](guide/template-syntax#class-binding).
|
||||
|
||||
[CSS 类绑定 (class binding)](guide/template-syntax#class-binding)。
|
||||
[CSS 类绑定 (class binding)](guide/template-syntax#class-binding)。
|
||||
|
||||
* [Style binding](guide/template-syntax#style-binding).
|
||||
|
||||
[样式绑定 (style binding)](guide/template-syntax#style-binding)。
|
||||
[样式绑定 (style binding)](guide/template-syntax#style-binding)。
|
||||
|
||||
* [Two-way data binding with ngModel](guide/template-syntax#ngModel).
|
||||
|
||||
[基于 ngModel 的双向数据绑定 (Two-way data binding with ngModel)](guide/template-syntax#ngModel)。
|
||||
[基于 ngModel 的双向数据绑定 (Two-way data binding with ngModel)](guide/template-syntax#ngModel)。
|
||||
|
||||
{@a decorator}
|
||||
|
||||
|
@ -333,11 +334,13 @@ Angular 使用自己的一套装饰器来实现应用程序各部件之间的相
|
|||
`@Component`装饰器中省略的参数对象会包含与组件有关的元数据。
|
||||
|
||||
```
|
||||
|
||||
@Component({...})
|
||||
export class AppComponent {
|
||||
constructor(@Inject('SpecialFoo') public foo:Foo) {}
|
||||
@Input() name:string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The scope of a decorator is limited to the language feature
|
||||
|
@ -346,7 +349,7 @@ classes that follow it in the file.
|
|||
|
||||
装饰器的作用域会被限制在它所装饰的语言特性。
|
||||
在同一文件中,装饰器不会“泄露”到它后面的其它类。
|
||||
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
Always include parentheses `()` when applying a decorator.
|
||||
|
@ -1238,4 +1241,4 @@ Learn more about zones in this
|
|||
[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).
|
||||
|
||||
|
||||
更多信息,见 [Brian Ford 的视频](https://www.youtube.com/watch?v=3IqtmUscE_U)。
|
||||
更多信息,见 [Brian Ford 的视频](https://www.youtube.com/watch?v=3IqtmUscE_U)。
|
||||
|
|
|
@ -64,11 +64,8 @@ open simultaneously.
|
|||
`HeroesListComponent`组件保存和管理着`HeroTaxReturnComponent`的多个实例。
|
||||
下图展示了当`HeroesCardComponent`的三个 `HeroTaxReturnComponent` 实例同时展开时的三级组件树状态。
|
||||
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/dependency-injection/component-hierarchy.png" alt="injector tree">
|
||||
|
||||
</figure>
|
||||
|
||||
### Injector bubbling
|
||||
|
@ -215,9 +212,7 @@ Each tax return component has the following characteristics:
|
|||
能把所做的修改保存到它的报税单中,或者放弃它们。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/dependency-injection/hid-heroes-anim.gif" alt="Heroes in action">
|
||||
|
||||
</figure>
|
||||
|
||||
One might suppose that the `HeroTaxReturnComponent` has logic to manage and restore changes.
|
||||
|
@ -325,9 +320,7 @@ Component (B) is the parent of another component (C) that defines its own, even
|
|||
组件B是另一个组件C的父组件,而组件C又定义了自己的,*更特殊的*`CarService`提供商。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/dependency-injection/car-components.png" alt="car components">
|
||||
|
||||
</figure>
|
||||
|
||||
Behind the scenes, each component sets up its own injector with zero, one, or more providers defined for that component itself.
|
||||
|
@ -341,9 +334,7 @@ its injector produces an instance of `Car` resolved by injector (C) with an `Eng
|
|||
当我们在最深层的组件C解析`Car`的实例时,它使用注入器C解析生成了一个`Car`的实例,使用注入器B解析了`Engine`,而`Tires`则是由根注入器A解析的。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/dependency-injection/injector-tree.png" alt="car injector tree">
|
||||
|
||||
</figure>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -354,4 +345,3 @@ which you can review and download from the <live-example></live-example>.
|
|||
*车辆*场景下的代码位于`car.components.ts`和`car.services.ts`文件中,这个例子你可以在<live-example></live-example>查看和下载。
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -454,12 +454,14 @@ Subscribing twice results in two HTTP requests.
|
|||
比如,下列代码会使用同样的数据发送两次同样的 POST 请求:
|
||||
|
||||
```javascript
|
||||
|
||||
const req = http.get<Heroes>('/api/heroes');
|
||||
// 0 requests made - .subscribe() not called.
|
||||
req.subscribe();
|
||||
// 1 request made.
|
||||
req.subscribe();
|
||||
// 2 requests made.
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
@ -592,7 +594,7 @@ The `switchMap()` operator has three important characteristics.
|
|||
it cancels that request and sends a new one.
|
||||
|
||||
3. It returns service responses in their original request order, even if the
|
||||
server returns them out of order.
|
||||
server returns them out of order.
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
@ -631,9 +633,11 @@ In this sense, each interceptor is fully capable of handling the request entirel
|
|||
Most interceptors inspect the request on the way in and forward the (perhaps altered) request to the `handle()` method of the `next` object which implements the [`HttpHandler`](api/common/http/HttpHandler) interface.
|
||||
|
||||
```javascript
|
||||
|
||||
export abstract class HttpHandler {
|
||||
abstract handle(req: HttpRequest<any>): Observable<HttpEvent<any>>;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Like `intercept()`, the `handle()` method transforms an HTTP request into an `Observable` of [`HttpEvents`](#httpevents) which ultimately include the server's response. The `intercept()` method could inspect that observable and alter it before returning it to the caller.
|
||||
|
@ -743,9 +747,12 @@ If an interceptor could modify the original request object, the re-tried operati
|
|||
TypeScript will prevent you from setting `HttpRequest` readonly properties.
|
||||
|
||||
```javascript
|
||||
|
||||
// Typescript disallows the following assignment because req.url is readonly
|
||||
req.url = req.url.replace('http://', 'https://');
|
||||
|
||||
```
|
||||
|
||||
To alter the request, clone it first and modify the clone before passing it to `next.handle()`.
|
||||
You can clone and modify the request in a single step as in this example.
|
||||
|
||||
|
@ -764,7 +771,9 @@ The `readonly` assignment guard can't prevent deep updates and, in particular,
|
|||
it can't prevent you from modifying a property of a request body object.
|
||||
|
||||
```javascript
|
||||
|
||||
req.body.name = req.body.name.trim(); // bad idea!
|
||||
|
||||
```
|
||||
|
||||
If you must mutate the request body, copy it first, change the copy,
|
||||
|
@ -787,9 +796,11 @@ If you set the cloned request body to `null`, Angular knows you intend to clear
|
|||
这种克隆一个请求并设置一组新的请求头的操作非常常见,因此有了一种快捷写法:
|
||||
|
||||
```javascript
|
||||
|
||||
newReq = req.clone({ ... }); // body not mentioned => preserve original body
|
||||
newReq = req.clone({ body: undefined }); // preserve original body
|
||||
newReq = req.clone({ body: null }); // clear the body
|
||||
|
||||
```
|
||||
|
||||
#### Set default headers
|
||||
|
@ -885,6 +896,7 @@ the cached response, by-passing the `next` handler (and all other interceptors d
|
|||
If a cachable request is not in cache, the code calls `sendRequest`.
|
||||
|
||||
{@a send-request}
|
||||
|
||||
<code-example
|
||||
path="http/src/app/http-interceptors/caching-interceptor.ts"
|
||||
region="send-request">
|
||||
|
@ -1082,10 +1094,7 @@ At the end, tests may verify that the app has made no unexpected requests.
|
|||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
You can run
|
||||
|
||||
<live-example stackblitz="specs">these sample tests</live-example>
|
||||
|
||||
You can run <live-example stackblitz="specs">these sample tests</live-example>
|
||||
in a live coding environment.
|
||||
|
||||
The tests described in this guide are in `src/testing/http-client.spec.ts`.
|
||||
|
@ -1197,4 +1206,3 @@ Call `request.error()` with an `ErrorEvent` instead of `request.flush()`, as in
|
|||
linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ import from `@angular/common/locales/extra`. An error message informs you when t
|
|||
<div class="l-sub-section">
|
||||
|
||||
This document refers to a unit of translatable text as "text," a "message", or a
|
||||
"text message."
|
||||
"text message."
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -244,7 +244,7 @@ You must then update the translation file with the new id.
|
|||
我们就要使用这个新的 id 来修改这个翻译文件。
|
||||
|
||||
Alternatively, you can specify a custom id in the `i18n` attribute by using the prefix `@@`.
|
||||
The example below defines the custom id `introductionHeader`:
|
||||
The example below defines the custom id `introductionHeader`:
|
||||
|
||||
<code-example path='i18n/doc-files/app.component.html' region='i18n-attribute-solo-id' title='app/app.component.html' linenums="false">
|
||||
|
||||
|
@ -304,11 +304,8 @@ Consider this translation to French:
|
|||
```xml
|
||||
|
||||
<trans-unit id="myId" datatype="html">
|
||||
|
||||
<source>Hello</source>
|
||||
|
||||
<target state="new">Bonjour</target>
|
||||
|
||||
</trans-unit>
|
||||
|
||||
```
|
||||
|
@ -421,7 +418,9 @@ the number of minutes.
|
|||
<div class="l-sub-section">
|
||||
|
||||
This syntax conforms to the
|
||||
|
||||
<a href="http://userguide.icu-project.org/formatparse/messages" title="ICU Message Format">ICU Message Format</a>
|
||||
|
||||
as specified in the
|
||||
<a href="http://cldr.unicode.org/index/cldr-spec/plural-rules" title="Pluralization Rules">CLDR pluralization rules</a>.
|
||||
|
||||
|
@ -520,8 +519,7 @@ You can also nest different ICU expressions together, as shown in this example:
|
|||
Use the `ng xi18n` command provided by the CLI to extract the text messages marked with `i18n` into
|
||||
a translation source file.
|
||||
|
||||
使用`ng-xi18n`提取工具来将带`i18n`标记的文本提取到一个翻译源文件中。
|
||||
|
||||
使用`ng-xi18n`提取工具来将带`i18n`标记的文本提取到一个翻译源文件中。
|
||||
|
||||
Open a terminal window at the root of the app project and enter the `ng xi18n` command:
|
||||
|
||||
|
@ -658,7 +656,6 @@ internationalization files, there.
|
|||
|
||||
其中一种方法是为本土化和相关资源(比如国际化文件)创建一个专门的目录。
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
Localization and internationalization are
|
||||
|
@ -705,6 +702,7 @@ This sample file is easy to translate without a special editor or knowledge of F
|
|||
1. Open `messages.fr.xlf` and find the first `<trans-unit>` section:
|
||||
|
||||
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello-before" title="src/locale/messages.fr.xlf (<trans-unit>)" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
> This XML element represents the translation of the `<h1>` greeting tag that you marked with the
|
||||
|
@ -720,11 +718,13 @@ This sample file is easy to translate without a special editor or knowledge of F
|
|||
the appropriate French translation.
|
||||
|
||||
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-hello" title="src/locale/messages.fr.xlf (<trans-unit>, after translation)" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
3. Translate the other text nodes the same way:
|
||||
|
||||
> <code-example path="i18n/doc-files/messages.fr.xlf.html" region="translated-other-nodes" title="src/locale/messages.fr.xlf (<trans-unit>)" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-important">
|
||||
|
@ -854,27 +854,16 @@ The sample app and its translation file are now as follows:
|
|||
下面是例子应用及其翻译文件:
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/app/app.component.html" path="i18n/src/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.ts" path="i18n/src/app/app.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.module.ts" path="i18n/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/main.ts" path="i18n/doc-files/main.1.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/locale/messages.fr.xlf" path="i18n/doc-files/messages.fr.xlf.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a merge}
|
||||
|
@ -1022,4 +1011,3 @@ error:
|
|||
<code-example path="i18n/doc-files/main.3.ts" title="src/main.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
|
|
@ -25,9 +25,7 @@ you can hit tab to complete.
|
|||
自动完成可以在输入时为我们提供当前情境下的候选内容和提示,从而提高开发速度。下面这个例子展示了插值表达式中的自动完成功能。当我们进行输入的时候,就可以按tab键来自动完成。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/language-service/language-completion.gif" alt="autocompletion">
|
||||
|
||||
</figure>
|
||||
|
||||
There are also completions within
|
||||
|
@ -41,14 +39,12 @@ show up in the completion list.
|
|||
## 错误检查
|
||||
|
||||
The Angular Language Service can also forewarn you of mistakes in your code.
|
||||
In this example, Angular doesn't know what `orders` is or where it comes from.
|
||||
In this example, Angular doesn't know what `orders` is or where it comes from.
|
||||
|
||||
Angular 语言服务还能对代码中存在的错误进行预警。在这个例子中,Angular 不知道什么是`orders`或者它来自哪里。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/language-service/language-error.gif" alt="error checking">
|
||||
|
||||
</figure>
|
||||
|
||||
## Navigation
|
||||
|
@ -62,9 +58,7 @@ click and press F12 to go directly to its definition.
|
|||
导航可以让我们在鼠标悬浮时看到某个组件、指令、模块等来自哪里,然后可以点击并按 F12 直接跳转到它的定义处。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/language-service/language-navigation.gif" alt="navigation">
|
||||
|
||||
</figure>
|
||||
|
||||
## Angular Language Service in your editor
|
||||
|
@ -89,7 +83,9 @@ Visual Studio Code 可以从商店中安装语言服务,这个功能就在左
|
|||
我们也可以使用 VS 的快速打开(⌘+P)功能来查找这个扩展插件。打开它之后就输入下列命令:
|
||||
|
||||
```sh
|
||||
|
||||
ext install Angular.ng-template
|
||||
|
||||
```
|
||||
|
||||
Then click the install button to install the Angular Language Service.
|
||||
|
@ -118,6 +114,7 @@ you need to have in `package.json`:
|
|||
devDependencies {
|
||||
"@angular/language-service": "^4.0.0"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Then in the terminal window at the root of your project,
|
||||
|
@ -126,15 +123,9 @@ install the `devDependencies` with `npm` or `yarn`:
|
|||
然后,打开终端窗口,在项目根目录下使用`npm`或`yarn`来安装这些`devDependencies`:
|
||||
|
||||
```sh
|
||||
|
||||
npm install
|
||||
```
|
||||
|
||||
*OR*
|
||||
|
||||
*或*
|
||||
|
||||
```sh
|
||||
yarn
|
||||
```
|
||||
|
||||
*OR*
|
||||
|
@ -142,7 +133,19 @@ yarn
|
|||
*或*
|
||||
|
||||
```sh
|
||||
|
||||
yarn
|
||||
|
||||
```
|
||||
|
||||
*OR*
|
||||
|
||||
*或*
|
||||
|
||||
```sh
|
||||
|
||||
yarn install
|
||||
|
||||
```
|
||||
|
||||
### Sublime Text
|
||||
|
@ -156,7 +159,9 @@ Install the latest version of typescript in a local `node_modules` directory:
|
|||
把最新版本的 TypeScript 安装到本地的`node_modules`目录下:
|
||||
|
||||
```sh
|
||||
|
||||
npm install --save-dev typescript
|
||||
|
||||
```
|
||||
|
||||
Then install the Angular Language Service in the same location:
|
||||
|
@ -164,7 +169,9 @@ Then install the Angular Language Service in the same location:
|
|||
然后把 Angular 语言服务安装到同一位置:
|
||||
|
||||
```sh
|
||||
|
||||
npm install --save-dev @angular/language-service
|
||||
|
||||
```
|
||||
|
||||
Starting with TypeScript 2.3, TypeScript has a language service plugin model that the language service can use.
|
||||
|
@ -176,7 +183,9 @@ Next, in your user preferences (`Cmd+,` or `Ctrl+,`), add:
|
|||
接下来,在你的用户首选项中(按`Cmd+,`或`Ctrl+,`)添加:
|
||||
|
||||
```json
|
||||
|
||||
"typescript-tsdk": "<path to your folder>/node_modules/typescript/lib"
|
||||
|
||||
```
|
||||
|
||||
## Installing in your project
|
||||
|
@ -189,18 +198,24 @@ following `npm` command:
|
|||
我们还可以使用下列`npm`命令来把 Angular 语言服务安装到工程中:
|
||||
|
||||
```sh
|
||||
|
||||
npm install --save-dev @angular/language-service
|
||||
|
||||
```
|
||||
|
||||
Additionally, add the following to the `"compilerOptions"` section of
|
||||
your project's `tsconfig.json`.
|
||||
|
||||
另外,还要在工程的`tsconfig.json`中添加下列`"compilerOptions"`区域:
|
||||
|
||||
```json
|
||||
|
||||
"plugins": [
|
||||
{"name": "@angular/language-service"}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
Note that this only provides diagnostics and completions in `.ts`
|
||||
files. You need a custom sublime plugin (or modifications to the current plugin)
|
||||
for completions in HTML files.
|
||||
|
@ -242,5 +257,5 @@ For more in-depth information, see the
|
|||
For more information, see [Chuck Jazdzewski's presentation](https://www.youtube.com/watch?v=ez3R0Gi4z5A&t=368s) on the Angular Language
|
||||
Service from [ng-conf](https://www.ng-conf.org/) 2017.
|
||||
|
||||
要了解更多信息,参见 [ng-conf](https://www.ng-conf.org/) 2017 中 [Chuck Jazdzewski的演讲](https://www.youtube.com/watch?v=ez3R0Gi4z5A&t=368s) 中讲解的 Angular 语言服务。
|
||||
|
||||
要了解更多信息,参见 [ng-conf](https://www.ng-conf.org/) 2017 中 [Chuck Jazdzewski的演讲](https://www.youtube.com/watch?v=ez3R0Gi4z5A&t=368s) 中讲解的 Angular 语言服务。
|
||||
|
|
|
@ -37,7 +37,9 @@ create one with the CLI. If you do already have an app, skip to
|
|||
where `customer-app` is the name of your app:
|
||||
|
||||
```sh
|
||||
|
||||
ng new customer-app --routing
|
||||
|
||||
```
|
||||
|
||||
This creates an app called `customer-app` and the `--routing` flag
|
||||
|
@ -51,7 +53,9 @@ Next, you’ll need a feature module to route to. To make one, enter
|
|||
the following command at the terminal window prompt where `customers` is the name of the module:
|
||||
|
||||
```sh
|
||||
|
||||
ng generate module customers --routing
|
||||
|
||||
```
|
||||
|
||||
This creates a customers folder with two files inside; `CustomersModule`
|
||||
|
@ -69,7 +73,9 @@ adding a JavaScript import statement at the top of the file and adding
|
|||
In order to see the module being lazy loaded in the browser, create a component to render some HTML when the app loads `CustomersModule`. At the command line, enter the following:
|
||||
|
||||
```sh
|
||||
|
||||
ng generate component customers/customer-list
|
||||
|
||||
```
|
||||
|
||||
This creates a folder inside of `customers` called `customer-list`
|
||||
|
@ -86,7 +92,9 @@ Just like with the routing module, the CLI imports the
|
|||
For another place to route to, create a second feature module with routing:
|
||||
|
||||
```sh
|
||||
|
||||
ng generate module orders --routing
|
||||
|
||||
```
|
||||
|
||||
This makes a new folder called `orders` containing an `OrdersModule` and an `OrdersRoutingModule`.
|
||||
|
@ -94,7 +102,9 @@ This makes a new folder called `orders` containing an `OrdersModule` and an `Ord
|
|||
Now, just like with the `CustomersModule`, give it some content:
|
||||
|
||||
```sh
|
||||
|
||||
ng generate component orders/order-list
|
||||
|
||||
```
|
||||
|
||||
## Set up the UI
|
||||
|
@ -111,15 +121,15 @@ so you can easily navigate to your modules in the browser:
|
|||
To see your app in the browser so far, enter the following command in the terminal window:
|
||||
|
||||
```sh
|
||||
|
||||
ng serve
|
||||
|
||||
```
|
||||
|
||||
Then go to `localhost:4200` where you should see “app works!” and three buttons.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/three-buttons.png" width="300" alt="three buttons in the browser">
|
||||
|
||||
</figure>
|
||||
|
||||
To make the buttons work, you need to configure the routing modules.
|
||||
|
@ -132,9 +142,7 @@ The two feature modules, `OrdersModule` and `CustomersModule`, have to be
|
|||
wired up to the `AppRoutingModule` so the router knows about them. The structure is as follows:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/lazy-load-relationship.jpg" width="400" alt="lazy loaded modules diagram">
|
||||
|
||||
</figure>
|
||||
|
||||
Each feature module acts as a doorway via the router. In the `AppRoutingModule`, you configure the routes to the feature modules, in this case `OrdersModule` and `CustomersModule`. This way, the router knows to go to the feature module. The feature module then connects the `AppRoutingModule` to the `CustomersRoutingModule` or the `OrdersRoutingModule`. Those routing modules tell the router where to go to load relevant components.
|
||||
|
@ -182,25 +190,19 @@ Now, if you view the app in the browser, the three buttons take you to each modu
|
|||
You can check to see that a module is indeed being lazy loaded with the Chrome developer tools. In Chrome, open the dev tools by pressing `Cmd+Option+i` on a Mac or `Ctrl+Alt+i` on a PC and go to the Network Tab.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/network-tab.png" width="600" alt="lazy loaded modules diagram">
|
||||
|
||||
</figure>
|
||||
|
||||
Click on the Orders or Customers button. If you see a chunk appear, you’ve wired everything up properly and the feature module is being lazy loaded. A chunk should appear for Orders and for Customers but will only appear once for each.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/chunk-arrow.png" width="600" alt="lazy loaded modules diagram">
|
||||
|
||||
</figure>
|
||||
|
||||
To see it again, or to test after working in the project, clear everything out by clicking the circle with a line through it in the upper left of the Network Tab:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/lazy-loading-ngmodules/clear.gif" width="200" alt="lazy loaded modules diagram">
|
||||
|
||||
</figure>
|
||||
|
||||
Then reload with `Cmd+r` or `Ctrl+r`, depending on your platform.
|
||||
|
|
|
@ -60,19 +60,23 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
当Angular使用构造函数新建一个组件或指令后,就会按下面的顺序在特定时刻调用这些生命周期钩子方法:
|
||||
|
||||
<table width="100%">
|
||||
|
||||
<col width="20%"></col>
|
||||
|
||||
<col width="80%"></col>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>Hook</th>
|
||||
<th>
|
||||
|
||||
<th>Purpose and Timing</th>
|
||||
Hook
|
||||
|
||||
</th>
|
||||
|
||||
<th>
|
||||
|
||||
Purpose and Timing
|
||||
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -96,7 +100,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -119,7 +122,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -141,7 +143,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -163,7 +164,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -185,7 +185,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -207,7 +206,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -229,7 +227,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -253,7 +250,6 @@ calls the lifecycle hook methods in the following sequence at specific moments:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
{@a interface-optional}
|
||||
|
@ -323,19 +319,25 @@ Here's a brief description of each exercise:
|
|||
下面是每个练习简短的描述:
|
||||
|
||||
<table width="100%">
|
||||
|
||||
<col width="20%"></col>
|
||||
|
||||
<col width="80%"></col>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>Component</th>
|
||||
<th>
|
||||
|
||||
<th>Description</th>
|
||||
Component
|
||||
|
||||
</th>
|
||||
|
||||
<th>
|
||||
|
||||
Description
|
||||
|
||||
描述
|
||||
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -354,7 +356,6 @@ Here's a brief description of each exercise:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -379,7 +380,6 @@ Here's a brief description of each exercise:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -400,7 +400,6 @@ Here's a brief description of each exercise:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -420,7 +419,6 @@ Here's a brief description of each exercise:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -440,7 +438,6 @@ Here's a brief description of each exercise:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -461,7 +458,6 @@ Here's a brief description of each exercise:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr style='vertical-align:top'>
|
||||
|
||||
<td>
|
||||
|
@ -490,7 +486,6 @@ Here's a brief description of each exercise:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
The remainder of this page discusses selected exercises in further detail.
|
||||
|
@ -518,9 +513,7 @@ This snapshot reflects the state of the log after the user clicked the *Create..
|
|||
用户点击**Create...**按钮,然后点击**Destroy...**按钮后,日志的状态如下图所示:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/lifecycle-hooks/peek-a-boo.png" alt="Peek-a-boo">
|
||||
|
||||
</figure>
|
||||
|
||||
The sequence of log messages follows the prescribed hook calling order:
|
||||
|
@ -575,7 +568,7 @@ The heroes will never know they're being watched.
|
|||
|
||||
1. Angular calls hook methods for *directives* as well as components.<br><br>
|
||||
|
||||
就像对组件一样,Angular也会对*指令*调用这些钩子方法。<br><br>
|
||||
就像对组件一样,Angular也会对*指令*调用这些钩子方法。<br><br>
|
||||
|
||||
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>`.
|
||||
|
@ -611,9 +604,7 @@ with an entry in the *Hook Log* as seen here:
|
|||
每个“侦探”的出生和死亡也同时标记出了存放英雄的那个`<div>`的出生和死亡。*钩子记录*中的结构是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/lifecycle-hooks/spy-directive.gif' alt="Spy Directive">
|
||||
|
||||
</figure>
|
||||
|
||||
Adding a hero results in a new hero `<div>`. The spy's `ngOnInit()` logs that event.
|
||||
|
@ -764,9 +755,7 @@ Here's the sample in action as the user makes changes.
|
|||
下面是此例子中的当用户做出更改时的操作演示:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/lifecycle-hooks/on-changes-anim.gif' alt="OnChanges">
|
||||
|
||||
</figure>
|
||||
|
||||
The log entries appear as the string value of the *power* property changes.
|
||||
|
@ -820,9 +809,7 @@ so you can see how often `DoCheck` is called. The results are illuminating:
|
|||
这样你可以看到`DoCheck`被调用的频率。结果非常显眼:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/lifecycle-hooks/do-check-anim.gif' alt="DoCheck">
|
||||
|
||||
</figure>
|
||||
|
||||
While the `ngDoCheck()` hook can detect when the hero's `name` has changed, it has a frightful cost.
|
||||
|
@ -909,9 +896,7 @@ Here's *AfterView* in action:
|
|||
这里是*AfterView*的操作演示:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/lifecycle-hooks/after-view-anim.gif' alt="AfterView">
|
||||
|
||||
</figure>
|
||||
|
||||
Notice that Angular frequently calls `AfterViewChecked()`, often when there are no changes of interest.
|
||||
|
@ -981,9 +966,7 @@ In this case, the projected content is the `<my-child>` from the parent.
|
|||
在这里,被投影进去的内容就是来自父组件的`<my-child>`标签。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/lifecycle-hooks/projected-child-view.png' alt="Projected Content">
|
||||
|
||||
</figure>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -1050,4 +1033,4 @@ There is a small window between the `AfterContent...` and `AfterView...` hooks t
|
|||
|
||||
回忆一下,Angular在每次调用*AfterView*钩子之前也会同时调用*AfterContent*。
|
||||
Angular在完成当前组件的视图合成之前,就已经完成了被投影内容的合成。
|
||||
所以我们仍然有机会去修改那个视图。
|
||||
所以我们仍然有机会去修改那个视图。
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
# Types of Feature Modules
|
||||
|
||||
#### Prerequisites
|
||||
|
@ -52,7 +50,11 @@ typical characteristics, in real world apps, you may see hybrids.
|
|||
|
||||
<tr>
|
||||
|
||||
<td>Domain</td>
|
||||
<td>
|
||||
|
||||
Domain
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
|
@ -71,10 +73,13 @@ typical characteristics, in real world apps, you may see hybrids.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>Routed</td>
|
||||
<td>
|
||||
|
||||
Routed
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
|
@ -94,7 +99,11 @@ typical characteristics, in real world apps, you may see hybrids.
|
|||
|
||||
<tr>
|
||||
|
||||
<td>Routing</td>
|
||||
<td>
|
||||
|
||||
Routing
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
|
@ -104,17 +113,41 @@ typical characteristics, in real world apps, you may see hybrids.
|
|||
|
||||
<ul>
|
||||
|
||||
<li>Defines routes.</li>
|
||||
<li>
|
||||
|
||||
<li>Adds router configuration to the module's imports.</li>
|
||||
Defines routes.
|
||||
|
||||
<li>Adds guard and resolver service providers to the module's providers.</li>
|
||||
</li>
|
||||
|
||||
<li>The name of the routing module should parallel the name of its companion module, using the suffix "Routing". For example, <code>FooModule</code> in <code>foo.module.ts</code> has a routing module named <code>FooRoutingModule</code> in <code>foo-routing.module.ts</code>. If the companion module is the root <code>AppModule</code>, the <code>AppRoutingModule</code> adds router configuration to its imports with <code>RouterModule.forRoot(routes)</code>. All other routing modules are children that import <code>RouterModule.forChild(routes)</code>.</li>
|
||||
<li>
|
||||
|
||||
<li>A routing module re-exports the <code>RouterModule</code> as a convenience so that components of the companion module have access to router directives such as <code>RouterLink</code> and <code>RouterOutlet</code>.</li>
|
||||
Adds router configuration to the module's imports.
|
||||
|
||||
<li>A routing module does not have its own declarations. Components, directives, and pipes are the responsibility of the feature module, not the routing module.</li>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
Adds guard and resolver service providers to the module's providers.
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
The name of the routing module should parallel the name of its companion module, using the suffix "Routing". For example, <code>FooModule</code> in <code>foo.module.ts</code> has a routing module named <code>FooRoutingModule</code> in <code>foo-routing.module.ts</code>. If the companion module is the root <code>AppModule</code>, the <code>AppRoutingModule</code> adds router configuration to its imports with <code>RouterModule.forRoot(routes)</code>. All other routing modules are children that import <code>RouterModule.forChild(routes)</code>.
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
A routing module re-exports the <code>RouterModule</code> as a convenience so that components of the companion module have access to router directives such as <code>RouterLink</code> and <code>RouterOutlet</code>.
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
A routing module does not have its own declarations. Components, directives, and pipes are the responsibility of the feature module, not the routing module.
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
@ -126,7 +159,11 @@ typical characteristics, in real world apps, you may see hybrids.
|
|||
|
||||
<tr>
|
||||
|
||||
<td>Service</td>
|
||||
<td>
|
||||
|
||||
Service
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
|
@ -140,7 +177,11 @@ typical characteristics, in real world apps, you may see hybrids.
|
|||
|
||||
<tr>
|
||||
|
||||
<td>Widget</td>
|
||||
<td>
|
||||
|
||||
Widget
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
|
@ -161,7 +202,6 @@ typical characteristics, in real world apps, you may see hybrids.
|
|||
The following table summarizes the key characteristics of each feature module group.
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th style="vertical-align: top">
|
||||
|
@ -198,74 +238,175 @@ The following table summarizes the key characteristics of each feature module gr
|
|||
|
||||
<tr>
|
||||
|
||||
<td>Domain</td>
|
||||
<td>
|
||||
|
||||
<td>Yes</td>
|
||||
Domain
|
||||
|
||||
<td>Rare</td>
|
||||
</td>
|
||||
|
||||
<td>Top component</td>
|
||||
<td>
|
||||
|
||||
<td>Feature, AppModule</td>
|
||||
Yes
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Rare
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Top component
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Feature, AppModule
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>Routed</td>
|
||||
<td>
|
||||
|
||||
<td>Yes</td>
|
||||
Routed
|
||||
|
||||
<td>Rare</td>
|
||||
</td>
|
||||
|
||||
<td>No</td>
|
||||
<td>
|
||||
|
||||
<td>None</td>
|
||||
Yes
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Rare
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
No
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
None
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>Routing</td>
|
||||
<td>
|
||||
|
||||
<td>No</td>
|
||||
Routing
|
||||
|
||||
<td>Yes (Guards)</td>
|
||||
</td>
|
||||
|
||||
<td>RouterModule</td>
|
||||
<td>
|
||||
|
||||
<td>Feature (for routing)</td>
|
||||
No
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Yes (Guards)
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
RouterModule
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Feature (for routing)
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>Service</td>
|
||||
<td>
|
||||
|
||||
<td>No</td>
|
||||
Service
|
||||
|
||||
<td>Yes</td>
|
||||
</td>
|
||||
|
||||
<td>No</td>
|
||||
<td>
|
||||
|
||||
<td>AppModule</td>
|
||||
No
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Yes
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
No
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
AppModule
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>Widget</td>
|
||||
<td>
|
||||
|
||||
<td>Yes</td>
|
||||
Widget
|
||||
|
||||
<td>Rare</td>
|
||||
</td>
|
||||
|
||||
<td>Yes</td>
|
||||
<td>
|
||||
|
||||
<td>Feature</td>
|
||||
Yes
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Rare
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Yes
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Feature
|
||||
|
||||
特性
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<hr />
|
||||
|
|
|
@ -26,6 +26,7 @@ into three categories:
|
|||
* **Composability/Grouping:** Bringing NgModules together and making them available via the `imports` and `exports` arrays.
|
||||
|
||||
```typescript
|
||||
|
||||
@NgModule({
|
||||
// Static, that is compiler configuration
|
||||
declarations: [], // Configure the selectors
|
||||
|
@ -38,6 +39,7 @@ into three categories:
|
|||
imports: [], // composing NgModules together
|
||||
exports: [] // making NgModules available to other parts of the app
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
## `@NgModule` metadata
|
||||
|
@ -81,22 +83,30 @@ The following table summarizes the `@NgModule` metadata properties.
|
|||
|
||||
<ol>
|
||||
|
||||
<li>When compiling a template, you need to determine a set of selectors which should be used for triggering their corresponding directives.</li>
|
||||
|
||||
<li>
|
||||
|
||||
The template is compiled within the context of an NgModule—the NgModule within which the template's component is declared—which determines the set of selectors using the following rules:
|
||||
|
||||
<ul>
|
||||
|
||||
<li>All selectors of directives listed in `declarations`.</li>
|
||||
|
||||
<li>All selectors of directives exported from imported NgModules.</li>
|
||||
|
||||
</ul>
|
||||
When compiling a template, you need to determine a set of selectors which should be used for triggering their corresponding directives.
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The template is compiled within the context of an NgModule—the NgModule within which the template's component is declared—which determines the set of selectors using the following rules:
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
All selectors of directives listed in `declarations`.
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
All selectors of directives exported from imported NgModules.
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
Components, directives, and pipes must belong to _exactly_ one module.
|
||||
|
|
|
@ -316,7 +316,9 @@ Angular's own `BrowserModule` exports a couple of NgModules like this:
|
|||
Angular自己的`BrowserModule`就重新导出了一组模块,例如:
|
||||
|
||||
```typescript
|
||||
|
||||
exports: [CommonModule, ApplicationModule]
|
||||
|
||||
```
|
||||
|
||||
An NgModule can export a combination of its own declarations, selected imported classes, and imported NgModules.
|
||||
|
@ -373,11 +375,12 @@ configure services in root and feature modules respectively.
|
|||
|
||||
Angular doesn't recognize these names but Angular developers do.
|
||||
Follow this convention when you write similar modules with configurable service providers.
|
||||
<!--KW--I don't understand how Angular doesn't understand these methods...-->
|
||||
|
||||
Angular并不识别这些名字,但是Angular的开发人员可以。
|
||||
当你写类似的需要可配置的服务提供商时,请遵循这个约定。
|
||||
|
||||
<!--KW--I don't understand how Angular doesn't understand these methods...-->
|
||||
|
||||
<hr/>
|
||||
|
||||
## Why is a service provided in a feature module visible everywhere?
|
||||
|
@ -1115,4 +1118,4 @@ the Angular compiler incorporates them into compiled component code too.
|
|||
how to link this module with other modules.
|
||||
|
||||
|
||||
`@NgModule`元数据告诉*Angular编译器*要为当前模块编译哪些组件,以及如何把当前模块和其它模块链接起来。
|
||||
`@NgModule`元数据告诉*Angular编译器*要为当前模块编译哪些组件,以及如何把当前模块和其它模块链接起来。
|
||||
|
|
|
@ -14,13 +14,17 @@ though they organize it differently, Angular apps rely on both.
|
|||
In JavaScript, modules are individual files with JavaScript code in them. To make what’s in them available, you write an export statement, usually after the relevant code, like this:
|
||||
|
||||
```typescript
|
||||
|
||||
export class AppComponent { ... }
|
||||
|
||||
```
|
||||
|
||||
Then, when you need that file’s code in another file, you import it like this:
|
||||
|
||||
```typescript
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
```
|
||||
|
||||
JavaScript modules help you namespace, preventing accidental global variables.
|
||||
|
@ -28,11 +32,13 @@ JavaScript modules help you namespace, preventing accidental global variables.
|
|||
## NgModules
|
||||
|
||||
<!-- KW-- perMisko: let's discuss. This does not answer the question why it is different. Also, last sentence is confusing.-->
|
||||
|
||||
NgModules are classes decorated with `@NgModule`. The `@NgModule` decorator’s `imports` array tells Angular what other NgModules the current module needs. The modules in the `imports` array are different than JavaScript modules because they are NgModules rather than regular JavaScript modules. Classes with an `@NgModule` decorator are by convention kept in their own files, but what makes them an `NgModule` isn’t being in their own file, like JavaScript modules; it’s the presence of `@NgModule` and its metadata.
|
||||
|
||||
The `AppModule` generated from the Angular CLI demonstrates both kinds of modules in action:
|
||||
|
||||
```typescript
|
||||
|
||||
/* These are JavaScript import statements. Angular doesn’t know anything about these. */
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
@ -51,6 +57,7 @@ import { AppComponent } from './app.component';
|
|||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
```
|
||||
|
||||
The NgModule classes differ from JavaScript module in the following key ways:
|
||||
|
|
|
@ -88,8 +88,8 @@ The `dependencies` section of `package.json` contains:
|
|||
|
||||
* **Angular packages**: Angular core and optional modules; their package names begin `@angular/`.
|
||||
|
||||
**Angular 包**:Angular 的核心和可选模块,它们的包名以`@angular/`开头。
|
||||
|
||||
**Angular 包**:Angular 的核心和可选模块,它们的包名以`@angular/`开头。
|
||||
|
||||
* **Support packages**: 3rd party libraries that must be present for Angular apps to run.
|
||||
|
||||
**支持包**:那些Angular 应用运行时必需的第三方库。
|
||||
|
@ -282,4 +282,4 @@ The browser downloads this bundle, not the original package files.
|
|||
See the [Deployment](guide/deployment) to learn more.
|
||||
|
||||
|
||||
参见[部署](guide/deployment)一章了解详情。
|
||||
参见[部署](guide/deployment)一章了解详情。
|
||||
|
|
|
@ -59,4 +59,3 @@ The [ActivatedRoute](https://angular.io/api/router/ActivatedRoute) is an injecte
|
|||
Reactive forms have properties that use observables to monitor form control values. The [`FormControl`](https://angular.io/api/forms/FormControl) properties `valueChanges` and `statusChanges` contain observables that raise change events. Subscribing to an observable form-control property is a way of triggering application logic within the component class. For example:
|
||||
|
||||
<code-example path="observables-in-angular/src/main.ts" title="Reactive forms" region="forms"></code-example>
|
||||
|
||||
|
|
|
@ -49,9 +49,7 @@ Here's an example of creating and subscribing to a simple observable, with an ob
|
|||
<code-example
|
||||
path="observables/src/subscribing.ts"
|
||||
region="observer"
|
||||
title="Subscribe using observer">
|
||||
|
||||
</code-example>
|
||||
title="Subscribe using observer"></code-example>
|
||||
|
||||
Alternatively, the `subscribe()` method can accept callback function definitions in line, for `next`, `error`, and `complete` handlers. For example, the following `subscribe()` call is the same as the one that specifies the predefined observer:
|
||||
|
||||
|
|
|
@ -146,9 +146,7 @@ As you click the button, the displayed date alternates between
|
|||
当我们点击按钮的时候,显示的日志会在“**<samp>04/15/1988</samp>**”和“**<samp>Friday, April 15, 1988</samp>**”之间切换。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/pipes/date-format-toggle-anim.gif' alt="Date Format Toggle">
|
||||
|
||||
</figure>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -255,9 +253,7 @@ Now you need a component to demonstrate the pipe.
|
|||
</code-example>
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/pipes/power-booster.png' alt="Power Booster">
|
||||
|
||||
</figure>
|
||||
|
||||
Note the following:
|
||||
|
@ -312,9 +308,7 @@ your pipe and two-way data binding with `ngModel`.
|
|||
</code-example>
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/pipes/power-boost-calculator-anim.gif' alt="Power Boost Calculator">
|
||||
|
||||
</figure>
|
||||
|
||||
{@a change-detection}
|
||||
|
@ -423,9 +417,7 @@ code with checkbox switches and additional displays to help you experience these
|
|||
这个*飞行英雄*的例子用检查框和其它显示内容扩展了原有代码,来帮我们体验这些效果。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/pipes/flying-heroes-anim.gif' alt="Flying Heroes">
|
||||
|
||||
</figure>
|
||||
|
||||
Replacing the array is an efficient way to signal Angular to update the display.
|
||||
|
@ -515,7 +507,6 @@ a point that's discussed later in this page.
|
|||
或者我们也可以完全不用管道。
|
||||
有时候,使用组件的属性能比用管道更好的达到目的,这一点我们等后面会再提起。
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<h3 class="no-toc">Impure pipes</h3>
|
||||
|
@ -664,9 +655,7 @@ The component renders as the following:
|
|||
组件渲染起来是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/pipes/hero-list.png' alt="Hero List">
|
||||
|
||||
</figure>
|
||||
|
||||
A breakpoint on the pipe's request for data shows the following:
|
||||
|
@ -836,4 +825,4 @@ If these performance and minification considerations don't apply to you, you can
|
|||
(similar to the [FlyingHeroesPipe](guide/pipes#impure-flying-heroes)) or find them in the community.
|
||||
|
||||
|
||||
如果你不需要顾虑这些性能和最小化问题,也可以创建自己的管道来实现这些功能(参考[FlyingHeroesPipe](guide/pipes#impure-flying-heroes)中的写法)或到社区中去找找。
|
||||
如果你不需要顾虑这些性能和最小化问题,也可以创建自己的管道来实现这些功能(参考[FlyingHeroesPipe](guide/pipes#impure-flying-heroes)中的写法)或到社区中去找找。
|
||||
|
|
|
@ -25,4 +25,3 @@ Writing this in full JavaScript can be quite involved. With observables, you can
|
|||
Exponential backoff is a technique in which you retry an API after failure, making the time in between retries longer after each consecutive failure, with a maximum number of retries after which the request is considered to have failed. This can be quite complex to implement with promises and other methods of tracking AJAX calls. With observables, it is very easy:
|
||||
|
||||
<code-example path="practical-observable-usage/src/backoff.ts" title="Exponential backoff"></code-example>
|
||||
|
||||
|
|
|
@ -20,7 +20,9 @@ Consider the default app generated by the CLI. In order to add a user service to
|
|||
you can generate one by entering the following command in the terminal window:
|
||||
|
||||
```sh
|
||||
|
||||
ng generate service User
|
||||
|
||||
```
|
||||
|
||||
This creates a service called `UserService`. You now need to make the service available in your
|
||||
|
@ -42,7 +44,9 @@ In the basic CLI generated app, modules are eagerly loaded which means that they
|
|||
This behavior necessarily changes when you use lazy loading. Lazy loading is when you load modules only when you need them; for example, when routing. They aren’t loaded right away like with eagerly loaded modules. This means that any services listed in their provider arrays aren’t available because the root injector doesn’t know about these modules.
|
||||
|
||||
<!-- KW--Make diagram here -->
|
||||
|
||||
<!-- KW--per Misko: not clear if the lazy modules are siblings or grand-children. They are both depending on router structure. -->
|
||||
|
||||
When the Angular router lazy-loads a module, it creates a new injector. This injector is a child of the root application injector. Imagine a tree of injectors; there is a single root injector and then a child injector for each lazy loaded module. The router adds all of the providers from the root injector to the child injector. When the router creates a component within the lazy-loaded context, Angular prefers service instances created from these providers to the service instances of the application root injector.
|
||||
|
||||
Any component created within a lazy loaded module’s context, such as by router navigation, gets the local instance of the service, not the instance in the root application injector. Components in external modules continue to receive the instance created for the application root.
|
||||
|
@ -68,6 +72,7 @@ Generally, provide services the whole app needs in the root module and scope ser
|
|||
The router works at the root level so if you put providers in a component, even `AppComponent`, lazy loaded modules, which rely on the router, can’t see them.
|
||||
|
||||
<!-- KW--Make a diagram here -->
|
||||
|
||||
Register a provider with a component when you must limit a service instance to a component and its component tree, that is, its child components. For example, a user editing component, `UserEditorComponent`, that needs a private copy of a caching `UserService` should register the `UserService` with the `UserEditorComponent`. Then each new instance of the `UserEditorComponent` gets its own cached service instance.
|
||||
|
||||
<hr>
|
||||
|
|
|
@ -134,9 +134,7 @@ Your app greets you with a message:
|
|||
本应用会用一条消息来跟你打招呼:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/cli-quickstart/app-works.png' alt="The app works!">
|
||||
|
||||
</figure>
|
||||
|
||||
<h2 id='first-component'>
|
||||
|
@ -172,9 +170,7 @@ Open `src/app/app.component.css` and give the component some style.
|
|||
<code-example path="cli-quickstart/src/app/app.component.css" title="src/app/app.component.css" linenums="false"></code-example>
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/cli-quickstart/my-first-app.png' alt="Output of QuickStart app">
|
||||
|
||||
</figure>
|
||||
|
||||
Looking good!
|
||||
|
@ -294,21 +290,14 @@ Any files outside of this folder are meant to support building your app.
|
|||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
td, th {vertical-align: top}
|
||||
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
|
||||
<col width="20%">
|
||||
|
||||
</col>
|
||||
|
||||
<col width="80%">
|
||||
|
||||
</col>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -328,7 +317,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -349,7 +337,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -371,7 +358,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -390,7 +376,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -418,7 +403,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -438,7 +422,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -461,7 +444,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -485,7 +467,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -508,7 +489,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -529,7 +509,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -550,7 +529,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -569,7 +547,6 @@ Any files outside of this folder are meant to support building your app.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
### The root folder
|
||||
|
@ -628,21 +605,14 @@ These files go in the root folder next to `src/`.
|
|||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
td, th {vertical-align: top}
|
||||
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
|
||||
<col width="20%">
|
||||
|
||||
</col>
|
||||
|
||||
<col width="80%">
|
||||
|
||||
</col>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -662,7 +632,6 @@ These files go in the root folder next to `src/`.
|
|||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -685,7 +654,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -704,7 +672,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -727,7 +694,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -749,7 +715,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -767,7 +732,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -786,7 +750,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -806,7 +769,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -825,7 +787,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -846,7 +807,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -864,7 +824,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -885,7 +844,6 @@ These files go in the root folder next to `src/`.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -902,4 +860,3 @@ You can skip the "Setup" step since you're already using the Angular CLI setup.
|
|||
你可以跳过“环境设置”一章,因为你已经在使用 Angular-CLI 设置好环境了。
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -447,9 +447,7 @@ Now that everything is wired up, the browser should display something like this:
|
|||
这些做好之后,浏览器中应该显示成这样:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/reactive-forms/just-formcontrol.png" alt="Single FormControl">
|
||||
|
||||
</figure>
|
||||
|
||||
{@a formgroup}
|
||||
|
@ -561,9 +559,7 @@ Piping it through the `JsonPipe` renders the model as JSON in the browser:
|
|||
用`JsonPipe`管道把这个模型以JSON格式渲染到浏览器中。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/reactive-forms/json-output.png" alt="JSON output">
|
||||
|
||||
</figure>
|
||||
|
||||
The initial `name` property value is the empty string.
|
||||
|
@ -695,9 +691,7 @@ The browser displays the following:
|
|||
浏览器会显示下列内容:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/reactive-forms/validators-json-output.png" alt="Single FormControl">
|
||||
|
||||
</figure>
|
||||
|
||||
`Validators.required` is working. The status is `INVALID` because the input box has no value.
|
||||
|
@ -857,9 +851,7 @@ with the nested address `FormGroup`:
|
|||
做完这些之后,浏览器中的JSON输出就变成了带有多级`FormGroup`的住址。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/reactive-forms/address-group.png" alt="JSON output">
|
||||
|
||||
</figure>
|
||||
|
||||
Great! You’ve made a group and you can see that the template
|
||||
|
@ -905,9 +897,7 @@ such as one of the following:
|
|||
我们可以使用此技术来显示`FromControl`的*任意*属性,代码如下:
|
||||
|
||||
<style>
|
||||
|
||||
td, th {vertical-align: top}
|
||||
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
|
@ -1309,9 +1299,7 @@ Together they look a bit like this:
|
|||
`HeroDetalComponent`是一个嵌套在`HeroListComponent`的*主从*视图中的子组件。如果把它们放在一起就是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/reactive-forms/hero-list.png" alt="HeroListComponent">
|
||||
|
||||
</figure>
|
||||
|
||||
The `HeroListComponent` uses an injected `HeroService` to retrieve heroes from the server
|
||||
|
@ -1609,9 +1597,7 @@ Back in the browser, select the hero named "Magneta".
|
|||
"Magneta"没有地址,我们会在表单底部的诊断用JSON中看到这一点。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/reactive-forms/addresses-array.png" alt="JSON output of addresses array">
|
||||
|
||||
</figure>
|
||||
|
||||
Click the "_Add a Secret Lair_" button.
|
||||
|
@ -1714,9 +1700,7 @@ After you implement both features in this section, the form will look like this:
|
|||
在实现完本节的这些特性之后,表单是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/reactive-forms/save-revert-buttons.png" alt="Form with save & revert buttons">
|
||||
|
||||
</figure>
|
||||
|
||||
### Save
|
||||
|
@ -1897,4 +1881,4 @@ You can download the complete source for all steps in this guide
|
|||
from the <live-example title="Reactive Forms Demo in Stackblitz">Reactive Forms Demo</live-example> live example.
|
||||
|
||||
|
||||
你可以到<live-example title="Reactive Forms Demo in Plunker">响应式表单在线例子</live-example>中下载本章所有步骤的完整代码。
|
||||
你可以到<live-example title="Reactive Forms Demo in Plunker">响应式表单在线例子</live-example>中下载本章所有步骤的完整代码。
|
||||
|
|
|
@ -15,9 +15,7 @@ of a small application that you can <live-example>run live in the browser</live-
|
|||
<!-- style for all tables on this page -->
|
||||
|
||||
<style>
|
||||
|
||||
td, th {vertical-align: top}
|
||||
|
||||
</style>
|
||||
|
||||
## Overview
|
||||
|
@ -296,7 +294,6 @@ It has a great deal of useful information including:
|
|||
它有一大堆有用的信息,包括:
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -496,7 +493,6 @@ It has a great deal of useful information including:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -525,7 +521,6 @@ During each navigation, the `Router` emits navigation events through the `Router
|
|||
在每次导航中,`Router`都会通过`Router.events`属性发布一些导航事件。这些事件的范围涵盖了从开始导航到结束导航之间的很多时间点。下表中列出了全部导航事件:
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -674,7 +669,6 @@ During each navigation, the `Router` emits navigation events through the `Router
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
These events are logged to the console when the `enableTracing` option is enabled also. Since the events are provided as an `Observable`, you can `filter()` for events of interest and `subscribe()` to them to make decisions based on the sequence of events in the navigation process.
|
||||
|
@ -726,7 +720,7 @@ Here are the key `Router` terms and their meanings:
|
|||
<td>
|
||||
|
||||
<code>Router</code>
|
||||
|
||||
|
||||
<code>路由器</code>
|
||||
|
||||
</td>
|
||||
|
@ -766,7 +760,7 @@ Here are the key `Router` terms and their meanings:
|
|||
<td>
|
||||
|
||||
<code>Routes</code>
|
||||
|
||||
|
||||
<code>路由定义(数组)</code>
|
||||
|
||||
</td>
|
||||
|
@ -786,7 +780,7 @@ Here are the key `Router` terms and their meanings:
|
|||
<td>
|
||||
|
||||
<code>Route</code>
|
||||
|
||||
|
||||
<code>路由器</code>
|
||||
|
||||
</td>
|
||||
|
@ -900,7 +894,7 @@ Here are the key `Router` terms and their meanings:
|
|||
<td>
|
||||
|
||||
<b><i>Link parameters array</i></b>
|
||||
|
||||
|
||||
<b><i>链接参数数组</i></b>
|
||||
|
||||
</td>
|
||||
|
@ -922,7 +916,7 @@ Here are the key `Router` terms and their meanings:
|
|||
<td>
|
||||
|
||||
<b><i>Routing component</i></b>
|
||||
|
||||
|
||||
<b><i>路由组件</i></b>
|
||||
|
||||
</td>
|
||||
|
@ -1038,9 +1032,7 @@ and the *Heroes* view with its list of heroes.
|
|||
等应用热身完毕,我们就会看到一排导航按钮,以及一个*英雄列表*视图。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/hero-list.png' alt="Hero List">
|
||||
|
||||
</figure>
|
||||
|
||||
Select one hero and the app takes you to a hero editing screen.
|
||||
|
@ -1048,9 +1040,7 @@ Select one hero and the app takes you to a hero editing screen.
|
|||
选择其中之一,该应用就会把我们带到此英雄的编辑页面。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/hero-detail.png' alt="Crisis Center Detail">
|
||||
|
||||
</figure>
|
||||
|
||||
Alter the name.
|
||||
|
@ -1071,9 +1061,7 @@ Now click the *Crisis Center* link for a list of ongoing crises.
|
|||
现在,点击*危机中心*链接,前往*危机*列表页。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/crisis-center-list.png' alt="Crisis Center List">
|
||||
|
||||
</figure>
|
||||
|
||||
Select a crisis and the application takes you to a crisis editing screen.
|
||||
|
@ -1089,9 +1077,7 @@ Notice that the corresponding name in the crisis list does _not_ change.
|
|||
注意,危机列表中的相应名称**并没有**修改。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/crisis-center-detail.png' alt="Crisis Center Detail">
|
||||
|
||||
</figure>
|
||||
|
||||
Unlike *Hero Detail*, which updates as you type,
|
||||
|
@ -1113,9 +1099,7 @@ Up pops a dialog box.
|
|||
我们会看到弹出了一个对话框。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/confirm-dialog.png' alt="Confirm Dialog">
|
||||
|
||||
</figure>
|
||||
|
||||
You can say "OK" and lose your changes or click "Cancel" and continue editing.
|
||||
|
@ -1148,9 +1132,7 @@ Begin with a simple version of the app that navigates between two empty views.
|
|||
开始本应用的一个简版,它在两个空路由之间导航。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/router-1-anim.gif' alt="App in action">
|
||||
|
||||
</figure>
|
||||
|
||||
{@a base-href}
|
||||
|
@ -1160,7 +1142,9 @@ Begin with a simple version of the app that navigates between two empty views.
|
|||
### 设置*<base href>*
|
||||
|
||||
The router uses the browser's
|
||||
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries" title="HTML5 browser history push-state">history.pushState</a>
|
||||
|
||||
for navigation. Thanks to `pushState`, you can make in-app URL paths look the way you want them to
|
||||
look, e.g. `localhost:3000/crisis-center`. The in-app URLs can be indistinguishable from server URLs.
|
||||
|
||||
|
@ -1208,7 +1192,7 @@ set the `href` value in **`index.html`** *exactly* as shown here.
|
|||
<header>
|
||||
|
||||
Live example note
|
||||
|
||||
|
||||
在线例子说明
|
||||
|
||||
</header>
|
||||
|
@ -1329,9 +1313,7 @@ and a *router outlet* where the router swaps views on and off the page. Here's w
|
|||
根组件`AppComponent`是本应用的壳。它在顶部有一个标题、一个带两个链接的导航条,在底部有一个*路由器出口*,路由器会在它所指定的位置上把视图切入或调出页面。就像下图中所标出的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/shell-and-outlet.png' alt="Shell">
|
||||
|
||||
</figure>
|
||||
|
||||
{@a shell-template}
|
||||
|
@ -1884,7 +1866,6 @@ then replacing `RouterModule.forRoot` in the `imports` array with the `AppRoutin
|
|||
接下来,修改`app.module.ts`文件,首先从`app-routing.module.ts`中导入新创建的`AppRoutingModule`,
|
||||
然后把`imports`数组中的`RouterModule.forRoot`替换为`AppRoutingModule`。
|
||||
|
||||
|
||||
<code-example path="router/src/app/app.module.2.ts" title="src/app/app.module.ts">
|
||||
|
||||
</code-example>
|
||||
|
@ -1977,9 +1958,7 @@ Here's how the user will experience this version of the app:
|
|||
下面是用户将看到的版本:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/router-2-anim.gif' alt="App in action">
|
||||
|
||||
</figure>
|
||||
|
||||
A typical application has multiple *feature areas*,
|
||||
|
@ -2511,7 +2490,6 @@ to handle parameter access for both route parameters (`paramMap`) and query para
|
|||
`ParamMap` API 是参照[URLSearchParams 接口](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)来设计的。它提供了一些方法来处理对路由参数(`paramMap`)和查询参数(`queryParamMap`)中的参数访问。
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -2603,7 +2581,6 @@ to handle parameter access for both route parameters (`paramMap`) and query para
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
{@a reuse}
|
||||
|
@ -2764,9 +2741,7 @@ it would be nice if the viewed hero was preselected in the list.
|
|||
比如,当从`HeroDetailComponent`返回英雄列表时,如果能自动选中刚刚查看过的英雄就好了。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/selected-hero.png' alt="Selected hero">
|
||||
|
||||
</figure>
|
||||
|
||||
You'll implement this feature in a moment by including the viewed hero's `id`
|
||||
|
@ -2999,9 +2974,7 @@ When the user navigates from the heroes list to the "Magneta" hero and back, "Ma
|
|||
当用户从英雄列表导航到英雄“Magneta”并返回时,“Magneta”看起来是选中的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/selected-hero.png' alt="Selected List">
|
||||
|
||||
</figure>
|
||||
|
||||
The optional `foo` route parameter is harmless and continues to be ignored.
|
||||
|
@ -3408,9 +3381,7 @@ If your app had many feature areas, the app component trees might look like this
|
|||
如果我们有更多特性区,它们的组件树是这样的:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/component-tree.png' alt="Component Tree">
|
||||
|
||||
</figure>
|
||||
|
||||
{@a child-routing-component}
|
||||
|
@ -3767,9 +3738,7 @@ and two buttons, "Send" and "Cancel".
|
|||
它显示一个简单的表单,包括一个头、一个消息输入框和两个按钮:“Send”和“Cancel”。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/router/contact-popup.png' alt="Contact popup">
|
||||
|
||||
</figure>
|
||||
|
||||
Here's the component and its template:
|
||||
|
@ -5856,4 +5825,3 @@ in the `AppModule`.
|
|||
<code-example path="router/src/app/app.module.6.ts" linenums="false" title="src/app/app.module.ts (hash URL strategy)">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
|
|
@ -101,4 +101,4 @@ This can be useful when scanning through code and looking for observable values.
|
|||
|
||||
For example:
|
||||
|
||||
<code-example path="rx-library/src/naming-convention.ts" title="Naming observables"></code-example>
|
||||
<code-example path="rx-library/src/naming-convention.ts" title="Naming observables"></code-example>
|
||||
|
|
|
@ -138,7 +138,7 @@ Angular定义了四个安全环境 - HTML,样式,URL,和资源URL:
|
|||
|
||||
* **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>`.
|
||||
|
||||
|
@ -186,9 +186,7 @@ tag but keeps safe content such as the text content of the `<script>` tag and th
|
|||
Angular认为这些值是不安全的,并自动进行无害化处理。它会移除`<script>`标签,但保留安全的内容,比如该片段中的文本内容或`<b>`元素。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/security/binding-inner-html.png' alt='A screenshot showing interpolated and bound HTML values'>
|
||||
|
||||
</figure>
|
||||
|
||||
### Avoid direct use of the DOM APIs
|
||||
|
@ -304,9 +302,7 @@ this, mark the URL value as a trusted URL using the `bypassSecurityTrustUrl` cal
|
|||
</code-example>
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/security/bypass-security-component.png' alt='A screenshot showing an alert box created from a trusted URL'>
|
||||
|
||||
</figure>
|
||||
|
||||
If you need to convert user input into a trusted value, use a
|
||||
|
@ -464,4 +460,4 @@ as security sensitive.
|
|||
|
||||
|
||||
Angular应用应该遵循和常规Web应用一样的安全原则并按照这些原则进行审计。Angular中某些应该在安全评审中被审计的API(
|
||||
比如[_bypassSecurityTrust_](guide/security#bypass-security-apis) API)都在文档中被明确标记为安全性敏感的。
|
||||
比如[_bypassSecurityTrust_](guide/security#bypass-security-apis) API)都在文档中被明确标记为安全性敏感的。
|
||||
|
|
|
@ -16,7 +16,9 @@ CLI processes the configuration file during `ng build --prod`. Manually, you can
|
|||
it with the `ngsw-config` tool:
|
||||
|
||||
```sh
|
||||
|
||||
ngsw-config dist src/ngsw-config.json /base/href
|
||||
|
||||
```
|
||||
|
||||
The configuration file uses the JSON format. All file paths must begin with `/`, which is the deployment directory—usually `dist` in CLI projects.
|
||||
|
@ -55,6 +57,7 @@ Specifies the file that serves as the index page to satisfy navigation requests.
|
|||
This field contains an array of asset groups, each of which defines a set of asset resources and the policy by which they are cached.
|
||||
|
||||
```json
|
||||
|
||||
{
|
||||
"assetGroups": [{
|
||||
...
|
||||
|
@ -62,6 +65,7 @@ This field contains an array of asset groups, each of which defines a set of ass
|
|||
...
|
||||
}]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Each asset group specifies both a group of resources and a policy that governs them. This policy determines when the resources are fetched and what happens when changes are detected.
|
||||
|
@ -69,6 +73,7 @@ Each asset group specifies both a group of resources and a policy that governs t
|
|||
Asset groups follow the Typescript interface shown here:
|
||||
|
||||
```typescript
|
||||
|
||||
interface AssetGroup {
|
||||
name: string;
|
||||
installMode?: 'prefetch' | 'lazy';
|
||||
|
@ -79,6 +84,7 @@ interface AssetGroup {
|
|||
urls?: string[];
|
||||
};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### `name`
|
||||
|
@ -118,6 +124,7 @@ Unlike asset resources, data requests are not versioned along with the app. They
|
|||
Data groups follow this Typescript interface:
|
||||
|
||||
```typescript
|
||||
|
||||
export interface DataGroup {
|
||||
name: string;
|
||||
urls: string[];
|
||||
|
@ -129,6 +136,7 @@ export interface DataGroup {
|
|||
strategy?: 'freshness' | 'performance';
|
||||
};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### `name`
|
||||
|
@ -182,4 +190,3 @@ The Angular service worker can use either of two caching strategies for data res
|
|||
* `performance`, the default, optimizes for responses that are as fast as possible. If a resource exists in the cache, the cached version is used. This allows for some staleness, depending on the `maxAge`, in exchange for better performance. This is suitable for resources that don't change often; for example, user avatar images.
|
||||
|
||||
* `freshness` optimizes for currency of data, preferentially fetching requested data from the network. Only if the network times out, according to `timeout`, does the request fall back to the cache. This is useful for resources that change frequently; for example, account balances.
|
||||
|
||||
|
|
|
@ -167,6 +167,7 @@ the `ngsw/` virtual directory. Currently, the single exposed URL
|
|||
is `ngsw/state`. Here is an example of this debug page's contents:
|
||||
|
||||
```
|
||||
|
||||
NGSW Debug Info:
|
||||
|
||||
Driver state: NORMAL ((nominal))
|
||||
|
@ -185,6 +186,7 @@ Task queue:
|
|||
* init post-load (update, cleanup)
|
||||
|
||||
Debug log:
|
||||
|
||||
```
|
||||
|
||||
#### Driver state
|
||||
|
@ -192,7 +194,9 @@ Debug log:
|
|||
The first line indicates the driver state:
|
||||
|
||||
```
|
||||
|
||||
Driver state: NORMAL ((nominal))
|
||||
|
||||
```
|
||||
|
||||
`NORMAL` indicates that the service worker is operating normally and is not in a degraded state.
|
||||
|
@ -215,7 +219,9 @@ error that caused the service worker to enter the degraded state.
|
|||
#### Latest manifest hash
|
||||
|
||||
```
|
||||
|
||||
Latest manifest hash: eea7f5f464f90789b621170af5a569d6be077e5c
|
||||
|
||||
```
|
||||
|
||||
This is the SHA1 hash of the most up-to-date version of the app that the service worker knows about.
|
||||
|
@ -223,7 +229,9 @@ This is the SHA1 hash of the most up-to-date version of the app that the service
|
|||
#### Last update check
|
||||
|
||||
```
|
||||
|
||||
Last update check: never
|
||||
|
||||
```
|
||||
|
||||
This indicates the last time the service worker checked for a new version, or update, of the app. `never` indicates that the service worker has never checked for an update.
|
||||
|
@ -233,9 +241,11 @@ In this example debug file, the update check is currently scheduled, as explaine
|
|||
#### Version
|
||||
|
||||
```
|
||||
|
||||
=== Version eea7f5f464f90789b621170af5a569d6be077e5c ===
|
||||
|
||||
Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100f65
|
||||
|
||||
```
|
||||
|
||||
In this example, the service worker has one version of the app cached and
|
||||
|
@ -247,12 +257,14 @@ API in the browser.
|
|||
#### Idle task queue
|
||||
|
||||
```
|
||||
|
||||
=== Idle Task Queue ===
|
||||
Last update tick: 1s496u
|
||||
Last update run: never
|
||||
Task queue:
|
||||
|
||||
* init post-load (update, cleanup)
|
||||
|
||||
```
|
||||
|
||||
The Idle Task Queue is the queue of all pending tasks that happen
|
||||
|
@ -270,7 +282,9 @@ which the queue might be processed.
|
|||
#### Debug log
|
||||
|
||||
```
|
||||
|
||||
Debug log:
|
||||
|
||||
```
|
||||
|
||||
Errors that occur within the service worker will be logged here.
|
||||
|
@ -332,4 +346,3 @@ the past on your site.
|
|||
You may also be interested in the following:
|
||||
|
||||
* [Service Worker Configuration](guide/service-worker-config).
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@ Beginning in Angular 5.0.0, you can easily enable Angular service worker support
|
|||
If you're generating a new CLI project, you can use the CLI to set up the Angular service worker as part of creating the project. To do so, add the `--service-worker` flag to the `ng new` command:
|
||||
|
||||
```sh
|
||||
|
||||
ng new my-project --service-worker
|
||||
|
||||
```
|
||||
|
||||
The `--service-worker` flag takes care of configuring your app to
|
||||
|
@ -44,7 +46,9 @@ To add a service worker to an existing app:
|
|||
Add the package `@angular/service-worker`, using the yarn utility as shown here:
|
||||
|
||||
```sh
|
||||
|
||||
yarn add @angular/service-worker
|
||||
|
||||
```
|
||||
|
||||
### Step 2: Enable service worker build support in the CLI
|
||||
|
@ -52,7 +56,9 @@ yarn add @angular/service-worker
|
|||
To enable the Angular service worker, the CLI must generate an Angular service worker manifest at build time. To cause the CLI to generate the manifest for an existing project, set the `serviceWorker` flag to `true` in the project's `.angular-cli.json` file as shown here:
|
||||
|
||||
```sh
|
||||
|
||||
ng set apps.0.serviceWorker=true
|
||||
|
||||
```
|
||||
|
||||
### Step 3: Import and register the service worker
|
||||
|
@ -85,7 +91,9 @@ Alternately, save the following as `src/ngsw-config.json`:
|
|||
Finally, build the project:
|
||||
|
||||
```sh
|
||||
|
||||
ng build --prod
|
||||
|
||||
```
|
||||
|
||||
The CLI project is now set up to use the Angular service worker.
|
||||
|
@ -102,8 +110,10 @@ Because `ng serve` does not work with service workers, you must use a seperate H
|
|||
To serve with `http-server`, change to the directory containing your web files and start the web server:
|
||||
|
||||
```sh
|
||||
|
||||
cd dist
|
||||
http-server -p 8080
|
||||
|
||||
```
|
||||
|
||||
### Initial load
|
||||
|
@ -123,9 +133,7 @@ To simulate a network issue, disable network interaction for your application. I
|
|||
3. Check the **Offline box**.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/service-worker/offline-checkbox.png" alt="The offline checkbox in the Network tab is checked">
|
||||
|
||||
</figure>
|
||||
|
||||
Now the app has no access to network interaction.
|
||||
|
@ -137,9 +145,7 @@ With the addition of an Angular service worker, the application behavior changes
|
|||
If you look at the Network tab, you can verify that the service worker is active.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/service-worker/sw-active.png" alt="Requests are marked as from ServiceWorker">
|
||||
|
||||
</figure>
|
||||
|
||||
Notice that under the "Size" column, the requests state is `(from ServiceWorker)`. This means that the resources are not being loaded from the network. Instead, they are being loaded from the service worker's cache.
|
||||
|
@ -176,9 +182,11 @@ next step is understanding how updates work.
|
|||
7. Build and run the server again:
|
||||
|
||||
```sh
|
||||
|
||||
ng build --prod
|
||||
cd dist
|
||||
http-server -p 8080
|
||||
|
||||
```
|
||||
|
||||
### Updating your application in the browser
|
||||
|
@ -188,9 +196,7 @@ Now look at how the browser and service worker handle the updated application.
|
|||
1. Open http://localhost:8080 again in the same window. What happens?
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/service-worker/welcome-msg-en.png" alt="It still says Welcome to Service Workers!">
|
||||
|
||||
</figure>
|
||||
|
||||
What went wrong? Nothing, actually. The Angular service worker is doing its job and serving the version of the application that it has **installed**, even though there is an update available. In the interest of speed, the service worker doesn't wait to check for updates before it serves the application that it has cached.
|
||||
|
@ -200,9 +206,7 @@ If you look at the `http-server` logs, you can see the service worker requesting
|
|||
2. Refresh the page.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/service-worker/welcome-msg-fr.png" alt="The text has changed to say Bienvenue à app!">
|
||||
|
||||
</figure>
|
||||
|
||||
The service worker installed the updated version of your app *in the background*, and the next time the page is loaded or reloaded, the service worker switches to the latest version.
|
||||
|
|
|
@ -81,9 +81,7 @@ Bind that method to three anchor tags and voilà!
|
|||
我们把这个方法绑定到三个A标签,瞧瞧!
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/set-document-title/set-title-anim.gif" alt="Set title">
|
||||
|
||||
</figure>
|
||||
|
||||
Here's the complete solution:
|
||||
|
@ -91,13 +89,9 @@ Here's the complete solution:
|
|||
这里是完整的方案(代码)。
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/main.ts" path="set-document-title/src/main.ts"></code-pane>
|
||||
|
||||
<code-pane title="src/app/app.module.ts" path="set-document-title/src/app/app.module.ts"></code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.ts" path="set-document-title/src/app/app.component.ts"></code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Why provide the `Title` service in `bootstrap`
|
||||
|
@ -120,5 +114,5 @@ you'll have to provide a different `Title` service that understands
|
|||
the concept of a "document title" for that specific platform.
|
||||
Ideally, the application itself neither knows nor cares about the runtime environment.
|
||||
|
||||
我们的做法正是如此。这里的`Title`服务是Angular*浏览器平台*的一部分。如果在其它平台上引导应用程序,就得提供另一个专为那个平台准备的`Title`服务。
|
||||
|
||||
我们的做法正是如此。这里的`Title`服务是Angular*浏览器平台*的一部分。如果在其它平台上引导应用程序,就得提供另一个专为那个平台准备的`Title`服务。
|
||||
|
|
|
@ -19,9 +19,7 @@ If you do, this page can help you understand their purpose.
|
|||
这些文件很少会需要变动,你可能永远都不需要阅览或者修改它们。
|
||||
|
||||
<style>
|
||||
|
||||
td, th {vertical-align: top}
|
||||
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
|
@ -74,7 +72,7 @@ If you do, this page can help you understand their purpose.
|
|||
|
||||
"Hello Angular" 这个例子中有 `AppComponent`、`AppModule`、 一个组件单元测试 (`app.component.spec.ts`) 以及引导文件 `main.ts`。
|
||||
|
||||
Try the <live-example name="setup">sample application</live-example>
|
||||
Try the <live-example name="setup">sample application</live-example>
|
||||
and the <live-example name="setup" stackblitz="quickstart-specs">unit test</live-example>
|
||||
as _live examples_.
|
||||
|
||||
|
@ -130,19 +128,21 @@ If you do, this page can help you understand their purpose.
|
|||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
<code>.editorconfig<br>
|
||||
.git/<br>
|
||||
.gitignore<br>
|
||||
.travis.yml</code>
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
Tooling configuration files and folders.
|
||||
Ignore them until you have a compelling reason to do otherwise.
|
||||
|
||||
配置文件和文件夹的工具。
|
||||
|
||||
Ignore them until you have a compelling reason to do otherwise.
|
||||
除非你有足够的理由,否则别动它。
|
||||
|
||||
</td>
|
||||
|
||||
|
@ -472,4 +472,3 @@ If you do, this page can help you understand their purpose.
|
|||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ Perform the _clone-to-launch_ steps with these terminal commands.
|
|||
|
||||
`npm start` fails in _Bash for Windows_ in versions earlier than the Creator's Update (April 2017).
|
||||
|
||||
在*Bash for Windows*中`npm start`可能会失败,因为到2017-04为止它还不支持访问网络上的服务器。
|
||||
在*Bash for Windows*中`npm start`可能会失败,因为到2017-01为止它还不支持访问网络上的服务器。
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -221,9 +221,7 @@ The following are all in `src/`
|
|||
`src/`目录文件详情如下:
|
||||
|
||||
<style>
|
||||
|
||||
td, th {vertical-align: top}
|
||||
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
|
|
|
@ -25,6 +25,7 @@ you need it in other parts of your app.
|
|||
Consider the following module from an imaginary app:
|
||||
|
||||
```typescript
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
@ -39,6 +40,7 @@ import { OrdersPipe } from './orders.pipe';
|
|||
CommonModule, FormsModule ]
|
||||
})
|
||||
export class SharedModule { }
|
||||
|
||||
```
|
||||
|
||||
Note the following:
|
||||
|
|
|
@ -166,20 +166,15 @@ Now `parentModule` exists and the constructor throws the error.
|
|||
Here are the two files in their entirety for reference:
|
||||
|
||||
<code-tabs linenums="false">
|
||||
|
||||
<code-pane
|
||||
title="app.module.ts"
|
||||
path="ngmodules/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="core.module.ts"
|
||||
region="whole-core-module"
|
||||
path="ngmodules/src/app/core/core.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
<hr>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# 结构型指令
|
||||
|
||||
<style>
|
||||
|
||||
h4 {font-size: 17px !important; text-transform: none !important;}
|
||||
.syntax { font-family: Consolas, 'Lucida Sans', Courier, sans-serif; color: black; font-size: 85%; }
|
||||
|
||||
|
@ -157,9 +156,7 @@ Confirm that fact using browser developer tools to inspect the DOM.
|
|||
使用浏览器的开发者工具就可以确认这一点。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/element-not-in-dom.png' alt="ngIf=false element not in DOM">
|
||||
|
||||
</figure>
|
||||
|
||||
The top paragraph is in the DOM. The bottom, disused paragraph is not;
|
||||
|
@ -192,9 +189,7 @@ While invisible, the element remains in the DOM.
|
|||
当不可见时,这个元素仍然留在DOM中。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/element-display-in-dom.png' alt="hidden element still in DOM">
|
||||
|
||||
</figure>
|
||||
|
||||
The difference between hiding and removing doesn't matter for a simple paragraph.
|
||||
|
@ -280,9 +275,7 @@ The first form is not actually rendered, only the finished product ends up in th
|
|||
只有最终产出的结果才会出现在DOM中。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/hero-div-in-dom.png' alt="hero div in DOM">
|
||||
|
||||
</figure>
|
||||
|
||||
Angular consumed the `<ng-template>` content during its actual rendering and
|
||||
|
@ -584,9 +577,7 @@ Angular erases the middle "Hip!", leaving the cheer a bit less enthusiastic.
|
|||
Angular 抹掉了中间的那个 "Hip!" ,让欢呼声显得不再那么热烈了。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/template-rendering.png' alt="template tag rendering">
|
||||
|
||||
</figure>
|
||||
|
||||
A structural directive puts a `<ng-template>` to work
|
||||
|
@ -651,9 +642,7 @@ The constructed paragraph renders strangely.
|
|||
这样渲染出来的段落就会非常奇怪。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/bad-paragraph.png' alt="spanned paragraph with bad style">
|
||||
|
||||
</figure>
|
||||
|
||||
The `p span` style, intended for use elsewhere, was inadvertently applied here.
|
||||
|
@ -680,9 +669,7 @@ the drop down is empty.
|
|||
下拉列表就是空的。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/bad-select.png' alt="spanned options don't work">
|
||||
|
||||
</figure>
|
||||
|
||||
The browser won't display an `<option>` within a `<span>`.
|
||||
|
@ -711,9 +698,7 @@ It renders properly.
|
|||
这次就渲染对了。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/good-paragraph.png' alt="ngcontainer paragraph with proper style">
|
||||
|
||||
</figure>
|
||||
|
||||
Now conditionally exclude a _select_ `<option>` with `<ng-container>`.
|
||||
|
@ -729,9 +714,7 @@ The drop down works properly.
|
|||
下拉框也工作正常。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/select-ngcontainer-anim.gif' alt="ngcontainer options work properly">
|
||||
|
||||
</figure>
|
||||
|
||||
The `<ng-container>` is a syntax element recognized by the Angular parser.
|
||||
|
@ -786,7 +769,7 @@ Creating a directive is similar to creating a component.
|
|||
|
||||
* Import the `Input`, `TemplateRef`, and `ViewContainerRef` symbols; you'll need them for _any_ structural directive.
|
||||
|
||||
导入符号`Input`、`TemplateRef` 和 `ViewContainerRef`,我们在*任何*结构型指令中都会需要它们。
|
||||
导入符号`Input`、`TemplateRef` 和 `ViewContainerRef`,我们在*任何*结构型指令中都会需要它们。
|
||||
|
||||
* Apply the decorator to the directive class.
|
||||
|
||||
|
@ -922,9 +905,7 @@ When the `condition` is truthy, the top (A) paragraph is removed and the bottom
|
|||
当`condition`为`true`时,顶部的段落被移除了,而底部的段落显示了出来。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/structural-directives/unless-anim.gif' alt="UnlessDirective in action">
|
||||
|
||||
</figure>
|
||||
|
||||
{@a summary}
|
||||
|
@ -1000,4 +981,4 @@ You learned
|
|||
* to write a [custom structural directive](guide/structural-directives#unless), `UnlessDirective`.
|
||||
|
||||
|
||||
写了一个[自定义结构型指令](guide/structural-directives#unless) —— `UnlessDirective`。
|
||||
写了一个[自定义结构型指令](guide/structural-directives#unless) —— `UnlessDirective`。
|
||||
|
|
|
@ -2724,7 +2724,7 @@ and more difficult in a flat structure.
|
|||
<a href="#file-tree">Refer to this _folder and file structure_ example.</a>
|
||||
|
||||
<a href="#file-tree">点这里查看目录和文件结构的范例</a>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
@ -4643,9 +4643,7 @@ Useful tools and tips for Angular.
|
|||
**考虑**使用 [Visual Studio Code](https://code.visualstudio.com/)的[代码片段](https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2) 来实施本风格指南。
|
||||
|
||||
<a href="https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2">
|
||||
|
||||
<img src="generated/images/guide/styleguide/use-extension.gif" alt="Use Extension">
|
||||
|
||||
</a>
|
||||
|
||||
**Consider** using [snippets](https://atom.io/packages/angular-2-typescript-snippets) for [Atom](https://atom.io/) that follow these styles and guidelines.
|
||||
|
|
|
@ -3,11 +3,9 @@
|
|||
# 模板语法
|
||||
|
||||
<style>
|
||||
|
||||
h4 {font-size: 17px !important; text-transform: none !important;}
|
||||
.syntax { font-family: Consolas, 'Lucida Sans', Courier, sans-serif; color: black; font-size: 85%; }
|
||||
h4 .syntax { font-size: 100%; }
|
||||
|
||||
</style>
|
||||
|
||||
The Angular application manages what the user sees and can do, achieving this through the interaction of a
|
||||
|
@ -172,11 +170,11 @@ JavaScript 中那些具有或可能引发副作用的表达式是被禁止的,
|
|||
|
||||
* <code>new</code>
|
||||
|
||||
`new`运算符
|
||||
`new`运算符
|
||||
|
||||
* chaining expressions with <code>;</code> or <code>,</code>
|
||||
|
||||
使用`;`或`,`的链式表达式
|
||||
使用`;`或`,`的链式表达式
|
||||
|
||||
* increment and decrement operators (`++` and `--`)
|
||||
|
||||
|
@ -400,7 +398,7 @@ However, certain JavaScript syntax is not allowed:
|
|||
|
||||
* <code>new</code>
|
||||
|
||||
`new`运算符
|
||||
`new`运算符
|
||||
|
||||
* increment and decrement operators, `++` and `--`
|
||||
|
||||
|
@ -510,25 +508,16 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _
|
|||
*从数据源到视图*、*从视图到数据源*以及双向的*从视图到数据源再到视图*。
|
||||
|
||||
<style>
|
||||
|
||||
td, th {vertical-align: top}
|
||||
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
|
||||
<col width="30%">
|
||||
|
||||
</col>
|
||||
|
||||
<col width="50%">
|
||||
|
||||
</col>
|
||||
|
||||
<col width="20%">
|
||||
|
||||
</col>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -556,7 +545,6 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _
|
|||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -579,30 +567,16 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _
|
|||
|
||||
<td>
|
||||
|
||||
Interpolation
|
||||
|
||||
插值表达式
|
||||
|
||||
<br>
|
||||
|
||||
Property
|
||||
|
||||
属性
|
||||
|
||||
<br>
|
||||
|
||||
Attribute
|
||||
|
||||
<br>
|
||||
|
||||
Class
|
||||
|
||||
CSS 类
|
||||
|
||||
<br>
|
||||
|
||||
Interpolation<br>
|
||||
Property<br>
|
||||
Attribute<br>
|
||||
Class<br>
|
||||
Style
|
||||
|
||||
插值表达式<br>
|
||||
属性<br>
|
||||
Attribute<br>
|
||||
CSS 类<br>
|
||||
样式
|
||||
|
||||
</td>
|
||||
|
@ -637,7 +611,6 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -668,31 +641,22 @@ from the _source-to-view_, from _view-to-source_, and in the two-way sequence: _
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
<!-- placeholder -->
|
||||
|
||||
译注:由于 HTML attribute 和 DOM property 在中文中都被翻译成了“属性”,无法区分,
|
||||
而接下来的部分重点是对它们进行比较。
|
||||
|
||||
<!-- placeholder -->
|
||||
|
||||
我们无法改变历史,因此,在本章的翻译中,保留了它们的英文形式,不加翻译,以免混淆。
|
||||
本章中,如果提到“属性”的地方,一定是指 property,因为在 Angular 中,实际上很少涉及 attribute。
|
||||
|
||||
<!-- placeholder -->
|
||||
|
||||
但在其它章节中,为简单起见,凡是能通过上下文明显区分开的,就仍统一译为“属性”,
|
||||
区分不明显的,会加注英文。
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -882,7 +846,6 @@ HTML attributes effectively disappear.
|
|||
在 Angular 的世界中,attribute 唯一的作用是用来初始化元素和指令的状态。
|
||||
当进行数据绑定时,只是在与元素和指令的 property 和事件打交道,而 attribute 就完全靠边站了。
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
With this model firmly in mind, read on to learn about binding targets.
|
||||
|
@ -904,25 +867,16 @@ The following table summarizes:
|
|||
下面是的汇总表:
|
||||
|
||||
<style>
|
||||
|
||||
td, th {vertical-align: top}
|
||||
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
|
||||
<col width="10%">
|
||||
|
||||
</col>
|
||||
|
||||
<col width="15%">
|
||||
|
||||
</col>
|
||||
|
||||
<col width="75%">
|
||||
|
||||
</col>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -950,7 +904,6 @@ The following table summarizes:
|
|||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -963,20 +916,12 @@ The following table summarizes:
|
|||
|
||||
<td>
|
||||
|
||||
Element property
|
||||
|
||||
元素的 property
|
||||
|
||||
<br>
|
||||
|
||||
Component property
|
||||
|
||||
组件的 property
|
||||
|
||||
<br>
|
||||
|
||||
Element property<br>
|
||||
Component property<br>
|
||||
Directive property
|
||||
|
||||
元素的 property<br>
|
||||
组件的 property<br>
|
||||
指令的 property
|
||||
|
||||
</td>
|
||||
|
@ -990,7 +935,6 @@ The following table summarizes:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -1003,20 +947,12 @@ The following table summarizes:
|
|||
|
||||
<td>
|
||||
|
||||
Element event
|
||||
|
||||
元素的事件
|
||||
|
||||
<br>
|
||||
|
||||
Component event
|
||||
|
||||
组件的事件
|
||||
|
||||
<br>
|
||||
|
||||
Element event<br>
|
||||
Component event<br>
|
||||
Directive event
|
||||
|
||||
元素的事件<br>
|
||||
组件的事件<br>
|
||||
指令的事件
|
||||
|
||||
</td>
|
||||
|
@ -1030,7 +966,6 @@ The following table summarizes:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -1058,7 +993,6 @@ The following table summarizes:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -1085,7 +1019,6 @@ The following table summarizes:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -1111,7 +1044,6 @@ The following table summarizes:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -1137,7 +1069,6 @@ The following table summarizes:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
With this broad view in mind, you're ready to look at binding types in detail.
|
||||
|
@ -1455,9 +1386,7 @@ content harmlessly.
|
|||
插值表达式处理 script 标签与属性绑定有所不同,但是二者都只渲染没有危害的内容。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/template-syntax/evil-title.png' alt="evil title made safe">
|
||||
|
||||
</figure>
|
||||
|
||||
<hr/>
|
||||
|
@ -1562,11 +1491,26 @@ Here's how the table renders:
|
|||
这里是表格渲染出来的样子:
|
||||
|
||||
<table border="1px">
|
||||
<tr><td colspan="2">
|
||||
|
||||
<tr><td colspan="2">One-Two</td></tr>
|
||||
One-Two
|
||||
|
||||
<tr><td>Five</td><td>Six</td></tr>
|
||||
1-2列
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
Five
|
||||
|
||||
五列
|
||||
|
||||
</td><td>
|
||||
|
||||
Six
|
||||
|
||||
六列
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
One of the primary use cases for attribute binding
|
||||
|
@ -2340,9 +2284,7 @@ Here are all variations in action, including the uppercase version:
|
|||
这里是所有这些变体的动画,包括这个大写转换的版本:
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/template-syntax/ng-model-anim.gif' alt="NgModel variations">
|
||||
|
||||
</figure>
|
||||
|
||||
<hr/>
|
||||
|
@ -2700,9 +2642,7 @@ Here is an illustration of the _trackBy_ effect.
|
|||
有了`trackBy`,则只有修改了`id`的按钮才会触发元素替换。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/template-syntax/ng-for-track-by-anim.gif" alt="trackBy">
|
||||
|
||||
</figure>
|
||||
|
||||
<hr/>
|
||||
|
@ -2731,9 +2671,7 @@ Angular只会把*选中的*元素放进DOM中。
|
|||
</code-example>
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/template-syntax/switch-anim.gif" alt="trackBy">
|
||||
|
||||
</figure>
|
||||
|
||||
`NgSwitch` is the controller directive. Bind it to an expression that returns the *switch value*.
|
||||
|
@ -2931,7 +2869,7 @@ Remember that all **components** are **directives**.
|
|||
记住,所有的**组件**都是**指令**。
|
||||
|
||||
The following discussion refers to _components_ for brevity and
|
||||
because this topic is mostly a concern for component authors.
|
||||
because this topic is mostly a concern for component authors.
|
||||
|
||||
为简洁起见,以下讨论会涉及到**组件**,因为这个主题主要是组件作者所关心的问题。
|
||||
|
||||
|
@ -2939,6 +2877,8 @@ because this topic is mostly a concern for component authors.
|
|||
|
||||
<h3 class="no-toc">Discussion</h3>
|
||||
|
||||
<h3 class="no-toc">讨论</h3>
|
||||
|
||||
You are usually binding a template to its _own component class_.
|
||||
In such binding expressions, the component's property or method is to the _right_ of the (`=`).
|
||||
|
||||
|
@ -3051,9 +2991,7 @@ The terms _input_ and _output_ reflect the perspective of the target directive.
|
|||
_输入_和_输出_这两个词是从目标指令的角度来说的。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/template-syntax/input-output.png" alt="Inputs and outputs">
|
||||
|
||||
</figure>
|
||||
|
||||
`HeroDetailComponent.hero` is an **input** property from the perspective of `HeroDetailComponent`
|
||||
|
@ -3423,4 +3361,4 @@ You've completed this survey of template syntax.
|
|||
Now it's time to put that knowledge to work on your own components and directives.
|
||||
|
||||
|
||||
我们完成了模板语法的概述。现在,该把如何写组件和指令的知识投入到实际工作当中了。
|
||||
我们完成了模板语法的概述。现在,该把如何写组件和指令的知识投入到实际工作当中了。
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# Testing
|
||||
|
||||
TBD. Original content [here](https://docs.google.com/document/d/1gGP5sqWNCHAWWV_GLdZQ1XyMO4K-CHksUxux0BFtVxk/edit#heading=h.ohqykkhzdhb2).
|
||||
TBD. Original content [here](https://docs.google.com/document/d/1gGP5sqWNCHAWWV_GLdZQ1XyMO4K-CHksUxux0BFtVxk/edit#heading=h.ohqykkhzdhb2).
|
||||
|
|
|
@ -7,13 +7,9 @@ This guide offers tips and techniques for unit and integration testing Angular a
|
|||
The guide presents tests of a sample CLI application that is much like the [_Tour of Heroes_ tutorial](tutorial).
|
||||
The sample application and all tests in this guide are available for inspection and experimentation:
|
||||
|
||||
*
|
||||
* <live-example embedded-style>Sample app</live-example>
|
||||
|
||||
<live-example embedded-style>Sample app</live-example>
|
||||
|
||||
*
|
||||
|
||||
<live-example stackblitz="specs">Tests</live-example>
|
||||
* <live-example stackblitz="specs">Tests</live-example>
|
||||
|
||||
<hr>
|
||||
|
||||
|
@ -54,9 +50,7 @@ It shows that Karma ran three tests that all passed.
|
|||
A chrome browser also opens and displays the test output in the "Jasmine HTML Reporter" like this.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/testing/initial-jasmine-html-reporter.png' alt="Jasmine HTML Reporter in the browser">
|
||||
|
||||
</figure>
|
||||
|
||||
Most people find this browser output easier to read than the console log.
|
||||
|
@ -765,8 +759,11 @@ Your instinct is to write a test that immediately inspects the `<h1>` like this:
|
|||
</code-example>
|
||||
|
||||
_That test fails_ with the message:
|
||||
|
||||
```javascript
|
||||
|
||||
expected '' to contain 'Test Tour of Heroes'.
|
||||
|
||||
```
|
||||
|
||||
Binding happens when Angular performs **change detection**.
|
||||
|
@ -1116,8 +1113,11 @@ The following test confirms the expected behavior when the service returns an `E
|
|||
</code-example>
|
||||
|
||||
Note that the `it()` function receives an argument of the following form.
|
||||
|
||||
```javascript
|
||||
|
||||
fakeAsync(() => { /* test body */ })`
|
||||
|
||||
```
|
||||
|
||||
The `fakeAsync` function enables a linear coding style by running the test body in a special _fakeAsync test zone_.
|
||||
|
@ -1401,10 +1401,12 @@ The second argument is null because the observable never emits a value.
|
|||
#### Learn about marble testing
|
||||
|
||||
{@a marble-frame}
|
||||
|
||||
A _marble frame_ is a virtual unit of testing time.
|
||||
Each symbol (`-`, `x`, `|`, `#`) marks the passing of one frame.
|
||||
|
||||
{@a cold-observable}
|
||||
|
||||
A _cold_ observable doesn't produce values until you subscribe to it.
|
||||
Most of your application observables are cold.
|
||||
All [_HttpClient_](guide/http) methods return cold observables.
|
||||
|
@ -1607,7 +1609,9 @@ in a helper such as the `click()` function below:
|
|||
|
||||
The first parameter is the _element-to-click_. If you wish, you can pass a
|
||||
custom event object as the second parameter. The default is a (partial)
|
||||
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button">left-button mouse event object</a>
|
||||
|
||||
accepted by many handlers including the `RouterLink` directive.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
@ -2036,6 +2040,7 @@ question for a separate set of tests.
|
|||
</div>
|
||||
|
||||
{@a by-directive}
|
||||
|
||||
{@a inject-directive}
|
||||
|
||||
#### _By.directive_ and injected directives
|
||||
|
@ -2121,9 +2126,7 @@ tests with the `RouterTestingModule`.
|
|||
The `HeroDetailComponent` is a simple view with a title, two hero fields, and two buttons.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/testing/hero-detail.component.png' alt="HeroDetailComponent in action">
|
||||
|
||||
</figure>
|
||||
|
||||
But there's plenty of template complexity even in this simple form.
|
||||
|
@ -2594,9 +2597,7 @@ A better solution is to create an artificial test component that demonstrates al
|
|||
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="test-component" title="app/shared/highlight.directive.spec.ts (TestComponent)" linenums="false"></code-example>
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/testing/highlight-directive-spec.png' alt="HighlightDirective spec in action">
|
||||
|
||||
</figure>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -2683,9 +2684,7 @@ Debug specs in the browser in the same way that you debug an application.
|
|||
1. Refresh the browser, and it stops at the breakpoint.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
|
||||
|
||||
</figure>
|
||||
|
||||
<hr>
|
||||
|
@ -2702,7 +2701,6 @@ The [_TestBed_](#testbed-api-summary) and [_ComponentFixture_](#component-fixtur
|
|||
Here's a summary of the stand-alone functions, in order of likely utility:
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -2878,7 +2876,6 @@ Here's a summary of the stand-alone functions, in order of likely utility:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
|
@ -2923,6 +2920,7 @@ appropriate to the method, that is, the parameter of an `@NgModule`,
|
|||
</code-example>
|
||||
|
||||
{@a testbed-methods}
|
||||
|
||||
{@a testbed-api-summary}
|
||||
|
||||
The `TestBed` API consists of static class methods that either update or reference a _global_ instance of the`TestBed`.
|
||||
|
@ -2935,7 +2933,6 @@ Call `TestBed` methods _within_ a `beforeEach()` to ensure a fresh start before
|
|||
Here are the most important static methods, in order of likely utility.
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -3156,7 +3153,6 @@ Here are the most important static methods, in order of likely utility.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table
|
||||
|
||||
A few of the `TestBed` instance methods are not covered by static `TestBed` _class_ methods.
|
||||
|
@ -3180,7 +3176,6 @@ its DOM representation, and aspects of its Angular environment.
|
|||
Here are the most important properties for testers, in order of likely utility.
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -3269,7 +3264,6 @@ Here are the most important properties for testers, in order of likely utility.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
{@a component-fixture-methods}
|
||||
|
@ -3282,7 +3276,6 @@ Call these method to trigger Angular behavior in response to simulated user acti
|
|||
Here are the most useful methods for testers.
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -3419,7 +3412,6 @@ Here are the most useful methods for testers.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
{@a debug-element-details}
|
||||
|
@ -3434,7 +3426,6 @@ you can walk (and query) the fixture's entire element and component subtrees.
|
|||
Here are the most useful `DebugElement` members for testers, in approximate order of utility:
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -3702,7 +3693,6 @@ Here are the most useful `DebugElement` members for testers, in approximate orde
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
{@a query-predicate}
|
||||
|
@ -3789,4 +3779,4 @@ accidental corruption of remote resources.
|
|||
It can even be hard to navigate to the component you want to test.
|
||||
|
||||
Because of these many obstacles, you should test DOM interaction
|
||||
with unit testing techniques as much as possible.
|
||||
with unit testing techniques as much as possible.
|
||||
|
|
|
@ -20,12 +20,11 @@ that are important to Angular developers, including details about the following
|
|||
|
||||
* [tsconfig.json](guide/typescript-configuration#tsconfig)—TypeScript compiler configuration.
|
||||
|
||||
[tsconfig.json](guide/typescript-configuration#tsconfig) - TypeScript编译器配置。
|
||||
|
||||
[tsconfig.json](guide/typescript-configuration#tsconfig) - TypeScript编译器配置。
|
||||
|
||||
* [typings](guide/typescript-configuration#typings)—TypesScript declaration files.
|
||||
|
||||
[typings](guide/typescript-configuration#typings) - TypesScript类型声明文件。
|
||||
|
||||
[typings](guide/typescript-configuration#typings) - TypesScript类型声明文件。
|
||||
|
||||
{@a tsconfig}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ There are three main reasons to create a Universal version of your app.
|
|||
1. Show the first page quickly
|
||||
|
||||
{@a seo}
|
||||
|
||||
{@a web-crawlers}
|
||||
|
||||
#### Facilitate web crawlers
|
||||
|
@ -146,57 +147,19 @@ When you're done, the folder structure will look like this:
|
|||
<code-example format="." language="none" linenums="false">
|
||||
|
||||
src/
|
||||
index.html
|
||||
|
||||
<i>app web page</i>
|
||||
|
||||
main.ts
|
||||
|
||||
<i>bootstrapper for client app</i>
|
||||
|
||||
main.server.ts
|
||||
|
||||
<i>* bootstrapper for server app</i>
|
||||
|
||||
tsconfig.app.json
|
||||
|
||||
<i>TypeScript client configuration</i>
|
||||
|
||||
tsconfig.server.json
|
||||
|
||||
<i>* TypeScript server configuration</i>
|
||||
|
||||
tsconfig.spec.json
|
||||
|
||||
<i>TypeScript spec configuration</i>
|
||||
|
||||
style.css
|
||||
|
||||
<i>styles for the app</i>
|
||||
|
||||
app/ ...
|
||||
|
||||
<i>application code</i>
|
||||
|
||||
app.server.module.ts
|
||||
|
||||
<i>* server-side application module</i>
|
||||
|
||||
server.ts
|
||||
|
||||
<i>* express web server</i>
|
||||
|
||||
tsconfig.json
|
||||
|
||||
<i>TypeScript client configuration</i>
|
||||
|
||||
package.json
|
||||
|
||||
<i>npm configuration</i>
|
||||
|
||||
webpack.server.config.js
|
||||
|
||||
<i>* Webpack server configuration</i>
|
||||
index.html <i>app web page</i>
|
||||
main.ts <i>bootstrapper for client app</i>
|
||||
main.server.ts <i>* bootstrapper for server app</i>
|
||||
tsconfig.app.json <i>TypeScript client configuration</i>
|
||||
tsconfig.server.json <i>* TypeScript server configuration</i>
|
||||
tsconfig.spec.json <i>TypeScript spec configuration</i>
|
||||
style.css <i>styles for the app</i>
|
||||
app/ ... <i>application code</i>
|
||||
app.server.module.ts <i>* server-side application module</i>
|
||||
server.ts <i>* express web server</i>
|
||||
tsconfig.json <i>TypeScript client configuration</i>
|
||||
package.json <i>npm configuration</i>
|
||||
webpack.server.config.js <i>* Webpack server configuration</i>
|
||||
|
||||
</code-example>
|
||||
|
||||
|
|
|
@ -373,7 +373,6 @@ frameworks in how it actually works.
|
|||
无论是在AngularJS中还是在Angular中,依赖注入都位于前沿和中心的位置,但在两个框架的工作原理上,却存在着一些关键的不同之处。
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -389,7 +388,6 @@ frameworks in how it actually works.
|
|||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -411,7 +409,6 @@ frameworks in how it actually works.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -433,7 +430,6 @@ frameworks in how it actually works.
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
Even accounting for these differences you can still have dependency injection
|
||||
|
@ -462,9 +458,7 @@ everything work seamlessly:
|
|||
当我们注册一个要降级的服务时,要明确指定一个打算在AngularJS中使用的*字符串令牌*。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/upgrade/injectors.png" alt="The two injectors in a hybrid application">
|
||||
|
||||
</figure>
|
||||
|
||||
#### Components and the DOM
|
||||
|
@ -519,9 +513,7 @@ ways:
|
|||
通过透传(transclude)或投影(project)来自另一个框架的内容。`UpgradeModule`牵线搭桥,把AngularJS的透传概念和Angular的内容投影概念关联起来。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/upgrade/dom.png" alt="DOM element ownership in a hybrid application">
|
||||
|
||||
</figure>
|
||||
|
||||
Whenever you use a component that belongs to the other framework, a
|
||||
|
@ -591,9 +583,7 @@ AngularJS and Angular approaches. Here's what happens:
|
|||
`UpgradeModule`将在每一次离开Angular zone时调用AngularJS的`$rootScope.$apply()`。这样也就同样会在每个事件之后触发AngularJS的变更检测。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src="generated/images/guide/upgrade/change_detection.png" alt="Change detection in a hybrid application">
|
||||
|
||||
</figure>
|
||||
|
||||
In practice, you do not need to call `$apply()`,
|
||||
|
@ -972,7 +962,6 @@ All that is left is to add it to `AppModule`'s `declarations` array.
|
|||
这样我们就得到一个完全升级的AngularJS组件,并且可以Angular中使用。
|
||||
剩下是工作就是把它加入到`AppModule`的`declarations`数组。
|
||||
|
||||
|
||||
<code-example path="upgrade-module/src/app/upgrade-static/hero-detail.component.ts" region="hero-detail-upgrade" title="hero-detail.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
@ -1003,7 +992,6 @@ observing the following rules:
|
|||
当我们从Angular模板中使用该组件时,我们要使用**Angular模板语法**来提供这些输入属性和输出属性,但要遵循下列规则:
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -1027,7 +1015,6 @@ observing the following rules:
|
|||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -1051,7 +1038,6 @@ observing the following rules:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -1075,7 +1061,6 @@ observing the following rules:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -1099,7 +1084,6 @@ observing the following rules:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -1128,7 +1112,6 @@ observing the following rules:
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
For example, imagine a hero detail AngularJS component directive
|
||||
|
@ -2900,7 +2883,6 @@ For PhoneCat you need to make the following changes in order to make things work
|
|||
这是因为E2E测试有一些匹配器是AngularJS中特有的。对于PhoneCat来说,为了让它能在Angular下工作,我们得做下列修改:
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
|
||||
<th>
|
||||
|
@ -2928,7 +2910,6 @@ For PhoneCat you need to make the following changes in order to make things work
|
|||
</th>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -2952,7 +2933,6 @@ For PhoneCat you need to make the following changes in order to make things work
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -2976,7 +2956,6 @@ For PhoneCat you need to make the following changes in order to make things work
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -3000,7 +2979,6 @@ For PhoneCat you need to make the following changes in order to make things work
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -3024,7 +3002,6 @@ For PhoneCat you need to make the following changes in order to make things work
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
@ -3048,7 +3025,6 @@ For PhoneCat you need to make the following changes in order to make things work
|
|||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
When the bootstrap method is switched from that of `UpgradeModule` to
|
||||
|
@ -3214,4 +3190,3 @@ the `RouteLink` directives work.
|
|||
<code-example path="upgrade-phonecat-3-final/app/phone-list/phone-list.component.spec.ts" region="routestuff" title="app/phone-list/phone-list.component.spec.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
|
|
@ -131,9 +131,7 @@ Here's what the UI displays:
|
|||
</code-example>
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/user-input/keyup1-anim.gif' alt="key up 1">
|
||||
|
||||
</figure>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -240,9 +238,7 @@ Type something in the input box, and watch the display update with each keystrok
|
|||
在输入框中输入,就会看到每次按键时,显示也随之更新了。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/user-input/keyup-loop-back-anim.gif' alt="loop back">
|
||||
|
||||
</figure>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -309,9 +305,7 @@ Here's how it works.
|
|||
下面展示了它是如何工作的。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/user-input/keyup3-anim.gif' alt="key up 3">
|
||||
|
||||
</figure>
|
||||
|
||||
## On blur
|
||||
|
@ -353,9 +347,7 @@ clicking **Add**.
|
|||
用户可以通过输入英雄名和点击“添加”按钮来添加英雄。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/user-input/little-tour-anim.gif' alt="Little Tour of Heroes">
|
||||
|
||||
</figure>
|
||||
|
||||
Below is the "Little Tour of Heroes" component.
|
||||
|
@ -439,4 +431,4 @@ two-way bindings with `NgModel`.
|
|||
|
||||
这些技术对小规模演示很实用,但是在处理大量用户输入时,很容易变得累赘和笨拙。
|
||||
要在数据录入字段和模型属性之间传递数据,双向数据绑定是更加优雅和简洁的方式。
|
||||
下一章`表单`解释了如何用`NgModel`来进行双向绑定。
|
||||
下一章`表单`解释了如何用`NgModel`来进行双向绑定。
|
||||
|
|
|
@ -38,7 +38,7 @@ Visual Studio 2015, follow these steps:
|
|||
If you prefer a `File | New Project` experience and are using **ASP.NET Core**,
|
||||
then consider the _experimental_
|
||||
<a href="http://blog.stevensanderson.com/2016/10/04/angular2-template-for-visual-studio/">ASP.NET Core + Angular template for Visual Studio 2015</a>.
|
||||
Note that the resulting code does not map to the docs. Adjust accordingly.
|
||||
Note that the resulting code does not map to the docs. Adjust accordingly.
|
||||
|
||||
如果你希望使用**ASP.NET Core**并体验全新项目,
|
||||
参见_预览版_<a href="http://blog.stevensanderson.com/2016/10/04/angular2-template-for-visual-studio/" target="_blank">ASP.NET Core + Angular template for Visual Studio 2015</a>。
|
||||
|
@ -116,13 +116,13 @@ Configure Visual Studio to use the global external web tools instead of the tool
|
|||
* 在右侧,将`$(PATH)`移动到 `$(DevEnvDir`)上面。这样,Visual Stuio就会在使用自带的外部工具时,优先使用全局路径中的外部工具(比如npm)。
|
||||
|
||||
* Click OK to close the dialog.
|
||||
|
||||
点击OK关闭对话框。
|
||||
|
||||
点击OK关闭对话框。
|
||||
|
||||
* Restart Visual Studio for this change to take effect.
|
||||
|
||||
重启Visual Studio,以让设置变化生效。
|
||||
|
||||
重启Visual Studio,以让设置变化生效。
|
||||
|
||||
Visual Studio now looks first for external tools in the current workspace and
|
||||
if it doesn't find them, it looks in the global path. If Visual Studio doesn't
|
||||
find them in either location, it will use its own versions of the tools.
|
||||
|
@ -436,4 +436,4 @@ Try editing any of the project files. Save and refresh the browser to
|
|||
see the changes.
|
||||
|
||||
|
||||
尝试编辑任何项目文件,*保存*并刷新浏览器来查看效果。
|
||||
尝试编辑任何项目文件,*保存*并刷新浏览器来查看效果。
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# Webpack简介
|
||||
|
||||
<style>
|
||||
|
||||
h4 {font-size: 17px !important; text-transform: none !important;}
|
||||
.syntax { font-family: Consolas, 'Lucida Sans', Courier, sans-serif; color: black; font-size: 85%; }
|
||||
|
||||
|
@ -781,23 +780,23 @@ There are additional plugins:
|
|||
|
||||
* *`NoEmitOnErrorsPlugin`—stops the build if there is an error.
|
||||
|
||||
*`NoEmitOnErrorsPlugin`* - 如果出错就停止构建。*
|
||||
*`NoEmitOnErrorsPlugin`* - 如果出错就停止构建。*
|
||||
|
||||
* *`UglifyJsPlugin`—minifies the bundles.
|
||||
|
||||
*`UglifyJsPlugin`* - 最小化(minify)生成的包。
|
||||
*`UglifyJsPlugin`* - 最小化(minify)生成的包。
|
||||
|
||||
* *`ExtractTextPlugin`—extracts embedded css as external files, adding cache-busting hash to the filename.
|
||||
|
||||
*`ExtractTextPlugin`* - 把内嵌的css抽取成外部文件,并为其文件名添加“缓存无效哈希”。
|
||||
*`ExtractTextPlugin`* - 把内嵌的css抽取成外部文件,并为其文件名添加“缓存无效哈希”。
|
||||
|
||||
* *`DefinePlugin`—use to define environment variables that you can reference within the application.
|
||||
|
||||
*`DefinePlugin`* - 用来定义环境变量,以便我们在自己的程序中引用它。
|
||||
*`DefinePlugin`* - 用来定义环境变量,以便我们在自己的程序中引用它。
|
||||
|
||||
* *`LoaderOptionsPlugins`—to override options of certain loaders.
|
||||
|
||||
*`LoaderOptionsPlugins`* - 为特定的加载器提供选项。
|
||||
*`LoaderOptionsPlugins`* - 为特定的加载器提供选项。
|
||||
|
||||
Thanks to the `DefinePlugin` and the `ENV` variable defined at top, you can enable Angular production mode like this:
|
||||
|
||||
|
@ -993,9 +992,9 @@ they're added behind the scenes by the `angular2-template-loader` plug-in.
|
|||
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 conclusion}
|
||||
|
||||
## Conclusion
|
||||
|
@ -1014,4 +1013,4 @@ _但我们还能做得更多_。搜索互联网来获得专家的建议,并扩
|
|||
[Back to top](guide/webpack#top)
|
||||
|
||||
|
||||
[回到顶部](guide/webpack#top)
|
||||
[回到顶部](guide/webpack#top)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
<h1 class="no-toc">What is Angular?</h1>
|
||||
|
||||
Angular is a platform that makes it easy to build applications with the web. Angular combines declarative templates, dependency injection, end to end tooling, and integrated best practices to solve development challenges. Angular empowers developers to build applications that live on the web, mobile, or the desktop
|
||||
|
@ -12,7 +10,7 @@ Angular 是一个开发平台。它能帮你更轻松的构建 Web 应用。Angu
|
|||
title="Experience Angular in a live coding environment">
|
||||
|
||||
<section>Get a Glimpse of Angular</section>
|
||||
|
||||
|
||||
<section>Angular 走马观花</section>
|
||||
|
||||
<p>A quick look at an Angular "hello world" application.</p>
|
||||
|
@ -44,7 +42,7 @@ Angular 是一个开发平台。它能帮你更轻松的构建 Web 应用。Angu
|
|||
<a href="guide/architecture" class="docs-card" title="Angular Architecture">
|
||||
|
||||
<section>Fundamentals</section>
|
||||
|
||||
|
||||
<section>基本原理</section>
|
||||
|
||||
<p>Learn Angular application fundamentals, starting with an architecture overview.</p>
|
||||
|
@ -54,6 +52,7 @@ Angular 是一个开发平台。它能帮你更轻松的构建 Web 应用。Angu
|
|||
<p class="card-footer">Architecture</p>
|
||||
|
||||
<p class="card-footer">架构</p>
|
||||
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
@ -97,4 +96,4 @@ Please consult and adhere to the
|
|||
|
||||
你可以到 Angular 在 Github 上的仓库中提出文档方面的[问题](https://github.com/angular/angular/issues "Angular Github issues"),并创建[Pull Requests](https://github.com/angular/angular/pulls "Angular Github pull requests")。
|
||||
[贡献者指南](https://github.com/angular/angular/blob/master/CONTRIBUTING.md "贡献者指南")将会帮助你更好的为社区做贡献。
|
||||
我们社区的价值观是互相尊重、互相支持。参见[社区行为规范](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md "contributor code of conduct")。
|
||||
我们社区的价值观是互相尊重、互相支持。参见[社区行为规范](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md "contributor code of conduct")。
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
<h1 class="no-toc">Tutorial: Tour of Heroes</h1>
|
||||
|
||||
<h1 class="no-toc">教程:英雄指南</h1>
|
||||
|
@ -74,9 +72,7 @@ view and the most heroic heroes:
|
|||
下面是本教程关于界面的构想:开始是“Dashboard(仪表盘)”视图,来展示我们最勇敢的英雄。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/toh/heroes-dashboard-1.png' alt="Output of heroes dashboard">
|
||||
|
||||
</figure>
|
||||
|
||||
You can click the two links above the dashboard ("Dashboard" and "Heroes")
|
||||
|
@ -91,9 +87,7 @@ where you can change the hero's name.
|
|||
当我们点击仪表盘上名叫“Magneta”的英雄时,路由将把我们带到这个英雄的详情页,在这里,我们可以修改英雄的名字。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/toh/hero-details-1.png' alt="Details of hero in app">
|
||||
|
||||
</figure>
|
||||
|
||||
Clicking the "Back" button returns you to the Dashboard.
|
||||
|
@ -105,9 +99,7 @@ If you click "Heroes," the app displays the "Heroes" master list view.
|
|||
如果我们点击“Heroes(英雄列表)”链接,应用将把我们带到“英雄”主列表视图。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/toh/heroes-list-2.png' alt="Output of heroes list app">
|
||||
|
||||
</figure>
|
||||
|
||||
When you click a different hero name, the read-only mini detail beneath the list reflects the new choice.
|
||||
|
@ -124,9 +116,7 @@ The following diagram captures all of the navigation options.
|
|||
下面这张图汇总了我们所有可能的导航路径。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
|
||||
</figure>
|
||||
|
||||
Here's the app in action:
|
||||
|
@ -134,8 +124,5 @@ Here's the app in action:
|
|||
下图演示了我们应用中的所有操作。
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/toh/toh-anim.gif' alt="Tour of Heroes in Action">
|
||||
|
||||
</figure>
|
||||
|
||||
|
|
|
@ -104,24 +104,20 @@ Here's an excerpt from the `styles.css` for the _Tour of Heroes_ sample app.
|
|||
The source code for this tutorial and the complete _Tour of Heroes_ global styles
|
||||
are available in the <live-example></live-example>.
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
Here are the code files discussed on this page.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/app/app.component.ts" path="toh-pt0/src/app/app.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.html" path="toh-pt0/src/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/styles.css (excerpt)"
|
||||
path="toh-pt0/src/styles.1.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
@ -132,4 +128,4 @@ Here are the code files discussed on this page.
|
|||
|
||||
* You learned that Angular components display data.
|
||||
|
||||
* You used the double curly braces of interpolation to display the app title.
|
||||
* You used the double curly braces of interpolation to display the app title.
|
||||
|
|
|
@ -68,7 +68,7 @@ Add a `hero` property to the `HeroesComponent` for a hero named "Windstorm."
|
|||
|
||||
Open the `heroes.component.html` template file.
|
||||
Delete the default text generated by the Angular CLI and
|
||||
replace it with a data binding to the new `hero` property.
|
||||
replace it with a data binding to the new `hero` property.
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.1.html" title="heroes.component.html" region="show-hero-1" linenums="false">
|
||||
|
||||
|
@ -278,29 +278,23 @@ Your app should look like this <live-example></live-example>. Here are the code
|
|||
<code-tabs>
|
||||
|
||||
<code-pane title="src/app/heroes/heroes.component.ts" path="toh-pt1/src/app/heroes/heroes.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/heroes/heroes.component.html" path="toh-pt1/src/app/heroes/heroes.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.module.ts"
|
||||
path="toh-pt1/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.ts" path="toh-pt1/src/app/app.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.html" path="toh-pt1/src/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/hero.ts"
|
||||
path="toh-pt1/src/app/hero.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
|
|
@ -68,7 +68,7 @@ In this example
|
|||
|
||||
* `heroes` is the list from the `HeroesComponent` class.
|
||||
|
||||
* `hero` holds the current hero object for each iteration through the list.
|
||||
* `hero` holds the current hero object for each iteration through the list.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
|
@ -254,19 +254,14 @@ Your app should look like this <live-example></live-example>.
|
|||
Here are the code files discussed on this page, including the `HeroesComponent` styles.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/app/heroes/heroes.component.ts" path="toh-pt2/src/app/heroes/heroes.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/heroes/heroes.component.html" path="toh-pt2/src/app/heroes/heroes.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/heroes/heroes.component.css" path="toh-pt2/src/app/heroes/heroes.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
|
|
@ -141,15 +141,12 @@ Here are the code files discussed on this page and your app should look like thi
|
|||
<code-tabs>
|
||||
|
||||
<code-pane title="src/app/hero-detail/hero-detail.component.ts" path="toh-pt3/src/app/hero-detail/hero-detail.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/hero-detail/hero-detail.component.html" path="toh-pt3/src/app/hero-detail/hero-detail.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/heroes/heroes.component.html" path="toh-pt3/src/app/heroes/heroes.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
|
|
@ -256,12 +256,10 @@ Find the `getHeroes` method and replace it with the following code
|
|||
|
||||
<code-pane title="heroes.component.ts (Observable)"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.ts" region="getHeroes">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="heroes.component.ts (Original)"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.1.ts" region="getHeroes">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
@ -439,42 +437,34 @@ Here are the code files discussed on this page and your app should look like thi
|
|||
|
||||
<code-pane title="src/app/hero.service.ts"
|
||||
path="toh-pt4/src/app/hero.service.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/message.service.ts"
|
||||
path="toh-pt4/src/app/message.service.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/heroes/heroes.component.ts"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/messages/messages.component.ts"
|
||||
path="toh-pt4/src/app/messages/messages.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/messages/messages.component.html"
|
||||
path="toh-pt4/src/app/messages/messages.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/messages/messages.component.css"
|
||||
path="toh-pt4/src/app/messages/messages.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.module.ts"
|
||||
path="toh-pt4/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.html"
|
||||
path="toh-pt4/src/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
|
|
@ -35,10 +35,7 @@ Use the CLI to generate it.
|
|||
|
||||
<div class="l-sub-section">
|
||||
|
||||
`--flat` puts the file in `src/app` instead of its own folder.
|
||||
|
||||
<br>
|
||||
|
||||
`--flat` puts the file in `src/app` instead of its own folder.<br>
|
||||
`--module=app` tells the CLI to register it in the `imports` array of the `AppModule`.
|
||||
|
||||
</div>
|
||||
|
@ -208,22 +205,17 @@ The CLI generates the files for the `DashboardComponent` and declares it in `App
|
|||
Replace the default file content in these three files as follows and then return for a little discussion:
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.1.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/dashboard/dashboard.component.ts" path="toh-pt5/src/app/dashboard/dashboard.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
The _template_ presents a grid of hero name links.
|
||||
|
@ -569,24 +561,20 @@ You've met all of the navigational requirements that propelled this page.
|
|||
Here are the code files discussed on this page and your app should look like this <live-example></live-example>.
|
||||
|
||||
{@a approutingmodule}
|
||||
|
||||
{@a appmodule}
|
||||
|
||||
#### _AppRoutingModule_ and _AppModule_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="src/app/app-routing.module.ts"
|
||||
path="toh-pt5/src/app/app-routing.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/app.module.ts"
|
||||
path="toh-pt5/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a appcomponent}
|
||||
|
@ -594,19 +582,15 @@ Here are the code files discussed on this page and your app should look like thi
|
|||
#### _AppComponent_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="src/app/app.component.html"
|
||||
path="toh-pt5/src/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/app.component.css"
|
||||
path="toh-pt5/src/app/app.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a dashboardcomponent}
|
||||
|
@ -614,22 +598,17 @@ Here are the code files discussed on this page and your app should look like thi
|
|||
#### _DashboardComponent_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/dashboard/dashboard.component.ts" path="toh-pt5/src/app/dashboard/dashboard.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a heroescomponent}
|
||||
|
@ -637,24 +616,19 @@ Here are the code files discussed on this page and your app should look like thi
|
|||
#### _HeroesComponent_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="src/app/heroes/heroes.component.html" path="toh-pt5/src/app/heroes/heroes.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/heroes/heroes.component.ts"
|
||||
path="toh-pt5/src/app/heroes/heroes.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/heroes/heroes.component.css"
|
||||
path="toh-pt5/src/app/heroes/heroes.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a herodetailcomponent}
|
||||
|
@ -662,22 +636,17 @@ Here are the code files discussed on this page and your app should look like thi
|
|||
#### _HeroDetailComponent_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="src/app/hero-detail/hero-detail.component.html" path="toh-pt5/src/app/hero-detail/hero-detail.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/hero-detail/hero-detail.component.ts" path="toh-pt5/src/app/hero-detail/hero-detail.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="src/app/hero-detail/hero-detail.component.css" path="toh-pt5/src/app/hero-detail/hero-detail.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
|
|
@ -592,9 +592,7 @@ Run the app again. In the *Dashboard*, enter some text in the search box.
|
|||
If you enter characters that match any existing hero names, you'll see something like this.
|
||||
|
||||
<figure>
|
||||
|
||||
<img src='generated/images/guide/toh/toh-hero-search.png' alt="Hero Search Component">
|
||||
|
||||
</figure>
|
||||
|
||||
## Final code review
|
||||
|
@ -604,31 +602,26 @@ Your app should look like this <live-example></live-example>.
|
|||
Here are the code files discussed on this page (all in the `src/app/` folder).
|
||||
|
||||
{@a heroservice}
|
||||
|
||||
{@a inmemorydataservice}
|
||||
|
||||
{@a appmodule}
|
||||
|
||||
#### _HeroService_, _InMemoryDataService_, _AppModule_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="hero.service.ts"
|
||||
path="toh-pt6/src/app/hero.service.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="in-memory-data.service.ts"
|
||||
path="toh-pt6/src/app/in-memory-data.service.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="app.module.ts"
|
||||
path="toh-pt6/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a heroescomponent}
|
||||
|
@ -636,25 +629,18 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
|||
#### _HeroesComponent_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="heroes/heroes.component.html"
|
||||
path="toh-pt6/src/app/heroes/heroes.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="heroes/heroes.component.ts"
|
||||
path="toh-pt6/src/app/heroes/heroes.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="heroes/heroes.component.css"
|
||||
path="toh-pt6/src/app/heroes/heroes.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a herodetailcomponent}
|
||||
|
@ -662,19 +648,14 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
|||
#### _HeroDetailComponent_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="hero-detail/hero-detail.component.html"
|
||||
path="toh-pt6/src/app/hero-detail/hero-detail.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="hero-detail/hero-detail.component.ts"
|
||||
path="toh-pt6/src/app/hero-detail/hero-detail.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a herosearchcomponent}
|
||||
|
@ -682,25 +663,18 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
|||
#### _HeroSearchComponent_
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane
|
||||
title="hero-search/hero-search.component.html"
|
||||
path="toh-pt6/src/app/hero-search/hero-search.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="hero-search/hero-search.component.ts"
|
||||
path="toh-pt6/src/app/hero-search/hero-search.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
title="hero-search/hero-search.component.css"
|
||||
path="toh-pt6/src/app/hero-search/hero-search.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
|
Loading…
Reference in New Issue