@@ -258,23 +397,40 @@ The following shows the new and the old implementations side-by-side.
## Predefined tokens and multiple providers
+## 预定义令牌与多提供商
+
Angular provides a number of built-in injection-token constants that you can use to customize the behavior of
various systems.
+Angular 提供了一些内置的注入令牌常量,你可以用它们来自定义系统的多种行为。
+
For example, you can use the following built-in tokens as hooks into the framework’s bootstrapping and initialization process.
A provider object can associate any of these injection tokens with one or more callback functions that take app-specific initialization actions.
+比如,你可以使用下列内置令牌来切入 Angular 框架的启动和初始化过程。
+提供商对象可以把任何一个注入令牌与一个或多个用来执行应用初始化操作的回调函数关联起来。
+
* [PLATFORM_INITIALIZER](api/core/PLATFORM_INITIALIZER): Callback is invoked when a platform is initialized.
+ [PLATFORM_INITIALIZER](api/core/PLATFORM_INITIALIZER):平台初始化之后调用的回调函数。
+
* [APP_BOOTSTRAP_LISTENER](api/core/APP_BOOTSTRAP_LISTENER): Callback is invoked for each component that is bootstrapped. The handler function receives the ComponentRef instance of the bootstrapped component.
+ [APP_BOOTSTRAP_LISTENER](api/core/APP_BOOTSTRAP_LISTENER):每个启动组件启动完成之后调用的回调函数。这个处理器函数会收到这个启动组件的 ComponentRef 实例。
+
* [APP_INITIALIZER](api/core/APP_INITIALIZER): Callback is invoked before an app is initialized. All registered initializers can optionally return a Promise. All initializer functions that return Promises must be resolved before the application is bootstrapped. If one of the initializers fails to resolves, the application is not bootstrapped.
+ [APP_INITIALIZER](api/core/APP_INITIALIZER):应用初始化之前调用的回调函数。注册的所有初始化器都可以(可选地)返回一个 Promise。所有返回 Promise 的初始化函数都必须在应用启动之前解析完。如果任何一个初始化器失败了,该应用就不会继续启动。
+
The provider object can have a third option, `multi: true`, which you can use with `APP_INITIALIZER`
to register multiple handlers for the provide event.
+该提供商对象还有第三个选项 `multi: true`,把它和 `APP_INITIALIZER` 一起使用可以为特定的事件注册多个处理器。
+
For example, when bootstrapping an application, you can register many initializers using the same token.
+比如,当启动应用时,你可以使用同一个令牌注册多个初始化器。
+
```
export const APP_TOKENS = [
{ provide: PLATFORM_INITIALIZER, useFactory: platformInitialized, multi: true },
@@ -288,15 +444,24 @@ For example, you can register a custom form validator using the built-in [NG_VAL
and provide multiple instances of a given validator provider by using the `multi: true` property in the provider object.
Angular adds your custom validators to the existing collection.
+在其它地方,多个提供商也同样可以和单个令牌关联起来。
+比如,你可以使用内置的 [NG_VALIDATORS](api/forms/NG_VALIDATORS) 令牌注册自定义表单验证器,还可以在提供商定义对象中使用 `multi: true` 属性来为指定的验证器令牌提供多个验证器实例。
+Angular 会把你的自定义验证器添加到现有验证器的集合中。
+
The Router also makes use of multiple providers associated with a single token.
When you provide multiple sets of routes using [RouterModule.forRoot](api/router/RouterModule#forroot)
and [RouterModule.forChild](api/router/RouterModule#forchild) in a single module,
the [ROUTES](api/router/ROUTES) token combines all the different provided sets of routes into a single value.
+路由器也同样用多个提供商关联到了一个令牌。
+当你在单个模块中用 [RouterModule.forRoot](api/router/RouterModule#forroot) 和 [RouterModule.forChild](api/router/RouterModule#forchild) 提供了多组路由时,[ROUTES](api/router/ROUTES) 令牌会把这些不同的路由组都合并成一个单一值。
+
Ideally, if an application isn't injecting a service, it shouldn't be included in the final output.
@@ -318,36 +489,59 @@ Angular can't identify all of the places in your code where this injection could
so it has no choice but to include the service in the injector.
Thus, services provided at the NgModule or component level are not tree-shakable.
+理想情况下,如果应用没有注入服务,它就不应该包含在最终输出中。
+不过,Angular 要能在构建期间识别出该服务是否需要。
+由于还可能用 `injector.get(Service)` 的形式直接注入服务,所以 Angular 无法准确识别出代码中可能发生此注入的全部位置,因此为保险起见,只能把服务包含在注入器中。
+因此,在 NgModule 或 组件级别提供的服务是无法被摇树优化掉的。
+
The following example of non-tree-shakable providers in Angular configures a service provider for the injector of an NgModule.
+下面这个不可摇树优化提供商的例子为 NgModule 注入器配置了一个服务提供商。
+
This module can then be imported into your application module
to make the service available for injection in your app,
as shown in the following example.
+该模块以后可以导入到你的应用模块中,以便该服务可注入到你的应用中,例子如下。
+
When `ngc` runs, it compiles `AppModule` into a module factory, which contains definitions for all the providers declared in all the modules it includes. At runtime, this factory becomes an injector that instantiates these services.
+当运行 `ngc` 时,它会把 `AppModule` 编译到模块工厂中,工厂包含该模块及其导入的所有模块中声明的所有提供商。在运行时,该工厂会变成负责实例化所有这些服务的注入器。
+
Tree-shaking doesn't work here because Angular can't decide to exclude one chunk of code (the provider definition for the service within the module factory) based on whether another chunk of code (the service class) is used. To make services tree-shakable, the information about how to construct an instance of the service (the provider definition) needs to be a part of the service class itself.
+这里摇树优化不起作用,因为 Angular 无法根据是否用到了其它代码块(服务类),来决定是否能排除这块代码(模块工厂中的服务提供商定义)。要让服务可以被摇树优化,关于如何构建该服务实例的信息(即提供商定义),就应该是服务类本身的一部分。
+
### Creating tree-shakable providers
+### 创建可摇树优化的提供商
+
You can make a provider tree-shakable by specifying it in the `@Injectable()` decorator on the service itself, rather than in the metadata for the NgModule or component that depends on the service.
+只要在服务本身的 `@Injectable()` 装饰器中指定,而不是在依赖该服务的 NgModule 或组件的元数据中指定,你就可以制作一个可摇树优化的提供商。
+
The following example shows the tree-shakable equivalent to the `ServiceModule` example above.
+下面的例子展示了与上面的 `ServiceModule` 例子等价的可摇树优化的版本。
+
The service can be instantiated by configuring a factory function, as in the following example.
+该服务还可以通过配置工厂函数来实例化,如下例所示。
+
To override a tree-shakable provider, configure the injector of a specific NgModule or component with another provider, using the `providers: []` array syntax of the `@NgModule()` or `@Component()` decorator.
-
\ No newline at end of file
+要想覆盖可摇树优化的提供商,请使用其它提供商来配置指定的 NgModule 或组件的注入器,只要使用 `@NgModule()` 或 `@Component()` 装饰器中的 `providers: []` 数组就可以了。
+
+