diff --git a/public/docs/ts/latest/guide/dependency-injection.jade b/public/docs/ts/latest/guide/dependency-injection.jade
index 5cc69da098..3efe0af3d9 100644
--- a/public/docs/ts/latest/guide/dependency-injection.jade
+++ b/public/docs/ts/latest/guide/dependency-injection.jade
@@ -19,12 +19,18 @@ block includes
然后,我们将学习在Angular应用中该[如何使用它](#angular-di)。
- [Why dependency injection?](#why-dependency-injection)
+ - [为什么依赖注入?](#why-dependency-injection)
- [Angular dependency injection](#angular-dependency-injection)
+ - [Angular依赖注入](#angular-dependency-injection)
- [Injector providers](#injector-providers)
+ - [注入器提供商](#injector-providers)
- [Dependency injection tokens](#dependency-injection-tokens)
+ - [依赖注入令牌](#dependency-injection-tokens)
- [Summary](#summary)
+ - [总结](#summary)
p Run the #[+liveExampleLink2()].
+p 运行#[+liveExampleLink2('在线例子')].
.l-main-section#why-di
:marked
@@ -115,13 +121,12 @@ p Run the #[+liveExampleLink2()].
我们该如何让`Car`更强壮、有弹性以及可测试?
- That's super easy. We change our `Car` constructor to a version with DI:
-
- 答案超级简单。我们把`Car`的构造函数改造成使用DI的版本:
-
That's super easy. We change our `Car` constructor to a version with DI:
+
+ 答案超级简单。我们把`Car`的构造函数改造成使用DI的版本:
+
+makeTabs(
'dependency-injection/ts/app/car/car.ts, dependency-injection/ts/app/car/car-no-di.ts',
'car-ctor, car-ctor',
@@ -333,10 +338,15 @@ block ctor-syntax
[separate concern](https://en.wikipedia.org/wiki/Separation_of_concerns),
we suggest that you
write the service code in its own file.
+
+ 因为服务是一个[分离关注点](https://en.wikipedia.org/wiki/Separation_of_concerns),
+ 我们建议你把服务代码放到它自己的文件里。
+ifDocsFor('ts')
:marked
See [this note](#one-class-per-file) for details.
+ 到[这个笔记](#one-class-per-file)看更多信息。
+
+makeExample('dependency-injection/ts/app/heroes/hero.service.1.ts',null, 'app/heroes/hero.service.ts' )
:marked
@@ -352,6 +362,8 @@ block ctor-syntax
Notice the `@Injectable()` #{_decorator} above the service class.
We'll discuss its purpose [shortly](#injectable).
+ 注意服务类上面这个`@Injectable()`装饰器。我们[很快](#injectable)会讨论它的用途。
+
- var _perhaps = _docsFor == 'dart' ? '' : 'perhaps';
.l-sub-section
:marked
@@ -467,7 +479,7 @@ block ctor-syntax
.l-sub-section
:marked
#### Focus on the constructor
- ### 来看构造函数
+ #### 来看构造函数
Adding a parameter to the constructor isn't all that's happening here.
@@ -482,19 +494,28 @@ block ctor-syntax
Also recall that the parent component (`HeroesComponent`)
has `providers` information for `HeroService`.
+ 注意构造函数参数有类型`HeroService`,并且`HeroListComponent`类有一个`@Component`装饰器
+ (往上翻可以确认)。另外,记得父级组件(`HeroesComponent`)有`HeroService`的`providers`信息。
+
The constructor parameter type, the `@Component` #{_decorator},
and the parent's `providers` information combine to tell the
Angular injector to inject an instance of
`HeroService` whenever it creates a new `HeroListComponent`.
+ 该构造函数类型、`@Component`装饰器、父级的`providers`信息这三个合起来,一起告诉Angular的注入器,在任何时候新建一个新的`HeroListComponent`的时候,注入一个`HeroService`的实例。
+
#di-metadata
:marked
### Implicit injector creation
+ ### 显性注入器的创建
+
When we introduced the idea of an injector above, we showed how to
use it to create a new `Car`. Here we also show how such an injector
would be explicitly created:
+ 当我们在上面介绍注入器的时候,我们展示了如何使用它创建一个新`Car`。这里,我们也展示一下如何显性的创建这样的注入器:
+
+makeExample('dependency-injection/ts/app/car/car-injector.ts','injector-create-and-call')(format=".")
:marked
@@ -587,12 +608,15 @@ block ctor-syntax
//- FIXME refer to Dart API when that page becomes available.
- var injMetaUrl = 'https://angular.io/docs/ts/latest/api/core/index/InjectableMetadata-class.html';
h3#injectable Why @Injectable()?
+h3#injectable 为何@Injectable()?
:marked
**@Injectable()** marks a class as available to an
injector for instantiation. Generally speaking, an injector will report an
error when trying to instantiate a class that is not marked as
`@Injectable()`.
+ **@Injectable()**标志着一个类可以被一个注入器实例化。通常来讲,在试图实例化一个没有被标识为`@Injectable()`的类时候,注入器将会报告错误。
+
block injectable-not-always-needed-in-ts
.l-sub-section
:marked
@@ -602,21 +626,31 @@ block injectable-not-always-needed-in-ts
We need it because Angular requires constructor parameter metadata
in order to inject a `Logger`.
+ 在这里,我们可以在我们第一版的`HeroService`里面省略`@Injectable()`,因为它没有注入的参数。但是现在我们必须要有它,因为我们的服务有了一个注入的依赖。我们需要它,因为Angular需要构造函数参数的元数据来注入一个`Logger`。
+
.callout.is-helpful
header Suggestion: add @Injectable() to every service class
+ header 建议:为每一个服务类都添加@Injectable()
:marked
We recommend adding `@Injectable()` to every service class, even those that don't have dependencies
and, therefore, do not technically require it. Here's why:
+ 我们建议为每个服务类都添加`@Injectable()`,包括那些没有依赖所以技术上不需要它的。因为:
+
ul(style="font-size:inherit")
li Future proofing: No need to remember @Injectable()
when we add a dependency later.
+ li 面向未来: 没有必要记得在后来添加了一个依赖的时候添加@Injectable()
。
li Consistency: All services follow the same rules, and we don't have to wonder why #{_a} #{_decorator} is missing.
+ li 一致性:所有的服务都遵循同样的规则,并且我们不需要考虑为什么少一个装饰器。
+
:marked
Injectors are also responsible for instantiating components
like `HeroesComponent`. Why haven't we marked `HeroesComponent` as
`@Injectable()`?
+ 注入器同时负责实例化像`HerosComponent`这样的组件。为什么我们不标记`HerosComponent`为`@Injectable()`呢?
+
We *can* add it if we really want to. It isn't necessary because the
`HeroesComponent` is already marked with `@Component`, and this
!{_decorator} class (like `@Directive` and `@Pipe`, which we'll learn about later)
@@ -624,6 +658,10 @@ block injectable-not-always-needed-in-ts
fact `InjectableMetadata` #{_decorator}s that
identify a class as a target for instantiation by an injector.
+ 如果真的想要这样做,我们*可以*添加它。但是这不是必须的,因为`HerosComponent`已经被`@Component`标识,这个装饰器类(像`@Directive`和`@Pipe`一样,我们一会儿将会学到)
+ 是一个InjectableMetadata的子类型。实际上,`InjectableMetadata`装饰器标识着一个类是注入器实例化的目标。
+
+
block ts-any-decorator-will-do
.l-sub-section
:marked
@@ -633,6 +671,10 @@ block ts-any-decorator-will-do
But of course, it is more meaningful to mark a class using the appropriate
InjectableMetadata #{_decorator}.
+ 注入器使用一个类的构造元数据来决定依赖类型,该构造元数据就是构造函数的参数类型所标识的。
+ TypeScript为任何带有一个装饰器的类生成这样的元数据,任何装饰器都生成。
+ 当然,使用一个合适的InjectableMetadata装饰器来标识一个类更加有意义。
+
.callout.is-critical
header Always include the parentheses
@@ -665,6 +707,8 @@ block ts-any-decorator-will-do
Our logger service is quite simple:
+ 我们的日志服务很简单:
+
+makeExample('dependency-injection/ts/app/logger.service.ts', null, 'app/logger.service.ts')
block real-logger
@@ -675,6 +719,8 @@ block real-logger
so we put it in the project's `#{_appDir}` folder, and
we register it in the `providers` #{_array} of the metadata for our application root component, `AppComponent`.
+ 我们比较可能在整个应用程序的任何地方都需要一样的日志服务,所以我们把它放到项目的`#{_appDir}`目录,并在应用程序根组件`AppComponent`的元数据的`providers`数组里面注册它。
+
+makeExcerpt('app/providers.component.ts','providers-logger','app/app.component.ts (excerpt)')
:marked
@@ -683,9 +729,6 @@ block real-logger
如果我们忘了注册这个日志服务,Angular会在首次查找这个日志服务时,抛出一个异常。
code-example(format="nocode").
- EXCEPTION: No provider for Logger! (HeroListComponent -> HeroService -> Logger)
-
-
EXCEPTION: No provider for Logger! (HeroListComponent -> HeroService -> Logger)
(异常:Logger类没有供应商!(HeroListComponent -> HeroService -> Logger))
@@ -755,18 +798,22 @@ code-example(format="nocode").
//- Dart limitation: the provide function isn't const so it cannot be used in an annotation.
- var __andProvideFn = _docsFor == 'dart' ? '' : 'and provide object literal';
+- var __andProvideFn = _docsFor == 'dart' ? '' : '和 provide 对象';
#provide
:marked
- ### The *Provider* class !{__andProvideFn}
-
+ ### *Provider* 类!{__andProvideFn}
:marked
We wrote the `providers` #{_array} like this:
+ 我们像下面一样写`providers`数组:
+
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-1')
:marked
This is actually a short-hand expression for a provider registration using the _provider_ object literal.
+ 这实际上是使用_provider_对象常量注册供应商的缩写表达式。
+
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-3a')
block provider-ctor-args
@@ -886,7 +933,6 @@ block dart-diff-const-metadata-ctor
which makes this object play the logger role.
于是我们可以通过`useValue`选项来注册一个供应商,它会让这个对象直接扮演logger的角色。
-+makeExample('dependency-injection/ts/app/providers.component.ts','providers-7')(format=".")
- var stylePattern = { otl: /(useValue: \w*)/gm };
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-7', '', stylePattern)(format=".")
@@ -896,6 +942,8 @@ block dart-diff-const-metadata-ctor
[Non-class dependencies](#non-class-dependencies) and
[OpaqueToken](#opaquetoken) sections.
+ 在[非类依赖](#non-class-dependencies)和[OpaqueToken](#opaquetoken)查看更多`useValue`的例子。
+
#factory-provider
:marked
### Factory providers
@@ -1065,17 +1113,18 @@ block dart-diff-const-metadata-ctor
//- TODO: if function injection is useful explain or illustrate why.
:marked
### Non-class dependencies
-p
- | What if the dependency value isn't a class? Sometimes the thing we want to inject is a
- block non-class-dep-eg
- span string, function, or object.
-p
- | Applications often define configuration objects with lots of small facts
- | (like the title of the application or the address of a web API endpoint)
- block config-obj-maps
- | but these configuration objects aren't always instances of a class.
- | They can be object literals
- | such as this one:
+ ### 非类依赖
+
+ What if the dependency value isn't a class? Sometimes the thing we want to inject is a string, function, or object.
+
+ 如果依赖值不是一个类呢?有时候我们想要注入的东西是一个字符串,函数或者对象。
+
+ Applications often define configuration objects with lots of small facts(like the title of the application or
+ the address of a web API endpoint) but these configuration objects aren't always instances of a class.
+ They can be object literals such as this one:
+
+ 应用程序经常为很多很小的因素(比如应用程序的标题,或者一个网络API终点的地址)定义配置对象,但是这些配置对象不总是类的实例。
+ 他们可能是对象,比如下面这个:
+makeExample('dependency-injection/ts/app/app.config.ts','config','app/app-config.ts (excerpt)')(format='.')
@@ -1167,12 +1216,16 @@ block dart-map-alternative
#optional
:marked
## Optional dependencies
+ ## 可选依赖
Our `HeroService` *requires* a `Logger`, but what if it could get by without
a logger?
We can tell Angular that the dependency is optional by annotating the
constructor argument with `@Optional()`:
+ 我们的`HeroService`*需要*一个`Logger`,但是如果它可以不用一个Logger就行呢?
+ 我们可以通过把构造函数的参数标记为`@Optional()`来告诉Angular该依赖是可选的:
+
+ifDocsFor('ts')
+makeExample('dependency-injection/ts/app/providers.component.ts','import-optional', '')
+makeExample('dependency-injection/ts/app/providers.component.ts','provider-10-ctor', '')(format='.')
@@ -1182,6 +1235,8 @@ block dart-map-alternative
don't register a logger somewhere up the line, the injector will set the
value of `logger` to null.
+ 当使用`@Optional()`时,我们的代码必须要为一个空值做准备。如果我们不在组件或父级组件中注册一个`logger`的话,注入器会设置该`logger`的值为空null。
+
.l-main-section
:marked
## Summary
@@ -1206,7 +1261,7 @@ block dart-map-alternative
.l-main-section#explicit-injector
:marked
## Appendix: Working with injectors directly
- ### 附录:直接使用注入器工作
+ ## 附录:直接使用注入器工作
We rarely work directly with an injector.
Here's an `InjectorComponent` that does.