基础知识的DI-校对一半了

This commit is contained in:
Zhimin(Rex) YE 2016-05-28 23:10:39 +01:00
parent e8e1f88d60
commit 399df5ae59
2 changed files with 26 additions and 25 deletions

View File

@ -4,5 +4,5 @@ import { HeroService } from './heroes/hero.service';
//#docregion bootstrap
bootstrap(AppComponent,
[HeroService]); // DISCOURAGED (but works)
[HeroService]); // DISCOURAGED (but works)不推荐(但可用)
//#enddocregion bootstrap

View File

@ -14,7 +14,7 @@ include ../_util-fns
In this chapter we'll learn what DI is and why we want it.
Then we'll learn [how to use it](#angular-di) in an Angular app.
在本章中我们将学习DI是什么以及为什么我们需要它。
在本章中我们将学习DI是什么以及我们为什么需要它。
然后我们将学习在Angular应用中该[如何使用它](#angular-di)。
// #enddocregion intro
:marked
@ -51,8 +51,8 @@ include ../_util-fns
the `Car` constructor creates its own copies by "new-ing" them from
the very specific classes, `Engine` and `Tires`.
我们的汽车(`Car`类需要一个引擎(`Engine`轮胎(`Tires`,它没有去请求一个现成的实例,
而是在构造函数中用具体的`Engine`和`Tires`新创建了一份只供自己用的副本。
我们的`Car`类需要一个`Engine`和`Tires`,它没有去请求一个现成的实例,
而是在构造函数中用具体的`Engine`和`Tires`新创建了一份只供自己用的副本。
What if the `Engine` class evolves and its constructor requires a parameter?
Our `Car` is broken and stays broken until we rewrite it along the lines of
@ -63,17 +63,17 @@ include ../_util-fns
when the definion of `Engine` changes, our `Car` class must change.
That makes `Car` brittle.
如果`Engine`类升级了,并且它的构造函数要求传入一个参数了怎么办?
我们这个`Car`类就被破坏了,并且直到我们把创建代码重写为`#{prefix}engine = new Engine(theNewParameter)`之前,它都坏着
当我们首次写`Car`类时,我们不会在乎`Engine`构造函数的参数。就算现在我们也不想在乎。
但当`Engine`类的定义发生变化时,我们就不得不在乎了,`Car`类也不得不跟着改变。
如果`Engine`类升级了,并且它的构造函数要求传入一个参数了,该怎么办?
我们这个`Car`类就被破坏了,而且直到我们把创建引擎的代码重写为`#{prefix}engine = new Engine(theNewParameter)`之前,它都是坏的
当我们首次写`Car`类时,我们不会在乎`Engine`构造函数的参数。现在我们也不想在乎。
当`Engine`类的定义发生变化时,我们就不得不在乎了,`Car`类也不得不跟着改变。
这就会让`Car`类过于脆弱。
What if we want to put a different brand of tires on our `Car`? Too bad.
We're locked into whatever brand the `Tires` class creates. That makes our `Car` inflexible.
如果我们想在我们的`Car`上用一个不同品牌的轮胎会怎样?太糟了。
我们被锁死在`Tires`类创建时使用的那个品牌上。这让我们的`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,
@ -108,7 +108,7 @@ include ../_util-fns
When we can't control the dependencies, a class becomes difficult to test.
我们没法控制这辆车背后隐藏的依赖。
而如果不能控制这些依赖,类就会变得难以测试。
当我们不能控制依赖时,类就会变得难以测试。
How can we make `Car` more robust, flexible, and testable?
@ -189,7 +189,7 @@ include ../_util-fns
during each test:
`Car`类非常容易测试,因为我们现在对它的依赖有了完全的控制权。
我们可以往构造函数中传入mock对象在每个测试期间,它们可以做到我们想让它们做的事:
在每个测试期间,我们可以往构造函数中传入mock对象做到我们想让它们做的事
// #enddocregion why-6
- var stylePattern = { otl: /(new Car.*$)/gm };
+makeExample('dependency-injection/ts/app/car/car-creations.ts', 'car-ctor-instantiation-with-mocks', '', stylePattern)(format=".")
@ -197,7 +197,7 @@ include ../_util-fns
:marked
**We 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.
@ -217,7 +217,7 @@ include ../_util-fns
We could write a giant class to do that:
我们可以写一个巨型类来做这件事:
我们可以写一个巨型类来做这件事(不好的模式)
// #enddocregion why-7
+makeExample('dependency-injection/ts/app/car/car-factory.ts', null, 'app/car/car-factory.ts')
// #docregion why-8
@ -234,7 +234,7 @@ include ../_util-fns
Wouldn't it be nice if we could simply list the things we 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_.
@ -256,7 +256,7 @@ include ../_util-fns
We 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`不需要知道如何创建`Engine`和`Tires`的任何事。
消费者不知道如何创建`Car`的任何事。
我们不需要一个巨大的工厂类来维护它们。
`Car`和消费者只要简单的说出它们想要什么,注入器就会交给它们。
@ -280,13 +280,13 @@ include ../_util-fns
Angular ships with its own dependency injection framework. This framework can also be used
as a standalone module by other applications and frameworks.
Angular自带了它自己的依赖注入框架。此框架也能被当做独立模块用于其它应用和框架中。
Angular自带了它自己的依赖注入框架。此框架也能被当做独立模块用于其它应用和框架中。
That sounds nice. What does it do for us when building components in Angular?
Let's see, one step at a time.
听起来很好。当我们在Angular中构建组件的时候它到底能为我们做什么
让我们看看,一次一步儿
让我们一步一个脚印的看看。
We'll begin with a simplified version of the `HeroesComponent`
that we built in the [The Tour of Heroes](../tutorial/).
@ -311,7 +311,7 @@ include ../_util-fns
Our stripped down version has only one child, `HeroListComponent`,
which displays a list of heroes.
`HeroesComponent`是*英雄*特性区域的根组件。它管理本区的所有子组件。
`HeroesComponent`是*英雄*特性区域的根组件。它管理本区的所有子组件。
我们简化后的版本只有一个子组件`HeroListComponent`,用来显示一个英雄列表。
// #enddocregion di-2
// #docregion di-3
@ -325,7 +325,7 @@ include ../_util-fns
现在`HeroListComponent`从`HEROES`获得英雄数据,一个在另一个文件中定义的内存数据集。
它在开发的早期阶段可能还够用,但离完美就差得远了。
一旦我们开始测试此组件,或者想从远端服务器获得英雄数据,我们就不得不修改`heroes`的实现,并要修改每个用到了`HEROES`模拟数据的地方。
我们一旦开始测试此组件,或者想从远端服务器获得英雄数据,我们就不得不修改`heroes`的实现,并要修改每个用到了`HEROES`模拟数据的地方。
Let's make a service that hides how we get hero data.
@ -361,13 +361,14 @@ include ../_util-fns
我们甚至没有假装这是一个真实的服务。
如果我们真的从一个远端服务器获取数据这个API必须是异步的可能得返回
[ES2015 承诺Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)。
我们也需要被迫重新处理组件如何消费该服务的方式。通常这个很重要,但是我们目前的故事不需要。
// #enddocregion di-5
// #docregion di-6
:marked
A service is nothing more than a class in Angular 2.
It remains nothing more than a class until we register it with an Angular injector.
在Angular 2中服务其实不过是一个类。
在Angular 2中服务只是一个类。
除非我们把它注册进一个Angular注入器否则它没有任何特别之处。
// #enddocregion di-6
// #docregion di-configure-injector-1
@ -392,7 +393,7 @@ include ../_util-fns
We'll explain what [providers](#providers) are later in this chapter.
Before we do, let's see an example of provider registration during bootstrapping:
我们必须先注册**供应商Provider**来配置好注入器,这在创建应用所需的服务时会用到
我们必须先注册**供应商Provider**来配置注入器,这些供应商为我们的应用程序创建所需服务
我们将在本章的稍后部分解释什么是[供应商](#providers)。
在此之前,我们先来看一个在启动期间注册供应商的例子。
// #enddocregion di-configure-injector-2
@ -419,7 +420,7 @@ include ../_util-fns
and nowhere else — the ideal place to register it is in the top-level `HeroesComponent`.
首选的方式是在应用的组件中注册供应商。
因为`HeroService`是用于*英雄*功能区的 —— 并且没别处用它 —— 所以注册它的理想地点就是`HeroesComponent`的顶层
因为`HeroService`是用于*英雄*功能区的 —— 并且没别处用它 —— 所以注册它的理想地点就是顶层的`HeroesComponent`。
// #enddocregion di-configure-injector-3
// #docregion di-register-providers-1
:marked
@ -490,7 +491,7 @@ include ../_util-fns
We're writing in TypeScript and have followed the parameter name with a type annotation, `:HeroService`.
The class is also decorated with the `@Component` decorator (scroll up to confirm that fact).
我们利用TypeScript编程在参数名后面带有一个类型注解:`:HeroService`。
我们利用TypeScript编程在参数名后面添加了一个类型注解:`:HeroService`。
这个类还有一个`@Component`的装饰器(往上翻翻就知道了)。
When the TypeScript compiler evaluates this class, it sees the `@Component` decorator and adds class metadata
@ -547,7 +548,7 @@ include ../_util-fns
Learn more about that in the [Hierarchical Injectors](./hierarchical-dependency-injection.html) chapter.
然而Angular DI是一个分层的依赖注入系统这意味着被嵌套的注入器可以创建它们自己的服务实例。
要了解更多知识,参见[分层注入器](./hierarchical-dependency-injection.html)一章。
要了解更多知识,参见[多级依赖注入器](./hierarchical-dependency-injection.html)一章。
// #enddocregion di-singleton-services
// Skip this for Dart, for now
@ -560,7 +561,7 @@ include ../_util-fns
Listing dependencies as constructor parameters may be all we need to test application parts effectively.
我们前面强调过,设计一个适合依赖注入的类,可以让这个类更容易测试。
要有效的测试应用中的一部分,需要我们做的一切,就只是在构造函数的参数中列出依赖。
要有效的测试应用中的一部分,在构造函数的参数中列出依赖就是我们需要做的一切
For example, we can create a new `HeroListComponent` with a mock service that we can manipulate
under test: