前面介绍过的,在@NgModule()或@Injectable()提供的服务称为ModuleInjector。在@Directive()或@Component()里提供的服务称为ElementInjector
- 服务查找规则
就近原则:优先查找ElementInjector => 父组件中ElementInjector=> ModuleInjector => 抛出错误
- 解析修饰符
默认情况下,Angular始终从当前的Injector开始,并一直向上搜索。使用修饰符可以更改开始(默认是自己)或结束位置
- 如果Angular找不到服务,用@Optional()阻止报错
constructor(@Optional() private mobileServe : MobileService)
- 用@SkipSelf()跳过自身,从父组件(指令)开始找
constructor(@Optional() @SkipSelf() private mobileServe : MobileService)
- 用@Self()只在当前组件(指令)开始找
constructor(@Optional() @Self() private mobileServe : MobileService)
- 用@Host()只在当前组件(指令)宿主上找
@Host属性装饰器会禁止宿主组件以上的搜索。宿主组件通常就是请求该依赖的那个组件。不过,当该组件投影进某个父组件时,那个父组件就会变成宿主。
constructor(@Host() private mobileServe : MobileService)
- 指定的ngModule注入
之前provideIn:'root'指定从根模块中提供该服务,也可以像下面这样指定其它模块提供服务
@Injectable({
provideIn:ComponentsModule
})
如果这么做,意味着这个服务无法在模块内部使用,会报一个循环依赖的错误,只能在其它引入了ComponentsModule的NgModule中,才能使用该服务
viewProviders
上面说了,组件会从自身开始寻找服务,然后遍历父组件的ElementInjector,直到找到为止。viewProviders也有这个特性,区别是,对投影内容不可见
<app-mobile-list>
<app-mobile-content></app-mobile-content>
</app-mobile-list>
MobileContent无法找到MobileList里,用viewProviders提供的服务
使用DI浏览组件树
- 在子组件中拿父组件的实例
constructor(readonly parent:ParentComponent)
- 通过父组件的类接口(implements)查找
网友评论