3.
依赖注入是分层的
bootstrap()
|-app-component
|-sub-component1
|-sub-component2
|-sub-sub-component21
当 Angulars DI 实例化组件或服务时,它会检查构造函数期望的参数并尝试查找匹配的提供者。
当sub-sub-component 被创建并且它有一个类似constructor(myService: MyService) 的构造函数时,如果找到匹配的提供者,DI 就会从sub-sub-components 提供者开始向上查找。如果它到达 `bootstrap() 并且仍然没有找到它,它会失败并显示错误消息。
对于层次结构中的每一层,只创建一个提供者实例。
当MyService 在bootstrap() 中注册为提供者时,任何请求MyService 的组件都将在bootstrap() 中创建的同一实例中传递。
当MyService也在sub-component2 中注册时,当sub-sub-component 请求MyService 时,它将从sub-component2 获得一个,因为这是它找到的第一个。当sub-component1 也请求MyService 时,DI 将返回bootstrap() 之一,因为向上的层次结构没有其他东西提供MyService。
如果您想与整个应用程序共享一些数据,只需在bootstrap()注册您要用于共享数据的服务即可。
1.
如果一个组件('子组件')有一个类似的构造函数
export class SubComponent {
constructor(private myService: MyService) {
}
someName: string;
clickHandler($event) {
this.myService.clickHappended = true;
this.someName = this.myService.loadNameFromServer();
}
}
然后将MyService 的引用分配给myService,SubComponent 中的代码可以读写MyServicess 字段并调用其方法。
4. 如果 someComponent 注入 someService,其中注入了 someService2,我是否需要在 someComponent 级别将它们都设置为提供者 [someService, someService2]?如果我已经在上层组件中注入了 someService2 somewere 或/和?
当 Angular 创建组件类或服务类时,它使用 DI。它查找请求类型的提供程序并创建一个实例或使用现有实例。当 DI 创建一个实例时,它会检查该类型的构造函数并再次查找这些类型的提供程序。这会在任意级别递归进行(即使在 DI 需要一些帮助的循环中)
所以,简短的回答:是的。由 DI 注入的所有东西都需要一个注册的提供者。
5. 为什么 HTTP_PROVIDERS 设置在引导级别?
HTTP_PROVIDERS 提供的类可以被整个应用程序重用。不需要为每个 HTTP 请求创建一个新实例,也不需要每个组件或服务都有自己的 Http 类实例。如果您希望特定组件使用不同的Http 类,您可以将该特定Http 类添加到该组件的提供程序列表中。此组件及其所有子组件将改为使用此提供程序。
export class MySpecialHttp {
}
@Component(selector: 'sub-sub',
providers: [provide(Http, {useClass: MySpecialHttp})]
export class SubSubComponent {
constructor(http: Http) {}
}
这里我们指示 DI,当SubSubComponent 或其子组件之一请求Http 时,改为传入MySpecialHttp。