批量把Provider/provide改译为提供商/提供,以和ISP(互联网服务提供商)的译法看齐
This commit is contained in:
parent
0303a18020
commit
6264d3bcde
|
@ -42,7 +42,7 @@ include ../_util-fns
|
|||
|
||||
[Define dependencies with providers](#providers)
|
||||
|
||||
[使用供应商定义依赖](#providers)
|
||||
[使用提供商定义依赖](#providers)
|
||||
|
||||
* [The *provide* Object literal](#provide)
|
||||
|
||||
|
@ -50,27 +50,27 @@ include ../_util-fns
|
|||
|
||||
* [useValue - the *value provider*](#usevalue)
|
||||
|
||||
* [useValue - *值供应商*](#usevalue)
|
||||
* [useValue - *值提供商*](#usevalue)
|
||||
|
||||
* [useClass - the *class provider*](#useclass)
|
||||
|
||||
* [useClass - *类供应商*](#useclass)
|
||||
* [useClass - *类提供商*](#useclass)
|
||||
|
||||
* [useExisting - the *alias provider*](#useexisting)
|
||||
|
||||
* [useExisting - *别名供应商*](#useexisting)
|
||||
* [useExisting - *别名提供商*](#useexisting)
|
||||
|
||||
* [useFactory - the *factory provider*](#usefactory)
|
||||
|
||||
* [useFactory - *工厂供应商*](#usefactory)
|
||||
* [useFactory - *工厂提供商*](#usefactory)
|
||||
|
||||
[Define providers with object literals](#object-literals)
|
||||
|
||||
[使用对象字面量定义供应商] (#object-literals)
|
||||
[使用对象字面量定义提供商] (#object-literals)
|
||||
|
||||
[Provider token alternatives](#tokens)
|
||||
|
||||
[供应商可选令牌](#tokens)
|
||||
[提供商可选令牌](#tokens)
|
||||
|
||||
* [class-interface](#class-interface)
|
||||
|
||||
|
@ -128,7 +128,7 @@ include ../_util-fns
|
|||
|
||||
Register providers for dependencies used throughout the application in the root application component, `AppComponent`.
|
||||
|
||||
在应用程序根组件`AppComponent`中注册那些被应用程序全局使用的依赖供应商。
|
||||
在应用程序根组件`AppComponent`中注册那些被应用程序全局使用的依赖提供商。
|
||||
|
||||
In the following example, we import and register several services
|
||||
(the `LoggerService`, `UserContext`, and the `UserService`)
|
||||
|
@ -142,7 +142,7 @@ include ../_util-fns
|
|||
Service classes can act as their own providers which is why listing them in the `providers` array
|
||||
is all the registration we need.
|
||||
|
||||
所有这些服务都是用类实现的。服务类能充当自己的供应商,这就是为什么只要把它们列在`providers`数组里就算注册成功了。
|
||||
所有这些服务都是用类实现的。服务类能充当自己的提供商,这就是为什么只要把它们列在`providers`数组里就算注册成功了。
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -150,7 +150,7 @@ include ../_util-fns
|
|||
Angular creates a service instance from a class provider by "new-ing" it.
|
||||
Learn more about Providers [below](#providers).
|
||||
|
||||
*供应商*是用来新建或者交付服务的。Angular拿到“类供应商”之后,会通过“new”操作来新建服务实例。从[下面](#providers)可以学到更多关于供应商的知识。
|
||||
*提供商*是用来新建或者交付服务的。Angular拿到“类提供商”之后,会通过“new”操作来新建服务实例。从[下面](#providers)可以学到更多关于提供商的知识。
|
||||
|
||||
:marked
|
||||
Now that we've registered these services,
|
||||
|
@ -170,7 +170,7 @@ include ../_util-fns
|
|||
|
||||
We can register _certain_ module providers when bootstrapping rather than in the root application component.
|
||||
|
||||
也可以在引导过程中注册_某些_模块供应商,而非在应用程序根组件里。
|
||||
也可以在引导过程中注册_某些_模块中的提供商,而非在应用程序根组件里。
|
||||
|
||||
We'd do this when we expect to select or configure external modules that support our application
|
||||
but (a) aren't conceptually part of the application and (b) that we could change later without
|
||||
|
@ -194,7 +194,7 @@ include ../_util-fns
|
|||
See both examples in the following `main.ts`
|
||||
where we list their service providers in an array in the second parameter of the `bootstrap` method.
|
||||
|
||||
在下面`main.ts`的两个例子中,在`bootstrap`方法的第二个数组型参数中,列出了它们的服务供应商。
|
||||
在下面`main.ts`的两个例子中,在`bootstrap`方法的第二个数组型参数中,列出了它们的服务提供商。
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/main.ts','bootstrap','app/main.ts')(format='.')
|
||||
|
||||
|
@ -445,7 +445,7 @@ a(id="qualify-dependency-lookup")
|
|||
When a component requests a dependency, Angular starts with that component's injector and walks up the injector tree
|
||||
until it finds the first suitable provider. Angular throws an error if it can't find the dependency during that walk.
|
||||
|
||||
当组件申请一个依赖时,Angular从该组件本身的注入器开始,沿着依赖注入器的树往上找,直到找到第一个符合要求的供应商。如果Angular不能在这个过程中找到合适的依赖,它就会抛出一个错误。
|
||||
当组件申请一个依赖时,Angular从该组件本身的注入器开始,沿着依赖注入器的树往上找,直到找到第一个符合要求的提供商。如果Angular不能在这个过程中找到合适的依赖,它就会抛出一个错误。
|
||||
|
||||
We *want* this behavior most of the time.
|
||||
But sometimes we need to limit the search and/or accommodate a missing dependency.
|
||||
|
@ -526,7 +526,7 @@ figure.image-display
|
|||
The host `HeroBioComponent` doesn't have its own `LoggerService` provider.
|
||||
|
||||
另一个`@Host()`函数是属性`loggerService`的装饰器,我们知道在应用程序中,只有一个`LoggerService`实例,也就是在`AppComponent`级提供的服务。
|
||||
该宿主`HeroBioComponent`没有自己的`LoggerService`供应商。
|
||||
该宿主`HeroBioComponent`没有自己的`LoggerService`提供商。
|
||||
|
||||
Angular would throw an error if we hadn't also decorated the property with the `@Optional()` function.
|
||||
Thanks to `@Optional()`, Angular sets the `loggerService` to null and the rest of the component adapts.
|
||||
|
@ -614,11 +614,11 @@ figure.image-display
|
|||
:marked
|
||||
## Define dependencies with providers
|
||||
|
||||
## 使用供应商来定义依赖
|
||||
## 使用提供商来定义依赖
|
||||
|
||||
In this section we learn to write providers that deliver dependent services.
|
||||
|
||||
在这个部分,我们学习如何编写供应商来提供被依赖的服务。
|
||||
在这个部分,我们学习如何编写提供商来提供被依赖的服务。
|
||||
|
||||
### Background
|
||||
### 背景知识
|
||||
|
@ -649,8 +649,8 @@ figure.image-display
|
|||
|
||||
注入器从哪儿得到的依赖?
|
||||
它可能在自己内部容器里已经有该依赖了。
|
||||
如果它没有,也能在***供应商***的帮助下新建一个。
|
||||
*供应商*就是一个用于交付服务的配方,它被关联到一个令牌。
|
||||
如果它没有,也能在***提供商***的帮助下新建一个。
|
||||
*提供商*就是一个用于交付服务的配方,它被关联到一个令牌。
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -658,42 +658,42 @@ figure.image-display
|
|||
to its parent injector, where the process repeats until there are no more injectors.
|
||||
If the search is futile, the injector throws an error ... unless the request was [optional](#optional).
|
||||
|
||||
如果注入器无法根据令牌在自己内部找到对应的供应商,它便将请求移交给它的父级注入器,这个过程不断重复,直到没有更多注入器为止。
|
||||
如果注入器无法根据令牌在自己内部找到对应的提供商,它便将请求移交给它的父级注入器,这个过程不断重复,直到没有更多注入器为止。
|
||||
如果没找到,注入器就抛出一个错误...除非这个请求是[可选的](#optional)。
|
||||
|
||||
Let's return our attention to providers themselves.
|
||||
|
||||
让我们把注意力转回到供应商。
|
||||
让我们把注意力转回到提供商。
|
||||
:marked
|
||||
A new injector has no providers.
|
||||
|
||||
新建的注入器中没有供应商。
|
||||
新建的注入器中没有提供商。
|
||||
|
||||
Angular initializes the injectors it creates with some providers it cares about.
|
||||
We have to register our _own_ application providers manually,
|
||||
usually in the `providers` array of the `Component` or `Directive` metadata:
|
||||
|
||||
Angular会使用一些自带的供应商来初始化这些注入器。我们必须自行注册属于_自己_的供应商,通常用`组件`或者`指令`元数据中的`providers`数组进行注册。
|
||||
Angular会使用一些自带的提供商来初始化这些注入器。我们必须自行注册属于_自己_的提供商,通常用`组件`或者`指令`元数据中的`providers`数组进行注册。
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/app.component.ts','providers','app/app.component.ts (供应商)')
|
||||
+makeExample('cb-dependency-injection/ts/app/app.component.ts','providers','app/app.component.ts (提供商)')
|
||||
:marked
|
||||
### Defining providers
|
||||
|
||||
### 定义供应商
|
||||
### 定义提供商
|
||||
|
||||
The simple class provider is the most typical by far.
|
||||
We mention the class in the `providers` array and we're done.
|
||||
|
||||
简单的类供应商是最典型的例子。只要在`providers`数值里面提到该类就可以了。
|
||||
简单的类提供商是最典型的例子。只要在`providers`数值里面提到该类就可以了。
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','class-provider','app/hero-bios.component.ts (类供应商)')(format='.')
|
||||
+makeExample('cb-dependency-injection/ts/app/hero-bios.component.ts','class-provider','app/hero-bios.component.ts (类提供商)')(format='.')
|
||||
:marked
|
||||
It's that simple because the most common injected service is an instance of a class.
|
||||
But not every dependency can be satisfied by creating a new instance of a class.
|
||||
We need other ways to deliver dependency values and that means we need other ways to specify a provider.
|
||||
|
||||
注册类供应商之所以这么简单,是因为最常见的可注入服务就是一个类的实例。
|
||||
但是,并不是所有的依赖都只要创建一个类的新实例就可以交付了。我们还需要其它的交付方式,这意味着我们也需要其它方式来指定供应商。
|
||||
注册类提供商之所以这么简单,是因为最常见的可注入服务就是一个类的实例。
|
||||
但是,并不是所有的依赖都只要创建一个类的新实例就可以交付了。我们还需要其它的交付方式,这意味着我们也需要其它方式来指定提供商。
|
||||
|
||||
The `HeroOfTheMonthComponent` example demonstrates many of the alternatives and why we need them.
|
||||
|
||||
|
@ -723,30 +723,30 @@ a(id='provide')
|
|||
The *definition* object has one main property, (e.g. `useValue`) that indicates how the provider
|
||||
should create or return the provided value.
|
||||
|
||||
该*定义*对象有一个主属性(即`userValue`),用来标识该供应商会如何新建和返回依赖。
|
||||
该*定义*对象有一个主属性(即`userValue`),用来标识该提供商会如何新建和返回依赖。
|
||||
|
||||
.l-main-section
|
||||
a(id='usevalue')
|
||||
:marked
|
||||
#### useValue - the *value provider*
|
||||
|
||||
#### useValue - *值-供应商*
|
||||
#### useValue - *值-提供商*
|
||||
|
||||
Set the `useValue` property to a ***fixed value*** that the provider can return as the dependency object.
|
||||
|
||||
把一个***固定的值**,也就是该供应商可以将其作为依赖对象返回的值,赋给`userValue`属性。
|
||||
把一个***固定的值**,也就是该提供商可以将其作为依赖对象返回的值,赋给`userValue`属性。
|
||||
|
||||
Use this technique to provide *runtime configuration constants* such as web-site base addresses and feature flags.
|
||||
We often use a *value provider* in a unit test to replace a production service with a fake or mock.
|
||||
|
||||
使用该技巧来进行*运行期常量设置*,比如网站的基础地址和功能标志等。
|
||||
我们通常在单元测试中使用*值-供应商*,用一个假的或模仿的(服务)来取代一个生产环境的服务。
|
||||
我们通常在单元测试中使用*值-提供商*,用一个假的或模仿的(服务)来取代一个生产环境的服务。
|
||||
|
||||
The `HeroOfTheMonthComponent` example has two *value providers*.
|
||||
The first provides an instance of the `Hero` class;
|
||||
the second specifies a literal string resource:
|
||||
|
||||
`HeroOfTheMonthComponent`例子有两个*值-供应商*。
|
||||
`HeroOfTheMonthComponent`例子有两个*值-提供商*。
|
||||
第一个提供了一个`Hero`类的实例;第二个指定了一个字符串资源:
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-value')(format='.')
|
||||
|
@ -754,37 +754,37 @@ a(id='usevalue')
|
|||
The `Hero` provider token is a class which makes sense because the value is a `Hero`
|
||||
and the consumer of the injected hero would want the type information.
|
||||
|
||||
`Hero`供应商的令牌是一个类,这很合理,因为它提供的结果是一个`Hero`实例,并且被注入该英雄的消费者也需要知道它类型信息。
|
||||
`Hero`提供商的令牌是一个类,这很合理,因为它提供的结果是一个`Hero`实例,并且被注入该英雄的消费者也需要知道它类型信息。
|
||||
|
||||
The `TITLE` provider token is *not a class*.
|
||||
It's a special kind of provider lookup key called an [OpaqueToken](#opaquetoken).
|
||||
We often use an `OpaqueToken` when the dependency is a simple value like a string, a number, or a function.
|
||||
|
||||
`TITLE` 供应商的令牌*不是一个类*。它是一个特别类型的供应商查询键,名叫[OpaqueToken](#opaquetoken).
|
||||
`TITLE` 提供商的令牌*不是一个类*。它是一个特别类型的提供商查询键,名叫[OpaqueToken](#opaquetoken).
|
||||
|
||||
The value of a *value provider* must be defined *now*. We can't create the value later.
|
||||
Obviously the title string literal is immediately available.
|
||||
The `someHero` variable in this example was set earlier in the file:
|
||||
|
||||
一个*值-供应商*的值必须要*立即*定义。不能事后再定义它的值。很显然,标题字符串是立刻可用的。
|
||||
一个*值-提供商*的值必须要*立即*定义。不能事后再定义它的值。很显然,标题字符串是立刻可用的。
|
||||
该例中的`someHero`变量是以前在下面这个文件中定义的:
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','some-hero')
|
||||
:marked
|
||||
The other providers create their values *lazily* when they're needed for injection.
|
||||
|
||||
其它供应商只在需要注入它们的时候才创建并*延迟加载*它们的值。
|
||||
其它提供商只在需要注入它们的时候才创建并*延迟加载*它们的值。
|
||||
|
||||
.l-main-section
|
||||
a(id='useclass')
|
||||
:marked
|
||||
#### useClass - the *class provider*
|
||||
|
||||
#### useClass - *类-供应商*
|
||||
#### useClass - *类-提供商*
|
||||
|
||||
The `useClass` provider creates and returns new instance of the specified class.
|
||||
|
||||
`userClass`供应商创建并返回一个指定类的新实例。
|
||||
`userClass`提供商创建并返回一个指定类的新实例。
|
||||
|
||||
Use this technique to ***substitute an alternative implementation*** for a common or default class.
|
||||
The alternative could implement a different strategy, extend the default class,
|
||||
|
@ -802,14 +802,14 @@ a(id='useclass')
|
|||
class to be created (`HeroService`) is also the provider's injection token.
|
||||
We wrote it in this long form to de-mystify the preferred short form.
|
||||
|
||||
第一个供应商是*展开了语法糖的*,是一个典型情况的展开。一般来说,被新建的类(`HeroService`)同时也是该供应商的注入令牌。
|
||||
第一个提供商是*展开了语法糖的*,是一个典型情况的展开。一般来说,被新建的类(`HeroService`)同时也是该提供商的注入令牌。
|
||||
这里用完整形态来编写它,来反衬我们更喜欢的缩写形式。
|
||||
|
||||
The second provider substitutes the `DateLoggerService` for the `LoggerService`.
|
||||
The `LoggerService` is already registered at the `AppComponent` level.
|
||||
When _this component_ requests the `LoggerService`, it receives the `DateLoggerService` instead.
|
||||
|
||||
第二个供应商使用`DateLoggerService`来满足`LoggerService`。该`LoggerService`在`AppComponent`级别已经被注册。当_这个组件_要求`LoggerService`的时候,它得到的却是`DateLoggerService`服务。
|
||||
第二个提供商使用`DateLoggerService`来满足`LoggerService`。该`LoggerService`在`AppComponent`级别已经被注册。当_这个组件_要求`LoggerService`的时候,它得到的却是`DateLoggerService`服务。
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -829,13 +829,13 @@ a(id='useexisting')
|
|||
:marked
|
||||
#### useExisting - the *alias provider*
|
||||
|
||||
#### useExisting - *别名-供应商*
|
||||
#### useExisting - *别名-提供商*
|
||||
|
||||
The `useExisting` provider maps one token to another.
|
||||
In effect, the first token is an ***alias*** for the service associated with second token,
|
||||
creating ***two ways to access the same service object***.
|
||||
|
||||
使用`useExisting`,供应商可以把一个令牌映射到另一个令牌上。实际上,第一个令牌是第二个令牌所对应的服务的一个***别名***,创造了***访问同一个服务对象的两种方法***。
|
||||
使用`useExisting`,提供商可以把一个令牌映射到另一个令牌上。实际上,第一个令牌是第二个令牌所对应的服务的一个***别名***,创造了***访问同一个服务对象的两种方法***。
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-existing')
|
||||
:marked
|
||||
|
@ -860,7 +860,7 @@ figure.image-display
|
|||
which happens to be the `DateLoggerService` thanks to the override provider registered previously via `useClass`.
|
||||
The following image, which displays the logging date, confirms the point:
|
||||
|
||||
实际上,Angular确实想把`logger`参数设置为注入器里`LoggerService`的完整版本。只是在之前的供应商注册里使用了`useClass`,
|
||||
实际上,Angular确实想把`logger`参数设置为注入器里`LoggerService`的完整版本。只是在之前的提供商注册里使用了`useClass`,
|
||||
所以该完整版本被`DateLoggerService`取代了。
|
||||
在下面的图片中,显示了日志日期,可以确认这一点:
|
||||
|
||||
|
@ -872,12 +872,12 @@ a(id='usefactory')
|
|||
:marked
|
||||
#### useFactory - the *factory provider*
|
||||
|
||||
#### useFactory - *工厂-供应商*
|
||||
#### useFactory - *工厂-提供商*
|
||||
|
||||
The `useFactory` provider creates a dependency object by calling a factory function
|
||||
as seen in this example.
|
||||
|
||||
`useFactory` 供应商通过调用工厂函数来新建一个依赖对象,如下例所示。
|
||||
`useFactory` 提供商通过调用工厂函数来新建一个依赖对象,如下例所示。
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-factory')
|
||||
:marked
|
||||
|
@ -900,7 +900,7 @@ a(id='usefactory')
|
|||
The `runnersUpFactory` itself isn't the provider factory function.
|
||||
The true provider factory function is the function that `runnersUpFactory` returns.
|
||||
|
||||
`runnersUpFactory`自身不是供应商工厂函数。真正的供应商工厂函数是`runnersUpFactory`返回的函数。
|
||||
`runnersUpFactory`自身不是提供商工厂函数。真正的提供商工厂函数是`runnersUpFactory`返回的函数。
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/runners-up.ts','factory-synopsis','runners-up.ts (excerpt)')(format='.')
|
||||
:marked
|
||||
|
@ -934,7 +934,7 @@ a(id="tokens")
|
|||
:marked
|
||||
## Provider token alternatives: the *class-interface* and *OpaqueToken*
|
||||
|
||||
## 备选供应商令牌:*类-接口*和*OpaqueToken*
|
||||
## 备选提供商令牌:*类-接口*和*OpaqueToken*
|
||||
|
||||
Angular dependency injection is easiest when the provider *token* is a class
|
||||
that is also the type of the returned dependency object (what we usually call the *service*).
|
||||
|
@ -953,7 +953,7 @@ a(id="tokens")
|
|||
In the previous *Hero of the Month* example, we used the `MinimalLogger` class
|
||||
as the token for a provider of a `LoggerService`.
|
||||
|
||||
在前面的*每月英雄*的例子中,我们用了`MinimalLogger`类作为`LoggerService` 供应商的令牌。
|
||||
在前面的*每月英雄*的例子中,我们用了`MinimalLogger`类作为`LoggerService` 提供商的令牌。
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','use-existing')
|
||||
:marked
|
||||
|
@ -984,7 +984,7 @@ a(id="tokens")
|
|||
The key benefit of a *class-interface* is that we can get the strong-typing of an interface
|
||||
and we can ***use it as a provider token*** in the same manner as a normal class.
|
||||
|
||||
我们称这种用法的类叫做*类-接口*。它关键的好处是:提供了接口的强类型,能像正常类一样***把它当做供应商令牌使用***。
|
||||
我们称这种用法的类叫做*类-接口*。它关键的好处是:提供了接口的强类型,能像正常类一样***把它当做提供商令牌使用***。
|
||||
|
||||
A ***class-interface*** should define *only* the members that its consumers are allowed to call.
|
||||
Such a narrowing interface helps decouple the concrete class from its consumers.
|
||||
|
@ -1004,13 +1004,13 @@ a(id="tokens")
|
|||
They exist only in the TypeScript design space.
|
||||
They disappear after the code is transpiled to JavaScript.
|
||||
|
||||
不能把接口当做供应商的令牌,因为接口不是有效的JavaScript对象。
|
||||
不能把接口当做提供商的令牌,因为接口不是有效的JavaScript对象。
|
||||
它们只存在在TypeScript的设计空间里。它们会在被编译为JavaScript之后消失。
|
||||
|
||||
A provider token must be a real JavaScript object of some kind:
|
||||
a function, an object, a string ... a class.
|
||||
|
||||
一个供应商令牌必须是一个真实的JavaScript对象,比如:一个函数,一个对象,一个字符串 ...一个类。
|
||||
一个提供商令牌必须是一个真实的JavaScript对象,比如:一个函数,一个对象,一个字符串 ...一个类。
|
||||
|
||||
Using a class as an interface gives us the characteristics of an interface in a JavaScript object.
|
||||
|
||||
|
@ -1049,7 +1049,7 @@ a(id='opaque-token')
|
|||
We encountered them twice in the *Hero of the Month* example,
|
||||
in the *title* value provider and in the *runnersUp* factory provider.
|
||||
|
||||
`OpaqueToken`具有这些特征。在*Hero of the Month*例子中遇见它们两次,一个是*title*的值,一个是*runnersUp* 工厂供应商。
|
||||
`OpaqueToken`具有这些特征。在*Hero of the Month*例子中遇见它们两次,一个是*title*的值,一个是*runnersUp* 工厂提供商。
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/hero-of-the-month.component.ts','provide-opaque-token')(format='.')
|
||||
:marked
|
||||
|
@ -1282,8 +1282,8 @@ a(id='alex')
|
|||
that creates an *alternative* way to inject the same component instance
|
||||
and add that provider to the `providers` array of the `@Component` metadata for the `AlexComponent`:
|
||||
|
||||
我们编写一个[*别名供应商*](#useexisting) —一个拥有`useExisting`定义的`provide`函数 —
|
||||
它新建一个*备选的*方式来注入同一个组件实例,并把这个供应商添加到`AlexComponent`的`@Component`元数据里的`providers`数组。
|
||||
我们编写一个[*别名提供商*](#useexisting) —一个拥有`useExisting`定义的`provide`函数 —
|
||||
它新建一个*备选的*方式来注入同一个组件实例,并把这个提供商添加到`AlexComponent`的`@Component`元数据里的`providers`数组。
|
||||
|
||||
a(id="alex-providers")
|
||||
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alex-providers','parent-finder.component.ts (AlexComponent providers)')(format='.')
|
||||
|
@ -1291,7 +1291,7 @@ a(id="alex-providers")
|
|||
[Parent](#parent-token) is the provider's *class-interface* token.
|
||||
The [*forwardRef*](#forwardref) breaks the circular reference we just created by having the `AlexComponent` refer to itself.
|
||||
|
||||
[Parent](#parent-token)是该供应商的*类-接口*令牌。`AlexComponent`引用了自身,造成循环引用,使用[*forwardRef*](#forwardRef)打破了该循环。
|
||||
[Parent](#parent-token)是该提供商的*类-接口*令牌。`AlexComponent`引用了自身,造成循环引用,使用[*forwardRef*](#forwardRef)打破了该循环。
|
||||
|
||||
*Carol*, the third of *Alex*'s child components, injects the parent into its `parent` parameter, the same way we've done it before:
|
||||
|
||||
|
@ -1333,7 +1333,7 @@ a(id="parent-tree")
|
|||
If we're going to keep writing [*alias providers*](#useexisting) like this we should create a [helper function](#provideparent).
|
||||
|
||||
*Barry*的`providers`数组看起来很像[*Alex*的那个](#alex-providers).
|
||||
如果准备一直像这样编写[*别名供应商*](#useexisting)的话,我们应该建立一个[帮助函数](#provideparent)。
|
||||
如果准备一直像这样编写[*别名提供商*](#useexisting)的话,我们应该建立一个[帮助函数](#provideparent)。
|
||||
|
||||
For now, focus on *Barry*'s constructor:
|
||||
|
||||
|
@ -1425,7 +1425,7 @@ a(id="provideparent")
|
|||
Writing variations of the same parent *alias provider* gets old quickly,
|
||||
especially this awful mouthful with a [*forwardRef*](#forwardref):
|
||||
|
||||
编写父组件相同的各种*别名供应商*很快就会变得啰嗦,在用[*forwardRef](#forwardRef)的时候尤其绕口:
|
||||
编写父组件相同的各种*别名提供商*很快就会变得啰嗦,在用[*forwardRef](#forwardRef)的时候尤其绕口:
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alex-providers')(format='.')
|
||||
:marked
|
||||
|
@ -1437,7 +1437,7 @@ a(id="provideparent")
|
|||
:marked
|
||||
Now we can add a simpler, more meaningful parent provider to our components:
|
||||
|
||||
现在就可以为组件添加一个更简单、直观的父级供应商了:
|
||||
现在就可以为组件添加一个更简单、直观的父级提供商了:
|
||||
|
||||
+makeExample('cb-dependency-injection/ts/app/parent-finder.component.ts','alice-providers')(format='.')
|
||||
:marked
|
||||
|
|
|
@ -77,8 +77,8 @@ code-example(format='')
|
|||
This means as we bootstrap our application using the Browser platform `boostrap()`
|
||||
function, we'll also have to include `Title` service explicitly as one of the bootstrap providers:
|
||||
|
||||
虽然该类是浏览器平台包的一部分,但它*没有被*Angular加载为*浏览器平台上的默认服务供应商*。
|
||||
这意味着,使用浏览器平台的`bootstrap()`函数来引导应用程序时,我们必须要明确地把`Title`服务作为引导期的供应商之一加入进来:
|
||||
虽然该类是浏览器平台包的一部分,但它*没有被*Angular加载为*浏览器平台上的默认服务提供商*。
|
||||
这意味着,使用浏览器平台的`bootstrap()`函数来引导应用程序时,我们必须要明确地把`Title`服务作为引导期的提供商之一加入进来:
|
||||
|
||||
+makeExample( "cb-set-document-title/ts/app/main.ts", "bootstrap-title", "app/main.ts (provide Title service)" )(format='.')
|
||||
:marked
|
||||
|
|
|
@ -130,7 +130,7 @@ include _util-fns
|
|||
between a "token" or "key" and a dependency [provider](#provider).
|
||||
This more rare usage should be clear in context.
|
||||
|
||||
有可能指的是[依赖注入(Dependency Injection)](#dependency-injection)在一个令牌(Token)或键值(Key)和一个依赖的[供应商(Provider)](#provider)之间的绑定。
|
||||
有可能指的是[依赖注入(Dependency Injection)](#dependency-injection)在一个令牌(Token)或键值(Key)和一个依赖的[提供商(Provider)](#provider)之间的绑定。
|
||||
这种用法很少,而且一般都会在上下文中写清楚。
|
||||
|
||||
:marked
|
||||
|
@ -144,7 +144,7 @@ include _util-fns
|
|||
[dependency injection system](#dependency-injection).
|
||||
|
||||
通过一个名叫`bootstrap`的方法来引导Angular应用程序。这个`bootstrap`方法会识别应用程序的顶级“根”[组件(Component)](#component),
|
||||
并可能通过[依赖注入体系(Dependency Injection System)](#dependency-injection)注册服务的[供应商(Provider)](#provider)。
|
||||
并可能通过[依赖注入体系(Dependency Injection System)](#dependency-injection)注册服务的[提供商(Provider)](#provider)。
|
||||
|
||||
One can bootstrap multiple apps in the same `index.html`, each with its own top level root.
|
||||
|
||||
|
@ -386,26 +386,26 @@ include _util-fns
|
|||
If the `Injector` can't find a value for a given token, it creates
|
||||
a new value using a `Provider` for that token.
|
||||
|
||||
注入器(`Injector`)维护一个令牌与相应依赖值的对照表(map)。如果注入器不能找到一个令牌对应的依赖值,它就会使用供应商(`Provider`)来创建一个依赖值。
|
||||
注入器(`Injector`)维护一个令牌与相应依赖值的对照表(map)。如果注入器不能找到一个令牌对应的依赖值,它就会使用提供商(`Provider`)来创建一个依赖值。
|
||||
|
||||
A [Provider](#provider) is a recipe for
|
||||
creating new instances of a dependency value associated with a particular token.
|
||||
|
||||
[供应商(Provider)](#provider)是创建依赖实例的“菜谱”之一,这个实例会与一个特定的令牌关联起来。
|
||||
[提供商(Provider)](#provider)是创建依赖实例的“菜谱”之一,这个实例会与一个特定的令牌关联起来。
|
||||
|
||||
An injector can only create a value for a given token if it has
|
||||
a `Provider` for that token in its internal provider registry.
|
||||
Registering providers is a critical preparatory step.
|
||||
|
||||
只有当注入器内部的供应商注册表中存在与令牌对应的供应商时,注入器才能为这个令牌创建一个依赖值。所以注册供应商是一个非常关键的准备步骤。
|
||||
只有当注入器内部的提供商注册表中存在与令牌对应的提供商时,注入器才能为这个令牌创建一个依赖值。所以注册提供商是一个非常关键的准备步骤。
|
||||
|
||||
Angular registers some of its own providers with every injector.
|
||||
We can register our own providers. Quite often the best time to register a `Provider`
|
||||
is when we [bootstrap](#bootstrap) the application.
|
||||
There are other opportunities to register as well.
|
||||
|
||||
Angular会为每个注册器注册很多Angular内建供应商。我们也可以注册自己的供应商。通常注册供应商的最佳时间是在应用程序开始[引导(Bootstrap)](#bootstrap)的时候。
|
||||
当然,我们也有其它很多机会注册供应商。
|
||||
Angular会为每个注册器注册很多Angular内建提供商。我们也可以注册自己的提供商。通常注册提供商的最佳时间是在应用程序开始[引导(Bootstrap)](#bootstrap)的时候。
|
||||
当然,我们也有其它很多机会注册提供商。
|
||||
|
||||
Learn more in the [Dependency Injection](/docs/ts/latest/guide/dependency-injection.html) chapter.
|
||||
|
||||
|
@ -539,7 +539,7 @@ include _util-fns
|
|||
that can find a named "dependency" in its cache or create such a thing
|
||||
with a registered [provider](#provider).
|
||||
|
||||
Angular[依赖注入系统(Dependency Injection System)](#dependency-injection)中的一个对象,它可以在自己的缓存中找到一个“有名字的依赖”或者利用一个已注册的[供应商(Provider)](#provider)来创建这样一个依赖。
|
||||
Angular[依赖注入系统(Dependency Injection System)](#dependency-injection)中的一个对象,它可以在自己的缓存中找到一个“有名字的依赖”或者利用一个已注册的[提供商(Provider)](#provider)来创建这样一个依赖。
|
||||
:marked
|
||||
## Input
|
||||
## 输入属性(Input)
|
||||
|
@ -775,13 +775,13 @@ include _util-fns
|
|||
|
||||
:marked
|
||||
## Provider
|
||||
## 供应商(Provider)
|
||||
## 提供商(Provider)
|
||||
.l-sub-section
|
||||
:marked
|
||||
A Provider creates a new instance of a dependency for the Dependency Injection system.
|
||||
It relates a lookup token to code - sometimes called a "recipe" - that can create a dependency value.
|
||||
|
||||
依赖注入系统依靠供应商来创建依赖的实例。它把一个供查阅用的令牌和代码(有时也叫“配方”)关联到一起,以便创建依赖值。
|
||||
依赖注入系统依靠提供商来创建依赖的实例。它把一个供查阅用的令牌和代码(有时也叫“配方”)关联到一起,以便创建依赖值。
|
||||
|
||||
For example, `new Provider(Foo, {useClass: Foo})` creates a `Provider`
|
||||
that relates the `Foo` token to a function that creates a new instance of the `Foo` class.
|
||||
|
|
|
@ -452,7 +452,7 @@ code-example(language="html").
|
|||
This is one way to tell Angular that our component's constructor requires a `HeroService`
|
||||
so it can get the list of heroes to display. We'll get to dependency injection in a moment.
|
||||
|
||||
* `providers` - 一个数组,包含组件所依赖的服务所需要的*依赖注入供应商*。
|
||||
* `providers` - 一个数组,包含组件所依赖的服务所需要的*依赖注入提供商*。
|
||||
这是在告诉Angular:该组件的构造函数需要一个`HeroService`服务,这样组件就可以从服务中获得用来显示英雄列表的那些数据。
|
||||
我们一会儿就讲到了依赖注入。
|
||||
|
||||
|
@ -821,14 +821,14 @@ figure
|
|||
In brief, we must have previously registered a **provider** of the `HeroService` with the `Injector`.
|
||||
A provider is something that can create or return a service, typically the service class itself.
|
||||
|
||||
简单的说,必须在要求注入`HeroService`之前,注册一个`HeroService`的**供应商Provider**到注入器。
|
||||
供应商可以创建并返回服务,通常返回的就是这个“服务类”本身。
|
||||
简单的说,必须在要求注入`HeroService`之前,注册一个`HeroService`的**提供商Provider**到注入器。
|
||||
提供商可以创建并返回服务,通常返回的就是这个“服务类”本身。
|
||||
|
||||
We can register providers at any level of the application component tree.
|
||||
We often do so at the root when we bootstrap the application so that
|
||||
the same instance of a service is available everywhere.
|
||||
|
||||
可以在应用程序的组件树中的任何级别上注册供应商。
|
||||
可以在应用程序的组件树中的任何级别上注册提供商。
|
||||
当需要一个服务的同一个实例在任何地方都是可用时,我们通常在应用引导程序中注册它。
|
||||
|
||||
+makeExample('architecture/ts/app/main.ts', 'bootstrap','app/main.ts (节选)')(format=".")
|
||||
|
@ -868,15 +868,15 @@ figure
|
|||
|
||||
* an injector can create a new service instance using a *provider*.
|
||||
|
||||
* 注入器能使用*供应商*创建一个新的服务实例。
|
||||
* 注入器能使用*提供商*创建一个新的服务实例。
|
||||
|
||||
* a *provider* is a recipe for creating a service.
|
||||
|
||||
* *供应商*是一个用于创建服务的“配方”。
|
||||
* *提供商*是一个用于创建服务的“配方”。
|
||||
|
||||
* we register *providers* with injectors.
|
||||
|
||||
* 把*供应商*注册到注入器。
|
||||
* 把*提供商*注册到注入器。
|
||||
|
||||
<a id="other-stuff"></a>
|
||||
.l-main-section
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
"bold": [
|
||||
"provide"
|
||||
],
|
||||
"description": "<p>以MyAppComponent作为根组件引导应用,并且配置DI的各种供应商。</p>\n"
|
||||
"description": "<p>以MyAppComponent作为根组件引导应用,并且配置DI的各种提供商。</p>\n"
|
||||
}
|
||||
],
|
||||
"index": 0
|
||||
|
@ -432,7 +432,7 @@
|
|||
"provide",
|
||||
"useClass"
|
||||
],
|
||||
"description": "<p>把MyService类的供应商设置或改写为MyMockService。</p>\n"
|
||||
"description": "<p>把MyService类的提供商设置或改写为MyMockService。</p>\n"
|
||||
},
|
||||
{
|
||||
"syntax": "provide(MyService, {useFactory: myFactory})",
|
||||
|
@ -440,7 +440,7 @@
|
|||
"provide",
|
||||
"useFactory"
|
||||
],
|
||||
"description": "<p>把MyService的供应商设置或改写为myFactory工厂函数。</p>\n"
|
||||
"description": "<p>把MyService的提供商设置或改写为myFactory工厂函数。</p>\n"
|
||||
},
|
||||
{
|
||||
"syntax": "provide(MyValue, {useValue: 41})",
|
||||
|
@ -448,7 +448,7 @@
|
|||
"provide",
|
||||
"useValue"
|
||||
],
|
||||
"description": "<p>把MyValue的供应商设置或改写为值41。</p>\n"
|
||||
"description": "<p>把MyValue的提供商设置或改写为值41。</p>\n"
|
||||
}
|
||||
],
|
||||
"index": 9
|
||||
|
|
|
@ -23,7 +23,7 @@ block includes
|
|||
- [Angular dependency injection](#angular-dependency-injection)
|
||||
- [Angular依赖注入](#angular-dependency-injection)
|
||||
- [Injector providers](#injector-providers)
|
||||
- [注入器供应商](#injector-providers)
|
||||
- [注入器提供商](#injector-providers)
|
||||
- [Dependency injection tokens](#dependency-injection-tokens)
|
||||
- [依赖注入令牌](#dependency-injection-tokens)
|
||||
- [Summary](#summary)
|
||||
|
@ -405,9 +405,9 @@ block ctor-syntax
|
|||
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**来配置注入器,这些供应商为我们的应用程序创建所需服务。
|
||||
我们将在本章的稍后部分解释什么是[供应商](#providers)。
|
||||
在此之前,我们先来看一个在启动期间注册供应商的例子。
|
||||
我们必须先注册**提供商Provider**来配置注入器,这些提供商为我们的应用程序创建所需服务。
|
||||
我们将在本章的稍后部分解释什么是[提供商](#providers)。
|
||||
在此之前,我们先来看一个在启动期间注册提供商的例子。
|
||||
|
||||
+makeExample('dependency-injection/ts/app/main.1.ts', 'bootstrap-discouraged')(format='.')
|
||||
|
||||
|
@ -425,18 +425,18 @@ block ctor-syntax
|
|||
|
||||
当然,我们不禁要问,为什么注释中告诉我们不要这么做。
|
||||
它*能*工作,但不是最佳实践。
|
||||
bootstrap函数的供应商选项是用来配置和改写Angular自身的预注册服务的,比如它的路由支持。
|
||||
bootstrap函数的提供商选项是用来配置和改写Angular自身的预注册服务的,比如它的路由支持。
|
||||
|
||||
The preferred approach is to register application providers in application components.
|
||||
Because the `HeroService` is used within the *Heroes* feature area —
|
||||
and nowhere else — the ideal place to register it is in the top-level `HeroesComponent`.
|
||||
|
||||
首选的方式是在应用的组件中注册供应商。
|
||||
首选的方式是在应用的组件中注册提供商。
|
||||
因为`HeroService`是用于*英雄*功能区的 —— 并且没别处用它 —— 所以注册它的理想地点就是顶层的`HeroesComponent`。
|
||||
|
||||
:marked
|
||||
### Registering providers in a component
|
||||
### 在组件中注册供应商
|
||||
### 在组件中注册提供商
|
||||
|
||||
Here's a revised `HeroesComponent` that registers the `HeroService`.
|
||||
|
||||
|
@ -727,7 +727,7 @@ block real-logger
|
|||
|
||||
code-example(format="nocode").
|
||||
EXCEPTION: No provider for Logger! (HeroListComponent -> HeroService -> Logger)
|
||||
(异常:Logger类没有供应商!(HeroListComponent -> HeroService -> Logger))
|
||||
(异常:Logger类没有提供商!(HeroListComponent -> HeroService -> Logger))
|
||||
|
||||
:marked
|
||||
That's Angular telling us that the dependency injector couldn't find the *provider* for the logger.
|
||||
|
@ -735,27 +735,27 @@ code-example(format="nocode").
|
|||
`HeroService`, which it needed to
|
||||
create and inject into a new `HeroListComponent`.
|
||||
|
||||
Angular这是在告诉我们,依赖注入器找不到日志服务的*供应商*。在创建`HeroListComponent`的新实例时需要创建和注入`HeroService`,然后`HeroService`需要创建和注入一个`Logger`实例,Angular需要这个供应商来创建一个`Logger`实例。
|
||||
Angular这是在告诉我们,依赖注入器找不到日志服务的*提供商*。在创建`HeroListComponent`的新实例时需要创建和注入`HeroService`,然后`HeroService`需要创建和注入一个`Logger`实例,Angular需要这个提供商来创建一个`Logger`实例。
|
||||
|
||||
The chain of creations started with the `Logger` provider. *Providers* are the subject of our next section.
|
||||
|
||||
这个“创建链”始于`Logger`的供应商。这个*供应商*就是我们下一节的主题。
|
||||
这个“创建链”始于`Logger`的提供商。这个*提供商*就是我们下一节的主题。
|
||||
|
||||
.l-main-section#providers
|
||||
:marked
|
||||
## Injector providers
|
||||
## 注入器的供应商们
|
||||
## 注入器的提供商们
|
||||
|
||||
A provider *provides* the concrete, runtime version of a dependency value.
|
||||
The injector relies on **providers** to create instances of the services
|
||||
that the injector injects into components and other services.
|
||||
|
||||
供应商*提供*所需依赖值的一个具体的运行期版本。
|
||||
注入器依靠**供应商们**来创建服务的实例,它会被注入器注入到组件或其它服务中。
|
||||
提供商*提供*所需依赖值的一个具体的运行期版本。
|
||||
注入器依靠**提供商们**来创建服务的实例,它会被注入器注入到组件或其它服务中。
|
||||
|
||||
We must register a service *provider* with the injector, or it won't know how to create the service.
|
||||
|
||||
我们必须为注入器注册一个服务的*供应商*,否则它就不知道该如何创建此服务。
|
||||
我们必须为注入器注册一个服务的*提供商*,否则它就不知道该如何创建此服务。
|
||||
|
||||
Earlier we registered the `Logger` service in the `providers` #{_array} of the metadata for the `AppComponent` like this:
|
||||
|
||||
|
@ -776,7 +776,7 @@ code-example(format="nocode").
|
|||
But it's not the only way.
|
||||
|
||||
有很多方式可以*提供*一些#{implementsCn} `Logger`类的东西。
|
||||
`Logger`类本身是一个显而易见而且自然而然的供应商 —— 它有正确的形态,并且它设计出来就是等着被创建的。
|
||||
`Logger`类本身是一个显而易见而且自然而然的提供商 —— 它有正确的形态,并且它设计出来就是等着被创建的。
|
||||
但它不是唯一的选项。
|
||||
|
||||
We can configure the injector with alternative providers that can deliver #{objectlike} a `Logger`.
|
||||
|
@ -784,14 +784,14 @@ code-example(format="nocode").
|
|||
We could give it a provider that calls a logger factory function.
|
||||
Any of these approaches might be a good choice under the right circumstances.
|
||||
|
||||
我们可以使用其它备选供应商来配置这个注入器,只要它们能交付#{objectlikeCn}`Logger`就可以了。
|
||||
我们可以使用其它备选提供商来配置这个注入器,只要它们能交付#{objectlikeCn}`Logger`就可以了。
|
||||
我们可以提供一个替身类。#{loggerlikeCn}
|
||||
我们可以给它一个供应商,让它调用一个可以创建日志服务的工厂函数。
|
||||
我们可以给它一个提供商,让它调用一个可以创建日志服务的工厂函数。
|
||||
所有这些方法,只要用在正确的场合,都可能是一个好的选择。
|
||||
|
||||
What matters is that the injector has a provider to go to when it needs a `Logger`.
|
||||
|
||||
最重要的是:当注入器需要一个`Logger`时,它得先有一个供应商。
|
||||
最重要的是:当注入器需要一个`Logger`时,它得先有一个提供商。
|
||||
|
||||
//- Dart limitation: the provide function isn't const so it cannot be used in an annotation.
|
||||
- var __andProvideFn = _docsFor == 'dart' ? '' : 'and <i>provide</i> object literal';
|
||||
|
@ -820,7 +820,7 @@ block provider-ctor-args
|
|||
The first is the [token](#token) that serves as the key for both locating a dependency value
|
||||
and registering the provider.
|
||||
|
||||
第一个是[令牌token](#token),它作为键值key使用,用于定位依赖值,以及注册这个供应商。
|
||||
第一个是[令牌token](#token),它作为键值key使用,用于定位依赖值,以及注册这个提供商。
|
||||
|
||||
The second is a !{_secondParam},
|
||||
which we can think of as a *recipe* for creating the dependency value.
|
||||
|
@ -834,7 +834,7 @@ block provider-ctor-args
|
|||
:marked
|
||||
### Alternative class providers
|
||||
|
||||
### 备选的“类”供应商
|
||||
### 备选的“类”提供商
|
||||
|
||||
Occasionally we'll ask a different class to provide the service.
|
||||
The following code tells the injector
|
||||
|
@ -851,7 +851,7 @@ block dart-diff-const-metadata
|
|||
:marked
|
||||
### Class provider with dependencies
|
||||
|
||||
### 带依赖的类供应商
|
||||
### 带依赖的类提供商
|
||||
|
||||
Maybe an `EvenBetterLogger` could display the user name in the log message.
|
||||
This logger gets the user from the injected `UserService`,
|
||||
|
@ -872,7 +872,7 @@ block dart-diff-const-metadata
|
|||
:marked
|
||||
### Aliased class providers
|
||||
|
||||
### 别名类供应商
|
||||
### 别名类提供商
|
||||
|
||||
Suppose an old component depends upon an `OldLogger` class.
|
||||
`OldLogger` has the same interface as the `NewLogger`, but for some reason
|
||||
|
@ -913,7 +913,7 @@ block dart-diff-const-metadata
|
|||
:marked
|
||||
### Value providers
|
||||
|
||||
### 值供应商
|
||||
### 值提供商
|
||||
|
||||
:marked
|
||||
Sometimes it's easier to provide a ready-made object rather than ask the injector to create it from a class.
|
||||
|
@ -929,7 +929,7 @@ block dart-diff-const-metadata-ctor
|
|||
Then we register a provider with the `useValue` option,
|
||||
which makes this object play the logger role.
|
||||
|
||||
于是我们可以通过`useValue`选项来注册一个供应商,它会让这个对象直接扮演logger的角色。
|
||||
于是我们可以通过`useValue`选项来注册一个提供商,它会让这个对象直接扮演logger的角色。
|
||||
|
||||
- var stylePattern = { otl: /(useValue: \w*)/gm };
|
||||
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-7', '', stylePattern)(format=".")
|
||||
|
@ -945,7 +945,7 @@ block dart-diff-const-metadata-ctor
|
|||
:marked
|
||||
### Factory providers
|
||||
|
||||
### 工厂供应商
|
||||
### 工厂提供商
|
||||
|
||||
Sometimes we need to create the dependent value dynamically,
|
||||
based on information we won't have until the last possible moment.
|
||||
|
@ -960,7 +960,7 @@ block dart-diff-const-metadata-ctor
|
|||
|
||||
This situation calls for a **factory provider**.
|
||||
|
||||
这种情况下,请呼叫**工厂供应商**。
|
||||
这种情况下,请呼叫**工厂提供商**。
|
||||
|
||||
Let's illustrate by adding a new business requirement:
|
||||
the HeroService must hide *secret* heroes from normal users.
|
||||
|
@ -1004,11 +1004,11 @@ block dart-diff-const-metadata-ctor
|
|||
We'll have to take over the creation of new instances of this `HeroService` with a factory provider.
|
||||
|
||||
我们可以注入`Logger`,但是我们不能注入逻辑型的`isAuthorized`。
|
||||
我们不得不通过通过一个工厂供应商创建这个`HeroService`的新实例。
|
||||
我们不得不通过通过一个工厂提供商创建这个`HeroService`的新实例。
|
||||
|
||||
A factory provider needs a factory function:
|
||||
|
||||
工厂供应商需要一个工厂方法:
|
||||
工厂提供商需要一个工厂方法:
|
||||
|
||||
+makeExample('dependency-injection/ts/app/heroes/hero.service.provider.ts','factory', 'app/heroes/hero.service.provider.ts (excerpt)')(format='.')
|
||||
|
||||
|
@ -1019,7 +1019,7 @@ block dart-diff-const-metadata-ctor
|
|||
|
||||
We inject both the `Logger` and the `UserService` into the factory provider and let the injector pass them along to the factory function:
|
||||
|
||||
我们同时把`Logger`和`UserService`注入到工厂供应商中,并且让注入器把它们传给工厂方法:
|
||||
我们同时把`Logger`和`UserService`注入到工厂提供商中,并且让注入器把它们传给工厂方法:
|
||||
|
||||
+makeExample('dependency-injection/ts/app/heroes/hero.service.provider.ts','provider', 'app/heroes/hero.service.provider.ts (excerpt)')(format='.')
|
||||
|
||||
|
@ -1028,14 +1028,14 @@ block dart-diff-const-metadata-ctor
|
|||
The `useFactory` field tells Angular that the provider is a factory function
|
||||
whose implementation is the `heroServiceFactory`.
|
||||
|
||||
`useFactory`字段告诉Angular:这个供应商是一个工厂方法,它的实现是`heroServiceFactory`。
|
||||
`useFactory`字段告诉Angular:这个提供商是一个工厂方法,它的实现是`heroServiceFactory`。
|
||||
|
||||
The `deps` property is #{_an} #{_array} of [provider tokens](#token).
|
||||
The `Logger` and `UserService` classes serve as tokens for their own class providers.
|
||||
The injector resolves these tokens and injects the corresponding services into the matching factory function parameters.
|
||||
|
||||
`deps`属性是一个[供应商令牌](#token)数组。
|
||||
`Logger`和`UserService`类作为它们自身供应商的令牌。
|
||||
`deps`属性是一个[提供商令牌](#token)数组。
|
||||
`Logger`和`UserService`类作为它们自身提供商的令牌。
|
||||
注入器解析这些令牌,并且把相应的服务注入到工厂函数中相应的参数中去。
|
||||
|
||||
- var anexportedvar = lang == 'dart' ? 'a constant' : 'an exported variable'
|
||||
|
@ -1048,8 +1048,8 @@ block dart-diff-const-metadata-ctor
|
|||
This extra step makes the factory provider reusable.
|
||||
We can register our `HeroService` with this #{variable} wherever we need it.
|
||||
|
||||
注意,我们在#{anexportedvarCn}中捕获了这个工厂供应商:`heroServiceProvider`。
|
||||
这个额外的步骤让工厂供应商可被复用。
|
||||
注意,我们在#{anexportedvarCn}中捕获了这个工厂提供商:`heroServiceProvider`。
|
||||
这个额外的步骤让工厂提供商可被复用。
|
||||
只要需要,我们就可以使用这个#{variableCn}注册`HeroService`,无论在哪儿。
|
||||
|
||||
In our sample, we need it only in the `HeroesComponent`,
|
||||
|
@ -1078,8 +1078,8 @@ block dart-diff-const-metadata-ctor
|
|||
The injector maintains an internal *token-provider* map that it references when
|
||||
asked for a dependency. The token is the key to the map.
|
||||
|
||||
当我们为注入器注册一个供应商时,实际上是把这个供应商和一个DI令牌关联起来了。
|
||||
注入器维护一个内部的*令牌-供应商*映射表,这个映射表会在请求一个依赖时被引用到。
|
||||
当我们为注入器注册一个提供商时,实际上是把这个提供商和一个DI令牌关联起来了。
|
||||
注入器维护一个内部的*令牌-提供商*映射表,这个映射表会在请求一个依赖时被引用到。
|
||||
令牌就是这个映射表中的键值key。
|
||||
|
||||
In all previous examples, the dependency value has been a class *instance*, and
|
||||
|
@ -1130,7 +1130,7 @@ block dart-diff-const-metadata-ctor
|
|||
We know we can register an object with a [value provider](#value-provider).
|
||||
|
||||
我们想让这个`config`对象在注入时可用。
|
||||
我们已经知道可以使用一个[值供应商](#value-provider)来注册一个对象。
|
||||
我们已经知道可以使用一个[值提供商](#value-provider)来注册一个对象。
|
||||
|
||||
block what-should-we-use-as-token
|
||||
:marked
|
||||
|
@ -1182,7 +1182,7 @@ block what-should-we-use-as-token
|
|||
:marked
|
||||
We register the dependency provider using the `OpaqueToken` object:
|
||||
|
||||
我们使用这个`OpaqueToken`对象注册依赖的供应商:
|
||||
我们使用这个`OpaqueToken`对象注册依赖的提供商:
|
||||
|
||||
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-9')(format=".")
|
||||
|
||||
|
@ -1245,7 +1245,7 @@ block dart-map-alternative
|
|||
adding a parameter to a constructor.
|
||||
|
||||
在本章中,我们学习了Angular依赖注入的基础。
|
||||
我们可以注册很多种类的供应商,还知道了该如何通过添加构造函数的参数来请求一个被注入对象(比如服务)。
|
||||
我们可以注册很多种类的提供商,还知道了该如何通过添加构造函数的参数来请求一个被注入对象(比如服务)。
|
||||
|
||||
Angular dependency injection is more capable than we've described.
|
||||
We can learn more about its advanced features, beginning with its support for
|
||||
|
|
|
@ -94,7 +94,7 @@ figure.image-display
|
|||
If we run out of ancestors, Angular throws an error.
|
||||
|
||||
当一个底层的组件申请获得一个依赖时,Angular先尝试用该组件自己的注入器来满足它。
|
||||
如果该组件的注入器没有找到对应的供应商,它就把这个申请转给它父组件的注入器来处理。
|
||||
如果该组件的注入器没有找到对应的提供商,它就把这个申请转给它父组件的注入器来处理。
|
||||
如果那个注入器也无法满足这个申请,它就继续转给*它的*父组件的注入器。
|
||||
这个申请继续往上冒泡 —— 直到我们找到了一个能处理此申请的注入器或者超出了组件树中的祖先位置为止。
|
||||
如果超出了组件树中的祖先还未找到,Angular就会抛出一个错误。
|
||||
|
@ -106,14 +106,14 @@ figure.image-display
|
|||
We'll reserve discussion of this option for another day.
|
||||
|
||||
其实还有第三种可能性。一个中层的组件可以声称它自己是“宿主”组件。
|
||||
向上查找供应商的过程会截止于这个“宿主”组件。
|
||||
向上查找提供商的过程会截止于这个“宿主”组件。
|
||||
我们先保留这个问题,等改天再讨论这个选项。
|
||||
:marked
|
||||
Such a proliferation of injectors makes little sense until we consider the possibility that injectors at different levels can be
|
||||
configured with different providers. We don't *have* to re-configure providers at every level. But we *can*.
|
||||
|
||||
除非注入器能在各个不同层次上使用不同的供应商进行配置,否则没必要让注入器分裂成这么多。
|
||||
虽然我们并不是*必须*在每一层都重新配置供应商,但我们*可以*这样做。
|
||||
除非注入器能在各个不同层次上使用不同的提供商进行配置,否则没必要让注入器分裂成这么多。
|
||||
虽然我们并不是*必须*在每一层都重新配置提供商,但我们*可以*这样做。
|
||||
|
||||
If we don't re-configure, the tree of injectors appears to be flat. All requests bubble up to the root injector that we
|
||||
configured with the `bootstrap` method.
|
||||
|
@ -122,7 +122,7 @@ figure.image-display
|
|||
|
||||
The ability to configure one or more providers at different levels opens up interesting and useful possibilities.
|
||||
|
||||
在不同层次上重新配置一个或多个供应商的能力,开启了一些既有趣又有用的可能性。
|
||||
在不同层次上重新配置一个或多个提供商的能力,开启了一些既有趣又有用的可能性。
|
||||
|
||||
Let’s return to our Car example.
|
||||
Suppose we configured the root injector (marked as A) with providers for `Car`, `Engine` and `Tires`.
|
||||
|
@ -130,13 +130,13 @@ figure.image-display
|
|||
This child is the parent of another component (C) that defines its own provider for `Car`.
|
||||
|
||||
让我们回到“汽车(Car)”类的例子。
|
||||
假设“根注入器”(记为A)配置过`Car`、`Engine`和`Tires`的供应商。
|
||||
然后创建了一个子组件(B),它为`Car`和`Engine`类定义了自己的供应商。
|
||||
这个子组件(B)又有另一个子组件(C),(C)也为`Car`定义了自己的供应商。
|
||||
假设“根注入器”(记为A)配置过`Car`、`Engine`和`Tires`的提供商。
|
||||
然后创建了一个子组件(B),它为`Car`和`Engine`类定义了自己的提供商。
|
||||
这个子组件(B)又有另一个子组件(C),(C)也为`Car`定义了自己的提供商。
|
||||
|
||||
Behind the scenes each component sets up its own injector with one or more providers defined for that component itself.
|
||||
|
||||
幕后的情况是这样的:每个组件都设置了它自己的注入器,这些注入器都带着一个或多个为组件自身设计的供应商。
|
||||
幕后的情况是这样的:每个组件都设置了它自己的注入器,这些注入器都带着一个或多个为组件自身设计的提供商。
|
||||
|
||||
When we resolve an instance of `Car` at the deepest component (C),
|
||||
its injector produces an instance of `Car` resolved by injector (C) with an `Engine` resolved by injector (B) and
|
||||
|
@ -156,7 +156,7 @@ figure.image-display
|
|||
In the previous section, we talked about injectors and how they are organized like a tree. Lookups follow the injector tree upwards until they find the requested thing to inject. But when do we actually want to provide providers on the root injector and when do we want to provide them on a child injector?
|
||||
|
||||
在前一节中,我们讨论了注入器以及它们是如何被组织成一棵树的。Angular会沿着注入器树往上逐级查找,直到发现了那个申请者要求注入的东西。
|
||||
但是,我们什么时候该在根注入器上提供供应商,什么时候又该在子注入器上提供它们呢?
|
||||
但是,我们什么时候该在根注入器上提供提供商,什么时候又该在子注入器上提供它们呢?
|
||||
|
||||
Consider you are building a component to show a list of super heroes that displays each super hero in a card with its name and superpower. There should also be an edit button that opens up an editor to change the name and superpower of our hero.
|
||||
|
||||
|
@ -242,7 +242,7 @@ figure.image-display
|
|||
This adds a `RestoreService` provider to the injector of the `HeroEditComponent`.
|
||||
Couldn’t we simply alter our bootstrap call to this?
|
||||
|
||||
它往`HeroEditComponent`的注入器中添加了一个`RestoreService`供应商。
|
||||
它往`HeroEditComponent`的注入器中添加了一个`RestoreService`提供商。
|
||||
不能简化点儿,直接把我们的bootstrap方法改成这样吗?
|
||||
|
||||
+makeExample('hierarchical-dependency-injection/ts/app/main.ts', 'bad-alternative')
|
||||
|
@ -255,7 +255,7 @@ figure.image-display
|
|||
|
||||
By configuring a provider for the `RestoreService` on the `HeroEditComponent`, we get exactly one new instance of the `RestoreService`per `HeroEditComponent`.
|
||||
|
||||
通过在`HeroEditComponent`上配置`RestoreService`的供应商,我们可以精确的实现每个`HeroEditComponent`都有一个`RestoreService`的新实例。
|
||||
通过在`HeroEditComponent`上配置`RestoreService`的提供商,我们可以精确的实现每个`HeroEditComponent`都有一个`RestoreService`的新实例。
|
||||
|
||||
Does that mean that services aren’t singletons anymore in Angular 2? Yes and no.
|
||||
There can be only one instance of a service type in a particular injector.
|
||||
|
@ -270,7 +270,7 @@ figure.image-display
|
|||
If we defined a `RestoreService` provider only on the root component,
|
||||
we would have exactly one instance of that service and it would be shared across the entire application.
|
||||
|
||||
如果我们只在根组件上定义了一个`RestoreService`供应商,我们就确实只有该服务的一个实例了,它会在整个应用程序中被共享。
|
||||
如果我们只在根组件上定义了一个`RestoreService`提供商,我们就确实只有该服务的一个实例了,它会在整个应用程序中被共享。
|
||||
|
||||
That’s clearly not what we want in this scenario. We want each component to have its own instance of the `RestoreService`.
|
||||
Defining (or re-defining) a provider at the component level creates a new instance of the service for each new instance
|
||||
|
@ -278,7 +278,7 @@ figure.image-display
|
|||
scoped to that component instance and its child components.
|
||||
|
||||
但很明显,这个场景下我们不希望这样。我们希望每个组件都有它自己的`RestoreService`实例。
|
||||
在组件级别上定义(或重定义)一个供应商,将会为该组件创建一个新的服务实例。
|
||||
在组件级别上定义(或重定义)一个提供商,将会为该组件创建一个新的服务实例。
|
||||
我们已经为`HeroEditComponent`制造了一种“私有”`RestoreService`单例,它的作用范围被局限在了该组件的实例及其子组件中。
|
||||
|
||||
<!--
|
||||
|
|
|
@ -134,7 +134,7 @@ a(id="dependencies")
|
|||
compile templates on the client. don’t use offline compilation.
|
||||
We use this package for boostrapping during development and for boostrapping plunker samples
|
||||
|
||||
***@angular/platform-browser-dynamic*** - 为应用程序提供一些供应商和一个bootstrap方法,以便在客户端编译模板。不要用于离线编译。
|
||||
***@angular/platform-browser-dynamic*** - 为应用程序提供一些提供商和一个bootstrap方法,以便在客户端编译模板。不要用于离线编译。
|
||||
我们使用这个包在开发期间引导应用,以及引导plunker中的范例。
|
||||
|
||||
***@angular/http*** - Angular's http client
|
||||
|
|
|
@ -229,19 +229,19 @@ include ../_util-fns
|
|||
We pass the configuration array to the `provideRouter()` function which returns
|
||||
(among other things) a configured *Router* [service provider](dependency-injection.html#!#injector-providers).
|
||||
|
||||
我们将把这份配置数组传给`provideRouter()`函数,它返回一个经过配置的*Router*[服务供应商](dependency-injection.html#!#injector-providers)(以及别的东西)。
|
||||
我们将把这份配置数组传给`provideRouter()`函数,它返回一个经过配置的*Router*[服务提供商](dependency-injection.html#!#injector-providers)(以及别的东西)。
|
||||
|
||||
Finally, we export this provider in the `APP_ROUTER_PROVIDERS` array
|
||||
so we can simplify registration of router dependencies later in `main.ts`.
|
||||
We don't have any other providers to register right now. But we will.
|
||||
|
||||
最后,我们通过`APP_ROUTER_PROVIDERS`数组导出这个供应商,以便我们以后将来在`main.ts`中简单的注册路由器依赖。
|
||||
目前我们还没有注册任何别的供应商,但很快就会这么做了!
|
||||
最后,我们通过`APP_ROUTER_PROVIDERS`数组导出这个提供商,以便我们以后将来在`main.ts`中简单的注册路由器依赖。
|
||||
目前我们还没有注册任何别的提供商,但很快就会这么做了!
|
||||
|
||||
:marked
|
||||
Next we open `main.ts` where we must register our router providers in the `bootstrap` method.
|
||||
|
||||
接下来,打开`main.ts`,我们必须在其中的`bootstrap`函数中注册路由器的供应商们。
|
||||
接下来,打开`main.ts`,我们必须在其中的`bootstrap`函数中注册路由器的提供商们。
|
||||
|
||||
+makeExample('router/ts/app/main.ts','','app/main.ts')(format='.')
|
||||
|
||||
|
@ -777,7 +777,7 @@ h4#provideRouter 调用<i>provideRouter</i>
|
|||
We pass the route configuration to the `provideRouter` function which returns an array containing the configured
|
||||
`Router` service provider ... and some other, unseen providers that the routing library requires.
|
||||
|
||||
我们把路由配置传给`provideRouter`函数,它返回一个数组,其中包括配置好的`Router`服务供应商……和路由库所需的某些你从未见过的供应商。
|
||||
我们把路由配置传给`provideRouter`函数,它返回一个数组,其中包括配置好的`Router`服务提供商……和路由库所需的某些你从未见过的提供商。
|
||||
|
||||
:marked
|
||||
We add the `provideRouter` array to an `APP_ROUTER_PROVIDERS` array and export it.
|
||||
|
@ -788,7 +788,7 @@ h4#provideRouter 调用<i>provideRouter</i>
|
|||
providers that are specific to our routing configuration.
|
||||
We don't have any yet. We will have some later in this chapter.
|
||||
|
||||
我们还可以往`APP_ROUTER_PROVIDERS`中添加一些*额外的*供应商,这取决于路由的具体配置。
|
||||
我们还可以往`APP_ROUTER_PROVIDERS`中添加一些*额外的*提供商,这取决于路由的具体配置。
|
||||
虽然目前还一个都没有呢,不过稍后就会看到了。
|
||||
|
||||
.l-sub-section
|
||||
|
@ -796,7 +796,7 @@ h4#provideRouter 调用<i>provideRouter</i>
|
|||
:marked
|
||||
Learn about *providers* in the [Dependency Injection](dependency-injection.html#!#injector-providers) chapter.
|
||||
|
||||
在[依赖注入](dependency-injection.html#!#injector-providers)一章中,可以学到关于*供应商*的更多知识。
|
||||
在[依赖注入](dependency-injection.html#!#injector-providers)一章中,可以学到关于*提供商*的更多知识。
|
||||
|
||||
h4#register-providers Register routing in bootstrap
|
||||
|
||||
|
@ -819,7 +819,7 @@ h4#register-providers 在启动时注册路由
|
|||
:marked
|
||||
Providing the router providers at bootstrap makes the Router available everywhere in our application.
|
||||
|
||||
在启动时注册此路由器的供应商会让该路由器在应用的任何地方都有效。
|
||||
在启动时注册此路由器的提供商会让该路由器在应用的任何地方都有效。
|
||||
|
||||
.alert.is-important
|
||||
|
||||
|
@ -827,7 +827,7 @@ h4#register-providers 在启动时注册路由
|
|||
We must register router providers in `bootstrap`.
|
||||
We cannot wait to do it in `AppComponent`.
|
||||
|
||||
我们必须在`bootstrap`中注册路由器的供应商,而不能等到`AppComponent`中再做。
|
||||
我们必须在`bootstrap`中注册路由器的提供商,而不能等到`AppComponent`中再做。
|
||||
|
||||
h3#shell The <i>AppComponent</i> shell
|
||||
|
||||
|
@ -1750,7 +1750,7 @@ h3#child-routing-component 子路由组件
|
|||
which makes it visible everywhere —
|
||||
we register the `CrisisService` in the component's providers array.
|
||||
|
||||
在*危机中心*领域之外既不需要也没人想要`CrisisService`。与其在根组件`AppComponent`的供应商中注册它导致它在应用的任何地方都可见,不如在组件供应商数组中注册`CrisisService`。
|
||||
在*危机中心*领域之外既不需要也没人想要`CrisisService`。与其在根组件`AppComponent`的提供商中注册它导致它在应用的任何地方都可见,不如在组件提供商数组中注册`CrisisService`。
|
||||
|
||||
+makeExample('router/ts/app/crisis-center/crisis-center.component.1.ts', 'providers')(format='.')
|
||||
|
||||
|
@ -2987,7 +2987,7 @@ code-example(format=".", language="bash").
|
|||
:marked
|
||||
The Angular Component Router supports both styles with two `LocationStrategy` providers:
|
||||
|
||||
Angular组件路由器通过两种`LocationStrategy`供应商来支持所有这些风格:
|
||||
Angular组件路由器通过两种`LocationStrategy`提供商来支持所有这些风格:
|
||||
|
||||
1. `PathLocationStrategy` - the default "HTML 5 pushState" style.
|
||||
|
||||
|
@ -3010,7 +3010,7 @@ code-example(format=".", language="bash").
|
|||
Learn about "providers" and the bootstrap process in the
|
||||
[Dependency Injection chapter](dependency-injection#bootstrap)
|
||||
|
||||
要学习关于“供应商”和启动过程的更多知识,参见[依赖注入](dependency-injection#bootstrap)一章。
|
||||
要学习关于“提供商”和启动过程的更多知识,参见[依赖注入](dependency-injection#bootstrap)一章。
|
||||
|
||||
:marked
|
||||
### Which Strategy is Best?
|
||||
|
|
|
@ -389,7 +389,7 @@ h3#xsrf 跨站请求伪造(XSRF)
|
|||
|
||||
Angular应用程序可以通过绑定它们自己的`CookieXSRFStrategy`值来自定义cookie和HTTP头的名字,
|
||||
也可以通过提供一个自定义类型绑定来完全制定`XSRFStrategy`,
|
||||
只要把下列代码之一加到你的供应商列表里就可以了:
|
||||
只要把下列代码之一加到你的提供商列表里就可以了:
|
||||
|
||||
code-example(language="typescript").
|
||||
{ provide: XSRFStrategy, useValue: new CookieXSRFStrategy('myCookieName', 'My-Header-Name')}
|
||||
|
|
|
@ -155,19 +155,19 @@ block demos-list
|
|||
:marked
|
||||
Before we can use the `#{_Http}` client , we'll have to register it as a service provider with the Dependency Injection system.
|
||||
|
||||
要想使用`#{_Http}`客户端,我们得先通过依赖注入系统把它注册成一个服务供应商。
|
||||
要想使用`#{_Http}`客户端,我们得先通过依赖注入系统把它注册成一个服务提供商。
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
Learn about providers in the [Dependency Injection](dependency-injection.html) chapter.
|
||||
|
||||
了解关于供应商的更多知识,参见[依赖注入](dependency-injection.html)一章。
|
||||
了解关于提供商的更多知识,参见[依赖注入](dependency-injection.html)一章。
|
||||
|
||||
:marked
|
||||
In this demo, we register providers in the `bootstrap()` method of
|
||||
<span ngio-ex>app/main.ts</span>.
|
||||
|
||||
在这个例子中,我们在<span ngio-ex>app/main.ts</span>文件的`bootstrap()`方法中注册供应商。
|
||||
在这个例子中,我们在<span ngio-ex>app/main.ts</span>文件的`bootstrap()`方法中注册提供商。
|
||||
|
||||
+makeExample('server-communication/ts/app/main.ts', 'v1', 'app/main.ts (v1)')(format='.')
|
||||
|
||||
|
@ -176,11 +176,11 @@ block http-providers
|
|||
We begin by importing the symbols we need, most of them familiar by now. The newcomer is `HTTP_PROVIDERS`,
|
||||
a collection of service providers from the !{_Angular_http_library}.
|
||||
|
||||
我们从导入所需的符号开始,它们中的大多数我们都熟悉了,只有`HTTP_PROVIDERS`是新面孔,它是来自!{_Angular_http_libraryCn}的一组服务供应商。
|
||||
我们从导入所需的符号开始,它们中的大多数我们都熟悉了,只有`HTTP_PROVIDERS`是新面孔,它是来自!{_Angular_http_libraryCn}的一组服务提供商。
|
||||
|
||||
We register HTTP providers in the bootstrap method by passing them in an array as the second parameter after the root component.
|
||||
|
||||
然后我们把这些HTTP服务供应商作为第二个参数传给bootstrap方法(第一个参数用来指定根组件),把它们注册进应用程序。
|
||||
然后我们把这些HTTP服务提供商作为第二个参数传给bootstrap方法(第一个参数用来指定根组件),把它们注册进应用程序。
|
||||
|
||||
### Why register in *bootstrap*?
|
||||
### 为什么在*bootstrap*中注册?
|
||||
|
@ -188,12 +188,12 @@ block http-providers
|
|||
We prefer to register application-wide providers in the metadata `providers` array
|
||||
of the root `AppComponent` like this:
|
||||
|
||||
要注册应用程序级的供应商,我们的首选方式把它放在根组件`AppComponent`元数据的`providers`数组中。就像这样:
|
||||
要注册应用程序级的提供商,我们的首选方式把它放在根组件`AppComponent`元数据的`providers`数组中。就像这样:
|
||||
+makeExample('server-communication/ts/app/app.component.ts','http-providers')(format='.')
|
||||
:marked
|
||||
Here we register the providers in the `bootstrap` method in the `main.ts` file. Why?
|
||||
|
||||
但这里我们却使用`main.ts`中的`bootstrap`方法注册了供应商。为什么呢?
|
||||
但这里我们却使用`main.ts`中的`bootstrap`方法注册了提供商。为什么呢?
|
||||
|
||||
This is a *sample application* that doesn't talk to a real server.
|
||||
We're going to reconfigure the (typically-hidden) `XhrBackend` service with a fake provider
|
||||
|
@ -201,7 +201,7 @@ block http-providers
|
|||
This replacement service is called the [*in-memory web api*](#in-mem-web-api).
|
||||
|
||||
因为这是一个*范例程序*,它不会跟真实的服务器打交道。
|
||||
我们准备用一个伪造的供应商[*内存Web API*](#in-mem-web-api)来重新配置(通常不可见的)`XhrBackend`服务。这个伪造的供应商会从一个内存存储区中获取和保存范例数据。
|
||||
我们准备用一个伪造的提供商[*内存Web API*](#in-mem-web-api)来重新配置(通常不可见的)`XhrBackend`服务。这个伪造的提供商会从一个内存存储区中获取和保存范例数据。
|
||||
|
||||
Such sleight-of-hand is something the root application component should *not* know about.
|
||||
For this reason, and this reason *only*, we hide it *above* the `AppComponent` in `main.ts`.
|
||||
|
@ -1203,7 +1203,7 @@ block redirect-to-web-api
|
|||
the in-memory web API service using standard Angular provider registration techniques.
|
||||
We initialize the in-memory web API with *seed data* from the mock hero dataset at the same time.
|
||||
|
||||
要想启用我们的服务模拟器,我们通过Angular标准的“供应商注册”技术,把默认的`XHRBackend`服务替换为了这个内存Web API服务。
|
||||
要想启用我们的服务模拟器,我们通过Angular标准的“提供商注册”技术,把默认的`XHRBackend`服务替换为了这个内存Web API服务。
|
||||
同时,我们使用来自模拟的英雄数据集的*种子数据*初始化了这个内存Web API。
|
||||
|
||||
:marked
|
||||
|
|
|
@ -1055,7 +1055,7 @@ figure
|
|||
Angular 2. This makes it possible to then inject it somewhere in Angular 2
|
||||
code. For example, we might have a service called `HeroesService` in Angular 1:
|
||||
|
||||
在这些情况下,把一个Angular 1供应商*升级到*Angular 2也是有可能的。这就让它将来有可能被注入到Angular 2代码中的某些地方。
|
||||
在这些情况下,把一个Angular 1提供商*升级到*Angular 2也是有可能的。这就让它将来有可能被注入到Angular 2代码中的某些地方。
|
||||
比如,我们可能在Angular 1中有一个名叫`HeroesService`的服务:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/1-to-2-providers/heroes.service.ts', null, 'heroes.service.ts')
|
||||
|
@ -1087,7 +1087,7 @@ figure
|
|||
|
||||
在这个例子中,我们升级了服务类。当我们注入它时,我们可以使用TypeScript类型注解来获得这些额外的好处。
|
||||
它没有影响该依赖的处理过程,同时还得到了启用静态类型检查的好处。
|
||||
任何Angular 1中的服务、工厂和供应商都能被升级 —— 尽管这不是必须的。
|
||||
任何Angular 1中的服务、工厂和提供商都能被升级 —— 尽管这不是必须的。
|
||||
|
||||
:marked
|
||||
## Making Angular 2 Dependencies Injectable to Angular 1
|
||||
|
@ -1117,7 +1117,7 @@ figure
|
|||
|
||||
我们又能使用`UpgradeAdapter`处理它了,但首先我们需要把`Heroes`服务注册到Angular 2自身的注入器。
|
||||
在纯Angular 2应用中,我们会在引导应用时这么做,就像[依赖注入指南](dependency-injection.html#!#providers)中描述的那样。
|
||||
但是因为混合式应用是使用`UpgradeAdapter`引导的,所以我们还得用`UpgradeAdapter`注册Angular 2的供应商。
|
||||
但是因为混合式应用是使用`UpgradeAdapter`引导的,所以我们还得用`UpgradeAdapter`注册Angular 2的提供商。
|
||||
它有一个`addProvider`方法就是用来做这个的。
|
||||
|
||||
Once we've registered the Angular 2 provider, we can turn `Heroes` into an *Angular 1
|
||||
|
@ -1125,7 +1125,7 @@ figure
|
|||
then plug the factory into an Angular 1 module, at which point we also choose what the
|
||||
name of the dependency will be in Angular 1:
|
||||
|
||||
一旦我们注册了Angular 2的供应商,就能用`upgradeAdapter.downgradeNg2Provider()`把`Heroes`转变成一个*Angular 1的工厂函数*。
|
||||
一旦我们注册了Angular 2的提供商,就能用`upgradeAdapter.downgradeNg2Provider()`把`Heroes`转变成一个*Angular 1的工厂函数*。
|
||||
然后我们就能把这个工厂插入到Angular 1模块中,那时,我们可以选择该依赖要在Angular 1中用的名字:
|
||||
|
||||
+makeExample('upgrade-adapter/ts/app/2-to-1-providers/app.module.ts', 'register', 'app.module.ts')
|
||||
|
@ -1681,7 +1681,7 @@ code-example(format="").
|
|||
|
||||
在标准的Angular 2应用中,我们可以把`HTTP_PROVIDERS`传给应用程序的`bootstrap`函数。
|
||||
但是在混合式应用中我们不能这么做 —— 比如现在这个。这是因为`UpgradeAdapter`的`bootstrap`方法
|
||||
希望以Angular 1模块作为依赖,而不是Angular 2供应商。
|
||||
希望以Angular 1模块作为依赖,而不是Angular 2提供商。
|
||||
|
||||
What we must do instead is register `HTTP_PROVIDERS` into the `UpgradeAdapter`
|
||||
separately. It has a method called `addProvider` for that purpose:
|
||||
|
@ -1769,7 +1769,7 @@ code-example(format="").
|
|||
1. Register `Phone` as an **Angular 2 provider** with the `addProvider`
|
||||
method. That's the same method that we used earlier for `HTTP_PROVIDERS`.
|
||||
|
||||
1. 用`addProvider`方法注册了一个名叫`Phone`的**Angular 2供应商**。这和我们以前使用`HTTP_PROVIDERS`的方法一样。
|
||||
1. 用`addProvider`方法注册了一个名叫`Phone`的**Angular 2提供商**。这和我们以前使用`HTTP_PROVIDERS`的方法一样。
|
||||
|
||||
2. Register an **Angular 1 factory** called `phone`, which will be a *downgraded*
|
||||
version of the `Phone` Angular 2 service.
|
||||
|
@ -2120,8 +2120,8 @@ code-example(format="").
|
|||
|
||||
我们现在就改用Angular 2中标准的`bootstrap`函数来引导本应用,而不再用`UpgradeAdapter`。
|
||||
`bootstrap`的第一个参数是应用程序的根组件`AppComponent`,第二个参数是一个由Angular 2中希望被注入的
|
||||
供应商构成的数组。这个数组中,我们包含了至今用`upgradeAdapter.addProvider`注册过的所有东西,
|
||||
比如各种供应商以及路由器中的指令:
|
||||
提供商构成的数组。这个数组中,我们包含了至今用`upgradeAdapter.addProvider`注册过的所有东西,
|
||||
比如各种提供商以及路由器中的指令:
|
||||
|
||||
+makeExample('upgrade-phonecat-3-final/ts/app/main.ts', 'bootstrap')
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ a(id="entries-outputs")
|
|||
We probably do not want one giant bundle of everything.
|
||||
We'll likely prefer to separate our volatile application app code from comparatively stable vendor code modules.
|
||||
|
||||
我们可能不会希望把所有东西打进一个巨型包儿,而更喜欢把多变的应用代码从相对稳定的第三方供应商模块中分离出来。
|
||||
我们可能不会希望把所有东西打进一个巨型包儿,而更喜欢把多变的应用代码从相对稳定的第三方提供商模块中分离出来。
|
||||
|
||||
We change the configuration so that we have two entry points, `app.ts` and `vendor.ts`:
|
||||
|
||||
|
@ -149,7 +149,7 @@ a(id="entries-outputs")
|
|||
and emits *two* bundle files, one called `app.js` containing only our application code and
|
||||
another called `vendor.js` with all the vendor dependencies.
|
||||
|
||||
Webpack会构造出两个独立的依赖图谱,并产出*两个*包儿文件:一个叫做`app.js`,它只包含我们的应用代码;另一个叫做`vendor.js`,它包含所有的供应商依赖。
|
||||
Webpack会构造出两个独立的依赖图谱,并产出*两个*包儿文件:一个叫做`app.js`,它只包含我们的应用代码;另一个叫做`vendor.js`,它包含所有的提供商依赖。
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -165,7 +165,7 @@ a(id="entries-outputs")
|
|||
:marked
|
||||
We met `app.ts` earlier. We wrote `vendor.ts` such that it imports the vendor modules we need:
|
||||
|
||||
我们以前见过`app.ts`,就不再赘述了。还要再写一个`vendor.ts`,让它导入我们要用的供应商模块:
|
||||
我们以前见过`app.ts`,就不再赘述了。还要再写一个`vendor.ts`,让它导入我们要用的提供商模块:
|
||||
|
||||
+makeExample('webpack/ts/src/vendor.ts', null,'src/vendor.ts')(format=".")
|
||||
|
||||
|
@ -337,7 +337,7 @@ a(id="common-configuration")
|
|||
|
||||
* vendor - the vendor files we need: Angular 2, lodash, bootstrap.css...
|
||||
|
||||
* vendor - 我们需要的供应商文件:Angular 2、Lodash、bootstrap.css……
|
||||
* vendor - 我们需要的提供商文件:Angular 2、Lodash、bootstrap.css……
|
||||
|
||||
* app - our application code.
|
||||
|
||||
|
@ -425,12 +425,12 @@ a(id="commons-chunk-plugin")
|
|||
|
||||
We want the `app.js` bundle to contain only app code and the `vendor.js` bundle to contain only the vendor code.
|
||||
|
||||
我们希望`app.js`包儿中只包含应用代码,而`vendor.js`包中只包含供应商代码。
|
||||
我们希望`app.js`包儿中只包含应用代码,而`vendor.js`包中只包含提供商代码。
|
||||
|
||||
Our application code `imports` vendor code. Webpack is not smart enough to keep the vendor code out of the `app.js` bundle.
|
||||
We rely on the `CommonsChunkPlugin` to do that job.
|
||||
|
||||
应用代码中`import`了供应商代码。Webpack还没有智能到自动把供应商代码排除在`app.js`包儿之外。
|
||||
应用代码中`import`了提供商代码。Webpack还没有智能到自动把提供商代码排除在`app.js`包儿之外。
|
||||
`CommonsChunkPlugin`插件能完成此工作。
|
||||
|
||||
.l-sub-section
|
||||
|
@ -624,7 +624,7 @@ a(id="test-configuration")
|
|||
The `karma-test-shim` tells Karma what files to pre-load and
|
||||
primes the Angular test framework with test versions of the providers that every app expects to be pre-loaded.
|
||||
|
||||
`karma-test-shim`告诉Karma哪些文件需要预加载,首要的是:带有“测试版供应商”的Angular测试框架是每个应用都希望预加载的。
|
||||
`karma-test-shim`告诉Karma哪些文件需要预加载,首要的是:带有“测试版提供商”的Angular测试框架是每个应用都希望预加载的。
|
||||
|
||||
+makeExample('webpack/ts/config/karma-test-shim.js', null, 'config/karma-test-shim.js')(format=".")
|
||||
|
||||
|
@ -722,7 +722,7 @@ p.
|
|||
The application imports these modules too; they'd be duplicated in the `app.js` bundle
|
||||
if the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `app.js`.
|
||||
|
||||
* `vendor.ts`由`import`供应商依赖的语句组成,它最终决定了`vender.js`的内容。
|
||||
* `vendor.ts`由`import`提供商依赖的语句组成,它最终决定了`vender.js`的内容。
|
||||
本应用也导入这些模块,如果没有`CommonsChunkPlugin`插件检测出这种重叠,并且把它们从`app.js`中移除,它们就会同时出现在`app.js`包中。
|
||||
|
||||
<a id="conclusions"></a>
|
||||
|
|
|
@ -737,7 +737,7 @@ h2#index 步骤4:添加#[code index.html]
|
|||
metadata, finds the `my-app` selector, locates an element tag named `my-app`,
|
||||
and renders our application's view between those tags.
|
||||
|
||||
当Angular在`main.ts`中调用`bootstrap`函数时,它读取`AppComponent`的元数据,
|
||||
当Angular在<span ngio-ex>main.ts</span>中调用`bootstrap`函数时,它读取`AppComponent`的元数据,
|
||||
发现选择器是`my-app`,于是它定位到一个元素名为`my-app`的DOM元素,并且把应用加载到这个标签中。
|
||||
:marked
|
||||
### Add some style
|
||||
|
|
|
@ -352,14 +352,14 @@ code-example(language="bash").
|
|||
|
||||
code-example(format="nocode").
|
||||
EXCEPTION: No provider for HeroService! (AppComponent -> HeroService)
|
||||
(异常:没有HeroService的供应商!(AppComponent -> HeroService))
|
||||
(异常:没有HeroService的提供商!(AppComponent -> HeroService))
|
||||
|
||||
:marked
|
||||
We have to teach the *injector* how to make a `HeroService` by registering a `HeroService` **provider**.
|
||||
Do that by adding the following `providers` array property to the bottom of the component metadata
|
||||
in the `@Component` call.
|
||||
|
||||
我们还得注册一个`HeroService`**供应商**,来告诉*注入器*如何创建`HeroService`。
|
||||
我们还得注册一个`HeroService`**提供商**,来告诉*注入器*如何创建`HeroService`。
|
||||
要做到这一点,我们应该在`@Component`组件的元数据底部添加`providers`数组属性如下:
|
||||
|
||||
+makeExcerpt('toh-4/ts/app/app.component.1.ts', 'providers')
|
||||
|
@ -642,7 +642,7 @@ a#child-component
|
|||
|
||||
* We defined our `HeroService` as a provider for our `AppComponent`.
|
||||
|
||||
* 我们把`HeroService`定义为`AppComponent`的一个供应商。
|
||||
* 我们把`HeroService`定义为`AppComponent`的一个提供商。
|
||||
|
||||
* We created mock hero data and imported them into our service.
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ block http-library
|
|||
:marked
|
||||
### Register (provide) *HTTP* services
|
||||
|
||||
### 注册(供应)*http*服务
|
||||
### 注册(提供)*http*服务
|
||||
|
||||
block http-providers
|
||||
:marked
|
||||
|
@ -87,14 +87,14 @@ block http-providers
|
|||
The `HTTP_PROVIDERS` array from `@angular/http` library holds providers for the complete set of http services.
|
||||
|
||||
我们的应用将会依赖于Angular的`http`服务,它本身又依赖于其它支持类服务。
|
||||
来自`@angular/http`库中的`HTTP_PROVIDERS`数组保存着这些http相关服务供应商的全集。
|
||||
来自`@angular/http`库中的`HTTP_PROVIDERS`数组保存着这些http相关服务提供商的全集。
|
||||
|
||||
:marked
|
||||
We should be able to access `!{_Http}` services from anywhere in the application.
|
||||
So we register them in the `bootstrap` call of <span ngio-ex>main.ts</span> where we
|
||||
launch the application and its root `AppComponent`.
|
||||
|
||||
我们要能从本应用的任何地方访问这些服务,所以,就要在`main.ts`中的`bootstrap`方法中注册它们。
|
||||
我们要能从本应用的任何地方访问这些服务,所以,就要在<span ngio-ex>main.ts</span>中的`bootstrap`方法中注册它们。
|
||||
这里同时也是我们启动应用及其根组件`AppComponent`的地方。
|
||||
|
||||
+makeExcerpt('app/main.ts','v1')
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Renders a link to a live/host example of the doc chapter
|
||||
* app this directive is contained in.
|
||||
*
|
||||
*
|
||||
* Usage:
|
||||
* <live-example [name="..."] [noSource] [srcText="..."]>text</live-example>
|
||||
* Example:
|
||||
|
@ -24,7 +24,7 @@ angularIO.directive('liveExample', ['$location', function ($location) {
|
|||
restrict: 'E',
|
||||
|
||||
compile: function (tElement, attrs) {
|
||||
var text = tElement.text() || 'live example';
|
||||
var text = tElement.text() || '在线例子';
|
||||
var ex = attrs.name || NgIoUtil.getExampleName($location);
|
||||
var href, template;
|
||||
|
||||
|
|
Loading…
Reference in New Issue