fix: 合并第一版的翻译

This commit is contained in:
Zhicheng Wang 2018-03-07 15:42:49 +08:00
parent fc58e0eee0
commit 964266f4b0
33 changed files with 288 additions and 44 deletions

View File

@ -1613,7 +1613,7 @@ also encapsulate a style sheet within a specific component.
### Link tag
### Link 标签
### Link标签
<code-example hideCopy>
@ -1639,8 +1639,8 @@ also encapsulate a style sheet within a specific component.
With the Angular CLI, you can configure your global styles in the `.angular-cli.json` file.
You can rename the extension to `.scss` to use sass.
在Angular2中我们可以继续在`index.html`中使用link标签来为应用程序定义样式。
但是也能在组件中封装样式
使用 Angular CLI我们可以在 `.angular-cli.json` 文件中配置全局样式。
也可以把扩展名改为 `.scss` 来使用 sass
### StyleUrls

View File

@ -12,7 +12,7 @@ This guide explains how to build with the AOT compiler using different compiler
<a href="https://www.youtube.com/watch?v=kW9cJsvcsGo">Watch compiler author Tobias Bosch explain the Angular Compiler</a> at AngularConnect 2016.
<a href="https://www.youtube.com/watch?v=kW9cJsvcsGo">观看 Angular 编译器的作者Tobias Bosch 在 AngularConnect 2016 上对编译器的解释。</a>
观看编译器作者Tobias Bosch在AngularConnect 2016大会里<a href="http://v.youku.com/v_show/id_XMTc1NTE4NTkwOA==.html?from=y1.7-1.4" target="_blank">Angular编译器</a>的演讲。
</div>
@ -20,7 +20,7 @@ This guide explains how to build with the AOT compiler using different compiler
## Angular compilation
## 概览
## Angular 中的编译
An Angular application consists largely of components and their HTML templates.
Before the browser can render the application,

View File

@ -307,11 +307,11 @@ template for our `HeroListComponent`:
Although this template uses typical HTML elements like `<h2>` and `<p>`, it also has some differences. Code like `*ngFor`, `{{hero.name}}`, `(click)`, `[hero]`, and `<app-hero-detail>` uses Angular's [template syntax](guide/template-syntax).
模板除了可以使用像`<h2>``<p>`这样的典型的 HTML 元素,还能使用其它元素。
例如,像`*ngFor``{{hero.name}}``(click)``[hero]``<hero-detail>`这样的代码使用了 Angular 的[模板语法](guide/template-syntax)。
例如,像`*ngFor``{{hero.name}}``(click)``[hero]``<app-hero-detail>`这样的代码使用了 Angular 的[模板语法](guide/template-syntax)。
In the last line of the template, the `<app-hero-detail>` tag is a custom element that represents a new component, `HeroDetailComponent`.
在模板的最后一行,`<hero-detail>`标签就是一个用来表示新组件`HeroDetailComponent`的自定义元素。
在模板的最后一行,`<app-hero-detail>`标签就是一个用来表示新组件`HeroDetailComponent`的自定义元素。
The `HeroDetailComponent` is a *different* component than the `HeroListComponent` you've been reviewing.
The `HeroDetailComponent` (code not shown) presents facts about a particular hero, the
@ -326,7 +326,7 @@ The `HeroDetailComponent` is a **child** of the `HeroListComponent`.
Notice how `<app-hero-detail>` rests comfortably among native HTML elements. Custom components mix seamlessly with native HTML in the same layouts.
注意到了吗?`<hero-detail>`舒适地躺在原生 HTML 元素之间。
注意到了吗?`<app-hero-detail>`舒适地躺在原生 HTML 元素之间。
自定义组件和原生 HTML 在同一布局中融合得天衣无缝。
<hr class="clear"/>
@ -384,8 +384,8 @@ where it finds a `<app-hero-list>` tag in *parent* HTML.
For example, if an app's HTML contains `<app-hero-list></app-hero-list>`, then
Angular inserts an instance of the `HeroListComponent` view between those tags.
`selector` CSS 选择器,它告诉 Angular 在*父级* HTML 中查找`<hero-list>`标签,创建并插入该组件。
例如,如果应用的 HTML 包含`<hero-list></hero-list>` Angular 就会把`HeroListComponent`的一个实例插入到这个标签中。
`selector` CSS 选择器,它告诉 Angular 在*父级* HTML 中查找`<app-hero-list>`标签,创建并插入该组件。
例如,如果应用的 HTML 包含`<app-hero-list></app-hero-list>` Angular 就会把`HeroListComponent`的一个实例插入到这个标签中。
* `templateUrl`: module-relative address of this component's HTML template, shown [above](guide/architecture#templates).

View File

@ -180,6 +180,8 @@ This first implementation sets the background color of the host element to yello
## Apply the attribute directive
## 使用属性型指令
To use the new `HighlightDirective`, add a paragraph (`<p>`) element to the template of the root `AppComponent` and apply the directive as an attribute.
运行应用,就会看到我们的指令确实高亮了段落中的文本。
@ -216,7 +218,7 @@ The directive could be more dynamic.
It could detect when the user mouses into or out of the element
and respond by setting or clearing the highlight color.
当前,`myHighlight`只是简单的设置元素的颜色。
当前,`appHighlight`只是简单的设置元素的颜色。
这个指令应该在用户鼠标悬浮一个元素时,设置它的颜色。
Begin by adding `HostListener` to the list of imported symbols.
@ -352,8 +354,8 @@ and sets the directive's highlight color with a property binding.
You're re-using the directive's attribute selector (`[appHighlight]`) to do both jobs.
That's a crisp, compact syntax.
`[myHighlight]`属性同时做了两件事:把这个高亮指令应用到了`<p>`元素上,并且通过属性绑定设置了该指令的高亮颜色。
我们复用了该指令的属性选择器`[myHighlight]`来同时完成它们。
`[appHighlight]`属性同时做了两件事:把这个高亮指令应用到了`<p>`元素上,并且通过属性绑定设置了该指令的高亮颜色。
我们复用了该指令的属性选择器`[appHighlight]`来同时完成它们。
这是清爽、简约的语法。
You'll have to rename the directive's `highlightColor` property to `appHighlight` because that's now the color property binding name.
@ -364,7 +366,7 @@ You'll have to rename the directive's `highlightColor` property to `appHighlight
This is disagreeable. The word, `appHighlight`, is a terrible property name and it doesn't convey the property's intent.
这可不好。因为`myHighlight`是一个糟糕的属性名,而且不能反映该属性的意图。
这可不好。因为`appHighlight`是一个糟糕的属性名,而且不能反映该属性的意图。
{@a input-alias}
@ -385,7 +387,7 @@ Restore the original property name and specify the selector as the alias in the
_Inside_ the directive the property is known as `highlightColor`.
_Outside_ the directive, where you bind to it, it's known as `appHighlight`.
在指令内部,该属性叫`highlightColor`,在外部,当我们绑定到它时,它叫`myHighlight`。
在指令内部,该属性叫`highlightColor`,在外部,当我们绑定到它时,它叫`appHighlight`。
You get the best of both worlds: the property name you want and the binding syntax you want:
@ -397,7 +399,7 @@ Now that you're binding via the alias to the `highlightColor`, modify the `onMou
If someone neglects to bind to `appHighlightColor`, highlight the host element in red:
现在,我们绑定到了`highlightColor`属性,并修改`onMouseEnter()`方法来使用它。
如果有人忘了绑定到`highlightColor`,那就用红色进行高亮。
如果有人忘了绑定到`appHighlightColor`,那就用红色进行高亮。
<code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" title="src/app/highlight.directive.ts (mouse enter)" region="mouse-enter"></code-example>
@ -469,7 +471,7 @@ then with the `defaultColor`, and falls back to "red" if both properties are und
How do you bind to a second property when you're already binding to the `appHighlight` attribute name?
当已经绑定过`myHighlight`属性时,要如何绑定到第二个属性呢?
当已经绑定过`appHighlight`属性时,要如何绑定到第二个属性呢?
As with components, you can add as many directive property bindings as you need by stringing them along in the template.
The developer should be able to write the following template HTML to both bind to the `AppComponent.color`
@ -623,5 +625,5 @@ Now apply that reasoning to the following example:
Therefore, the directive property must carry the `@Input` decorator.
`myHighlight`属性位于左侧,它引用了`MyHighlightDirective`中一个*带别名的*属性,它不是模板所属组件的一部分,因此存在信任问题。
`appHighlight`属性位于左侧,它引用了`HighlightDirective`中一个*带别名的*属性,它不是模板所属组件的一部分,因此存在信任问题。
所以,该属性必须带`@Input`装饰器。

View File

@ -59,6 +59,8 @@ The `@NgModule` decorator identifies `AppModule` as an `NgModule` class.
* **_bootstrap_**&mdash;the _root_ component that Angular creates and inserts
into the `index.html` host web page.
**_bootstrap_** &mdash; _根_组件Angular 创建它并插入`index.html`宿主页面。
The default CLI application only has one component, `AppComponent`, so it
is in both the `declarations` and the `bootstrap` arrays.

View File

@ -790,7 +790,7 @@ computed with the <a href="http://closure-compiler.appspot.com/home">closure com
## Polyfills for non-CLI users
## 不使用 CLI 的用户的腻子脚本
## CLI 的用户的腻子脚本
If you are not using the CLI, you should add your polyfill scripts directly to the host web page (`index.html`), perhaps like this.

View File

@ -952,6 +952,8 @@ so the <code>@Directive</code> configuration applies to components as well</p>
</p>
<p>由类的方法实现。</p>
</th>
</tr>

View File

@ -337,6 +337,8 @@ inside `<style>` tags.
### Template link tags
### 模板中的link标签
You can also write `<link>` tags into the component's HTML template.
我们也可以在组件的 HTML 模板中写`<link>`标签。
@ -474,7 +476,7 @@ in most cases.
## Inspecting generated CSS
## 附录 1查看仿真 (Emulated) 模式下生成的 CSS
## 查看仿真 (Emulated) 模式下生成的 CSS
When using emulated view encapsulation, Angular preprocesses
all component styles so that they approximate the standard shadow CSS scoping rules.

View File

@ -1242,7 +1242,7 @@ This isn't necessarily good design.
This example is examining *whether a component can
inject its parent via the parent's base class*.
*.这并不是好的设计。问题是*一个组件是否能通过它父组件的基类来注入它的父组件呢*
这并不是好的设计。问题是*一个组件是否能通过它父组件的基类来注入它的父组件呢*
The sample's `CraigComponent` explores this question. [Looking back](guide/dependency-injection-in-action#alex),
you see that the `Alex` component *extends* (*inherits*) from a class named `Base`.

View File

@ -15,9 +15,13 @@ the [Angular Dependency Injection](guide/dependency-injection) guide to see how
## Why dependency injection?
## 为什么需要依赖注入?
To understand why dependency injection is so important, consider an example without it.
Imagine writing the following code:
要理解为什么依赖注入这么重要,不妨先考虑不使用它的一个例子。想象下列代码:
<code-example path="dependency-injection/src/app/car/car-no-di.ts" region="car" title="src/app/car/car.ts (without DI)">
</code-example>
@ -30,6 +34,9 @@ This `Car` needs an engine and tires. Instead of asking for them,
the `Car` constructor instantiates its own copies from
the very specific classes `Engine` and `Tires`.
`Car`类需要一个引擎 (engine) 和一些轮胎 (tire),它没有去请求现成的实例,
而是在构造函数中用具体的`Engine``Tires`类实例化出自己的副本。
What if the `Engine` class evolves and its constructor requires a parameter?
That would break the `Car` class and it would stay broken until you rewrote it along the lines of
`this.engine = new Engine(theNewParameter)`.
@ -39,33 +46,62 @@ But you'll *have* to start caring because
when the definition of `Engine` changes, the `Car` class must change.
That makes `Car` brittle.
如果`Engine`类升级了,它的构造函数要求传入一个参数,这该怎么办?
这个`Car`类就被破坏了,在把创建引擎的代码重写为`this.engine = new Engine(theNewParameter)`之前,它都是坏的。
当第一次写`Car`类时,我们不关心`Engine`构造函数的参数,现在也不想关心。
但是,当`Engine`类的定义发生变化时,就不得不在乎了,`Car`类也不得不跟着改变。
这就会让`Car`类过于脆弱。
What if you want to put a different brand of tires on your `Car`? Too bad.
You're locked into whatever brand the `Tires` class creates. That makes the
`Car` class inflexible.
如果想在`Car`上使用不同品牌的轮胎会怎样?太糟了。
我们被锁定在`Tires`类创建时使用的那个品牌上。这让`Car`类缺乏弹性。
Right now each new car gets its own `engine`. It can't share an `engine` with other cars.
While that makes sense for an automobile engine,
surely you can think of other dependencies that should be shared, such as the onboard
wireless connection to the manufacturer's service center. This `Car` lacks the flexibility
to share services that have been created previously for other consumers.
现在,每辆车都有它自己的引擎。它不能和其它车辆共享引擎。
虽然这对于汽车来说还算可以理解,但是设想一下那些应该被共享的依赖,比如用来联系厂家服务中心的车载无线电。
我们的车缺乏必要的弹性,无法共享当初给其它消费者创建的车载无线电。
When you write tests for `Car` you're at the mercy of its hidden dependencies.
Is it even possible to create a new `Engine` in a test environment?
What does `Engine` depend upon? What does that dependency depend on?
Will a new instance of `Engine` make an asynchronous call to the server?
You certainly don't want that going on during tests.
当给`Car`类写测试的时候,我们就会受制于它背后的那些依赖。
能在测试环境中成功创建新的`Engine`吗?
`Engine`自己又依赖什么?那些依赖本身又依赖什么?
`Engine`的新实例会发起到服务器的异步调用吗?
我们当然不想在测试期间这么一层层追下去。
What if the `Car` should flash a warning signal when tire pressure is low?
How do you confirm that it actually does flash a warning
if you can't swap in low-pressure tires during the test?
如果`Car`应该在轮胎气压低的时候闪动警示灯该怎么办?
如果没法在测试期间换上一个低气压的轮胎,那该如何确认它能正确的闪警示灯?
You have no control over the car's hidden dependencies.
When you can't control the dependencies, a class becomes difficult to test.
我们没法控制这辆车背后隐藏的依赖。
当不能控制依赖时,类就会变得难以测试。
How can you make `Car` more robust, flexible, and testable?
该如何让`Car`更强壮、有弹性以及可测试?
{@a ctor-injection}
答案非常简单。把`Car`的构造函数改造成使用 DI 的版本:
That's super easy. Change the `Car` constructor to a version with DI:
<code-tabs>
@ -83,15 +119,23 @@ now in the constructor.
The `Car` class no longer creates an `engine` or `tires`.
It just consumes them.
发生了什么?我们把依赖的定义移到了构造函数中。
`Car`类不再创建引擎`engine`或者轮胎`tires`
它仅仅“消费”它们。
<div class="l-sub-section">
This example leverages TypeScript's constructor syntax for declaring
parameters and properties simultaneously.
这个例子又一次借助 TypeScript 的构造器语法来同时定义参数和属性。
</div>
Now you can create a car by passing the engine and tires to the constructor.
现在,通过往构造函数中传入引擎和轮胎来创建一辆车。
<code-example path="dependency-injection/src/app/car/car-creations.ts" region="car-ctor-instantiation" linenums="false">
</code-example>
@ -102,13 +146,20 @@ decoupled from the `Car` class.
You can pass in any kind of `engine` or `tires` you like, as long as they
conform to the general API requirements of an `engine` or `tires`.
酷!引擎和轮胎这两个依赖的定义与`Car`类本身解耦了。
只要喜欢,可以传入任何类型的引擎或轮胎,只要它们能满足引擎或轮胎的通用 API 需求。
Now, if someone extends the `Engine` class, that is not `Car`'s problem.
这样一来,如果有人扩展了`Engine`类,那就不再是`Car`类的烦恼了。
<div class="l-sub-section">
The _consumer_ of `Car` has the problem. The consumer must update the car creation code to
something like this:
`Car`的_消费者_也有这个问题。消费者必须更新创建这辆车的代码就像这样
<code-example path="dependency-injection/src/app/car/car-creations.ts" region="car-ctor-instantiation-with-param" linenums="false">
</code-example>
@ -116,6 +167,8 @@ something like this:
The critical point is this: the `Car` class did not have to change.
You'll take care of the consumer's problem shortly.
这里的要点是:`Car`本身不必变化。下面就来解决消费者的问题。
</div>
The `Car` class is much easier to test now because you are in complete control
@ -123,23 +176,37 @@ of its dependencies.
You can pass mocks to the constructor that do exactly what you want them to do
during each test:
`Car`类非常容易测试,因为现在我们对它的依赖有了完全的控制权。
在每个测试期间,我们可以往构造函数中传入 mock 对象,做想让它们做的事:
<code-example path="dependency-injection/src/app/car/car-creations.ts" region="car-ctor-instantiation-with-mocks" linenums="false">
</code-example>
**You just learned what dependency injection is**.
**刚刚学习了什么是依赖注入**
It's a coding pattern in which a class receives its dependencies from external
sources rather than creating them itself.
它是一种编程模式,可以让类从外部源中获得它的依赖,而不必亲自创建它们。
Cool! But what about that poor consumer?
Anyone who wants a `Car` must now
create all three parts: the `Car`, `Engine`, and `Tires`.
The `Car` class shed its problems at the consumer's expense.
You need something that takes care of assembling these parts.
酷!但是,可怜的消费者怎么办?
那些希望得到一个`Car`的人们现在必须创建所有这三部分了:`Car``Engine``Tires`
`Car`类把它的快乐建立在了消费者的痛苦之上。
需要某种机制为我们把这三个部分装配好。
You _could_ write a giant class to do that:
可以写一个巨型类来做这件事:
<code-example path="dependency-injection/src/app/car/car-factory.ts" title="src/app/car/car-factory.ts">
</code-example>
@ -149,15 +216,27 @@ But maintaining it will be hairy as the application grows.
This factory is going to become a huge spiderweb of
interdependent factory methods!
现在只需要三个创建方法,这还不算太坏。
但是当应用规模变大之后,维护它将变得惊险重重。
这个工厂类将变成由相互依赖的工厂方法构成的巨型蜘蛛网。
Wouldn't it be nice if you could simply list the things you want to build without
having to define which dependency gets injected into what?
如果能简单的列出想建造的东西,而不用定义该把哪些依赖注入到哪些对象中,那该多好!
This is where the dependency injection framework comes into play.
Imagine the framework had something called an _injector_.
You register some classes with this injector, and it figures out how to create them.
到了依赖注入框架一展身手的时候了!
想象框架中有一个叫做_注入器 (injector)_ 的东西。
用这个注入器注册一些类,它会弄明白如何创建它们。
When you need a `Car`, you simply ask the injector to get it for you and you're good to go.
当需要一个`Car`时,就简单的找注入器取车就可以了。
<code-example path="dependency-injection/src/app/car/car-injector.ts" region="injector-call" title="src/app/car/car-injector.ts" linenums="false">
</code-example>
@ -167,7 +246,14 @@ The consumer knows nothing about creating a `Car`.
You don't have a gigantic factory class to maintain.
Both `Car` and consumer simply ask for what they need and the injector delivers.
皆大欢喜。`Car`不需要知道如何创建`Engine``Tires`
消费者不需要知道如何创建`Car`
开发人员不需要维护巨大的工厂类。
`Car`和消费者只要简单地请求想要什么,注入器就会交付它们。
This is what a **dependency injection framework** is all about.
这就是“**依赖注入框架**”存在的原因。
Now that you know what dependency injection is and appreciate its benefits,
turn to the [Angular Dependency Injection](guide/dependency-injection) guide to see how it is implemented in Angular.

View File

@ -820,7 +820,7 @@ There is no `AppConfig` class.
The `HERO_DI_CONFIG` constant conforms to the `AppConfig` interface.
Unfortunately, you cannot use a TypeScript interface as a token:
`CONFIG`常量有一个接口:`AppConfig`。不幸的是,不能把 TypeScript 接口用作令牌:
`HERO_DI_CONFIG`常量有一个接口:`AppConfig`。不幸的是,不能把 TypeScript 接口用作令牌:
<code-example path="dependency-injection/src/app/providers.component.ts" region="providers-9-interface" linenums="false">

View File

@ -70,6 +70,8 @@ It might be good enough for sharing your progress and ideas internally with mana
## Optimize for production
## 为生产环境优化
Although deploying directly from the development environment works,
you can generate an optimized build with additional CLI command line flags,
starting with `--prod`.
@ -204,13 +206,23 @@ The cause may not be what you think it is.
You can waste a lot of time and money optimizing something that has no tangible benefit or even makes the app slower.
You should measure the app's actual behavior when running in the environments that are important to you.
如果我们能对“是什么导致了应用变慢”的问题有一个清晰、准确的理解,那就可以对优化什么、如何优化做出更好地决策了。
真正的原因可能并不是你所想的那样。
我们可能花费大量的时间和金钱去优化一些东西,但它却无法产生可感知的效果甚至让应用变得更慢。
我们应该在那些最重要的环境中实际运行,来度量应用的实际行为。
The
<a href="https://developers.google.com/web/tools/chrome-devtools/network-performance/understanding-resource-timing" title="Chrome DevTools Network Performance">
Chrome DevTools Network Performance page</a> is a good place to start learning about measuring performance.
<a href="https://developers.google.com/web/tools/chrome-devtools/network-performance/understanding-resource-timing" target="_blank" title="Chrome DevTools Network Performance">
Chrome开发工具的网络性能页</a>是开始学习度量性能的好地方。
The [WebPageTest](https://www.webpagetest.org/) tool is another good choice
that can also help verify that your deployment was successful.
[WebPageTest](https://www.webpagetest.org/)工具是另一个不错的选择,它能帮你验证你的部署是否成功了。
{@a inspect-bundle}
### Inspect the bundles
@ -270,19 +282,30 @@ For example, given the `<base href="/my/app/">`, the browser resolves a URL such
into a server request for `my/app/some/place/foo.jpg`.
During navigation, the Angular router uses the _base href_ as the base path to component, template, and module files.
HTML中的[_&lt;base href="..."/&gt;_](https://angular.io/docs/ts/latest/guide/router.html#!)用于指定一个解析相对路径的基地址,如图片、脚本和样式表。
比如,指定`<base href="/my/app/">`时,浏览器就会把`some/place/foo.jpg`这样的URL解析成到`my/app/some/place/foo.jpg`的服务端请求。
在浏览期间Angular路由器会使用*base href*作为组件、模板和模块文件的基地址。
<div class="l-sub-section">
See also the [*APP_BASE_HREF*](api/common/APP_BASE_HREF "API: APP_BASE_HREF") alternative.
参见另一种备选方案[*APP_BASE_HREF*](api/common/APP_BASE_HREF "API: APP_BASE_HREF")。
</div>
In development, you typically start the server in the folder that holds `index.html`.
That's the root folder and you'd add `<base href="/">` near the top of `index.html` because `/` is the root of the app.
在开发期间,我们通常会在`index.html`所在的目录中启动服务器。这个目录就是根目录,因为`/`就是本应用的根,所以我们要在`index.html`的顶部添加`<base href="/">`
But on the shared or production server, you might serve the app from a subfolder.
For example, when the URL to load the app is something like `http://www.mysite.com/my/app/`,
the subfolder is `my/app/` and you should add `<base href="/my/app/">` to the server version of the `index.html`.
但是在共享服务器或生产服务器上,我们可能得从子目录下启动服务器。
比如当加载本应用的URL是`http://www.mysite.com/my/app/`时,子目录就是`my/app/`,而我们就要在服务器版的`index.html`中添加`<base href="/my/app/">`
When the `base` tag is mis-configured, the app fails to load and the browser console displays `404 - Not Found` errors
for the missing files. Look at where it _tried_ to find those files and adjust the base tag appropriately.

View File

@ -46,7 +46,7 @@ With interpolation, you put the property name in the view template, enclosed in
Follow the [quickstart](guide/quickstart) instructions for creating a new project
named <code>displaying-data</code>.
按照[开发环境](guide/setup)的说明,创建一个新项目,名为<code>displaying-data</code>
按照[快速起步](guide/quickstart)的说明,创建一个新项目,名为<code>displaying-data</code>
Delete the <code>app.component.html</code> file. It is not needed for this example.

View File

@ -160,8 +160,8 @@ The `<app-question>` tag matches the `DynamicFormQuestionComponent`,
the component responsible for rendering the details of each _individual_
question based on values in the data-bound question object.
它代表了问卷问题列表,每个问题都被绑定到一个`<df-question>`组件元素。
`<df-question>`标签匹配到的是组件`DynamicFormQuestionComponent`,该组件的职责是根据各个问卷问题对象的值来动态渲染表单控件。
它代表了问卷问题列表,每个问题都被绑定到一个`<app-question>`组件元素。
`<app-question>`标签匹配到的是组件`DynamicFormQuestionComponent`,该组件的职责是根据各个问卷问题对象的值来动态渲染表单控件。
<code-tabs>

View File

@ -325,7 +325,7 @@ Update it with the following:
There are two changes:
处更改
处更改
1. You import `FormsModule`.
@ -358,7 +358,7 @@ Update it with the following:
Replace the contents of its template with the following:
“快速上手”的版本内容替换成下列代码:
模板中的内容替换成如下代码:
<code-example path="forms/src/app/app.component.html" title="src/app/app.component.html">

View File

@ -129,6 +129,8 @@ of some of the things they contain:
<code>RouterModule</code>
<code>RouterModule</code>(路由器模块)
</td>
<td>

View File

@ -163,12 +163,12 @@ between a "token"&mdash;also referred to as a "key"&mdash;and a dependency [prov
You launch an Angular application by "bootstrapping" it using the application root NgModule (`AppModule`).
通过应用程序根 Angular 模块(`AppModule`)来启动 Angular 应用程序。
Bootstrapping identifies an application's top level "root" [component](guide/glossary#component),
which is the first component that is loaded for the application.
通过应用程序根 Angular 模块来启动 Angular 应用程序。
启动过程标识应用的顶级“根”[组件 (component)](guide/glossary#component),也就是应用加载的第一个组件。
更多信息,见[设置](guide/setup)。
启动过程标识应用的顶级“根”[组件 (component)](guide/glossary#component),也就是应用加载的第一个组件。
You can bootstrap multiple apps in the same `index.html`, each app with its own top-level root.

View File

@ -1,5 +1,7 @@
# Internationalization (i18n)
# 国际化i18n
Application internationalization is a many-faceted area of development, focused on making
applications available and user-friendly to a worldwide audience. This page describes Angular's
internationalization (i18n) tools, which can help you make your app available in multiple languages.
@ -7,7 +9,7 @@ internationalization (i18n) tools, which can help you make your app available in
See the <live-example downloadOnly name="i18n">i18n Example</live-example> for a simple example of
an AOT-compiled app, translated into French.
可以把这个翻译为法语版的 AOT 应用<live-example name="i18n">i18n 例子</live-example>作为一个简单的例子。
可以把这个翻译为法语版的 AOT 应用<live-example downloadOnly name="i18n">i18n 例子</live-example>作为一个简单的例子。
{@a angular-i18n}
@ -143,6 +145,8 @@ The i18n template translation process has four phases:
1. Mark static text messages in your component templates for translation.
在组件模板中标记需要翻译的静态文本信息。
2. An Angular i18n tool extracts the marked text into an industry standard translation source file.
3. A translator edits that file, translating the extracted text into the target language,
@ -454,6 +458,8 @@ Pluralization categories include (depending on the language):
* other
other其它
After the pluralization category, put the default English text in braces (`{}`).
把默认的*英语*翻译结果放在复数类别之后的括号(`{}`)中。
@ -512,7 +518,7 @@ You can also nest different ICU expressions together, as shown in this example:
## Create a translation source file with _ng xi18n_
## 使用_ng-xi18n_工具创建翻译源文件
## 使用*ng-xi18n*工具创建翻译源文件
Use the `ng xi18n` command provided by the CLI to extract the text messages marked with `i18n` into
a translation source file.
@ -749,6 +755,8 @@ must be just below the translation unit for the logo.
### Translate _plural_
### 翻译*复数*
To translate a `plural`, translate its ICU format match values:
要翻译一个复数就要翻译它的ICU格式中匹配的值
@ -911,6 +919,8 @@ options with the `ng serve` or `ng build` commands:
* `--i18nFile`: the path to the translation file.
`--i18nFile`: 翻译文件的路径
* `--i18nFormat`: the format of the translation file.
* `--locale`: the locale id.
@ -984,6 +994,8 @@ Then provide the `LOCALE_ID` in the main module:
### Report missing translations
### 汇报缺失的翻译
By default, when a translation is missing, the build succeeds but generates a warning such as
`Missing translation for message "foo"`. You can configure the level of warning that is generated by
the Angular compiler:

View File

@ -114,6 +114,9 @@ The following table summarizes the `@NgModule` metadata properties.
Components, directives, and pipes must belong to _exactly_ one module.
The compiler emits an error if you try to declare the same class in more than one module.
组件、指令和管道*只能*属于一个模块。
如果尝试把同一个类声明在多个模块中,编译器就会报告一个错误。
Don't re-declare a class imported from another module.
</td>
@ -198,6 +201,8 @@ The following table summarizes the `@NgModule` metadata properties.
A list of declarations&mdash;*component*, *directive*, and *pipe* classes&mdash;that
an importing module can use.
可供导入了自己的模块使用的可声明对象(**组件**、**指令**、**管道类**)的列表。
Exported declarations are the module's _public API_.
A component in another module can [use](guide/ngmodule-faq#q-template-reference) _this_
module's `UserComponent` if it imports this module and this module exports `UserComponent`.
@ -213,6 +218,8 @@ The following table summarizes the `@NgModule` metadata properties.
A module can list another module among its `exports`, in which case
all of that module's public components, directives, and pipes are exported.
一个模块可以把另一个模块加入自己的`exports`列表中,这时,另一个模块的所有公开组件、指令和管道都会被导出。
[Re-export](guide/ngmodule-faq#q-reexport) makes module transitivity explicit.
If Module 'A' re-exports `CommonModule` and Module 'B' imports Module 'A',
Module 'B' components can use `ngIf` even though 'B' itself didn't import `CommonModule`.

View File

@ -149,7 +149,7 @@ The "x" class isn't visible to other modules until you add it to the `exports` l
Import NgModules whose public (exported) [declarable classes](guide/bootstrapping#the-declarations-array)
you need to reference in this module's component templates.
一句话:导入你需要在当前模块的组件模板中使用的那些公开的(被导出的)[可声明类](guide/ngmodule-faq#q-declarable)。
导入你需要在当前模块的组件模板中使用的那些公开的(被导出的)[可声明类](guide/ngmodule-faq#q-declarable)。
This always means importing `CommonModule` from `@angular/common` for access to
the Angular directives such as `NgIf` and `NgFor`.
@ -339,18 +339,18 @@ Its only purpose is to add http service providers to the application as a whole.
## What is the `forRoot()` method?
## *forRoot*方法是什么?
## *forRoot()*方法是什么?
The `forRoot()` static method is a convention that makes it easy for developers to configure the module's providers.
静态方法`forRoot`是一个约定,它可以让开发人员更轻松的配置模块的提供商。
静态方法`forRoot()`是一个约定,它可以让开发人员更轻松的配置模块的提供商。
The `RouterModule.forRoot()` method is a good example.
Apps pass a `Routes` object to `RouterModule.forRoot()` in order to configure the app-wide `Router` service with routes.
`RouterModule.forRoot()` returns a [ModuleWithProviders](api/core/ModuleWithProviders).
You add that result to the `imports` list of the root `AppModule`.
`RouterModule.forRoot`就是一个很好的例子。
`RouterModule.forRoot()`就是一个很好的例子。
应用把一个`Routes`对象传给`RouterModule.forRoot`,为的就是使用路由配置全应用级的`Router`服务。
`RouterModule.forRoot`返回一个[ModuleWithProviders](api/core/ModuleWithProviders)对象。
我们把这个结果添加到根模块`AppModule``imports`列表中。

View File

@ -73,6 +73,8 @@ you list the module's classes in the `@NgModule.declarations` list.
* An NgModule can only export the [declarable classes](guide/ngmodule-faq#q-declarable)
it owns or imports from other modules. It doesn't declare or export any other kind of class.
Angular模块只能导出[_可声明的类_](guide/ngmodule-faq#q-declarable)。这可能是它自己拥有的也可能是从其它模块中导入的。它不会声明或导出任何其它类型的类。
* Unlike JavaScript modules, an NgModule can extend the _entire_ application with services
by adding providers to the `@NgModule.providers` list.

View File

@ -32,6 +32,8 @@ section.
Modules are a great way to organize an application and extend it with capabilities from external libraries.
模块是组织应用和使用外部库扩展应用的最佳途径。
Angular libraries are NgModules, such as `FormsModule`, `HttpClientModule`, and `RouterModule`.
Many third-party libraries are available as NgModules such as
<a href="https://material.angular.io/">Material Design</a>,

View File

@ -319,7 +319,7 @@ read the [Form Validation](guide/form-validation) guide.
Now update the component's template, with the following markup.
现在,在创建组件的模板文件`src/app/hero-detail.component.html`,内容如下:
现在,修改组件的模板文件`src/app/hero-detail.component.html`,内容如下:
<code-example path="reactive-forms/src/app/hero-detail/hero-detail-1.component.html" region="simple-control" title="src/app/hero-detail/hero-detail.component.html" linenums="false">

View File

@ -3496,7 +3496,7 @@ The `Crisis Detail` route is a child of the `Crisis List`. Since the router [reu
by default, the `Crisis Detail` component will be re-used as you select different crises.
In contrast, back in the `Hero Detail` route, the component was recreated each time you selected a different hero.
`Crisis Detail`路由是`Crisis List`的子路由。由于路由器默认会[复用组件](guide/router#reuse),因此当我们选择了另一个危机时,`CrisisDetailComponent`会被复用。
`Crisis Detail`路由是`Crisis List`的子路由。由于路由器默认会[复用组件](#reuse),因此当我们选择了另一个危机时,`CrisisDetailComponent`会被复用。
作为对比,回到`Hero Detail`路由时,每当我们选择了不同的英雄时,该组件都会被重新创建。
At the top level, paths that begin with `/` refer to the root of the application.

View File

@ -101,4 +101,6 @@ 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>

View File

@ -53,6 +53,8 @@ Note the following:
* It re-exports the `CommonModule` and `FormsModule`.
它重新导出了`CommonModule``FormsModule`
By re-exporting `CommonModule` and `FormsModule`, any other module that imports this
`SharedModule`, gets access to directives like `NgIf` and `NgFor` from `CommonModule`
and can bind to component properties with `[(ngModel)]`, a directive in the `FormsModule`.

View File

@ -173,6 +173,11 @@ a _child_ of the root injector.
Of course it finds the instance imported by the root `AppModule`.
Now `parentModule` exists and the constructor throws the error.
Angular 创建一个惰性加载模块,它具有自己的注入器,它是根注入器的*子注入器*。
`@SkipSelf`让 Angular 在其父注入器中查找`CoreModule`,这次,它的父注入器却是根注入器了(而上次父注入器是空)。
当然,这次它找到了由根模块`AppModule`导入的实例。
该构造函数检测到存在`parentModule`,于是抛出一个错误。
Here are the two files in their entirety for reference:
<code-tabs linenums="false">

View File

@ -836,13 +836,13 @@ You inject both in the directive constructor as private variables of the class.
### The _appUnless_ property
### *myUnless* 属性
### *appUnless* 属性
The directive consumer expects to bind a true/false condition to `[appUnless]`.
That means the directive needs an `appUnless` property, decorated with `@Input`
该指令的使用者会把一个true/false条件绑定到`[myUnless]`属性上。
也就是说,该指令需要一个带有`@Input``myUnless`属性。
该指令的使用者会把一个true/false条件绑定到`[appUnless]`属性上。
也就是说,该指令需要一个带有`@Input``appUnless`属性。
<div class="l-sub-section">
@ -859,7 +859,7 @@ Read about `@Input` in the [_Template Syntax_](guide/template-syntax#inputs-outp
Angular sets the `appUnless` property whenever the value of the condition changes.
Because the `appUnless` property does work, it needs a setter.
一旦该值的条件发生了变化Angular 就会去设置 `myUnless` 属性这时候我们就需要为它定义一个设置器setter
一旦该值的条件发生了变化Angular 就会去设置 `appUnless` 属性这时候我们就需要为它定义一个设置器setter
* If the condition is falsy and the view hasn't been created previously,
tell the _view container_ to create the _embedded view_ from the template.
@ -873,7 +873,7 @@ clear the container which also destroys the view.
Nobody reads the `appUnless` property so it doesn't need a getter.
没有人会读取`myUnless`属性因此它不需要定义设置器getter
没有人会读取`appUnless`属性因此它不需要定义设置器getter
The completed directive code looks like this:

View File

@ -248,6 +248,8 @@ region="ng-imports">
When the browser refreshes, the app should work again. You can edit the hero's name and see the changes reflected immediately in the `<h2>` above the textbox.
浏览器刷新。又见到我们的英雄了。我们可以编辑英雄的名字,也能看到这个改动立刻体现在`<h2>`中。
### Declare _HeroesComponent_
Every component must be declared in _exactly one_ [NgModule](guide/ngmodules).

View File

@ -3,6 +3,9 @@
In this page, you'll expand the Tour of Heroes app to display a list of heroes, and
allow users to select a hero and display the hero's details.
我们需要管理多个英雄。我们将扩展《英雄指南》应用,让它显示一个英雄列表,
允许用户选择一个英雄,查看该英雄的详细信息。
## Create mock heroes
You'll need some heroes to display.
@ -21,6 +24,8 @@ title="src/app/mock-heroes.ts">
## Displaying heroes
## 显示我们的英雄
You're about to display the list of heroes at the top of the `HeroesComponent`.
Open the `HeroesComponent` class file and import the mock `HEROES`.
@ -82,6 +87,8 @@ After the browser refreshes, the list of heroes appears.
### Style the heroes
### 给我们的英雄们“美容”
The heroes list should be attractive and should respond visually when users
hover over and select a hero from the list.
@ -129,6 +136,8 @@ and update the hero detail.
Add a click event binding to the `<li>` like this:
我们再往`<li>`元素上插入一句点击事件的绑定代码:
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="selectedHero-click" title="heroes.component.html (template excerpt)" linenums="false">
</code-example>
@ -215,6 +224,8 @@ When the user picks a hero, `selectedHero` has a value and
### Style the selected hero
### 给所选英雄添加样式
It's difficult to identify the _selected hero_ in the list when all `<li>` elements look alike.
If the user clicks "Magneta", that hero should render with a distinctive but subtle background color like this:
@ -251,6 +262,8 @@ The finished `<li>` looks like this:
Your app should look like this <live-example></live-example>.
我们的应用现在变成了这样:<live-example></live-example>
Here are the code files discussed on this page, including the `HeroesComponent` styles.
<code-tabs>

View File

@ -119,6 +119,8 @@ The browser refreshes and the app starts working again as it did before.
## What changed?
## 有哪些变化?
As [before](tutorial/toh-pt2), whenever a user clicks on a hero name,
the hero detail appears below the hero list.
Now the `HeroDetailComponent` is presenting those details instead of the `HeroesComponent`.

View File

@ -2,16 +2,28 @@
There are new requirements for the Tour of Heroes app:
我们收到了《英雄指南》的一些新需求:
* Add a *Dashboard* view.
添加一个*仪表盘*视图。
* Add the ability to navigate between the *Heroes* and *Dashboard* views.
在*英雄列表*和*仪表盘*视图之间导航。
* When users click a hero name in either view, navigate to a detail view of the selected hero.
无论在哪个视图中点击一个英雄,都会导航到该英雄的详情页。
* When users click a *deep link* in an email, open the detail view for a particular hero.
在邮件中点击一个*深链接*,会直接打开一个特定英雄的详情视图。
When youre done, users will be able to navigate the app like this:
完成时,用户就能像这样在应用中导航:
<figure>
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
@ -300,6 +312,8 @@ After the browser refreshes you can navigate freely between the two views by cli
## Navigating to hero details
## 导航到英雄详情
The `HeroDetailsComponent` displays details of a selected hero.
At the moment the `HeroDetailsComponent` is only visible at the bottom of the `HeroesComponent`
@ -440,6 +454,8 @@ The `HeroDetailComponent` needs a new way to obtain the _hero-to-display_.
Add the following imports:
先添加下列导入语句:
<code-example
path="toh-pt5/src/app/hero-detail/hero-detail.component.ts"
region="added-imports"
@ -452,6 +468,8 @@ Add the following imports:
Inject the `ActivatedRoute`, `HeroService`, and `Location` services
into the constructor, saving their values in private fields:
然后注入`ActivatedRoute``HeroService`服务到构造函数中,将它们的值保存到私有变量中:
<code-example
path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="ctor">
@ -492,6 +510,8 @@ Add it now.
### Add *HeroService.getHero()*
### 添加 *HeroService.getHero()*
Open `HeroService` and add this `getHero()` method
<code-example
@ -528,6 +548,8 @@ the router navigates to the detail view for the hero with `id: 11`, "Mr. Nice".
### Find the way back
### 回到原路
By clicking the browser's back button,
you can go back to the hero list or dashboard view,
depending upon which sent you to the detail view.
@ -556,8 +578,14 @@ Refresh the browser and start clicking.
Users can navigate around the app, from the dashboard to hero details and back,
from heroes list to the mini detail to the hero details and back to the heroes again.
刷新浏览器,并开始点击。
我们能在应用中导航:从仪表盘到英雄详情再回来,从英雄列表到 mini 版英雄详情到英雄详情,再回到英雄列表。
我们可以在仪表盘和英雄列表之间跳来跳去。
You've met all of the navigational requirements that propelled this page.
我们已经满足了在本章开头设定的所有导航需求。
## Final code review
Here are the code files discussed on this page and your app should look like this <live-example></live-example>.
@ -667,6 +695,8 @@ Here are the code files discussed on this page and your app should look like thi
* You added the Angular router to navigate among different components.
添加了 Angular *路由器*在各个不同组件之间导航。
* You turned the `AppComponent` into a navigation shell with `<a>` links and a `<router-outlet>`.
* You configured the router in an `AppRoutingModule`
@ -680,3 +710,6 @@ Here are the code files discussed on this page and your app should look like thi
* You used router link parameters to navigate to the detail view of a user-selected hero.
* You shared the `HeroService` among multiple components.
在多个组件之间共享了`HeroService`服务。

View File

@ -1,5 +1,7 @@
# HTTP
# HTTP 服务
In this tutorial, you'll add the following data persistence features with help from
Angular's `HttpClient`.
@ -11,6 +13,8 @@ Angular's `HttpClient`.
When you're done with this page, the app should look like this <live-example></live-example>.
当我们完成这一章时,应用会变成这样:<live-example></live-example>
## Enable HTTP services
`HttpClient` is Angular's mechanism for communicating with a remote server over HTTP.
@ -93,6 +97,8 @@ Now back to the `HttpClient` story.
## Heroes and HTTP
## 英雄与 HTTP
Import some HTTP symbols that you'll need:
<code-example
@ -150,6 +156,8 @@ Convert that method to use `HttpClient`
Refresh the browser. The hero data should successfully load from the
mock server.
刷新浏览器后,英雄数据就会从模拟服务器被成功读取。
You've swapped `of` for `http.get` and the app keeps working without any other changes
because both functions return an `Observable<Hero[]>`.
@ -256,6 +264,8 @@ Here is the final version of `getHeroes` with the `tap` that logs the operation.
### Get hero by id
### 通过id获取英雄
Most web APIs support a _get by id_ request in the form `api/hero/:id`
(such as `api/hero/11`).
Add a `HeroService.getHero()` method to make that request:
@ -283,6 +293,8 @@ the server.
At the end of the hero detail template, add a save button with a `click` event
binding that invokes a new component method named `save()`.
我们先来确保对英雄名字的编辑不会丢失。先在英雄详情模板的底部添加一个保存按钮,它绑定了一个`click`事件,事件绑定会调用组件中一个名叫`save()`的新方法:
<code-example path="toh-pt6/src/app/hero-detail/hero-detail.component.html" region="save" title="src/app/hero-detail/hero-detail.component.html (save)"></code-example>
Add the following `save()` method, which persists hero name changes using the hero service
@ -339,6 +351,8 @@ the heading:
In response to a click event, call the component's click handler and then
clear the input field so that it's ready for another name.
当点击事件触发时,我们调用组件的点击处理器,然后清空这个输入框,以便用来输入另一个名字。
<code-example path="toh-pt6/src/app/heroes/heroes.component.ts" region="add" title="src/app/heroes/heroes.component.ts (add)"></code-example>
When the given name is non-blank, the handler creates a `Hero`-like object
@ -422,6 +436,8 @@ Note that
Refresh the browser and try the new delete functionality.
刷新浏览器,并试一下这个新的删除功能。
## Search by name
In this last exercise, you learn to chain `Observable` operators together
@ -488,6 +504,8 @@ as listed in the [final code review](#herosearchcomponent) below.
As the user types in the search box, a *keyup* event binding calls the component's `search()`
method with the new search box value.
当用户在搜索框中输入时,一个 *keyup* 事件绑定会调用该组件的`search()`方法,并传入新的搜索框的值。
{@a asyncpipe}
### _AsyncPipe_
@ -564,11 +582,20 @@ Here's the code.
* `debounceTime(300)` waits until the flow of new string events pauses for 300 milliseconds
before passing along the latest string. You'll never make requests more frequently than 300ms.
在传出最终字符串之前,`debounceTime(300)`将会等待,直到新增字符串的事件暂停了 300 毫秒。
我们实际发起请求的间隔永远不会小于 300ms。
* `distinctUntilChanged` ensures that a request is sent only if the filter text changed.
`distinctUntilChanged`确保只在过滤条件变化时才发送请求,
这样就不会重复请求同一个搜索词了。
* `switchMap()` calls the search service for each search term that makes it through `debounce` and `distinctUntilChanged`.
It cancels and discards previous search observables, returning only the latest search service observable.
`switchMap()`会为每个从`debounce``distinctUntilChanged`中通过的搜索词调用搜索服务。
它会取消并丢弃以前的搜索可观察对象,只保留最近的。
<div class="l-sub-section">
With the [switchMap operator](http://www.learnrxjs.io/operators/transformation/switchmap.html),
@ -601,6 +628,8 @@ If you enter characters that match any existing hero names, you'll see something
Your app should look like this <live-example></live-example>.
我们的应用现在变成了这样:<live-example></live-example>
Here are the code files discussed on this page (all in the `src/app/` folder).
{@a heroservice}
@ -693,18 +722,32 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
You're at the end of your journey, and you've accomplished a lot.
旅程即将结束,不过我们已经收获颇丰。
* You added the necessary dependencies to use HTTP in the app.
我们添加了在应用程序中使用 HTTP 的必备依赖。
* You refactored `HeroService` to load heroes from a web API.
我们重构了`HeroService`,以通过 web API 来加载英雄数据。
* You extended `HeroService` to support `post()`, `put()`, and `delete()` methods.
我们扩展了`HeroService`来支持 `post()``put()``delete()` 方法。
* You updated the components to allow adding, editing, and deleting of heroes.
我们更新了组件,以允许用户添加、编辑和删除英雄。
* You configured an in-memory web API.
我们配置了一个内存 Web API。
* You learned how to use Observables.
我们学会了如何使用“可观察对象”。
This concludes the "Tour of Heroes" tutorial.
You're ready to learn more about Angular development in the fundamentals section,
starting with the [Architecture](guide/architecture "Architecture") guide.